mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-10 19:38:39 +00:00
Compare commits
6 Commits
v0.15.0-ca
...
v0.15.0-ca
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
609766d898 | ||
|
|
3b8345ea5a | ||
|
|
29e7fa1371 | ||
|
|
278336168f | ||
|
|
96cdb041c6 | ||
|
|
f05b51ab49 |
78
Cargo.lock
generated
78
Cargo.lock
generated
@@ -106,9 +106,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.83"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3"
|
||||
checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
|
||||
|
||||
[[package]]
|
||||
name = "arbitrary"
|
||||
@@ -243,9 +243,9 @@ checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.97"
|
||||
version = "1.0.98"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4"
|
||||
checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
@@ -314,9 +314,9 @@ checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.12"
|
||||
version = "0.5.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95"
|
||||
checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
@@ -332,9 +332,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.19"
|
||||
version = "0.8.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
|
||||
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
@@ -353,7 +353,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -388,7 +388,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -417,9 +417,9 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.11.0"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2"
|
||||
checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@@ -858,9 +858,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.154"
|
||||
version = "0.2.155"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346"
|
||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
@@ -880,9 +880,9 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
|
||||
|
||||
[[package]]
|
||||
name = "libmimalloc-sys"
|
||||
version = "0.1.37"
|
||||
version = "0.1.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81eb4061c0582dedea1cbc7aff2240300dd6982e0239d1c99e65c1dbf4a30ba7"
|
||||
checksum = "0e7bb23d733dfcc8af652a78b7bf232f0e967710d044732185e561e47c0336b6"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
@@ -901,9 +901,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.13"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
|
||||
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
@@ -963,9 +963,9 @@ checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
|
||||
|
||||
[[package]]
|
||||
name = "mimalloc"
|
||||
version = "0.1.41"
|
||||
version = "0.1.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f41a2280ded0da56c8cf898babb86e8f10651a34adcfff190ae9a1159c6908d"
|
||||
checksum = "e9186d86b79b52f4a77af65604b51225e8db1d6ee7e3f41aec1e40829c71a176"
|
||||
dependencies = [
|
||||
"libmimalloc-sys",
|
||||
]
|
||||
@@ -978,9 +978,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.2"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
|
||||
checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae"
|
||||
dependencies = [
|
||||
"adler",
|
||||
]
|
||||
@@ -1039,7 +1039,7 @@ dependencies = [
|
||||
"napi-derive-backend",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1054,7 +1054,7 @@ dependencies = [
|
||||
"quote",
|
||||
"regex",
|
||||
"semver",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1285,9 +1285,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.82"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b"
|
||||
checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@@ -1565,7 +1565,7 @@ checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1940,9 +1940,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.63"
|
||||
version = "2.0.65"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf5be731623ca1a1fb7d8be6f261a3be6d3e2337b8a1f97be944d020c8fcb704"
|
||||
checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -1969,22 +1969,22 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.60"
|
||||
version = "1.0.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18"
|
||||
checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.60"
|
||||
version = "1.0.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524"
|
||||
checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2054,7 +2054,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2088,7 +2088,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2264,7 +2264,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@@ -2286,7 +2286,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
@@ -2571,7 +2571,7 @@ checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
NotAcceptableException,
|
||||
OnApplicationBootstrap,
|
||||
} from '@nestjs/common';
|
||||
import { Cron, CronExpression } from '@nestjs/schedule';
|
||||
import type { User } from '@prisma/client';
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import type { CookieOptions, Request, Response } from 'express';
|
||||
@@ -455,4 +456,23 @@ export class AuthService implements OnApplicationBootstrap {
|
||||
to: email,
|
||||
});
|
||||
}
|
||||
|
||||
@Cron(CronExpression.EVERY_DAY_AT_MIDNIGHT)
|
||||
async cleanExpiredSessions() {
|
||||
await this.db.session.deleteMany({
|
||||
where: {
|
||||
expiresAt: {
|
||||
lte: new Date(),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await this.db.userSession.deleteMany({
|
||||
where: {
|
||||
expiresAt: {
|
||||
lte: new Date(),
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,8 +87,8 @@ export class TokenService {
|
||||
}
|
||||
|
||||
@Cron(CronExpression.EVERY_DAY_AT_MIDNIGHT)
|
||||
cleanExpiredTokens() {
|
||||
return this.db.verificationToken.deleteMany({
|
||||
async cleanExpiredTokens() {
|
||||
await this.db.verificationToken.deleteMany({
|
||||
where: {
|
||||
expiresAt: {
|
||||
lte: new Date(),
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { BlockElement } from '@blocksuite/block-std';
|
||||
import { ViewService } from '@affine/core/modules/workbench/services/view';
|
||||
import type { BaseSelection, BlockElement } from '@blocksuite/block-std';
|
||||
import type { Disposable } from '@blocksuite/global/utils';
|
||||
import type {
|
||||
AffineEditorContainer,
|
||||
@@ -7,7 +8,7 @@ import type {
|
||||
} from '@blocksuite/presets';
|
||||
import type { Doc } from '@blocksuite/store';
|
||||
import { Slot } from '@blocksuite/store';
|
||||
import type { DocMode } from '@toeverything/infra';
|
||||
import { type DocMode, useServiceOptional } from '@toeverything/infra';
|
||||
import clsx from 'clsx';
|
||||
import type React from 'react';
|
||||
import type { RefObject } from 'react';
|
||||
@@ -102,10 +103,11 @@ export const BlocksuiteEditorContainer = forwardRef<
|
||||
{ page, mode, className, style, defaultSelectedBlockId, referenceRenderer },
|
||||
ref
|
||||
) {
|
||||
const [scrolled, setScrolled] = useState(false);
|
||||
const scrolledRef = useRef(false);
|
||||
const rootRef = useRef<HTMLDivElement>(null);
|
||||
const docRef = useRef<PageEditor>(null);
|
||||
const edgelessRef = useRef<EdgelessEditor>(null);
|
||||
const renderStartRef = useRef<number>(Date.now());
|
||||
|
||||
const slots: BlocksuiteEditorContainerRef['slots'] = useMemo(() => {
|
||||
return {
|
||||
@@ -208,39 +210,18 @@ export const BlocksuiteEditorContainer = forwardRef<
|
||||
}, [affineEditorContainerProxy, ref]);
|
||||
|
||||
const blockElement = useBlockElementById(rootRef, defaultSelectedBlockId);
|
||||
const currentView = useServiceOptional(ViewService)?.view;
|
||||
|
||||
useEffect(() => {
|
||||
let disposable: Disposable | undefined = undefined;
|
||||
|
||||
// update the hash when the block is selected
|
||||
const handleUpdateComplete = () => {
|
||||
const selectManager = affineEditorContainerProxy?.host?.selection;
|
||||
if (!selectManager) return;
|
||||
|
||||
disposable = selectManager.slots.changed.on(() => {
|
||||
const selectedBlock = selectManager.find('block');
|
||||
const selectedId = selectedBlock?.blockId;
|
||||
|
||||
const newHash = selectedId ? `#${selectedId}` : '';
|
||||
//TODO: use activeView.history which is in workbench instead of history.replaceState
|
||||
history.replaceState(null, '', `${window.location.pathname}${newHash}`);
|
||||
|
||||
// Dispatch a custom event to notify the hash change
|
||||
const hashChangeEvent = new CustomEvent('hashchange-custom', {
|
||||
detail: { hash: newHash },
|
||||
});
|
||||
window.dispatchEvent(hashChangeEvent);
|
||||
});
|
||||
};
|
||||
|
||||
// scroll to the block element when the block id is provided and the page is first loaded
|
||||
let canceled = false;
|
||||
const handleScrollToBlock = (blockElement: BlockElement) => {
|
||||
if (mode === 'page') {
|
||||
blockElement.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'center',
|
||||
});
|
||||
if (!mode || !blockElement) {
|
||||
return;
|
||||
}
|
||||
blockElement.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'center',
|
||||
});
|
||||
const selectManager = affineEditorContainerProxy.host?.selection;
|
||||
if (!blockElement.path.length || !selectManager) {
|
||||
return;
|
||||
@@ -249,22 +230,65 @@ export const BlocksuiteEditorContainer = forwardRef<
|
||||
blockId: blockElement.blockId,
|
||||
});
|
||||
selectManager.set([newSelection]);
|
||||
setScrolled(true);
|
||||
};
|
||||
|
||||
affineEditorContainerProxy.updateComplete
|
||||
.then(() => {
|
||||
if (blockElement && !scrolled) {
|
||||
if (blockElement && !scrolledRef.current && !canceled) {
|
||||
handleScrollToBlock(blockElement);
|
||||
scrolledRef.current = true;
|
||||
}
|
||||
handleUpdateComplete();
|
||||
})
|
||||
.catch(console.error);
|
||||
return () => {
|
||||
canceled = true;
|
||||
};
|
||||
}, [blockElement, affineEditorContainerProxy, mode]);
|
||||
|
||||
useEffect(() => {
|
||||
let disposable: Disposable | null = null;
|
||||
let canceled = false;
|
||||
// Function to handle block selection change
|
||||
const handleSelectionChange = (selection: BaseSelection[]) => {
|
||||
const viewLocation = currentView?.location$.value;
|
||||
const currentPath = viewLocation?.pathname;
|
||||
const locationHash = viewLocation?.hash;
|
||||
if (
|
||||
!currentView ||
|
||||
!currentPath ||
|
||||
// do not update the hash during the initial render
|
||||
renderStartRef.current > Date.now() - 1000
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if (selection[0]?.type !== 'block') {
|
||||
return currentView.history.replace(currentPath);
|
||||
}
|
||||
|
||||
const selectedId = selection[0]?.blockId;
|
||||
if (!selectedId) {
|
||||
return;
|
||||
}
|
||||
const newHash = `#${selectedId}`;
|
||||
|
||||
// Only update the hash if it has changed
|
||||
if (locationHash !== newHash) {
|
||||
currentView.history.replace(currentPath + newHash);
|
||||
}
|
||||
};
|
||||
affineEditorContainerProxy.updateComplete
|
||||
.then(() => {
|
||||
const selectManager = affineEditorContainerProxy.host?.selection;
|
||||
if (!selectManager || canceled) return;
|
||||
// Set up the new disposable listener
|
||||
disposable = selectManager.slots.changed.on(handleSelectionChange);
|
||||
})
|
||||
.catch(console.error);
|
||||
|
||||
return () => {
|
||||
canceled = true;
|
||||
disposable?.dispose();
|
||||
};
|
||||
}, [blockElement, affineEditorContainerProxy, mode, scrolled]);
|
||||
}, [affineEditorContainerProxy, currentView]);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
useLitPortalFactory,
|
||||
} from '@affine/component';
|
||||
import { useJournalInfoHelper } from '@affine/core/hooks/use-journal';
|
||||
import { WorkbenchService } from '@affine/core/modules/workbench';
|
||||
import {
|
||||
BiDirectionalLinkPanel,
|
||||
DocMetaTags,
|
||||
@@ -11,6 +12,7 @@ import {
|
||||
PageEditor,
|
||||
} from '@blocksuite/presets';
|
||||
import type { Doc } from '@blocksuite/store';
|
||||
import { useLiveData, useService } from '@toeverything/infra';
|
||||
import React, {
|
||||
forwardRef,
|
||||
Fragment,
|
||||
@@ -70,6 +72,10 @@ export const BlocksuiteDocEditor = forwardRef<
|
||||
useState<HTMLElementTagNameMap['affine-page-root']>();
|
||||
const { isJournal } = useJournalInfoHelper(page.collection, page.id);
|
||||
|
||||
const workbench = useService(WorkbenchService).workbench;
|
||||
const activeView = useLiveData(workbench.activeView$);
|
||||
const hash = useLiveData(activeView.location$).hash;
|
||||
|
||||
const onDocRef = useCallback(
|
||||
(el: PageEditor) => {
|
||||
docRef.current = el;
|
||||
@@ -98,13 +104,14 @@ export const BlocksuiteDocEditor = forwardRef<
|
||||
if (docPage) {
|
||||
setDocPage(docPage);
|
||||
}
|
||||
if (titleRef.current) {
|
||||
if (titleRef.current && !hash) {
|
||||
const richText = titleRef.current.querySelector('rich-text');
|
||||
richText?.inlineEditor?.focusEnd();
|
||||
} else {
|
||||
docPage?.focusFirstParagraph();
|
||||
}
|
||||
});
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { toast } from '@affine/component';
|
||||
import { notify } from '@affine/component';
|
||||
import { getAffineCloudBaseUrl } from '@affine/core/modules/cloud/services/fetch';
|
||||
import { WorkbenchService } from '@affine/core/modules/workbench';
|
||||
import { mixpanel } from '@affine/core/utils';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useLiveData, useService } from '@toeverything/infra';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
|
||||
type UrlType = 'share' | 'workspace';
|
||||
|
||||
@@ -19,28 +21,18 @@ const useGenerateUrl = ({ workspaceId, pageId, urlType }: UseSharingUrl) => {
|
||||
// to generate a public url like https://app.affine.app/share/123/456
|
||||
// or https://app.affine.app/share/123/456?mode=edgeless
|
||||
|
||||
const [hash, setHash] = useState(window.location.hash);
|
||||
|
||||
useEffect(() => {
|
||||
const handleLocationChange = () => {
|
||||
setHash(window.location.hash);
|
||||
};
|
||||
window.addEventListener('hashchange-custom', handleLocationChange);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('hashchange-custom', handleLocationChange);
|
||||
};
|
||||
}, [setHash]);
|
||||
const workbench = useService(WorkbenchService).workbench;
|
||||
const activeView = useLiveData(workbench.activeView$);
|
||||
const hash = useLiveData(activeView.location$).hash;
|
||||
|
||||
const baseUrl = getAffineCloudBaseUrl();
|
||||
|
||||
const url = useMemo(() => {
|
||||
// baseUrl is null when running in electron and without network
|
||||
if (!baseUrl) return null;
|
||||
|
||||
try {
|
||||
return new URL(
|
||||
`${baseUrl}/${urlType}/${workspaceId}/${pageId}${urlType === 'workspace' ? `${hash}` : ''}`
|
||||
`${baseUrl}/${urlType}/${workspaceId}/${pageId}${urlType === 'workspace' && hash ? `${hash}` : ''}`
|
||||
).toString();
|
||||
} catch (e) {
|
||||
return null;
|
||||
@@ -63,7 +55,9 @@ export const useSharingUrl = ({
|
||||
navigator.clipboard
|
||||
.writeText(sharingUrl)
|
||||
.then(() => {
|
||||
toast(t['Copied link to clipboard']());
|
||||
notify.success({
|
||||
title: t['Copied link to clipboard'](),
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
@@ -73,7 +67,9 @@ export const useSharingUrl = ({
|
||||
type: 'link',
|
||||
});
|
||||
} else {
|
||||
toast('Network not available');
|
||||
notify.error({
|
||||
title: 'Network not available',
|
||||
});
|
||||
}
|
||||
}, [sharingUrl, t, urlType]);
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ export class WorkspaceSQLiteDB {
|
||||
logger.debug(`trim ${this.workspaceId}:${dbID} ${count}`);
|
||||
const updates = await this.adapter.getUpdates(dbID);
|
||||
const update = mergeUpdate(updates.map(row => row.data));
|
||||
const insertRows = [{ data: update, dbID }];
|
||||
const insertRows = [{ data: update, docId: dbID }];
|
||||
await this.adapter?.replaceUpdates(dbID, insertRows);
|
||||
logger.debug(`trim ${this.workspaceId}:${dbID} successfully`);
|
||||
return update;
|
||||
|
||||
@@ -66,7 +66,7 @@ export const LOCALES = [
|
||||
originalName: '简体中文',
|
||||
flagEmoji: '🇨🇳',
|
||||
base: false,
|
||||
completeRate: 1,
|
||||
completeRate: 0.99,
|
||||
res: zh_Hans,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import './polyfill/dispose';
|
||||
import './polyfill/intl-segmenter';
|
||||
import './polyfill/promise-with-resolvers';
|
||||
import './polyfill/request-idle-callback';
|
||||
import '@affine/core/bootstrap/preload';
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
import 'core-js/features/promise/with-resolvers';
|
||||
@@ -8,6 +8,7 @@
|
||||
"electron",
|
||||
"server",
|
||||
"core",
|
||||
"web",
|
||||
"docs",
|
||||
"storybook",
|
||||
"component",
|
||||
|
||||
Reference in New Issue
Block a user