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:
commit
22cb92aefd
2 changed files with 95 additions and 28 deletions
|
@ -9,8 +9,64 @@ import 'material-design-icons-iconfont';
|
|||
import '../../styles/scrollstyles.scss';
|
||||
import '../../components/listview/listview.scss';
|
||||
|
||||
function getOffsets(elems) {
|
||||
const results = [];
|
||||
interface OptionItem {
|
||||
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) {
|
||||
return results;
|
||||
|
@ -30,12 +86,12 @@ function getOffsets(elems) {
|
|||
return results;
|
||||
}
|
||||
|
||||
function getPosition(options, dlg) {
|
||||
function getPosition(positionTo: Element, options: Options, dlg: HTMLElement) {
|
||||
const windowSize = dom.getWindowSize();
|
||||
const windowHeight = windowSize.innerHeight;
|
||||
const windowWidth = windowSize.innerWidth;
|
||||
|
||||
const pos = getOffsets([options.positionTo])[0];
|
||||
const pos = getOffsets([positionTo])[0];
|
||||
|
||||
if (options.positionY !== 'top') {
|
||||
pos.top += (pos.height || 0) / 2;
|
||||
|
@ -71,19 +127,22 @@ function getPosition(options, dlg) {
|
|||
return pos;
|
||||
}
|
||||
|
||||
function centerFocus(elem, horiz, on) {
|
||||
function centerFocus(elem: Element, horiz: boolean, on: boolean) {
|
||||
import('../../scripts/scrollHelper').then((scrollHelper) => {
|
||||
const fn = on ? 'on' : 'off';
|
||||
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
|
||||
// positionTo
|
||||
// showCancel
|
||||
// title
|
||||
const dialogOptions = {
|
||||
const dialogOptions: DialogOptions = {
|
||||
removeOnClose: true,
|
||||
enableHistory: options.enableHistory,
|
||||
scrollY: false
|
||||
|
@ -239,7 +298,10 @@ export function show(options) {
|
|||
dlg.innerHTML = html;
|
||||
|
||||
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');
|
||||
|
@ -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) {
|
||||
timeout = setTimeout(function () {
|
||||
dialogHelper.close(dlg);
|
||||
|
@ -259,16 +321,16 @@ export function show(options) {
|
|||
}
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
let isResolved;
|
||||
let isResolved = false;
|
||||
|
||||
dlg.addEventListener('click', function (e) {
|
||||
const actionSheetMenuItem = dom.parentWithClass(e.target, 'actionSheetMenuItem');
|
||||
const actionSheetMenuItem = dom.parentWithClass(e.target as HTMLElement, 'actionSheetMenuItem');
|
||||
|
||||
if (actionSheetMenuItem) {
|
||||
selectedId = actionSheetMenuItem.getAttribute('data-id');
|
||||
|
||||
if (options.resolveOnClick) {
|
||||
if (options.resolveOnClick.indexOf) {
|
||||
if (Array.isArray(options.resolveOnClick)) {
|
||||
if (options.resolveOnClick.indexOf(selectedId) !== -1) {
|
||||
resolve(selectedId);
|
||||
isResolved = true;
|
||||
|
@ -285,12 +347,15 @@ export function show(options) {
|
|||
|
||||
dlg.addEventListener('close', function () {
|
||||
if (layoutManager.tv) {
|
||||
centerFocus(dlg.querySelector('.actionSheetScroller'), false, false);
|
||||
const scroller = dlg.querySelector('.actionSheetScroller');
|
||||
if (scroller) {
|
||||
centerFocus(scroller, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
timeout = null;
|
||||
timeout = undefined;
|
||||
}
|
||||
|
||||
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) {
|
||||
dlg.style.position = 'fixed';
|
||||
dlg.style.margin = 0;
|
||||
dlg.style.margin = '0';
|
||||
dlg.style.left = pos.left + 'px';
|
||||
dlg.style.top = pos.top + 'px';
|
||||
}
|
|
@ -2,17 +2,17 @@ import focusManager from '../components/focusManager';
|
|||
import dom from './dom';
|
||||
import '../styles/scrollstyles.scss';
|
||||
|
||||
function getBoundingClientRect(elem) {
|
||||
function getBoundingClientRect(elem: Element) {
|
||||
// Support: BlackBerry 5, iOS 3 (original iPhone)
|
||||
// If we don't have gBCR, just use 0,0 rather than error
|
||||
if (elem.getBoundingClientRect) {
|
||||
return elem.getBoundingClientRect();
|
||||
} 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 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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
if (focused) {
|
||||
|
@ -89,16 +89,16 @@ function centerOnFocus(e, scrollSlider, horizontal) {
|
|||
}
|
||||
}
|
||||
|
||||
function centerOnFocusHorizontal(e) {
|
||||
function centerOnFocusHorizontal(this: HTMLElement, e: Event) {
|
||||
centerOnFocus(e, this, true);
|
||||
}
|
||||
|
||||
function centerOnFocusVertical(e) {
|
||||
function centerOnFocusVertical(this: HTMLElement, e: Event) {
|
||||
centerOnFocus(e, this, false);
|
||||
}
|
||||
|
||||
export const centerFocus = {
|
||||
on: function (element, horizontal) {
|
||||
on: function (element: Element, horizontal: boolean) {
|
||||
element.setAttribute(`data-scroll-mode-${horizontal ? 'x' : 'y'}`, 'custom');
|
||||
|
||||
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'}`);
|
||||
|
||||
if (horizontal) {
|
Loading…
Add table
Add a link
Reference in a new issue