diff --git a/src/bower_components/alameda/alameda.js b/src/bower_components/alameda/alameda.js
index 4f2a805250..4ac0f7496b 100644
--- a/src/bower_components/alameda/alameda.js
+++ b/src/bower_components/alameda/alameda.js
@@ -239,6 +239,7 @@ var requirejs, require, define;
}
function delayedError(e) {
+ console.log(e.stack);
return setTimeout(function() {
e.dynaId && trackedErrors[e.dynaId] || (trackedErrors[e.dynaId] = !0, req.onError(e))
}), e
@@ -265,7 +266,7 @@ var requirejs, require, define;
trackedErrors = obj(),
urlFetched = obj(),
bundlesMap = obj(),
- asyncResolve = Promise.resolve();
+ asyncResolve = Promise.resolve(undefined);
return load = "function" == typeof importScripts ? function(map) {
var url = map.url;
urlFetched[url] || (urlFetched[url] = !0, getDefer(map.id), importScripts(url), takeQueue(map.id))
@@ -415,4 +416,4 @@ var requirejs, require, define;
baseUrl: subPath
})), topReq([dataMain])))
}
-}(this, "undefined" != typeof Promise ? Promise : void 0);
\ No newline at end of file
+}(this, "undefined" != typeof Promise ? Promise : void 0);
diff --git a/src/bower_components/fetch/fetch.js b/src/bower_components/fetch/fetch.js
new file mode 100644
index 0000000000..cd40b3ed2d
--- /dev/null
+++ b/src/bower_components/fetch/fetch.js
@@ -0,0 +1,263 @@
+! function(self) {
+ "use strict";
+
+ function normalizeName(name) {
+ if ("string" != typeof name && (name = String(name)), /[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(name)) throw new TypeError("Invalid character in header field name");
+ return name.toLowerCase()
+ }
+
+ function normalizeValue(value) {
+ return "string" != typeof value && (value = String(value)), value
+ }
+
+ function iteratorFor(items) {
+ var iterator = {
+ next: function() {
+ var value = items.shift();
+ return {
+ done: void 0 === value,
+ value: value
+ }
+ }
+ };
+ return support.iterable && (iterator[Symbol.iterator] = function() {
+ return iterator
+ }), iterator
+ }
+
+ function Headers(headers) {
+ this.map = {}, headers instanceof Headers ? headers.forEach(function(value, name) {
+ this.append(name, value)
+ }, this) : headers && Object.getOwnPropertyNames(headers).forEach(function(name) {
+ this.append(name, headers[name])
+ }, this)
+ }
+
+ function consumed(body) {
+ if (body.bodyUsed) return Promise.reject(new TypeError("Already read"));
+ body.bodyUsed = !0
+ }
+
+ function fileReaderReady(reader) {
+ return new Promise(function(resolve, reject) {
+ reader.onload = function() {
+ resolve(reader.result)
+ }, reader.onerror = function() {
+ reject(reader.error)
+ }
+ })
+ }
+
+ function readBlobAsArrayBuffer(blob) {
+ var reader = new FileReader,
+ promise = fileReaderReady(reader);
+ return reader.readAsArrayBuffer(blob), promise
+ }
+
+ function readBlobAsText(blob) {
+ var reader = new FileReader,
+ promise = fileReaderReady(reader);
+ return reader.readAsText(blob), promise
+ }
+
+ function readArrayBufferAsText(buf) {
+ for (var view = new Uint8Array(buf), chars = new Array(view.length), i = 0; i < view.length; i++) chars[i] = String.fromCharCode(view[i]);
+ return chars.join("")
+ }
+
+ function bufferClone(buf) {
+ if (buf.slice) return buf.slice(0);
+ var view = new Uint8Array(buf.byteLength);
+ return view.set(new Uint8Array(buf)), view.buffer
+ }
+
+ function Body() {
+ return this.bodyUsed = !1, this._initBody = function(body) {
+ if (this._bodyInit = body, body)
+ if ("string" == typeof body) this._bodyText = body;
+ else if (support.blob && Blob.prototype.isPrototypeOf(body)) this._bodyBlob = body;
+ else if (support.formData && FormData.prototype.isPrototypeOf(body)) this._bodyFormData = body;
+ else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) this._bodyText = body.toString();
+ else if (support.arrayBuffer && support.blob && isDataView(body)) this._bodyArrayBuffer = bufferClone(body.buffer), this._bodyInit = new Blob([this._bodyArrayBuffer]);
+ else {
+ if (!support.arrayBuffer || !ArrayBuffer.prototype.isPrototypeOf(body) && !isArrayBufferView(body)) throw new Error("unsupported BodyInit type");
+ this._bodyArrayBuffer = bufferClone(body)
+ } else this._bodyText = "";
+ this.headers.get("content-type") || ("string" == typeof body ? this.headers.set("content-type", "text/plain;charset=UTF-8") : this._bodyBlob && this._bodyBlob.type ? this.headers.set("content-type", this._bodyBlob.type) : support.searchParams && URLSearchParams.prototype.isPrototypeOf(body) && this.headers.set("content-type", "application/x-www-form-urlencoded;charset=UTF-8"))
+ }, support.blob && (this.blob = function() {
+ var rejected = consumed(this);
+ if (rejected) return rejected;
+ if (this._bodyBlob) return Promise.resolve(this._bodyBlob);
+ if (this._bodyArrayBuffer) return Promise.resolve(new Blob([this._bodyArrayBuffer]));
+ if (this._bodyFormData) throw new Error("could not read FormData body as blob");
+ return Promise.resolve(new Blob([this._bodyText]))
+ }, this.arrayBuffer = function() {
+ return this._bodyArrayBuffer ? consumed(this) || Promise.resolve(this._bodyArrayBuffer) : this.blob().then(readBlobAsArrayBuffer)
+ }), this.text = function() {
+ var rejected = consumed(this);
+ if (rejected) return rejected;
+ if (this._bodyBlob) return readBlobAsText(this._bodyBlob);
+ if (this._bodyArrayBuffer) return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer));
+ if (this._bodyFormData) throw new Error("could not read FormData body as text");
+ return Promise.resolve(this._bodyText)
+ }, support.formData && (this.formData = function() {
+ return this.text().then(decode)
+ }), this.json = function() {
+ return this.text().then(JSON.parse)
+ }, this
+ }
+
+ function normalizeMethod(method) {
+ var upcased = method.toUpperCase();
+ return methods.indexOf(upcased) > -1 ? upcased : method
+ }
+
+ function Request(input, options) {
+ options = options || {};
+ var body = options.body;
+ if ("string" == typeof input) this.url = input;
+ else {
+ if (input.bodyUsed) throw new TypeError("Already read");
+ this.url = input.url, this.credentials = input.credentials, options.headers || (this.headers = new Headers(input.headers)), this.method = input.method, this.mode = input.mode, body || null == input._bodyInit || (body = input._bodyInit, input.bodyUsed = !0)
+ }
+ if (this.credentials = options.credentials || this.credentials || "omit", !options.headers && this.headers || (this.headers = new Headers(options.headers)), this.method = normalizeMethod(options.method || this.method || "GET"), this.mode = options.mode || this.mode || null, this.referrer = null, ("GET" === this.method || "HEAD" === this.method) && body) throw new TypeError("Body not allowed for GET or HEAD requests");
+ this._initBody(body)
+ }
+
+ function decode(body) {
+ var form = new FormData;
+ return body.trim().split("&").forEach(function(bytes) {
+ if (bytes) {
+ var split = bytes.split("="),
+ name = split.shift().replace(/\+/g, " "),
+ value = split.join("=").replace(/\+/g, " ");
+ form.append(decodeURIComponent(name), decodeURIComponent(value))
+ }
+ }), form
+ }
+
+ function parseHeaders(rawHeaders) {
+ var headers = new Headers;
+ return rawHeaders.split("\r\n").forEach(function(line) {
+ var parts = line.split(":"),
+ key = parts.shift().trim();
+ if (key) {
+ var value = parts.join(":").trim();
+ headers.append(key, value)
+ }
+ }), headers
+ }
+
+ function Response(bodyInit, options) {
+ options || (options = {}), this.type = "default", this.status = "status" in options ? options.status : 200, this.ok = this.status >= 200 && this.status < 300, this.statusText = "statusText" in options ? options.statusText : "OK", this.headers = new Headers(options.headers), this.url = options.url || "", this._initBody(bodyInit)
+ }
+ if (!self.fetch) {
+ var support = {
+ searchParams: "URLSearchParams" in self,
+ iterable: "Symbol" in self && "iterator" in Symbol,
+ blob: "FileReader" in self && "Blob" in self && function() {
+ try {
+ return new Blob, !0
+ } catch (e) {
+ return !1
+ }
+ }(),
+ formData: "FormData" in self,
+ arrayBuffer: "ArrayBuffer" in self
+ };
+ if (support.arrayBuffer) var viewClasses = ["[object Int8Array]", "[object Uint8Array]", "[object Uint8ClampedArray]", "[object Int16Array]", "[object Uint16Array]", "[object Int32Array]", "[object Uint32Array]", "[object Float32Array]", "[object Float64Array]"],
+ isDataView = function(obj) {
+ return obj && DataView.prototype.isPrototypeOf(obj)
+ },
+ isArrayBufferView = ArrayBuffer.isView || function(obj) {
+ return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1
+ };
+ Headers.prototype.append = function(name, value) {
+ name = normalizeName(name), value = normalizeValue(value);
+ var list = this.map[name];
+ list || (list = [], this.map[name] = list), list.push(value)
+ }, Headers.prototype.delete = function(name) {
+ delete this.map[normalizeName(name)]
+ }, Headers.prototype.get = function(name) {
+ var values = this.map[normalizeName(name)];
+ return values ? values[0] : null
+ }, Headers.prototype.getAll = function(name) {
+ return this.map[normalizeName(name)] || []
+ }, Headers.prototype.has = function(name) {
+ return this.map.hasOwnProperty(normalizeName(name))
+ }, Headers.prototype.set = function(name, value) {
+ this.map[normalizeName(name)] = [normalizeValue(value)]
+ }, Headers.prototype.forEach = function(callback, thisArg) {
+ Object.getOwnPropertyNames(this.map).forEach(function(name) {
+ this.map[name].forEach(function(value) {
+ callback.call(thisArg, value, name, this)
+ }, this)
+ }, this)
+ }, Headers.prototype.keys = function() {
+ var items = [];
+ return this.forEach(function(value, name) {
+ items.push(name)
+ }), iteratorFor(items)
+ }, Headers.prototype.values = function() {
+ var items = [];
+ return this.forEach(function(value) {
+ items.push(value)
+ }), iteratorFor(items)
+ }, Headers.prototype.entries = function() {
+ var items = [];
+ return this.forEach(function(value, name) {
+ items.push([name, value])
+ }), iteratorFor(items)
+ }, support.iterable && (Headers.prototype[Symbol.iterator] = Headers.prototype.entries);
+ var methods = ["DELETE", "GET", "HEAD", "OPTIONS", "POST", "PUT"];
+ Request.prototype.clone = function() {
+ return new Request(this, {
+ body: this._bodyInit
+ })
+ }, Body.call(Request.prototype), Body.call(Response.prototype), Response.prototype.clone = function() {
+ return new Response(this._bodyInit, {
+ status: this.status,
+ statusText: this.statusText,
+ headers: new Headers(this.headers),
+ url: this.url
+ })
+ }, Response.error = function() {
+ var response = new Response(null, {
+ status: 0,
+ statusText: ""
+ });
+ return response.type = "error", response
+ };
+ var redirectStatuses = [301, 302, 303, 307, 308];
+ Response.redirect = function(url, status) {
+ if (-1 === redirectStatuses.indexOf(status)) throw new RangeError("Invalid status code");
+ return new Response(null, {
+ status: status,
+ headers: {
+ location: url
+ }
+ })
+ }, self.Headers = Headers, self.Request = Request, self.Response = Response, self.fetch = function(input, init) {
+ return new Promise(function(resolve, reject) {
+ var request = new Request(input, init),
+ xhr = new XMLHttpRequest;
+ xhr.onload = function() {
+ var options = {
+ status: xhr.status,
+ statusText: xhr.statusText,
+ headers: parseHeaders(xhr.getAllResponseHeaders() || "")
+ };
+ options.url = "responseURL" in xhr ? xhr.responseURL : options.headers.get("X-Request-URL");
+ var body = "response" in xhr ? xhr.response : xhr.responseText;
+ resolve(new Response(body, options))
+ }, xhr.onerror = function() {
+ reject(new TypeError("Network request failed"))
+ }, xhr.ontimeout = function() {
+ reject(new TypeError("Network request failed"))
+ }, xhr.open(request.method, request.url, !0), "include" === request.credentials && (xhr.withCredentials = !0), "responseType" in xhr && support.blob && (xhr.responseType = "blob"), request.headers.forEach(function(value, name) {
+ xhr.setRequestHeader(name, value)
+ }), xhr.send(void 0 === request._bodyInit ? null : request._bodyInit)
+ })
+ }, self.fetch.polyfill = !0
+ }
+}("undefined" != typeof self ? self : this);
\ No newline at end of file
diff --git a/src/components/alert.js b/src/components/alert.js
index 0e8c16501f..6cf7fea75d 100644
--- a/src/components/alert.js
+++ b/src/components/alert.js
@@ -1,6 +1,11 @@
define(['browser', 'dialog', 'globalize'], function (browser, dialog, globalize) {
'use strict';
+ function replaceAll(originalString, strReplace, strWith) {
+ var reg = new RegExp(strReplace, 'ig');
+ return originalString.replace(reg, strWith);
+ }
+
return function (text, title) {
var options;
diff --git a/src/components/appRouter.js b/src/components/appRouter.js
index f9761d4d61..d79f3544a4 100644
--- a/src/components/appRouter.js
+++ b/src/components/appRouter.js
@@ -329,7 +329,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
events.on(appHost, 'resume', onAppResume);
connectionManager.connect({
-
enableAutoLogin: appSettings.enableAutoLogin()
}).then(function (result) {
@@ -343,7 +342,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
hashbang: options.hashbang !== false,
enableHistory: enableHistory()
});
- }).finally(function () {
+ }).catch().then(function() {
loading.hide();
});
}
diff --git a/src/components/apphost.js b/src/components/apphost.js
index 4106cac285..775fc9c7db 100644
--- a/src/components/apphost.js
+++ b/src/components/apphost.js
@@ -107,10 +107,10 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet
deviceName = browser.tizen ? "Samsung Smart TV" : browser.web0s ? "LG Smart TV" : browser.operaTv ? "Opera TV" : browser.xboxOne ? "Xbox One" : browser.ps4 ? "Sony PS4" : browser.chrome ? "Chrome" : browser.edge ? "Edge" : browser.firefox ? "Firefox" : browser.msie ? "Internet Explorer" : browser.opera ? "Opera" : "Web Browser";
if (browser.ipad) {
- deviceName += " Ipad";
+ deviceName += " iPad";
} else {
if (browser.iphone) {
- deviceName += " Iphone";
+ deviceName += " iPhone";
} else {
if (browser.android) {
deviceName += " Android";
diff --git a/src/components/fullscreenManager.js b/src/components/fullscreenManager.js
index 079267a6c4..360986cc54 100644
--- a/src/components/fullscreenManager.js
+++ b/src/components/fullscreenManager.js
@@ -79,10 +79,10 @@ define(['events', 'dom', 'apphost', 'browser'], function (events, dom, appHost,
passive: true
});
+ function isTargetValid(target) {
+ return !dom.parentWithTag(target, ['BUTTON', 'INPUT', 'TEXTAREA']);
+ }
if (appHost.supports("fullscreenchange") && (browser.edgeUwp || -1 !== navigator.userAgent.toLowerCase().indexOf("electron"))) {
- function isTargetValid(target) {
- return !dom.parentWithTag(target, ['BUTTON', 'INPUT', 'TEXTAREA']);
- }
dom.addEventListener(window, 'dblclick', function (e) {
diff --git a/src/components/playback/mediasession.js b/src/components/playback/mediasession.js
index b92e581b25..63e0bde6c1 100644
--- a/src/components/playback/mediasession.js
+++ b/src/components/playback/mediasession.js
@@ -273,11 +273,11 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f
events.on(currentPlayer, 'timeupdate', onGeneralEvent);
}
+ function execute(name) {
+ playbackManager[name](currentPlayer);
+ }
if (navigator.mediaSession) {
- function execute(name) {
- playbackManager[name](currentPlayer);
- }
navigator.mediaSession.setActionHandler('previoustrack', function () {
execute('previousTrack');
@@ -310,4 +310,4 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f
});
bindToPlayer(playbackManager.getCurrentPlayer());
-});
\ No newline at end of file
+});
diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js
index d9ea0a905b..5eb6011157 100644
--- a/src/components/playback/playbackmanager.js
+++ b/src/components/playback/playbackmanager.js
@@ -2576,7 +2576,6 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
} else {
- playerStartPositionTicks = null;
contentType = getMimeType(type.toLowerCase(), mediaSource.TranscodingContainer);
if (mediaUrl.toLowerCase().indexOf('copytimestamps=true') === -1) {
diff --git a/src/components/polyfills/objectassign.js b/src/components/polyfills/objectassign.js
new file mode 100644
index 0000000000..bf8d7118a5
--- /dev/null
+++ b/src/components/polyfills/objectassign.js
@@ -0,0 +1,23 @@
+if (typeof Object.assign != 'function') {
+ (function () {
+ Object.assign = function (target) {
+ 'use strict';
+ if (target === undefined || target === null) {
+ throw new TypeError('Cannot convert undefined or null to object');
+ }
+
+ var output = Object(target);
+ for (var index = 1; index < arguments.length; index++) {
+ var source = arguments[index];
+ if (source !== undefined && source !== null) {
+ for (var nextKey in source) {
+ if (source.hasOwnProperty(nextKey)) {
+ output[nextKey] = source[nextKey];
+ }
+ }
+ }
+ }
+ return output;
+ };
+ })();
+}
diff --git a/src/controllers/loginpage.js b/src/controllers/loginpage.js
index 1c291e4c20..57a1513f92 100644
--- a/src/controllers/loginpage.js
+++ b/src/controllers/loginpage.js
@@ -152,8 +152,7 @@ define(["apphost", "appSettings", "dom", "connectionManager", "loading", "cardSt
view.querySelector("#txtManualName").value = "";
showManualForm(view, false, false);
}
-
- }).finally(function () {
+ }).catch().then(function() {
loading.hide();
});
@@ -162,4 +161,4 @@ define(["apphost", "appSettings", "dom", "connectionManager", "loading", "cardSt
});
});
}
-});
\ No newline at end of file
+});
diff --git a/src/index.html b/src/index.html
index c27740295c..82526e5731 100644
--- a/src/index.html
+++ b/src/index.html
@@ -20,7 +20,46 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/manifest.json b/src/manifest.json
index 0ff87a92e5..a438ba9ccd 100644
--- a/src/manifest.json
+++ b/src/manifest.json
@@ -3,10 +3,11 @@
"name": "Jellyfin",
"description": "Jellyfin: the Free Software Media System.",
"lang": "en-US",
- "display": "minimal-ui",
- "short_name": "Emby",
+ "short_name": "Jellyfin",
"start_url": "/web/index.html",
"theme_color": "#101010",
+ "background_color": "#101010",
+ "display": "standalone",
"icons": [{
"sizes": "72x72",
"src": "touchicon72.png",
@@ -21,6 +22,11 @@
"sizes": "144x144",
"src": "touchicon144.png",
"type": "image/png"
+ },
+ {
+ "sizes": "512x512",
+ "src": "touchicon512.png",
+ "type": "image/png"
}
],
"related_applications": [{
diff --git a/src/scripts/site.js b/src/scripts/site.js
index 2832d69973..b56e9410a0 100644
--- a/src/scripts/site.js
+++ b/src/scripts/site.js
@@ -467,6 +467,13 @@ var AppInfo = {};
define("buttonenabled", ["legacy/buttonenabled"], returnFirstDependency);
var promises = [];
+ if (!window.fetch) {
+ promises.push(require(["fetch"]));
+ }
+ if ("function" != typeof Object.assign) {
+ promises.push(require(["objectassign"]));
+ }
+
Promise.all(promises).then(function () {
createConnectionManager().then(function () {
console.log("initAfterDependencies promises resolved");
@@ -818,6 +825,8 @@ var AppInfo = {};
define("jstree", ["thirdparty/jstree/jstree", "css!thirdparty/jstree/themes/default/style.css"], returnFirstDependency);
define("dashboardcss", ["css!css/dashboard"], returnFirstDependency);
define("slideshow", [componentsPath + "/slideshow/slideshow"], returnFirstDependency);
+ define("fetch", [bowerPath + "/fetch/fetch"], returnFirstDependency);
+ define("objectassign", [componentsPath + "/polyfills/objectassign"], returnFirstDependency);
define("clearButtonStyle", ["css!" + componentsPath + "/clearbutton"], returnFirstDependency);
define("userdataButtons", [componentsPath + "/userdatabuttons/userdatabuttons"], returnFirstDependency);
define("emby-playstatebutton", [componentsPath + "/userdatabuttons/emby-playstatebutton"], returnFirstDependency);
@@ -1135,7 +1144,7 @@ var AppInfo = {};
})();
require(["css!css/site"]);
-
+
return require(["browser"], onWebComponentsReady);
}();
pageClassOn("viewshow", "standalonePage", function () {
diff --git a/src/splashscreens/ipad_splash.png b/src/splashscreens/ipad_splash.png
new file mode 100755
index 0000000000..0faca927b7
Binary files /dev/null and b/src/splashscreens/ipad_splash.png differ
diff --git a/src/splashscreens/ipad_splash_l.png b/src/splashscreens/ipad_splash_l.png
new file mode 100644
index 0000000000..3ecf2d5adc
Binary files /dev/null and b/src/splashscreens/ipad_splash_l.png differ
diff --git a/src/splashscreens/ipadpro1_splash.png b/src/splashscreens/ipadpro1_splash.png
new file mode 100755
index 0000000000..9e7fdb7f6c
Binary files /dev/null and b/src/splashscreens/ipadpro1_splash.png differ
diff --git a/src/splashscreens/ipadpro1_splash_l.png b/src/splashscreens/ipadpro1_splash_l.png
new file mode 100644
index 0000000000..cffad337c8
Binary files /dev/null and b/src/splashscreens/ipadpro1_splash_l.png differ
diff --git a/src/splashscreens/ipadpro2_splash.png b/src/splashscreens/ipadpro2_splash.png
new file mode 100755
index 0000000000..a2e9624c65
Binary files /dev/null and b/src/splashscreens/ipadpro2_splash.png differ
diff --git a/src/splashscreens/ipadpro2_splash_l.png b/src/splashscreens/ipadpro2_splash_l.png
new file mode 100644
index 0000000000..588902a2b1
Binary files /dev/null and b/src/splashscreens/ipadpro2_splash_l.png differ
diff --git a/src/splashscreens/ipadpro3_splash.png b/src/splashscreens/ipadpro3_splash.png
new file mode 100755
index 0000000000..89a04afe07
Binary files /dev/null and b/src/splashscreens/ipadpro3_splash.png differ
diff --git a/src/splashscreens/ipadpro3_splash_l.png b/src/splashscreens/ipadpro3_splash_l.png
new file mode 100644
index 0000000000..a0b6c56904
Binary files /dev/null and b/src/splashscreens/ipadpro3_splash_l.png differ
diff --git a/src/splashscreens/iphone5_splash.png b/src/splashscreens/iphone5_splash.png
new file mode 100755
index 0000000000..3e073a9e1b
Binary files /dev/null and b/src/splashscreens/iphone5_splash.png differ
diff --git a/src/splashscreens/iphone5_splash_l.png b/src/splashscreens/iphone5_splash_l.png
new file mode 100644
index 0000000000..28fa8838e1
Binary files /dev/null and b/src/splashscreens/iphone5_splash_l.png differ
diff --git a/src/splashscreens/iphone6_splash.png b/src/splashscreens/iphone6_splash.png
new file mode 100755
index 0000000000..afe42fa26a
Binary files /dev/null and b/src/splashscreens/iphone6_splash.png differ
diff --git a/src/splashscreens/iphone6_splash_l.png b/src/splashscreens/iphone6_splash_l.png
new file mode 100644
index 0000000000..c7de58510f
Binary files /dev/null and b/src/splashscreens/iphone6_splash_l.png differ
diff --git a/src/splashscreens/iphoneplus_splash.png b/src/splashscreens/iphoneplus_splash.png
new file mode 100755
index 0000000000..2cc62163ac
Binary files /dev/null and b/src/splashscreens/iphoneplus_splash.png differ
diff --git a/src/splashscreens/iphoneplus_splash_l.png b/src/splashscreens/iphoneplus_splash_l.png
new file mode 100644
index 0000000000..c989f2237e
Binary files /dev/null and b/src/splashscreens/iphoneplus_splash_l.png differ
diff --git a/src/splashscreens/iphonex_splash.png b/src/splashscreens/iphonex_splash.png
new file mode 100755
index 0000000000..2d9698c287
Binary files /dev/null and b/src/splashscreens/iphonex_splash.png differ
diff --git a/src/splashscreens/iphonex_splash_l.png b/src/splashscreens/iphonex_splash_l.png
new file mode 100644
index 0000000000..9eb9e037ce
Binary files /dev/null and b/src/splashscreens/iphonex_splash_l.png differ
diff --git a/src/splashscreens/iphonexr_splash.png b/src/splashscreens/iphonexr_splash.png
new file mode 100755
index 0000000000..0f911eb2e8
Binary files /dev/null and b/src/splashscreens/iphonexr_splash.png differ
diff --git a/src/splashscreens/iphonexr_splash_l.png b/src/splashscreens/iphonexr_splash_l.png
new file mode 100644
index 0000000000..1522f372a9
Binary files /dev/null and b/src/splashscreens/iphonexr_splash_l.png differ
diff --git a/src/splashscreens/iphonexsmax_splash.png b/src/splashscreens/iphonexsmax_splash.png
new file mode 100755
index 0000000000..3e9aaf56af
Binary files /dev/null and b/src/splashscreens/iphonexsmax_splash.png differ
diff --git a/src/splashscreens/iphonexsmax_splash_l.png b/src/splashscreens/iphonexsmax_splash_l.png
new file mode 100644
index 0000000000..e2961f512e
Binary files /dev/null and b/src/splashscreens/iphonexsmax_splash_l.png differ
diff --git a/src/touchicon512.png b/src/touchicon512.png
new file mode 100644
index 0000000000..954bc25003
Binary files /dev/null and b/src/touchicon512.png differ