Merge pull request #458 from toeverything/develop

chore: sync & i18n
This commit is contained in:
DarkSky
2022-09-23 19:26:02 +08:00
committed by GitHub
10 changed files with 208 additions and 62 deletions

View File

@@ -203,10 +203,10 @@ module.exports = function (webpackConfig) {
new BundleAnalyzerPlugin({ analyzerMode: 'static' }), new BundleAnalyzerPlugin({ analyzerMode: 'static' }),
].filter(Boolean); ].filter(Boolean);
// Workaround for webpack infinite recompile errors
config.watchOptions = { config.watchOptions = {
// followSymlinks: false, // followSymlinks: false,
ignored: ['**/*.css'], // Ignore css to workaround webpack infinite recompile errors
ignored: ['**/node_modules', '**/*.css'],
}; };
return config; return config;

View File

@@ -80,7 +80,8 @@ const AffineBoard = ({
); );
}, },
async onChangePage(app, shapes, bindings, assets) { async onChangePage(app, shapes, bindings, assets) {
Promise.all( await services.api.editorBlock.suspend(workspace, true);
await Promise.all(
Object.entries(shapes).map(async ([id, shape]) => { Object.entries(shapes).map(async ([id, shape]) => {
if (shape === undefined) { if (shape === undefined) {
return services.api.editorBlock.delete({ return services.api.editorBlock.delete({
@@ -120,6 +121,7 @@ const AffineBoard = ({
} }
}) })
); );
await services.api.editorBlock.suspend(workspace, false);
}, },
}} }}
/> />

View File

@@ -1,4 +1,4 @@
import { Editor } from '@toeverything/components/board-shapes'; import { defaultStyle, Editor } from '@toeverything/components/board-shapes';
import type { TDShape } from '@toeverything/components/board-types'; import type { TDShape } from '@toeverything/components/board-types';
import type { ReturnEditorBlock } from '@toeverything/datasource/db-service'; import type { ReturnEditorBlock } from '@toeverything/datasource/db-service';
import { services } from '@toeverything/datasource/db-service'; import { services } from '@toeverything/datasource/db-service';
@@ -12,7 +12,35 @@ export const useShapes = (workspace: string, rootBlockId: string) => {
const [blocks, setBlocks] = useState<{ const [blocks, setBlocks] = useState<{
shapes: [ReturnEditorBlock[]]; shapes: [ReturnEditorBlock[]];
}>(); }>();
useEffect(() => { useEffect(() => {
const unobservesMap = new Map();
const observeChild = async (childId: string) => {
unobservesMap.set(
childId,
await services.api.editorBlock.observe(
{ workspace, id: childId },
blockData => {
setBlocks(data => {
const blockShapes = data?.shapes?.[0];
const idx =
blockShapes.findIndex(
s => s.id === blockData.id
) || -1;
const newBlockShapes = [...blockShapes];
if (idx > -1) {
newBlockShapes[idx] = blockData;
} else {
newBlockShapes.push(blockData);
}
return {
shapes: [newBlockShapes],
};
});
}
)
);
};
Promise.all([ Promise.all([
services.api.editorBlock services.api.editorBlock
.get({ workspace, ids: [rootBlockId] }) .get({ workspace, ids: [rootBlockId] })
@@ -25,6 +53,7 @@ export const useShapes = (workspace: string, rootBlockId: string) => {
ids: [childId], ids: [childId],
}) })
)?.[0]; )?.[0];
observeChild(childBlock.id);
return childBlock; return childBlock;
}) })
); );
@@ -47,6 +76,9 @@ export const useShapes = (workspace: string, rootBlockId: string) => {
ids: [childId], ids: [childId],
}) })
)?.[0]; )?.[0];
if (!unobservesMap.has(childBlock.id)) {
observeChild(childBlock.id);
}
return childBlock; return childBlock;
}) })
).then(shapes => { ).then(shapes => {
@@ -65,17 +97,27 @@ export const useShapes = (workspace: string, rootBlockId: string) => {
}, [workspace, rootBlockId]); }, [workspace, rootBlockId]);
let groupCount = 0; let groupCount = 0;
let blocksShapes = blocks?.shapes[0]?.reduce((acc, block) => { const blocksShapes = blocks?.shapes[0]?.reduce((acc, block) => {
const shapeProps = block.properties.shapeProps?.value const shapeProps = block.properties.shapeProps?.value
? JSON.parse(block.properties.shapeProps.value) ? JSON.parse(block.properties.shapeProps.value)
: {}; : {};
if (block.type === 'shape') { if (block.type === 'shape') {
acc[block.id] = { ...shapeProps, id: block.id }; acc[block.id] = {
type: 'rectangle',
size: [0, 0],
point: [0, 0],
parentId: rootBlockId,
...shapeProps,
id: block.id,
style: { ...defaultStyle },
workspace,
};
} else { } else {
acc[block.id] = Editor.getShape({ acc[block.id] = Editor.getShape({
point: [groupCount * editorShapeInitSize + 200, 200], point: [groupCount * editorShapeInitSize + 200, 200],
id: block.id, id: block.id,
size: [editorShapeInitSize, 200], size: [editorShapeInitSize, 200],
parentId: rootBlockId,
...shapeProps, ...shapeProps,
affineId: shapeProps.affineId ?? block.id, affineId: shapeProps.affineId ?? block.id,
workspace: block.workspace, workspace: block.workspace,

View File

@@ -35,8 +35,8 @@ export abstract class ServiceBaseClass {
name: string, name: string,
callback: (meta: Map<string, any>) => void callback: (meta: Map<string, any>) => void
) { ) {
const db = await this.database.getDatabase(workspace); // const db = await this.database.getDatabase(workspace);
db.history.onPush(name, callback); // db.history.onPush(name, callback);
} }
async onHistoryRevoke( async onHistoryRevoke(
@@ -44,8 +44,8 @@ export abstract class ServiceBaseClass {
name: string, name: string,
callback: (meta: Map<string, any>) => void callback: (meta: Map<string, any>) => void
) { ) {
const db = await this.database.getDatabase(workspace); // const db = await this.database.getDatabase(workspace);
db.history.onPop(name, callback); // db.history.onPop(name, callback);
} }
async undo(workspace: string) { async undo(workspace: string) {

View File

@@ -32,7 +32,7 @@ async function _getCurrentToken() {
const _enabled = { const _enabled = {
demo: [], demo: [],
AFFiNE: process.env['NX_KECK'] ? ['idb', 'keck'] : ['idb'], AFFiNE: process.env['NX_KECK'] ? ['keck'] : ['idb'],
} as any; } as any;
async function _getBlockDatabase( async function _getBlockDatabase(

View File

@@ -3,6 +3,8 @@
// To overwrite this, please overwrite download.ts // To overwrite this, please overwrite download.ts
import en from './en.json'; import en from './en.json';
import zh_Hans from './zh-Hans.json'; import zh_Hans from './zh-Hans.json';
import zh_Hant from './zh-Hant.json';
import sr from './sr.json';
export const LOCALES = [ export const LOCALES = [
{ {
@@ -25,4 +27,24 @@ export const LOCALES = [
completeRate: 1, completeRate: 1,
res: zh_Hans, res: zh_Hans,
}, },
{
id: 1000016012,
name: 'Traditional Chinese',
tag: 'zh-Hant',
originalName: '繁體中文',
flagEmoji: '🇭🇰',
base: false,
completeRate: 1,
res: zh_Hant,
},
{
id: 1000034005,
name: 'Serbian',
tag: 'sr',
originalName: 'српски',
flagEmoji: '🇷🇸',
base: false,
completeRate: 0.9166666666666666,
res: sr,
},
] as const; ] as const;

View File

@@ -0,0 +1,27 @@
{
"// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.": "",
"Clear Workspace": "Očisti radni prostor",
"ComingSoon": "Podešavanja za izgled dolaze",
"Comment": "Komentar",
"Copy Page Link": "Kopiraj link stranice",
"Delete": "Obriši",
"Duplicate Page": "Dupliraj stranicu",
"Export As HTML": "Izvezi kao HTML",
"Export As Markdown": "Izvezi kao Markdown",
"Export As PDF (Unsupported)": "Izvezi kao PDF (nepodržano)",
"Export Workspace": "Izvezi radnu površinu",
"Import Workspace": "Poboljšaj radnu površinu",
"Language": "Jezik",
"Last edited by": "Zadnju promenu uradio {{ime}}",
"Layout": "Izgled",
"Logout": "Odjava",
"Settings": "Podešavanja",
"Share": "Podeli",
"Sync to Disk": "Sinhroniziraj sa diskom",
"Turn into": "Promeni u",
"WarningTips": {
"DoNotStore": "AFFiNE je u stanju aktivnog razvoja i trenutna verzija je NESTABILNA. Molimo vas, NEMOJTE čuvati informacije ili podatke.",
"IsNotLocalWorkspace": "Dobrodošli u AFFiNE demo. Da bi započeli proces čuvanja promena možete kliknuti SINHRONIZUJ SA DISKOM.",
"IsNotfsApiSupported": "Dobrodošli u AFFiNE demo. Da bi započeli proces čuvanja promena možete SINHRONIZOVATI NA DISK sa poslednjom verzijom pretraživača tipa Chromium, kao što su Chrome/Edge."
}
}

View File

@@ -0,0 +1,29 @@
{
"// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.": "",
"Add A Below Block": "在下方新添塊",
"Clear Workspace": "清空工作區",
"ComingSoon": "自定義佈局功能即將與您見面",
"Comment": "評論",
"Copy Page Link": "拷貝頁面鏈接",
"Delete": "刪除",
"Divide Here As A New Group": "從此地劃分成新組",
"Duplicate Page": "複製界面",
"Export As HTML": "導出 HTML",
"Export As Markdown": "以 Markdown 導出",
"Export As PDF (Unsupported)": "導出為 PDF(即將可用)",
"Export Workspace": "導出 Workspace",
"Import Workspace": "導入 Workspace",
"Language": "語言",
"Last edited by": "最後編輯者為 {{name}}",
"Layout": "佈局",
"Logout": "退出登錄",
"Settings": "設置",
"Share": "分享",
"Sync to Disk": "同步到磁盤",
"Turn into": "轉換為",
"WarningTips": {
"DoNotStore": "我們正在積極開發 AFFiNE,目前版本尚不穩定,請避免存儲信息或數據。",
"IsNotLocalWorkspace": "歡迎來到 AFFiNE 演示界面。您可以通過「同步到磁盤」來保存更改。",
"IsNotfsApiSupported": "歡迎進入AFFINE演示!使用最新版本的基於 Chromium 內核的瀏覽器如Chrome/Edge,您可以通過「同步到磁盤」來保存更改"
}
}

View File

@@ -65,6 +65,26 @@ export const registerWebsocket = (
let websocket: WebSocket | undefined = undefined; let websocket: WebSocket | undefined = undefined;
const broadcastMessage = (buf: ArrayBuffer) => {
if (state === WebSocketState.connected) {
websocket?.send(buf);
}
};
const disconnect = () => {
if (websocket != null) {
websocket.close();
websocket = undefined;
state = WebSocketState.disconnected;
if (resyncInterval !== 0) {
clearInterval(resyncInterval);
}
clearInterval(checkInterval);
}
};
const ret = { broadcastMessage, disconnect };
_getToken( _getToken(
provider.url, provider.url,
token, token,
@@ -126,15 +146,26 @@ export const registerWebsocket = (
if (reconnect <= 0) provider.emit('lost-connection', []); if (reconnect <= 0) provider.emit('lost-connection', []);
// Start with no reconnect timeout and increase timeout by // Start with no reconnect timeout and increase timeout by
// using exponential backoff starting with 100ms // using exponential backoff starting with 100ms
setTimeout( setTimeout(() => {
registerWebsocket, const newRet = registerWebsocket(
_getTimeout(provider), provider,
provider, token,
token, resyncInterval,
resyncInterval, reconnect > 0 ? reconnect - 1 : 3,
reconnect > 0 ? reconnect - 1 : 3, protocol
protocol );
); ret.broadcastMessage = newRet.broadcastMessage;
ret.disconnect = newRet.disconnect;
}, _getTimeout(provider));
// setTimeout(
// registerWebsocket,
// _getTimeout(provider),
// provider,
// token,
// resyncInterval,
// reconnect > 0 ? reconnect - 1 : 3,
// protocol
// );
}; };
websocket.onopen = () => { websocket.onopen = () => {
lastMessageReceived = time.getUnixTime(); lastMessageReceived = time.getUnixTime();
@@ -172,14 +203,24 @@ export const registerWebsocket = (
.catch(err => { .catch(err => {
provider.emit('lost-connection', []); provider.emit('lost-connection', []);
provider.wsUnsuccessfulReconnects++; provider.wsUnsuccessfulReconnects++;
setTimeout( setTimeout(() => {
registerWebsocket, const newRet = registerWebsocket(
_getTimeout(provider), provider,
provider, token,
token, resyncInterval,
resyncInterval, reconnect > 0 ? reconnect - 1 : 3
reconnect > 0 ? reconnect - 1 : 3 );
); ret.broadcastMessage = newRet.broadcastMessage;
ret.disconnect = newRet.disconnect;
}, _getTimeout(provider));
// setTimeout(
// registerWebsocket,
// _getTimeout(provider),
// provider,
// token,
// resyncInterval,
// reconnect > 0 ? reconnect - 1 : 3
// );
}); });
let resyncInterval = 0; let resyncInterval = 0;
@@ -206,23 +247,5 @@ export const registerWebsocket = (
} }
}, WEBSOCKET_RECONNECT / 10); }, WEBSOCKET_RECONNECT / 10);
const broadcastMessage = (buf: ArrayBuffer) => { return ret;
if (state === WebSocketState.connected) {
websocket?.send(buf);
}
};
const disconnect = () => {
if (websocket != null) {
websocket.close();
websocket = undefined;
state = WebSocketState.disconnected;
if (resyncInterval !== 0) {
clearInterval(resyncInterval);
}
clearInterval(checkInterval);
}
};
return { broadcastMessage, disconnect };
}; };

View File

@@ -1,23 +1,24 @@
// eslint-disable-next-line no-restricted-imports // eslint-disable-next-line no-restricted-imports
export { export {
debounce,
throttle,
cloneDeep, cloneDeep,
isEqual, countBy,
sum,
has,
forEach,
upperFirst,
curry, curry,
isFunction, debounce,
isString,
isPlainObject,
lowerFirst,
last,
first,
without,
difference, difference,
escape, escape,
countBy, first,
forEach,
has,
isEqual,
isFunction,
isPlainObject,
isString,
last,
lowerFirst,
maxBy, maxBy,
pickBy,
sum,
throttle,
upperFirst,
without,
} from 'lodash-es'; } from 'lodash-es';