2020-10-17 19:08:56 +01:00
|
|
|
import ServerConnections from '../components/ServerConnections';
|
2020-10-18 15:18:15 +01:00
|
|
|
import toast from '../components/toast/toast';
|
|
|
|
import loading from '../components/loading/loading';
|
2023-05-01 10:04:13 -04:00
|
|
|
import { appRouter } from '../components/router/appRouter';
|
2020-10-18 15:18:15 +01:00
|
|
|
import baseAlert from '../components/alert';
|
|
|
|
import baseConfirm from '../components/confirm/confirm';
|
2020-10-18 20:00:39 +01:00
|
|
|
import globalize from '../scripts/globalize';
|
2022-04-10 02:22:13 -04:00
|
|
|
import * as webSettings from '../scripts/settings/webSettings';
|
2021-06-11 03:32:34 +03:00
|
|
|
import datetime from '../scripts/datetime';
|
2022-04-12 16:22:00 -04:00
|
|
|
import { setBackdropTransparency } from '../components/backdrop/backdrop';
|
2021-09-08 02:46:43 +03:00
|
|
|
import DirectoryBrowser from '../components/directorybrowser/directorybrowser';
|
2021-06-11 03:32:34 +03:00
|
|
|
import dialogHelper from '../components/dialogHelper/dialogHelper';
|
2021-06-11 23:59:57 +03:00
|
|
|
import itemIdentifier from '../components/itemidentifier/itemidentifier';
|
2022-04-10 02:22:13 -04:00
|
|
|
import { getLocationSearch } from './url.ts';
|
2024-06-01 18:42:06 -04:00
|
|
|
import { queryClient } from './query/queryClient';
|
|
|
|
import viewContainer from 'components/viewContainer';
|
2020-08-14 05:48:59 +02:00
|
|
|
|
2020-08-08 15:26:03 +02:00
|
|
|
export function getCurrentUser() {
|
|
|
|
return window.ApiClient.getCurrentUser(false);
|
|
|
|
}
|
|
|
|
|
2020-09-10 23:20:55 +09:00
|
|
|
// TODO: investigate url prefix support for serverAddress function
|
|
|
|
export async function serverAddress() {
|
2023-05-18 18:14:12 -04:00
|
|
|
const apiClient = window.ApiClient ?? ServerConnections.currentApiClient();
|
2020-08-08 15:26:03 +02:00
|
|
|
|
2020-09-10 23:20:55 +09:00
|
|
|
if (apiClient) {
|
|
|
|
return Promise.resolve(apiClient.serverAddress());
|
2020-08-08 15:26:03 +02:00
|
|
|
}
|
|
|
|
|
2020-11-22 04:07:29 +01:00
|
|
|
// Use servers specified in config.json
|
|
|
|
const urls = await webSettings.getServers();
|
2020-11-22 15:07:12 +01:00
|
|
|
|
2021-05-09 10:43:16 +03:00
|
|
|
if (urls.length === 0) {
|
|
|
|
// Otherwise use computed base URL
|
2021-09-20 00:22:56 +03:00
|
|
|
let url;
|
2020-11-22 04:07:29 +01:00
|
|
|
const index = window.location.href.toLowerCase().lastIndexOf('/web');
|
|
|
|
if (index != -1) {
|
2021-09-20 00:22:56 +03:00
|
|
|
url = window.location.href.substring(0, index);
|
2020-11-22 04:07:29 +01:00
|
|
|
} else {
|
2020-11-26 16:46:55 +01:00
|
|
|
// fallback to location without path
|
2021-09-20 00:22:56 +03:00
|
|
|
url = window.location.origin;
|
2020-11-22 15:07:12 +01:00
|
|
|
}
|
2021-09-20 00:22:56 +03:00
|
|
|
|
|
|
|
// Don't use bundled app URL (file:) as server URL
|
|
|
|
if (url.startsWith('file:')) {
|
|
|
|
return Promise.resolve();
|
|
|
|
}
|
|
|
|
|
|
|
|
urls.push(url);
|
2020-11-22 15:07:12 +01:00
|
|
|
}
|
|
|
|
|
2020-11-24 20:44:14 +01:00
|
|
|
console.debug('URL candidates:', urls);
|
2020-11-22 15:07:12 +01:00
|
|
|
|
2020-09-12 09:12:40 +09:00
|
|
|
const promises = urls.map(url => {
|
2022-07-01 12:06:41 -04:00
|
|
|
return fetch(`${url}/System/Info/Public`)
|
|
|
|
.then(async resp => {
|
|
|
|
if (!resp.ok) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-10-20 13:48:03 -04:00
|
|
|
let config;
|
|
|
|
try {
|
|
|
|
config = await resp.json();
|
|
|
|
} catch (err) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-07-01 12:06:41 -04:00
|
|
|
return {
|
2022-07-11 10:26:28 -04:00
|
|
|
url,
|
2023-10-20 13:48:03 -04:00
|
|
|
config
|
2022-07-01 12:06:41 -04:00
|
|
|
};
|
2022-07-11 10:26:28 -04:00
|
|
|
}).catch(error => {
|
|
|
|
console.error(error);
|
|
|
|
});
|
2020-09-10 23:20:55 +09:00
|
|
|
});
|
2020-08-08 15:26:03 +02:00
|
|
|
|
2020-09-10 23:20:55 +09:00
|
|
|
return Promise.all(promises).then(responses => {
|
2022-07-01 12:06:41 -04:00
|
|
|
return responses.filter(obj => obj?.config);
|
2020-11-22 15:07:12 +01:00
|
|
|
}).then(configs => {
|
2020-11-24 21:20:05 +01:00
|
|
|
const selection = configs.find(obj => !obj.config.StartupWizardCompleted) || configs[0];
|
2022-07-01 12:06:41 -04:00
|
|
|
return selection?.url;
|
2020-11-07 16:02:28 +09:00
|
|
|
}).catch(error => {
|
2022-07-11 10:26:28 -04:00
|
|
|
console.error(error);
|
2020-09-10 23:20:55 +09:00
|
|
|
});
|
2020-08-08 15:26:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export function getCurrentUserId() {
|
2020-08-14 05:48:59 +02:00
|
|
|
const apiClient = window.ApiClient;
|
2020-08-08 15:26:03 +02:00
|
|
|
|
|
|
|
if (apiClient) {
|
|
|
|
return apiClient.getCurrentUserId();
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2022-04-11 10:33:58 -04:00
|
|
|
export function onServerChanged(_userId, _accessToken, apiClient) {
|
2020-10-17 19:08:56 +01:00
|
|
|
ServerConnections.setLocalApiClient(apiClient);
|
2020-08-08 15:26:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export function logout() {
|
2020-10-17 19:08:56 +01:00
|
|
|
ServerConnections.logout().then(function () {
|
2024-06-01 18:42:06 -04:00
|
|
|
// Clear the query cache
|
|
|
|
queryClient.clear();
|
|
|
|
// Reset cached views
|
|
|
|
viewContainer.reset();
|
2020-09-10 23:20:55 +09:00
|
|
|
webSettings.getMultiServer().then(multi => {
|
|
|
|
multi ? navigate('selectserver.html') : navigate('login.html');
|
|
|
|
});
|
2020-08-08 15:26:03 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-09-02 20:50:32 +09:00
|
|
|
export function getPluginUrl(name) {
|
2020-12-06 22:33:00 +03:00
|
|
|
return 'configurationpage?name=' + encodeURIComponent(name);
|
2020-08-08 15:26:03 +02:00
|
|
|
}
|
|
|
|
|
2021-06-14 02:21:15 +03:00
|
|
|
export function getConfigurationResourceUrl(name) {
|
|
|
|
return ApiClient.getUrl('web/ConfigurationPage', {
|
|
|
|
name: name
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-05-02 11:24:53 -04:00
|
|
|
/**
|
|
|
|
* Navigate to a url.
|
|
|
|
* @param {string} url - The url to navigate to.
|
|
|
|
* @param {boolean} [preserveQueryString] - A flag to indicate the current query string should be appended to the new url.
|
|
|
|
* @returns {Promise<any>}
|
|
|
|
*/
|
2020-08-08 15:26:03 +02:00
|
|
|
export function navigate(url, preserveQueryString) {
|
|
|
|
if (!url) {
|
|
|
|
throw new Error('url cannot be null or empty');
|
|
|
|
}
|
|
|
|
|
2022-04-07 16:06:26 -04:00
|
|
|
const queryString = getLocationSearch();
|
2020-08-08 15:26:03 +02:00
|
|
|
|
|
|
|
if (preserveQueryString && queryString) {
|
|
|
|
url += queryString;
|
|
|
|
}
|
|
|
|
|
2020-10-18 15:18:15 +01:00
|
|
|
return appRouter.show(url);
|
2020-08-08 15:26:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export function processPluginConfigurationUpdateResult() {
|
2020-10-18 15:18:15 +01:00
|
|
|
loading.hide();
|
2020-11-07 12:04:37 +00:00
|
|
|
toast(globalize.translate('SettingsSaved'));
|
2020-08-08 15:26:03 +02:00
|
|
|
}
|
|
|
|
|
2021-01-26 22:20:12 -05:00
|
|
|
export function processServerConfigurationUpdateResult() {
|
2020-10-18 15:18:15 +01:00
|
|
|
loading.hide();
|
2020-11-07 12:09:46 +00:00
|
|
|
toast(globalize.translate('SettingsSaved'));
|
2020-08-08 15:26:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export function processErrorResponse(response) {
|
2020-10-18 15:18:15 +01:00
|
|
|
loading.hide();
|
2020-08-08 15:26:03 +02:00
|
|
|
|
2020-08-14 05:48:59 +02:00
|
|
|
let status = '' + response.status;
|
2020-08-08 15:26:03 +02:00
|
|
|
|
|
|
|
if (response.statusText) {
|
|
|
|
status = response.statusText;
|
|
|
|
}
|
|
|
|
|
2021-05-26 13:17:32 -04:00
|
|
|
baseAlert({
|
2020-08-08 15:26:03 +02:00
|
|
|
title: status,
|
2021-05-26 13:17:32 -04:00
|
|
|
text: response.headers ? response.headers.get('X-Application-Error-Code') : null
|
2020-08-08 15:26:03 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
export function alert(options) {
|
|
|
|
if (typeof options == 'string') {
|
2020-11-08 11:01:05 +00:00
|
|
|
toast({
|
2020-10-18 15:18:15 +01:00
|
|
|
text: options
|
2020-08-08 15:26:03 +02:00
|
|
|
});
|
2020-10-18 15:18:15 +01:00
|
|
|
} else {
|
2020-11-08 10:58:30 +00:00
|
|
|
baseAlert({
|
2020-10-18 20:00:39 +01:00
|
|
|
title: options.title || globalize.translate('HeaderAlert'),
|
2020-08-08 15:26:03 +02:00
|
|
|
text: options.message
|
2022-03-01 10:57:48 -05:00
|
|
|
}).then(options.callback || function () { /* no-op */ });
|
2020-10-18 15:18:15 +01:00
|
|
|
}
|
2020-08-08 15:26:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export function capabilities(appHost) {
|
2020-10-22 00:36:38 +01:00
|
|
|
return Object.assign({
|
2020-08-08 15:26:03 +02:00
|
|
|
PlayableMediaTypes: ['Audio', 'Video'],
|
|
|
|
SupportedCommands: ['MoveUp', 'MoveDown', 'MoveLeft', 'MoveRight', 'PageUp', 'PageDown', 'PreviousLetter', 'NextLetter', 'ToggleOsd', 'ToggleContextMenu', 'Select', 'Back', 'SendKey', 'SendString', 'GoHome', 'GoToSettings', 'VolumeUp', 'VolumeDown', 'Mute', 'Unmute', 'ToggleMute', 'SetVolume', 'SetAudioStreamIndex', 'SetSubtitleStreamIndex', 'DisplayContent', 'GoToSearch', 'DisplayMessage', 'SetRepeatMode', 'SetShuffleQueue', 'ChannelUp', 'ChannelDown', 'PlayMediaSource', 'PlayTrailers'],
|
2020-08-25 10:12:35 +09:00
|
|
|
SupportsPersistentIdentifier: window.appMode === 'cordova' || window.appMode === 'android',
|
2020-08-08 15:26:03 +02:00
|
|
|
SupportsMediaControl: true
|
2020-10-22 00:36:38 +01:00
|
|
|
}, appHost.getPushTokenInfo());
|
2020-08-08 15:26:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export function selectServer() {
|
|
|
|
if (window.NativeShell && typeof window.NativeShell.selectServer === 'function') {
|
|
|
|
window.NativeShell.selectServer();
|
|
|
|
} else {
|
|
|
|
navigate('selectserver.html');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function hideLoadingMsg() {
|
2020-10-18 15:18:15 +01:00
|
|
|
loading.hide();
|
2020-08-08 15:26:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export function showLoadingMsg() {
|
2020-10-18 15:18:15 +01:00
|
|
|
loading.show();
|
2020-08-08 15:26:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export function confirm(message, title, callback) {
|
2020-10-18 15:18:15 +01:00
|
|
|
baseConfirm(message, title).then(function() {
|
2020-11-07 12:05:09 +00:00
|
|
|
callback(true);
|
2020-10-18 15:18:15 +01:00
|
|
|
}).catch(function() {
|
2020-11-07 12:05:09 +00:00
|
|
|
callback(false);
|
2020-08-08 15:26:03 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-11-09 00:14:33 +00:00
|
|
|
export const pageClassOn = function(eventName, className, fn) {
|
|
|
|
document.addEventListener(eventName, function (event) {
|
|
|
|
const target = event.target;
|
|
|
|
|
|
|
|
if (target.classList.contains(className)) {
|
|
|
|
fn.call(target, event);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
export const pageIdOn = function(eventName, id, fn) {
|
|
|
|
document.addEventListener(eventName, function (event) {
|
|
|
|
const target = event.target;
|
|
|
|
|
|
|
|
if (target.id === id) {
|
|
|
|
fn.call(target, event);
|
|
|
|
}
|
|
|
|
});
|
2020-08-08 15:26:03 +02:00
|
|
|
};
|
|
|
|
|
2020-10-12 23:08:55 +01:00
|
|
|
const Dashboard = {
|
2020-08-08 15:26:03 +02:00
|
|
|
alert,
|
|
|
|
capabilities,
|
|
|
|
confirm,
|
2020-09-02 20:50:32 +09:00
|
|
|
getPluginUrl,
|
2021-06-14 02:21:15 +03:00
|
|
|
getConfigurationResourceUrl,
|
2020-08-08 15:26:03 +02:00
|
|
|
getCurrentUser,
|
|
|
|
getCurrentUserId,
|
|
|
|
hideLoadingMsg,
|
|
|
|
logout,
|
|
|
|
navigate,
|
|
|
|
onServerChanged,
|
|
|
|
processErrorResponse,
|
|
|
|
processPluginConfigurationUpdateResult,
|
|
|
|
processServerConfigurationUpdateResult,
|
|
|
|
selectServer,
|
|
|
|
serverAddress,
|
2021-06-11 03:32:34 +03:00
|
|
|
showLoadingMsg,
|
|
|
|
datetime,
|
2021-06-11 20:29:07 +03:00
|
|
|
DirectoryBrowser,
|
2021-06-11 23:59:57 +03:00
|
|
|
dialogHelper,
|
2022-04-12 16:22:00 -04:00
|
|
|
itemIdentifier,
|
|
|
|
setBackdropTransparency
|
2020-08-08 15:26:03 +02:00
|
|
|
};
|
|
|
|
|
2020-10-12 23:08:55 +01:00
|
|
|
// This is used in plugins and templates, so keep it defined for now.
|
|
|
|
// TODO: Remove once plugins don't need it
|
|
|
|
window.Dashboard = Dashboard;
|
|
|
|
|
|
|
|
export default Dashboard;
|