implement reduced motion

closes #1410
pull/1452/head
Mikael Finstad 2023-02-16 13:14:15 +08:00
rodzic c5374d0859
commit e9840d793d
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 25AB36E3E81CBC26
17 zmienionych plików z 84 dodań i 37 usunięć

Wyświetl plik

@ -61,12 +61,13 @@ import { shouldCopyStreamByDefault, getAudioStreams, getRealVideoStreams, isAudi
import { exportEdlFile, readEdlFile, saveLlcProject, loadLlcProject, askForEdlImport } from './edlStore'; import { exportEdlFile, readEdlFile, saveLlcProject, loadLlcProject, askForEdlImport } from './edlStore';
import { formatYouTube, getFrameCountRaw } from './edlFormats'; import { formatYouTube, getFrameCountRaw } from './edlFormats';
import { import {
getOutPath, getSuffixedOutPath, toast, errorToast, handleError, getOutDir, getFileDir, getOutPath, getSuffixedOutPath, handleError, getOutDir, getFileDir,
checkDirWriteAccess, dirExists, isMasBuild, isStoreBuild, dragPreventer, checkDirWriteAccess, dirExists, isMasBuild, isStoreBuild, dragPreventer,
filenamify, getOutFileExtension, generateSegFileName, defaultOutSegTemplate, filenamify, getOutFileExtension, generateSegFileName, defaultOutSegTemplate,
havePermissionToReadFile, resolvePathIfNeeded, getPathReadAccessError, html5ifiedPrefix, html5dummySuffix, findExistingHtml5FriendlyFile, havePermissionToReadFile, resolvePathIfNeeded, getPathReadAccessError, html5ifiedPrefix, html5dummySuffix, findExistingHtml5FriendlyFile,
deleteFiles, isOutOfSpaceError, getNumDigits, isExecaFailure, readFileSize, readFileSizes, checkFileSizes, setDocumentTitle, deleteFiles, isOutOfSpaceError, getNumDigits, isExecaFailure, readFileSize, readFileSizes, checkFileSizes, setDocumentTitle,
} from './util'; } from './util';
import { toast, errorToast } from './swal';
import { formatDuration } from './util/duration'; import { formatDuration } from './util/duration';
import { adjustRate } from './util/rate-calculator'; import { adjustRate } from './util/rate-calculator';
import { askExtractFramesAsImages } from './dialogs/extractFrames'; import { askExtractFramesAsImages } from './dialogs/extractFrames';

Wyświetl plik

@ -16,7 +16,8 @@ import ToggleExportConfirm from './components/ToggleExportConfirm';
import CaptureFormatButton from './components/CaptureFormatButton'; import CaptureFormatButton from './components/CaptureFormatButton';
import SimpleModeButton from './components/SimpleModeButton'; import SimpleModeButton from './components/SimpleModeButton';
import { withBlur, toast, mirrorTransform, checkAppPath } from './util'; import { withBlur, mirrorTransform, checkAppPath } from './util';
import { toast } from './swal';
import { getSegColor } from './util/colors'; import { getSegColor } from './util/colors';
import { formatDuration, parseDuration } from './util/duration'; import { formatDuration, parseDuration } from './util/duration';
import useUserSettings from './hooks/useUserSettings'; import useUserSettings from './hooks/useUserSettings';

Wyświetl plik

@ -15,7 +15,8 @@ import ToggleExportConfirm from './components/ToggleExportConfirm';
import OutSegTemplateEditor from './components/OutSegTemplateEditor'; import OutSegTemplateEditor from './components/OutSegTemplateEditor';
import HighlightedText from './components/HighlightedText'; import HighlightedText from './components/HighlightedText';
import { withBlur, toast } from './util'; import { withBlur } from './util';
import { toast } from './swal';
import { isMov as ffmpegIsMov } from './util/streams'; import { isMov as ffmpegIsMov } from './util/streams';
import useUserSettings from './hooks/useUserSettings'; import useUserSettings from './hooks/useUserSettings';

Wyświetl plik

@ -2,13 +2,13 @@ import React, { memo, useMemo, useRef, useCallback } from 'react';
import { FaYinYang, FaSave, FaPlus, FaMinus, FaTag, FaSortNumericDown, FaAngleRight, FaRegCheckCircle, FaRegCircle } from 'react-icons/fa'; import { FaYinYang, FaSave, FaPlus, FaMinus, FaTag, FaSortNumericDown, FaAngleRight, FaRegCheckCircle, FaRegCircle } from 'react-icons/fa';
import { AiOutlineSplitCells } from 'react-icons/ai'; import { AiOutlineSplitCells } from 'react-icons/ai';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import Swal from 'sweetalert2';
import { useTranslation, Trans } from 'react-i18next'; import { useTranslation, Trans } from 'react-i18next';
import { ReactSortable } from 'react-sortablejs'; import { ReactSortable } from 'react-sortablejs';
import isEqual from 'lodash/isEqual'; import isEqual from 'lodash/isEqual';
import useDebounce from 'react-use/lib/useDebounce'; import useDebounce from 'react-use/lib/useDebounce';
import scrollIntoView from 'scroll-into-view-if-needed'; import scrollIntoView from 'scroll-into-view-if-needed';
import Swal from './swal';
import useContextMenu from './hooks/useContextMenu'; import useContextMenu from './hooks/useContextMenu';
import useUserSettings from './hooks/useUserSettings'; import useUserSettings from './hooks/useUserSettings';
import { saveColor, controlsBackground, primaryTextColor } from './colors'; import { saveColor, controlsBackground, primaryTextColor } from './colors';

Wyświetl plik

@ -4,9 +4,9 @@ import { TextInput, IconButton, Alert, Checkbox, Dialog, Button, Paragraph } fro
import { AiOutlineMergeCells } from 'react-icons/ai'; import { AiOutlineMergeCells } from 'react-icons/ai';
import { FaQuestionCircle, FaCheckCircle, FaExclamationTriangle } from 'react-icons/fa'; import { FaQuestionCircle, FaCheckCircle, FaExclamationTriangle } from 'react-icons/fa';
import i18n from 'i18next'; import i18n from 'i18next';
import Swal from 'sweetalert2';
import withReactContent from 'sweetalert2-react-content'; import withReactContent from 'sweetalert2-react-content';
import Swal from '../swal';
import { readFileMeta, getSmarterOutFormat } from '../ffmpeg'; import { readFileMeta, getSmarterOutFormat } from '../ffmpeg';
import useFileFormatState from '../hooks/useFileFormatState'; import useFileFormatState from '../hooks/useFileFormatState';
import OutputFormatSelect from './OutputFormatSelect'; import OutputFormatSelect from './OutputFormatSelect';

Wyświetl plik

@ -3,9 +3,9 @@ import { useDebounce } from 'use-debounce';
import i18n from 'i18next'; import i18n from 'i18next';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Text, Button, Alert, IconButton, TickIcon, ResetIcon, Heading } from 'evergreen-ui'; import { Text, Button, Alert, IconButton, TickIcon, ResetIcon, Heading } from 'evergreen-ui';
import Swal from 'sweetalert2';
import withReactContent from 'sweetalert2-react-content'; import withReactContent from 'sweetalert2-react-content';
import Swal from '../swal';
import HighlightedText from './HighlightedText'; import HighlightedText from './HighlightedText';
import { defaultOutSegTemplate } from '../util'; import { defaultOutSegTemplate } from '../util';
import useUserSettings from '../hooks/useUserSettings'; import useUserSettings from '../hooks/useUserSettings';

Wyświetl plik

@ -1,6 +1,7 @@
import Swal from 'sweetalert2';
import i18n from 'i18next'; import i18n from 'i18next';
import Swal from '../swal';
// eslint-disable-next-line import/prefer-default-export // eslint-disable-next-line import/prefer-default-export
export async function askExtractFramesAsImages({ segmentNumFrames, fps }) { export async function askExtractFramesAsImages({ segmentNumFrames, fps }) {

Wyświetl plik

@ -1,9 +1,11 @@
import React, { useState, useCallback } from 'react'; import React, { useState, useCallback } from 'react';
import { Checkbox, RadioGroup, Paragraph } from 'evergreen-ui'; import { Checkbox, RadioGroup, Paragraph } from 'evergreen-ui';
import Swal from 'sweetalert2';
import i18n from 'i18next'; import i18n from 'i18next';
import withReactContent from 'sweetalert2-react-content'; import withReactContent from 'sweetalert2-react-content';
import Swal from '../swal';
const ReactSwal = withReactContent(Swal); const ReactSwal = withReactContent(Swal);

Wyświetl plik

@ -1,6 +1,5 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { HelpIcon, TickCircleIcon, WarningSignIcon, InfoSignIcon, Checkbox } from 'evergreen-ui'; import { HelpIcon, TickCircleIcon, WarningSignIcon, InfoSignIcon, Checkbox } from 'evergreen-ui';
import Swal from 'sweetalert2';
import i18n from 'i18next'; import i18n from 'i18next';
import { Trans } from 'react-i18next'; import { Trans } from 'react-i18next';
import withReactContent from 'sweetalert2-react-content'; import withReactContent from 'sweetalert2-react-content';
@ -9,7 +8,7 @@ import { tomorrow as style } from 'react-syntax-highlighter/dist/esm/styles/hljs
import JSON5 from 'json5'; import JSON5 from 'json5';
import { parseDuration, formatDuration } from '../util/duration'; import { parseDuration, formatDuration } from '../util/duration';
import { swalToastOptions, toast } from '../util'; import Swal, { swalToastOptions, toast } from '../swal';
import { parseYouTube } from '../edlFormats'; import { parseYouTube } from '../edlFormats';
import CopyClipboardButton from '../components/CopyClipboardButton'; import CopyClipboardButton from '../components/CopyClipboardButton';

Wyświetl plik

@ -1,9 +1,11 @@
import React, { useState, useCallback, useRef, useEffect } from 'react'; import React, { useState, useCallback, useRef, useEffect } from 'react';
import { Button, TextInputField, LinkIcon } from 'evergreen-ui'; import { Button, TextInputField, LinkIcon } from 'evergreen-ui';
import Swal from 'sweetalert2';
import i18n from 'i18next'; import i18n from 'i18next';
import withReactContent from 'sweetalert2-react-content'; import withReactContent from 'sweetalert2-react-content';
import Swal from '../swal';
const { shell } = window.require('electron'); const { shell } = window.require('electron');
const ReactSwal = withReactContent(Swal); const ReactSwal = withReactContent(Swal);

Wyświetl plik

@ -7,7 +7,8 @@ import pMap from 'p-map';
import sortBy from 'lodash/sortBy'; import sortBy from 'lodash/sortBy';
import { blackDetect, silenceDetect, detectSceneChanges as ffmpegDetectSceneChanges, readFrames, mapTimesToSegments, findKeyframeNearTime } from '../ffmpeg'; import { blackDetect, silenceDetect, detectSceneChanges as ffmpegDetectSceneChanges, readFrames, mapTimesToSegments, findKeyframeNearTime } from '../ffmpeg';
import { errorToast, handleError, shuffleArray } from '../util'; import { handleError, shuffleArray } from '../util';
import { errorToast } from '../swal';
import { showParametersDialog } from '../dialogs/parameters'; import { showParametersDialog } from '../dialogs/parameters';
import { createNumSegments as createNumSegmentsDialog, createFixedDurationSegments as createFixedDurationSegmentsDialog, createRandomSegments as createRandomSegmentsDialog, labelSegmentDialog, showEditableJsonDialog, askForShiftSegments, askForAlignSegments, selectSegmentsByLabelDialog } from '../dialogs'; import { createNumSegments as createNumSegmentsDialog, createFixedDurationSegments as createFixedDurationSegmentsDialog, createRandomSegments as createRandomSegmentsDialog, labelSegmentDialog, showEditableJsonDialog, askForShiftSegments, askForAlignSegments, selectSegmentsByLabelDialog } from '../dialogs';
import { createSegment, findSegmentsAtCursor, sortSegments, invertSegments, getSegmentTags, combineOverlappingSegments as combineOverlappingSegments2, isDurationValid, getSegApparentStart, getSegApparentEnd as getSegApparentEnd2 } from '../segments'; import { createSegment, findSegmentsAtCursor, sortSegments, invertSegments, getSegmentTags, combineOverlappingSegments as combineOverlappingSegments2, isDurationValid, getSegApparentStart, getSegApparentEnd as getSegApparentEnd2 } from '../segments';

Wyświetl plik

@ -1,7 +1,7 @@
import { useEffect, useState, useRef, useCallback } from 'react'; import { useEffect, useState, useRef, useCallback } from 'react';
import i18n from 'i18next'; import i18n from 'i18next';
import { errorToast } from '../util'; import { errorToast } from '../swal';
import isDev from '../isDev'; import isDev from '../isDev';
const remote = window.require('@electron/remote'); const remote = window.require('@electron/remote');

Wyświetl plik

@ -1,5 +1,6 @@
import React, { Suspense } from 'react'; import React, { Suspense } from 'react';
import { createRoot } from 'react-dom/client'; import { createRoot } from 'react-dom/client';
import { MotionConfig } from 'framer-motion';
import App from './App'; import App from './App';
import ErrorBoundary from './ErrorBoundary'; import ErrorBoundary from './ErrorBoundary';
@ -19,7 +20,9 @@ const root = createRoot(container);
root.render( root.render(
<ErrorBoundary> <ErrorBoundary>
<Suspense fallback={<div />}> <Suspense fallback={<div />}>
<MotionConfig reducedMotion="user">
<App /> <App />
</MotionConfig>
</Suspense> </Suspense>
</ErrorBoundary>, </ErrorBoundary>,
); );

Wyświetl plik

@ -1,7 +1,8 @@
import ky from 'ky'; import ky from 'ky';
import { runFfmpegStartupCheck, getFfmpegPath } from './ffmpeg'; import { runFfmpegStartupCheck, getFfmpegPath } from './ffmpeg';
import { toast, handleError } from './util'; import { toast } from './swal';
import { handleError } from './util';
import isDev from './isDev'; import isDev from './isDev';

Wyświetl plik

@ -1,11 +1,11 @@
import React from 'react'; import React from 'react';
import Swal from 'sweetalert2';
import withReactContent from 'sweetalert2-react-content'; import withReactContent from 'sweetalert2-react-content';
import i18n from 'i18next'; import i18n from 'i18next';
import { Trans } from 'react-i18next'; import { Trans } from 'react-i18next';
import CopyClipboardButton from './components/CopyClipboardButton'; import CopyClipboardButton from './components/CopyClipboardButton';
import { isStoreBuild, isMasBuild, isWindowsStoreBuild } from './util'; import { isStoreBuild, isMasBuild, isWindowsStoreBuild } from './util';
import Swal from './swal';
const electron = window.require('electron'); const electron = window.require('electron');
const os = window.require('os'); const os = window.require('os');

55
src/swal.js 100644
Wyświetl plik

@ -0,0 +1,55 @@
import SwalRaw from 'sweetalert2';
import { primaryColor } from './colors';
const { systemPreferences } = window.require('@electron/remote');
const animationSettings = systemPreferences.getAnimationSettings();
let commonSwalOptions = {
confirmButtonColor: primaryColor,
};
if (animationSettings.prefersReducedMotion) {
commonSwalOptions = {
...commonSwalOptions,
showClass: {
popup: '',
backdrop: '',
icon: '',
},
hideClass: {
popup: '',
backdrop: '',
icon: '',
},
};
}
const Swal = SwalRaw.mixin({
...commonSwalOptions,
});
export default Swal;
export const swalToastOptions = {
...commonSwalOptions,
toast: true,
position: 'top',
showConfirmButton: false,
showCloseButton: true,
timer: 5000,
timerProgressBar: true,
didOpen: (self) => {
self.addEventListener('mouseenter', Swal.stopTimer);
self.addEventListener('mouseleave', Swal.resumeTimer);
},
};
export const toast = Swal.mixin(swalToastOptions);
export const errorToast = (text) => toast.fire({
icon: 'error',
text,
});

Wyświetl plik

@ -1,4 +1,3 @@
import Swal from 'sweetalert2';
import i18n from 'i18next'; import i18n from 'i18next';
import lodashTemplate from 'lodash/template'; import lodashTemplate from 'lodash/template';
import pMap from 'p-map'; import pMap from 'p-map';
@ -6,6 +5,7 @@ import ky from 'ky';
import prettyBytes from 'pretty-bytes'; import prettyBytes from 'pretty-bytes';
import isDev from './isDev'; import isDev from './isDev';
import Swal, { toast } from './swal';
const { dirname, parse: parsePath, join, extname, isAbsolute, resolve, basename } = window.require('path'); const { dirname, parse: parsePath, join, extname, isAbsolute, resolve, basename } = window.require('path');
const fsExtra = window.require('fs-extra'); const fsExtra = window.require('fs-extra');
@ -99,26 +99,6 @@ export async function transferTimestamps(inPath, outPath, offset = 0) {
} }
} }
export const swalToastOptions = {
toast: true,
position: 'top',
showConfirmButton: false,
showCloseButton: true,
timer: 5000,
timerProgressBar: true,
didOpen: (self) => {
self.addEventListener('mouseenter', Swal.stopTimer);
self.addEventListener('mouseleave', Swal.resumeTimer);
},
};
export const toast = Swal.mixin(swalToastOptions);
export const errorToast = (text) => toast.fire({
icon: 'error',
text,
});
export function handleError(arg1, arg2) { export function handleError(arg1, arg2) {
console.error('handleError', arg1, arg2); console.error('handleError', arg1, arg2);