Skip to content

Commit

Permalink
fix: after import first time open will reload 2 times
Browse files Browse the repository at this point in the history
fixes #31
  • Loading branch information
linonetwo committed Jan 13, 2024
1 parent b237596 commit 1fc31fa
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 24 deletions.
1 change: 1 addition & 0 deletions src/pages/Importer/Index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ export const Importer: FC<StackScreenProps<RootStackParameterList, 'Importer'>>
<OpenWikiButton
mode='elevated'
onPress={() => {
navigation.navigate('MainMenu', { fromWikiID: createdWikiWorkspace.id });
navigation.navigate('WikiWebView', { id: createdWikiWorkspace.id });
}}
>
Expand Down
49 changes: 25 additions & 24 deletions src/pages/WikiWebView/useTiddlyWiki.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
/* eslint-disable @typescript-eslint/promise-function-async */
/* eslint-disable @typescript-eslint/strict-boolean-expressions */
/* eslint-disable unicorn/no-null */
import { Asset } from 'expo-asset';
import * as fs from 'expo-file-system';
import { useEffect, useState } from 'react';
import { useEffect, useRef, useState } from 'react';
import expoFileSystemSyncadaptorUiAssetID from '../../../assets/plugins/syncadaptor-ui.html';
import expoFileSystemSyncadaptorAssetID from '../../../assets/plugins/syncadaptor.html';
import { getWikiFilePath, getWikiTiddlerStorePath } from '../../constants/paths';
import { replaceTiddlerStoreScriptToTriggerFullReload } from '../../services/WikiHookService';
import { getSkinnyTiddlersJSONFromSQLite } from '../../services/WikiStorageService';
import { IWikiWorkspace } from '../../store/workspace';
import { usePromiseValue } from '../../utils/usePromiseValue';

export interface IHtmlContent {
html: string;
Expand All @@ -17,30 +19,29 @@ export interface IHtmlContent {
}
export function useTiddlyWiki(workspace: IWikiWorkspace, injectHtmlAndTiddlersStore: (htmlContent: IHtmlContent) => void, webviewLoaded: boolean, keyToTriggerReload: number) {
const [loadHtmlError, setLoadHtmlError] = useState('');

/**
* @url file:///data/user/0/host.exp.exponent/files/wikis/wiki/index.html or 'file:///data/user/0/host.exp.exponent/cache/ExponentAsset-8568a405f924c561e7d18846ddc10c97.html'
*/
const html = usePromiseValue<string>(() => fs.readAsStringAsync(getWikiFilePath(workspace)));
/**
* @url file:///data/user/0/host.exp.exponent/files/wikis/wiki/tiddlerStore.json
*/
const tiddlerStoreScript = usePromiseValue<string>(() => fs.readAsStringAsync(getWikiTiddlerStorePath(workspace)));
const skinnyTiddlerStore = usePromiseValue<string>(() => getSkinnyTiddlersJSONFromSQLite(workspace));
const pluginJSONStrings = usePromiseValue<ITidGiMobilePlugins>(() => getTidGiMobilePlugins());
useEffect(() => {
if (!webviewLoaded) return;
const fetchHTML = async () => {
try {
const [html, tiddlerStoreScript, skinnyTiddlerStore, pluginJSONStrings] = await Promise.all([
fs.readAsStringAsync(getWikiFilePath(workspace)), // file:///data/user/0/host.exp.exponent/files/wikis/wiki/index.html or 'file:///data/user/0/host.exp.exponent/cache/ExponentAsset-8568a405f924c561e7d18846ddc10c97.html'
fs.readAsStringAsync(getWikiTiddlerStorePath(workspace)), // file:///data/user/0/host.exp.exponent/files/wikis/wiki/tiddlerStore.json
getSkinnyTiddlersJSONFromSQLite(workspace),
getTidGiMobilePlugins(),
]);

const htmlWithPrefix = `<!doctype html>${html}`;
// inject tidgi syncadaptor plugins
const tidgiMobilePlugins = `,${pluginJSONStrings.expoFileSystemSyncadaptor},${pluginJSONStrings.expoFileSystemSyncadaptorUi}`;
const tiddlerStoreScriptWithTidGiMobilePlugins = `${patchTiddlyWiki(tiddlerStoreScript).slice(0, -1)}${tidgiMobilePlugins}]`;
injectHtmlAndTiddlersStore({ html: htmlWithPrefix, tiddlerStoreScript: tiddlerStoreScriptWithTidGiMobilePlugins, skinnyTiddlerStore });
} catch (error) {
console.error(error, (error as Error).stack);
setLoadHtmlError((error as Error).message);
}
};
void fetchHTML();
}, [workspace, injectHtmlAndTiddlersStore, webviewLoaded, keyToTriggerReload]);
if (!webviewLoaded || !html || !tiddlerStoreScript || !skinnyTiddlerStore || !pluginJSONStrings) return;
try {
const htmlWithPrefix = `<!doctype html>${html}`;
// inject tidgi syncadaptor plugins
const tidgiMobilePlugins = `,${pluginJSONStrings.expoFileSystemSyncadaptor},${pluginJSONStrings.expoFileSystemSyncadaptorUi}`;
const tiddlerStoreScriptWithTidGiMobilePlugins = `${patchTiddlyWiki(tiddlerStoreScript).slice(0, -1)}${tidgiMobilePlugins}]`;
injectHtmlAndTiddlersStore({ html: htmlWithPrefix, tiddlerStoreScript: tiddlerStoreScriptWithTidGiMobilePlugins, skinnyTiddlerStore });
} catch (error) {
console.error(error, (error as Error).stack);
setLoadHtmlError((error as Error).message);
}
}, [injectHtmlAndTiddlersStore, webviewLoaded, keyToTriggerReload, html, tiddlerStoreScript, skinnyTiddlerStore, pluginJSONStrings]);
return { loadHtmlError };
}
function patchTiddlyWiki(tiddlyWikiHTML: string): string {
Expand Down
32 changes: 32 additions & 0 deletions src/utils/usePromiseValue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { useEffect, useState } from 'react';
import { AsyncReturnType } from 'type-fest';

/**
* Use value from service, especially constant value that never changes
* This will only update once, won't listen on later update.
* @param valuePromise A promise contain the value we want to use in React
* @param defaultValue empty array or undefined, as initial value
*/
export function usePromiseValue<T, DefaultValueType = T | undefined>(
asyncValue: () => Promise<T>,
defaultValue?: AsyncReturnType<typeof asyncValue>,
dependency: unknown[] = [],
): T | DefaultValueType {
const [value, valueSetter] = useState<T | DefaultValueType>(defaultValue as T | DefaultValueType);
// use initial value
useEffect(() => {
void (async () => {
try {
valueSetter(await asyncValue());
} catch (error) {
console.error(error);
if (defaultValue !== undefined) {
valueSetter(defaultValue);
}
}
})();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, dependency);

return value;
}

0 comments on commit 1fc31fa

Please sign in to comment.