Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d9ee10926 | ||
|
|
f136082181 |
@@ -80,10 +80,8 @@ jobs:
|
||||
- name: ESLint
|
||||
run: npm run check:eslint
|
||||
|
||||
- name: Prettier Check and Fix
|
||||
run: |
|
||||
npx prettier --write .
|
||||
npm run check:prettier
|
||||
- name: Prettier
|
||||
run: npm run check:prettier
|
||||
|
||||
# ── Security (informational — findings shouldn't block a deploy) ─────
|
||||
- name: Audit (high/critical)
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Report something that isn't working in Lotus Chat
|
||||
title: ''
|
||||
labels: bug
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what went wrong.
|
||||
|
||||
**Steps to reproduce**
|
||||
|
||||
1. Go to '...'
|
||||
2. Click on '...'
|
||||
3. See error
|
||||
|
||||
**Expected behavior**
|
||||
What you expected to happen instead.
|
||||
|
||||
**Client info**
|
||||
|
||||
- Lotus Chat version (Settings → Help & About):
|
||||
- Platform: Web / Desktop (Windows / macOS / Linux)
|
||||
- Browser + version (if web):
|
||||
|
||||
**Screenshots / logs**
|
||||
If applicable, add screenshots or the browser devtools console output.
|
||||
@@ -1 +1,5 @@
|
||||
blank_issues_enabled: true
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Features, Bug Reports, Questions
|
||||
url: https://github.com/cinnyapp/cinny/discussions/new/choose
|
||||
about: Our preferred starting point if you have any questions or suggestions about features or behavior.
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
---
|
||||
name: Feature Request
|
||||
about: Suggest an idea or improvement for Lotus Chat
|
||||
title: ''
|
||||
labels: enhancement
|
||||
---
|
||||
|
||||
**What would you like?**
|
||||
A clear and concise description of the feature or change.
|
||||
|
||||
**Why / use case**
|
||||
What problem does it solve, or what does it make better?
|
||||
|
||||
**Alternatives considered**
|
||||
Any workarounds or other approaches you've thought about.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
name: Pre-Discussed and Approved Topics
|
||||
about: |-
|
||||
Only for topics already discussed and approved in the GitHub Discussions section.
|
||||
---
|
||||
|
||||
**DO NOT OPEN A NEW ISSUE. PLEASE USE THE DISCUSSIONS SECTION.**
|
||||
|
||||
**I DIDN'T READ THE ABOVE LINE. PLEASE CLOSE THIS ISSUE.**
|
||||
+1
-1
@@ -109,7 +109,7 @@ export default [
|
||||
{ argsIgnorePattern: '^_', varsIgnorePattern: '^_', caughtErrorsIgnorePattern: '^_' },
|
||||
],
|
||||
'@typescript-eslint/no-shadow': 'error',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'warn',
|
||||
|
||||
// jsx-a11y — media captions not required for this app
|
||||
'jsx-a11y/media-has-caption': 'off',
|
||||
|
||||
Generated
+365
-453
File diff suppressed because it is too large
Load Diff
+9
-7
@@ -12,12 +12,13 @@
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"lint": "npm run check:eslint && npm run check:prettier",
|
||||
"check:eslint": "eslint \"src/**/*.{js,jsx,ts,tsx}\"",
|
||||
"check:eslint": "eslint src/*",
|
||||
"check:prettier": "prettier --check .",
|
||||
"fix:prettier": "prettier --write .",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"test": "node --import tsx --test $(find src -name '*.test.ts')",
|
||||
"prepare": "husky",
|
||||
"commit": "git-cz",
|
||||
"postinstall": "node scripts/patch-folds.mjs",
|
||||
"sync:decorations": "node scripts/syncDecorations.mjs"
|
||||
},
|
||||
@@ -25,6 +26,11 @@
|
||||
"*.{ts,tsx,js,jsx}": "eslint",
|
||||
"*": "prettier --ignore-unknown --write"
|
||||
},
|
||||
"config": {
|
||||
"commitizen": {
|
||||
"path": "./node_modules/cz-conventional-changelog"
|
||||
}
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Ajay Bura",
|
||||
"license": "AGPL-3.0-only",
|
||||
@@ -37,7 +43,7 @@
|
||||
"@fontsource-variable/inter": "5.2.8",
|
||||
"@giphy/js-fetch-api": "5.8.0",
|
||||
"@giphy/js-types": "5.1.0",
|
||||
"@giphy/js-util": "2.0.0",
|
||||
"@giphy/js-util": "5.2.0",
|
||||
"@giphy/react-components": "10.1.2",
|
||||
"@sapphi-red/web-noise-suppressor": "0.3.5",
|
||||
"@tanstack/react-query": "5.100.13",
|
||||
@@ -89,7 +95,7 @@
|
||||
"react-i18next": "17.0.8",
|
||||
"react-range": "1.10.0",
|
||||
"react-router-dom": "7.15.1",
|
||||
"sanitize-html": "2.17.6",
|
||||
"sanitize-html": "2.17.4",
|
||||
"slate": "0.124.1",
|
||||
"slate-dom": "0.124.1",
|
||||
"slate-history": "0.113.1",
|
||||
@@ -124,7 +130,6 @@
|
||||
"cz-conventional-changelog": "3.3.0",
|
||||
"eslint": "9.39.4",
|
||||
"eslint-config-airbnb": "19.0.4",
|
||||
"eslint-config-airbnb-base": "15.0.0",
|
||||
"eslint-config-prettier": "10.1.8",
|
||||
"eslint-plugin-import": "2.32.0",
|
||||
"eslint-plugin-jsx-a11y": "6.10.2",
|
||||
@@ -144,8 +149,5 @@
|
||||
"dompurify": ">=3.3.4"
|
||||
},
|
||||
"js-cookie": ">=3.0.6"
|
||||
},
|
||||
"allowScripts": {
|
||||
"esbuild@0.28.1": true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ export default function KaTeX({ latex, displayMode = false }: KaTeXProps) {
|
||||
return (
|
||||
<Wrapper
|
||||
// KaTeX output is generated by our own render call (trusted-safe).
|
||||
// eslint-disable-next-line react/no-danger
|
||||
dangerouslySetInnerHTML={{ __html: html }}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import React, { KeyboardEvent, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { Box, Chip, color, config, Icon, Icons, Text, toRem } from 'folds';
|
||||
import { RelationsEvent } from 'matrix-js-sdk/lib/models/relations';
|
||||
|
||||
@@ -58,6 +58,7 @@ export function DeveloperTools({ requestClose }: DeveloperToolsProps) {
|
||||
|
||||
const submitAccountData: AccountDataSubmitCallback = useCallback(
|
||||
async (type, content) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
await mx.setRoomAccountData(room.roomId, type as any, content);
|
||||
},
|
||||
[mx, room.roomId],
|
||||
|
||||
@@ -55,6 +55,7 @@ export function RoomQuality({ permissions }: RoomQualityProps) {
|
||||
const [submitState, submit] = useAsyncCallback(
|
||||
useCallback(
|
||||
async (next: RoomQualityContent) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
await sendStateEvent(mx, room.roomId, StateEvent.LotusRoomQuality, next);
|
||||
},
|
||||
[mx, room.roomId],
|
||||
|
||||
@@ -31,6 +31,7 @@ export function RoomRetention({ permissions }: RoomRetentionProps) {
|
||||
const content: RetentionContent = ms > 0 ? { max_lifetime: ms } : {};
|
||||
// Lotus custom-state convention: cast the type key (RoomRetention isn't a
|
||||
// typed key in the SDK's StateEvents map).
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
await sendStateEvent(mx, room.roomId, StateEvent.RoomRetention, content);
|
||||
},
|
||||
[mx, room.roomId],
|
||||
|
||||
@@ -46,6 +46,7 @@ const extractText = (event: MatrixEvent): ExtractedText | null => {
|
||||
const content = event.getContent();
|
||||
|
||||
if (POLL_START_TYPES.includes(evType)) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const poll = (content['m.poll'] ?? content['org.matrix.msc3381.poll.start']) as any;
|
||||
if (!poll) return null;
|
||||
const qBody =
|
||||
@@ -56,6 +57,7 @@ const extractText = (event: MatrixEvent): ExtractedText | null => {
|
||||
.map(
|
||||
(a) =>
|
||||
((a['m.text'] as Array<{ body: string }> | undefined)?.[0]?.body ??
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(a['org.matrix.msc3381.poll.answer'] as any)?.body ??
|
||||
'') as string,
|
||||
)
|
||||
@@ -102,6 +104,7 @@ const rowToResultItem = (row: SearchCacheRow): ResultItem => {
|
||||
};
|
||||
return {
|
||||
rank: 0,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
event: syntheticEvent as any,
|
||||
context: { events_before: [], events_after: [], profile_info: {} },
|
||||
};
|
||||
@@ -224,6 +227,7 @@ export const useLocalMessageSearch = () => {
|
||||
};
|
||||
memoryItems.push({
|
||||
rank: 0,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
event: syntheticEvent as any,
|
||||
context: { events_before: [], events_after: [], profile_info: {} },
|
||||
});
|
||||
|
||||
@@ -146,6 +146,7 @@ export const useMessageSearch = (params: MessageSearchParams) => {
|
||||
...(fromTs !== undefined && { from_ts: fromTs }),
|
||||
...(toTs !== undefined && { to_ts: toTs }),
|
||||
...(containsUrl !== undefined && { contains_url: containsUrl }),
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} as any,
|
||||
include_state: false,
|
||||
order_by: order as SearchOrderBy.Recent,
|
||||
|
||||
@@ -341,6 +341,7 @@ export function RoomServerACL({ requestClose }: RoomServerACLProps) {
|
||||
variant="Primary"
|
||||
/>
|
||||
<Box direction="Column" gap="0">
|
||||
{/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
|
||||
<label
|
||||
htmlFor="allow-ip-literals"
|
||||
style={{ cursor: canEdit ? 'pointer' : 'default' }}
|
||||
|
||||
@@ -318,6 +318,7 @@ export function ForwardMessageDialog({ mEvent, onClose }: Props) {
|
||||
const results = await Promise.allSettled(
|
||||
ids.map((id) => {
|
||||
// threadId-aware overload (P3-8): explicit null = send to the main timeline.
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const sendForward = () => mx.sendEvent(id, null, mEvent.getType() as any, fwdContent);
|
||||
// Send the optional comment first so it reads as a note above the
|
||||
// forwarded content. The room counts as failed if either send rejects.
|
||||
@@ -326,6 +327,7 @@ export function ForwardMessageDialog({ mEvent, onClose }: Props) {
|
||||
const needsComment = commentBody && !commentSentRef.current.has(id);
|
||||
const step = needsComment
|
||||
? mx
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
.sendMessage(id, null, { msgtype: MsgType.Text, body: commentBody } as any)
|
||||
.then(() => {
|
||||
commentSentRef.current.add(id);
|
||||
|
||||
@@ -1390,6 +1390,7 @@ export const Message = React.memo(
|
||||
after={<Icon size="100" src={Icons.Send} />}
|
||||
radii="300"
|
||||
onClick={() => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(mx as any).resendEvent(mEvent, room);
|
||||
closeMenu();
|
||||
}}
|
||||
@@ -1408,6 +1409,7 @@ export const Message = React.memo(
|
||||
after={<Icon size="100" src={Icons.Cross} />}
|
||||
radii="300"
|
||||
onClick={() => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(mx as any).cancelPendingEvent(mEvent);
|
||||
closeMenu();
|
||||
}}
|
||||
|
||||
@@ -187,6 +187,7 @@ export const MessageEditor = as<'div', MessageEditorProps>(
|
||||
rel_type: RelationType.Replace,
|
||||
},
|
||||
};
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return mx.sendMessage(roomId, content as any);
|
||||
}
|
||||
|
||||
@@ -235,6 +236,7 @@ export const MessageEditor = as<'div', MessageEditorProps>(
|
||||
},
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return mx.sendMessage(roomId, content as any);
|
||||
}, [
|
||||
mx,
|
||||
|
||||
@@ -564,6 +564,7 @@ export function ThreadTimeline({ room, thread, editor }: ThreadTimelineProps) {
|
||||
mx.sendEvent(
|
||||
room.roomId,
|
||||
thread.id,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
MessageEvent.Reaction as any,
|
||||
getReactionContent(targetEventId, key, rShortcode),
|
||||
);
|
||||
|
||||
@@ -60,6 +60,7 @@ export function RoomWidgetView({ room, widget }: RoomWidgetViewProps) {
|
||||
clientApi.stop();
|
||||
iframe.remove();
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [mx, room.roomId, widget.id, widget.templateUrl]);
|
||||
|
||||
if (blocked) {
|
||||
|
||||
@@ -84,6 +84,7 @@ export function WidgetsPanel({ room, requestClose }: WidgetsPanelProps) {
|
||||
data: {},
|
||||
};
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
await sendStateEvent(mx, room.roomId, StateEvent.Widget, content, id);
|
||||
setAdding(false);
|
||||
} catch (e) {
|
||||
@@ -95,6 +96,7 @@ export function WidgetsPanel({ room, requestClose }: WidgetsPanelProps) {
|
||||
|
||||
const handleRemove = (id: string) => {
|
||||
if (viewingId === id) setViewingId(null);
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
sendStateEvent(mx, room.roomId, StateEvent.Widget, {}, id).catch(() => undefined);
|
||||
};
|
||||
|
||||
|
||||
@@ -44,7 +44,13 @@ export function getLocalRoomNamesContent(
|
||||
mx: ReturnType<typeof useMatrixClient>,
|
||||
): LocalRoomNamesContent {
|
||||
const raw: unknown = getAccountData<unknown>(mx, LOCAL_ROOM_NAMES_KEY);
|
||||
if (raw && typeof raw === 'object' && 'rooms' in raw && typeof (raw as any).rooms === 'object') {
|
||||
if (
|
||||
raw &&
|
||||
typeof raw === 'object' &&
|
||||
'rooms' in raw &&
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
typeof (raw as any).rooms === 'object'
|
||||
) {
|
||||
return raw as LocalRoomNamesContent;
|
||||
}
|
||||
return { rooms: {} };
|
||||
|
||||
@@ -70,12 +70,16 @@ import {
|
||||
THREAD_NOTIFICATIONS_FALLBACK_BEHAVIOR,
|
||||
} from '../../utils/threadNotifications';
|
||||
|
||||
const LogoSVG = withOriginBaseUrl(getOriginBaseUrl(), '/lotus.png');
|
||||
const LogoUnreadSVG = withOriginBaseUrl(getOriginBaseUrl(), '/lotus-unread.png');
|
||||
const LogoHighlightSVG = withOriginBaseUrl(getOriginBaseUrl(), '/lotus-highlight.png');
|
||||
|
||||
// Grace period after the initial sync settles before invite notifications arm, so
|
||||
// the async invite-atom population lands first and isn't mistaken for new invites.
|
||||
const LogoSVG = withOriginBaseUrl(getOriginBaseUrl(), '/public/res/lotus.png');
|
||||
const LogoUnreadSVG = withOriginBaseUrl(getOriginBaseUrl(), '/public/res/lotus-unread.png');
|
||||
const LogoHighlightSVG = withOriginBaseUrl(getOriginBaseUrl(), '/public/res/lotus-highlight.png');
|
||||
|
||||
// Grace period after the initial sync settles before invite notifications arm, so
|
||||
// the async invite-atom population lands first and isn't mistaken for new invites.
|
||||
const INVITE_NOTIFY_ARM_DELAY_MS = 3000;
|
||||
|
||||
function SystemEmojiFeature() {
|
||||
|
||||
@@ -25,8 +25,10 @@ export const setMarkedUnread = (
|
||||
unread: boolean,
|
||||
): Promise<unknown> =>
|
||||
Promise.all([
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
mx.setRoomAccountData(roomId, AccountDataEvent.MarkedUnread as any, { unread }),
|
||||
// Best-effort mirror for older servers; never fail the primary write on it.
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
mx.setRoomAccountData(roomId, UNSTABLE_MARKED_UNREAD as any, { unread }).catch(() => undefined),
|
||||
]);
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ export function getAccountData<T>(
|
||||
mx: MatrixClient,
|
||||
eventType: AccountDataEvent | string,
|
||||
): T | undefined {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const event = (mx as any).getAccountData(eventType) as MatrixEvent | undefined;
|
||||
return event?.getContent() as T | undefined;
|
||||
}
|
||||
@@ -22,5 +23,6 @@ export function setAccountData<T>(
|
||||
eventType: AccountDataEvent | string,
|
||||
content: T,
|
||||
): Promise<void> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return (mx as any).setAccountData(eventType, content);
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ export async function buildModelNode(
|
||||
model: DenoiseModelId,
|
||||
): Promise<DenoiseNode> {
|
||||
if (model === 'dtln') {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const mod: any = await import(/* @vite-ignore */ `${BASE}workadventure/audio-worklet.js`);
|
||||
const handle = await mod.createNoiseSuppressionAudioWorklet(ctx, { bypassUntilReady: true });
|
||||
return { node: handle.node, dispose: () => handle.dispose() };
|
||||
@@ -80,6 +81,7 @@ export async function buildModelNode(
|
||||
// deepfilternet/v2/... Override its cdnUrl to our absolute base so nothing
|
||||
// hits the upstream CDN. DeepFilterNet3Core builds the worklet node directly.
|
||||
const dfnBase = new URL(`${BASE}deepfilternet`, window.location.href).href;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const mod: any = await import(/* @vite-ignore */ `${BASE}deepfilternet/index.esm.js`);
|
||||
const core = new mod.DeepFilterNet3Core({
|
||||
sampleRate: sampleRateFor(model),
|
||||
|
||||
@@ -44,10 +44,12 @@ test('onTabPress fires only on Tab', () => {
|
||||
|
||||
test('preventScrollWithArrowKey prevents default only on arrows', () => {
|
||||
const up = evt('ArrowUp', 38);
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
preventScrollWithArrowKey(up as any);
|
||||
assert.equal(up.prevented, true);
|
||||
|
||||
const a = evt('a', 65);
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
preventScrollWithArrowKey(a as any);
|
||||
assert.equal(a.prevented, false);
|
||||
});
|
||||
@@ -93,12 +95,14 @@ test('stopPropagation: stops unless an editable element is focused', () => {
|
||||
// nothing focused → stops, returns true
|
||||
withActive(null);
|
||||
let k = makeKeyEvt();
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
assert.equal(stopPropagation(k.ev as any), true);
|
||||
assert.equal(k.wasStopped(), true);
|
||||
|
||||
// input focused → does not stop, returns false
|
||||
withActive({ nodeName: 'INPUT', getAttribute: () => null });
|
||||
k = makeKeyEvt();
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
assert.equal(stopPropagation(k.ev as any), false);
|
||||
assert.equal(k.wasStopped(), false);
|
||||
|
||||
@@ -108,5 +112,6 @@ test('stopPropagation: stops unless an editable element is focused', () => {
|
||||
getAttribute: (a: string) => (a === 'contenteditable' ? 'true' : null),
|
||||
});
|
||||
k = makeKeyEvt();
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
assert.equal(stopPropagation(k.ev as any), false);
|
||||
});
|
||||
|
||||
@@ -22,6 +22,7 @@ const makeMx = (
|
||||
if (opts.forgetRejects) throw new Error('forget failed');
|
||||
return {};
|
||||
},
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} as any;
|
||||
return { mx, calls };
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { M_POLL_KIND_DISCLOSED } from 'matrix-js-sdk';
|
||||
|
||||
// Pure helpers for poll display. matrix-js-sdk 41.7.0's PollStartEvent /
|
||||
|
||||
@@ -58,6 +58,7 @@ export function sendStateEvent<T extends object>(
|
||||
content: T,
|
||||
stateKey = '',
|
||||
): Promise<ISendEventResponse> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return mx.sendStateEvent(roomId, eventType as any, content, stateKey);
|
||||
}
|
||||
|
||||
|
||||
+6
-28
@@ -22,40 +22,18 @@ document.body.classList.add(configClass, varsClass);
|
||||
|
||||
// Register Service Worker
|
||||
if ('serviceWorker' in navigator) {
|
||||
const isProduction = import.meta.env.PROD;
|
||||
const swUrl = isProduction
|
||||
? `${trimTrailingSlash(import.meta.env.BASE_URL)}/sw.js`
|
||||
: `/dev-sw.js?dev-sw`;
|
||||
const swUrl =
|
||||
import.meta.env.MODE === 'production'
|
||||
? `${trimTrailingSlash(import.meta.env.BASE_URL)}/sw.js`
|
||||
: `/dev-sw.js?dev-sw`;
|
||||
|
||||
const sendSessionToSW = () => {
|
||||
const session = getFallbackSession();
|
||||
pushSessionToSW(session?.baseUrl, session?.accessToken);
|
||||
};
|
||||
|
||||
const registerServiceWorker = async () => {
|
||||
try {
|
||||
const registration = await navigator.serviceWorker.register(
|
||||
swUrl,
|
||||
isProduction
|
||||
? undefined
|
||||
: {
|
||||
type: 'module',
|
||||
scope: '/',
|
||||
},
|
||||
);
|
||||
|
||||
sendSessionToSW();
|
||||
|
||||
await navigator.serviceWorker.ready;
|
||||
sendSessionToSW();
|
||||
|
||||
console.info('Service worker registered:', registration.scope);
|
||||
} catch (error) {
|
||||
console.error('Service worker registration failed:', error);
|
||||
}
|
||||
};
|
||||
|
||||
registerServiceWorker();
|
||||
navigator.serviceWorker.register(swUrl).then(sendSessionToSW);
|
||||
navigator.serviceWorker.ready.then(sendSessionToSW);
|
||||
|
||||
navigator.serviceWorker.addEventListener('message', (ev) => {
|
||||
const { type } = ev.data ?? {};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { globalStyle, keyframes, style } from '@vanilla-extract/css';
|
||||
|
||||
const glitch1 = keyframes({
|
||||
|
||||
Reference in New Issue
Block a user