From f86b8f99f8f0c90079b55ee7159ce5c44d8023a6 Mon Sep 17 00:00:00 2001 From: undefined Date: Sun, 11 Aug 2024 23:53:40 +0800 Subject: [PATCH] ui: add view-transistions --- packages/ui-default/entry.js | 2 +- .../ui-default/pages/problem_main.page.ts | 2 +- .../ui-default/pages/record_detail.page.tsx | 16 +++++----- packages/ui-default/pages/record_main.page.ts | 30 +++++++++++-------- packages/ui-default/utils/base.ts | 19 ++++++++++++ packages/ui-default/utils/pjax.js | 4 +-- 6 files changed, 49 insertions(+), 24 deletions(-) diff --git a/packages/ui-default/entry.js b/packages/ui-default/entry.js index 7190822e7..869a0bf00 100644 --- a/packages/ui-default/entry.js +++ b/packages/ui-default/entry.js @@ -52,7 +52,7 @@ if (process.env.NODE_ENV === 'production' && UiContext.sentry_dsn) { if (!e.isUserFacingError) window._sentryEvents.push(e); }; const script = document.createElement('script'); - script.src = new URL('/sentry.js', UiContext.cdn_prefix).href; + script.src = '/sentry.js'; document.body.appendChild(script); } diff --git a/packages/ui-default/pages/problem_main.page.ts b/packages/ui-default/pages/problem_main.page.ts index fc23662fc..0c23998ee 100644 --- a/packages/ui-default/pages/problem_main.page.ts +++ b/packages/ui-default/pages/problem_main.page.ts @@ -9,7 +9,7 @@ import Notification from 'vj/components/notification'; import { downloadProblemSet } from 'vj/components/zipDownloader'; import { NamedPage } from 'vj/misc/Page'; import { - addSpeculationRules, delay, i18n, pjax, request, tpl, + addSpeculationRules, delay, i18n, pjax, request, setTemporaryViewTransitionNames, tpl, } from 'vj/utils'; const list = []; diff --git a/packages/ui-default/pages/record_detail.page.tsx b/packages/ui-default/pages/record_detail.page.tsx index 766e9d479..cd37906bc 100644 --- a/packages/ui-default/pages/record_detail.page.tsx +++ b/packages/ui-default/pages/record_detail.page.tsx @@ -2,7 +2,7 @@ import $ from 'jquery'; import React from 'react'; import { InfoDialog } from 'vj/components/dialog'; import { NamedPage } from 'vj/misc/Page'; -import { tpl } from 'vj/utils'; +import { tpl, withTransistionCallback } from 'vj/utils'; export default new NamedPage('record_detail', async () => { if (!UiContext.socketUrl) return; @@ -15,13 +15,15 @@ export default new NamedPage('record_detail', async () => { const dd = new DiffDOM(); sock.onmessage = (_, data) => { const msg = JSON.parse(data); - const newStatus = $(msg.status_html); - const oldStatus = $('#status'); - dd.apply(oldStatus[0], dd.diff(oldStatus[0], newStatus[0])); - const newSummary = $(msg.summary_html); - const oldSummary = $('#summary'); - dd.apply(oldSummary[0], dd.diff(oldSummary[0], newSummary[0])); if (typeof msg.status === 'number' && window.parent) window.parent.postMessage({ status: msg.status }); + withTransistionCallback(() => { + const newStatus = $(msg.status_html); + const oldStatus = $('#status'); + dd.apply(oldStatus[0], dd.diff(oldStatus[0], newStatus[0])); + const newSummary = $(msg.summary_html); + const oldSummary = $('#summary'); + dd.apply(oldSummary[0], dd.diff(oldSummary[0], newSummary[0])); + }); }; $(document).on('click', '.subtask-case', function () { const text = $(this).find('.message').text(); diff --git a/packages/ui-default/pages/record_main.page.ts b/packages/ui-default/pages/record_main.page.ts index 024516a20..1b345d730 100644 --- a/packages/ui-default/pages/record_main.page.ts +++ b/packages/ui-default/pages/record_main.page.ts @@ -3,7 +3,9 @@ import ProblemSelectAutoComplete from 'vj/components/autocomplete/ProblemSelectA import UserSelectAutoComplete from 'vj/components/autocomplete/UserSelectAutoComplete'; import Notification from 'vj/components/notification'; import { NamedPage } from 'vj/misc/Page'; -import { getAvailableLangs, request, tpl } from 'vj/utils'; +import { + getAvailableLangs, request, tpl, withTransistionCallback, +} from 'vj/utils'; const page = new NamedPage('record_main', async () => { const [{ default: WebSocket }, { DiffDOM }] = await Promise.all([ @@ -18,18 +20,20 @@ const page = new NamedPage('record_main', async () => { sock.onmessage = (_, data) => { const msg = JSON.parse(data); const $newTr = $(msg.html); - const $oldTr = $(`.record_main__table tr[data-rid="${$newTr.attr('data-rid')}"]`); - if ($oldTr.length) { - $oldTr.trigger('vjContentRemove'); - dd.apply($oldTr[0], dd.diff($oldTr[0], $newTr[0])); - $oldTr.trigger('vjContentNew'); - } else { - if (+new URLSearchParams(window.location.search).get('page') > 1 - || new URLSearchParams(window.location.search).get('nopush')) return; - $('.record_main__table tbody').prepend($newTr); - $('.record_main__table tbody tr:last').remove(); - $newTr.trigger('vjContentNew'); - } + withTransistionCallback(() => { + const $oldTr = $(`.record_main__table tr[data-rid="${$newTr.attr('data-rid')}"]`); + if ($oldTr.length) { + $oldTr.trigger('vjContentRemove'); + dd.apply($oldTr[0], dd.diff($oldTr[0], $newTr[0])); + $oldTr.trigger('vjContentNew'); + } else { + if (+new URLSearchParams(window.location.search).get('page') > 1 + || new URLSearchParams(window.location.search).get('nopush')) return; + $('.record_main__table tbody').prepend($newTr); + $('.record_main__table tbody tr:last').remove(); + $newTr.trigger('vjContentNew'); + } + }); }; UserSelectAutoComplete.getOrConstruct($('[name="uidOrName"]'), { clearDefaultValue: false, diff --git a/packages/ui-default/utils/base.ts b/packages/ui-default/utils/base.ts index f3b9cf62f..90ad558db 100644 --- a/packages/ui-default/utils/base.ts +++ b/packages/ui-default/utils/base.ts @@ -183,6 +183,23 @@ export const request = { }, }; +export function withTransistionCallback(callback: () => (Promise | void)) { + // @ts-ignore + if (!document.startViewTransition) return callback?.(); + // @ts-ignore + return document.startViewTransition(() => callback()); +} + +export async function setTemporaryViewTransitionNames(entries, vtPromise: Promise) { + for (const [$el, name] of entries) { + $el.style.viewTransitionName = name; + } + await vtPromise; + for (const [$el] of entries) { + $el.style.viewTransitionName = ''; + } +} + Object.assign(window.Hydro.utils, { i18n, rawHtml, @@ -192,4 +209,6 @@ Object.assign(window.Hydro.utils, { tpl, delay, zIndexManager, + withTransistionCallback, + setTemporaryViewTransitionNames, }); diff --git a/packages/ui-default/utils/pjax.js b/packages/ui-default/utils/pjax.js index d1bdaf0ab..79f648da1 100644 --- a/packages/ui-default/utils/pjax.js +++ b/packages/ui-default/utils/pjax.js @@ -5,7 +5,7 @@ import $ from 'jquery'; import { nanoid } from 'nanoid'; import NProgress from 'nprogress'; import Notification from 'vj/components/notification'; -import { request } from './base'; +import { request, withTransistionCallback } from './base'; const pjax = {}; @@ -115,7 +115,7 @@ pjax.request = async (opt) => { } } $target.trigger('vjContentRemove'); - $target.replaceWith($el); + withTransistionCallback(() => $target.replaceWith($el)); $el.trigger('vjContentNew'); } } catch (err) {