1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

Merge pull request #5212 from terite/terite-more-typescript

This commit is contained in:
Bill Thornton 2024-02-23 10:56:42 -05:00 committed by GitHub
commit 22cb92aefd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 95 additions and 28 deletions

View file

@ -9,8 +9,64 @@ import 'material-design-icons-iconfont';
import '../../styles/scrollstyles.scss'; import '../../styles/scrollstyles.scss';
import '../../components/listview/listview.scss'; import '../../components/listview/listview.scss';
function getOffsets(elems) { interface OptionItem {
const results = []; asideText?: string;
divider?: boolean;
icon?: string;
id?: string;
innerText?: string;
name?: string;
secondaryText?: string;
selected?: boolean;
textContent?: string;
value?: string;
}
interface Options {
items: OptionItem[];
border?: boolean;
callback?: (id: string) => void;
dialogClass?: string;
enableHistory?: boolean;
entryAnimationDuration?: number;
entryAnimation?: string;
exitAnimationDuration?: number;
exitAnimation?: string;
menuItemClass?: string;
offsetLeft?: number;
offsetTop?: number;
positionTo?: Element | null;
positionY?: string;
resolveOnClick?: boolean | (string | null)[];
shaded?: boolean;
showCancel?: boolean;
text?: string;
timeout?: number;
title?: string;
}
interface Offset {
top: number;
left: number;
width: number;
height: number;
}
interface DialogOptions {
autoFocus?: boolean;
enableHistory?: boolean;
entryAnimationDuration?: number;
entryAnimation?: string;
exitAnimationDuration?: number;
exitAnimation?: string;
modal?: boolean;
removeOnClose?: boolean;
scrollY?: boolean;
size?: string;
}
function getOffsets(elems: Element[]): Offset[] {
const results: Offset[] = [];
if (!document) { if (!document) {
return results; return results;
@ -30,12 +86,12 @@ function getOffsets(elems) {
return results; return results;
} }
function getPosition(options, dlg) { function getPosition(positionTo: Element, options: Options, dlg: HTMLElement) {
const windowSize = dom.getWindowSize(); const windowSize = dom.getWindowSize();
const windowHeight = windowSize.innerHeight; const windowHeight = windowSize.innerHeight;
const windowWidth = windowSize.innerWidth; const windowWidth = windowSize.innerWidth;
const pos = getOffsets([options.positionTo])[0]; const pos = getOffsets([positionTo])[0];
if (options.positionY !== 'top') { if (options.positionY !== 'top') {
pos.top += (pos.height || 0) / 2; pos.top += (pos.height || 0) / 2;
@ -71,19 +127,22 @@ function getPosition(options, dlg) {
return pos; return pos;
} }
function centerFocus(elem, horiz, on) { function centerFocus(elem: Element, horiz: boolean, on: boolean) {
import('../../scripts/scrollHelper').then((scrollHelper) => { import('../../scripts/scrollHelper').then((scrollHelper) => {
const fn = on ? 'on' : 'off'; const fn = on ? 'on' : 'off';
scrollHelper.centerFocus[fn](elem, horiz); scrollHelper.centerFocus[fn](elem, horiz);
}).catch(e => {
console.warn('Error in centerFocus', e);
}); });
} }
export function show(options) { /* eslint-disable-next-line sonarjs/cognitive-complexity */
export function show(options: Options) {
// items // items
// positionTo // positionTo
// showCancel // showCancel
// title // title
const dialogOptions = { const dialogOptions: DialogOptions = {
removeOnClose: true, removeOnClose: true,
enableHistory: options.enableHistory, enableHistory: options.enableHistory,
scrollY: false scrollY: false
@ -239,7 +298,10 @@ export function show(options) {
dlg.innerHTML = html; dlg.innerHTML = html;
if (layoutManager.tv) { if (layoutManager.tv) {
centerFocus(dlg.querySelector('.actionSheetScroller'), false, true); const scroller = dlg.querySelector('.actionSheetScroller');
if (scroller) {
centerFocus(scroller, false, true);
}
} }
const btnCloseActionSheet = dlg.querySelector('.btnCloseActionSheet'); const btnCloseActionSheet = dlg.querySelector('.btnCloseActionSheet');
@ -249,9 +311,9 @@ export function show(options) {
}); });
} }
let selectedId; let selectedId: string | null = null;
let timeout; let timeout: ReturnType<typeof setTimeout> | undefined;
if (options.timeout) { if (options.timeout) {
timeout = setTimeout(function () { timeout = setTimeout(function () {
dialogHelper.close(dlg); dialogHelper.close(dlg);
@ -259,16 +321,16 @@ export function show(options) {
} }
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
let isResolved; let isResolved = false;
dlg.addEventListener('click', function (e) { dlg.addEventListener('click', function (e) {
const actionSheetMenuItem = dom.parentWithClass(e.target, 'actionSheetMenuItem'); const actionSheetMenuItem = dom.parentWithClass(e.target as HTMLElement, 'actionSheetMenuItem');
if (actionSheetMenuItem) { if (actionSheetMenuItem) {
selectedId = actionSheetMenuItem.getAttribute('data-id'); selectedId = actionSheetMenuItem.getAttribute('data-id');
if (options.resolveOnClick) { if (options.resolveOnClick) {
if (options.resolveOnClick.indexOf) { if (Array.isArray(options.resolveOnClick)) {
if (options.resolveOnClick.indexOf(selectedId) !== -1) { if (options.resolveOnClick.indexOf(selectedId) !== -1) {
resolve(selectedId); resolve(selectedId);
isResolved = true; isResolved = true;
@ -285,12 +347,15 @@ export function show(options) {
dlg.addEventListener('close', function () { dlg.addEventListener('close', function () {
if (layoutManager.tv) { if (layoutManager.tv) {
centerFocus(dlg.querySelector('.actionSheetScroller'), false, false); const scroller = dlg.querySelector('.actionSheetScroller');
if (scroller) {
centerFocus(scroller, false, false);
}
} }
if (timeout) { if (timeout) {
clearTimeout(timeout); clearTimeout(timeout);
timeout = null; timeout = undefined;
} }
if (!isResolved) { if (!isResolved) {
@ -306,13 +371,15 @@ export function show(options) {
} }
}); });
dialogHelper.open(dlg); dialogHelper.open(dlg).catch(e => {
console.warn('DialogHelper.open error', e);
});
const pos = options.positionTo && dialogOptions.size !== 'fullscreen' ? getPosition(options, dlg) : null; const pos = options.positionTo && dialogOptions.size !== 'fullscreen' ? getPosition(options.positionTo, options, dlg) : null;
if (pos) { if (pos) {
dlg.style.position = 'fixed'; dlg.style.position = 'fixed';
dlg.style.margin = 0; dlg.style.margin = '0';
dlg.style.left = pos.left + 'px'; dlg.style.left = pos.left + 'px';
dlg.style.top = pos.top + 'px'; dlg.style.top = pos.top + 'px';
} }

View file

@ -2,17 +2,17 @@ import focusManager from '../components/focusManager';
import dom from './dom'; import dom from './dom';
import '../styles/scrollstyles.scss'; import '../styles/scrollstyles.scss';
function getBoundingClientRect(elem) { function getBoundingClientRect(elem: Element) {
// Support: BlackBerry 5, iOS 3 (original iPhone) // Support: BlackBerry 5, iOS 3 (original iPhone)
// If we don't have gBCR, just use 0,0 rather than error // If we don't have gBCR, just use 0,0 rather than error
if (elem.getBoundingClientRect) { if (elem.getBoundingClientRect) {
return elem.getBoundingClientRect(); return elem.getBoundingClientRect();
} else { } else {
return { top: 0, left: 0 }; return { top: 0, left: 0, width: undefined, height: undefined };
} }
} }
export function getPosition(scrollContainer, item, horizontal) { export function getPosition(scrollContainer: HTMLElement, item: HTMLElement, horizontal: boolean) {
const slideeOffset = getBoundingClientRect(scrollContainer); const slideeOffset = getBoundingClientRect(scrollContainer);
const itemOffset = getBoundingClientRect(item); const itemOffset = getBoundingClientRect(item);
@ -41,7 +41,7 @@ export function getPosition(scrollContainer, item, horizontal) {
}; };
} }
export function toCenter(container, elem, horizontal, skipWhenVisible) { export function toCenter(container: HTMLElement, elem: HTMLElement, horizontal: boolean, skipWhenVisible?: boolean) {
const pos = getPosition(container, elem, horizontal); const pos = getPosition(container, elem, horizontal);
if (skipWhenVisible && pos.isVisible) { if (skipWhenVisible && pos.isVisible) {
@ -61,7 +61,7 @@ export function toCenter(container, elem, horizontal, skipWhenVisible) {
} }
} }
export function toStart(container, elem, horizontal, skipWhenVisible) { export function toStart(container: HTMLElement, elem: HTMLElement, horizontal: boolean, skipWhenVisible?: boolean) {
const pos = getPosition(container, elem, horizontal); const pos = getPosition(container, elem, horizontal);
if (skipWhenVisible && pos.isVisible) { if (skipWhenVisible && pos.isVisible) {
@ -81,7 +81,7 @@ export function toStart(container, elem, horizontal, skipWhenVisible) {
} }
} }
function centerOnFocus(e, scrollSlider, horizontal) { function centerOnFocus(e: Event, scrollSlider: HTMLElement, horizontal: boolean) {
const focused = focusManager.focusableParent(e.target); const focused = focusManager.focusableParent(e.target);
if (focused) { if (focused) {
@ -89,16 +89,16 @@ function centerOnFocus(e, scrollSlider, horizontal) {
} }
} }
function centerOnFocusHorizontal(e) { function centerOnFocusHorizontal(this: HTMLElement, e: Event) {
centerOnFocus(e, this, true); centerOnFocus(e, this, true);
} }
function centerOnFocusVertical(e) { function centerOnFocusVertical(this: HTMLElement, e: Event) {
centerOnFocus(e, this, false); centerOnFocus(e, this, false);
} }
export const centerFocus = { export const centerFocus = {
on: function (element, horizontal) { on: function (element: Element, horizontal: boolean) {
element.setAttribute(`data-scroll-mode-${horizontal ? 'x' : 'y'}`, 'custom'); element.setAttribute(`data-scroll-mode-${horizontal ? 'x' : 'y'}`, 'custom');
if (horizontal) { if (horizontal) {
@ -113,7 +113,7 @@ export const centerFocus = {
}); });
} }
}, },
off: function (element, horizontal) { off: function (element: Element, horizontal: boolean) {
element.removeAttribute(`data-scroll-mode-${horizontal ? 'x' : 'y'}`); element.removeAttribute(`data-scroll-mode-${horizontal ? 'x' : 'y'}`);
if (horizontal) { if (horizontal) {