mirror of
https://github.com/tiddly-gittly/TidGi-Desktop.git
synced 2025-12-06 02:30:47 -08:00
feat: auto open clone repo tab after login, by update windowMeta after reload
This commit is contained in:
parent
e55097618f
commit
4724020772
17 changed files with 69 additions and 40 deletions
|
|
@ -33,8 +33,6 @@ export function useGetGithubUserInfoOnLoad(): void {
|
|||
useEffect(() => {
|
||||
void window.service.auth.get(`${SupportedStorageServices.github}-token`).then(async (githubToken) => {
|
||||
try {
|
||||
// DEBUG: console githubToken
|
||||
console.log(`githubToken`, githubToken);
|
||||
if (githubToken) {
|
||||
// get user name and email using github api
|
||||
const response = await fetch('https://api.github.com/user', {
|
||||
|
|
@ -44,8 +42,6 @@ export function useGetGithubUserInfoOnLoad(): void {
|
|||
},
|
||||
});
|
||||
const userInfo = await (response.json() as Promise<{ email: string; login: string; name: string }>);
|
||||
// DEBUG: console userInfo
|
||||
console.log(`userInfo`, userInfo);
|
||||
await window.service.auth.set(`${SupportedStorageServices.github}-userName`, userInfo.login);
|
||||
await window.service.auth.set('userName', userInfo.name);
|
||||
await window.service.auth.set(`${SupportedStorageServices.github}-email`, userInfo.email);
|
||||
|
|
|
|||
|
|
@ -86,16 +86,16 @@ export enum WikiChannel {
|
|||
name = 'WikiChannel',
|
||||
openTiddler = 'wiki-open-tiddler',
|
||||
printTiddler = 'print-tiddler',
|
||||
/**
|
||||
* Render wiki text to html
|
||||
*/
|
||||
renderWikiText = 'render-wiki-text',
|
||||
runFilter = 'wiki-run-filter',
|
||||
sendActionMessage = 'wiki-send-action-message',
|
||||
setState = 'wiki-set-state',
|
||||
setTiddlerText = 'wiki-set-tiddler-text',
|
||||
/** show message inside tiddlywiki to show git sync progress */
|
||||
syncProgress = 'wiki-sync-progress',
|
||||
/**
|
||||
* Render wiki text to html
|
||||
*/
|
||||
renderWikiText = 'render-wiki-text',
|
||||
}
|
||||
export enum WikiGitWorkspaceChannel {
|
||||
name = 'WikiGitWorkspaceChannel',
|
||||
|
|
@ -145,6 +145,7 @@ export enum MetaDataChannel {
|
|||
browserViewMetaData = 'browserViewMetaData',
|
||||
getViewMetaData = 'getViewMetaData',
|
||||
name = 'MetaDataChannel',
|
||||
pushViewMetaData = 'pushViewMetaData',
|
||||
}
|
||||
|
||||
export type Channels =
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import os from 'os';
|
||||
import path from 'path';
|
||||
import { isMac } from '../helpers/system';
|
||||
import { GITHUB_LOGIN_REDIRECT_PATH, GITHUB_OAUTH_APP_CLIENT_ID } from './auth';
|
||||
import { isDevelopmentOrTest } from './environment';
|
||||
import { developmentWikiFolderName, localizationFolderName } from './fileNames';
|
||||
|
||||
|
|
|
|||
6
src/pages/AddWorkspace/constants.ts
Normal file
6
src/pages/AddWorkspace/constants.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
export enum CreateWorkspaceTabs {
|
||||
CloneOnlineWiki = 'CloneOnlineWiki',
|
||||
CreateNewWiki = 'CreateNewWiki',
|
||||
OpenLocalWiki = 'OpenLocalWiki',
|
||||
OpenLocalWikiFromHtml = 'OpenLocalWikiFromHtml',
|
||||
}
|
||||
|
|
@ -20,18 +20,13 @@ import { IErrorInWhichComponent, useWikiWorkspaceForm } from './useForm';
|
|||
|
||||
import { TokenForm } from '@/components/TokenForm';
|
||||
import { usePromiseValue } from '@/helpers/useServiceValue';
|
||||
import { IPossibleWindowMeta, WindowMeta, WindowNames } from '@services/windows/WindowProperties';
|
||||
import { CreateWorkspaceTabs } from './constants';
|
||||
import { LocationPickerContainer, LocationPickerInput } from './FormComponents';
|
||||
import { GitRepoUrlForm } from './GitRepoUrlForm';
|
||||
import { ImportHtmlWikiDoneButton } from './ImportHtmlWikiDoneButton';
|
||||
import { ImportHtmlWikiForm } from './ImportHtmlWikiForm';
|
||||
|
||||
enum CreateWorkspaceTabs {
|
||||
CloneOnlineWiki = 'CloneOnlineWiki',
|
||||
CreateNewWiki = 'CreateNewWiki',
|
||||
OpenLocalWiki = 'OpenLocalWiki',
|
||||
OpenLocalWikiFromHtml = 'OpenLocalWikiFromHtml',
|
||||
}
|
||||
|
||||
export const Paper = styled(PaperRaw)`
|
||||
border-color: ${({ theme }) => theme.palette.divider};
|
||||
background: ${({ theme }) => theme.palette.background.paper};
|
||||
|
|
@ -78,7 +73,9 @@ const AdvancedSettingsAccordionSummary = styled(AccordionSummary)`
|
|||
|
||||
export function AddWorkspace(): JSX.Element {
|
||||
const { t } = useTranslation();
|
||||
const [currentTab, currentTabSetter] = useState<CreateWorkspaceTabs>(CreateWorkspaceTabs.CreateNewWiki);
|
||||
const [currentTab, currentTabSetter] = useState<CreateWorkspaceTabs>(
|
||||
(window.meta() as IPossibleWindowMeta<WindowMeta[WindowNames.addWorkspace]>)?.addWorkspaceTab ?? CreateWorkspaceTabs.CreateNewWiki,
|
||||
);
|
||||
const isCreateSyncedWorkspace = currentTab === CreateWorkspaceTabs.CloneOnlineWiki;
|
||||
const [isCreateMainWorkspace, isCreateMainWorkspaceSetter] = useState(true);
|
||||
const form = useWikiWorkspaceForm();
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ const getValidIconPath = (iconPath?: string | null): string => {
|
|||
return defaultIcon;
|
||||
};
|
||||
|
||||
const workspaceID = (window.meta as WindowMeta[WindowNames.editWorkspace]).workspaceID as string;
|
||||
const workspaceID = (window.meta() as WindowMeta[WindowNames.editWorkspace]).workspaceID as string;
|
||||
|
||||
export default function EditWorkspace(): JSX.Element {
|
||||
const { t } = useTranslation();
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ export default function Notifications(): JSX.Element {
|
|||
<ListItemText
|
||||
primary={pauseNotificationsInfo.reason === 'scheduled' ? 'Adjust schedule...' : 'Pause notifications by schedule...'}
|
||||
onClick={async () => {
|
||||
await window.service.window.open(WindowNames.preferences, { gotoTab: PreferenceSections.notifications });
|
||||
await window.service.window.open(WindowNames.preferences, { preferenceGotoTab: PreferenceSections.notifications });
|
||||
void window.remote.closeCurrentWindow();
|
||||
}}
|
||||
/>
|
||||
|
|
@ -179,7 +179,7 @@ export default function Notifications(): JSX.Element {
|
|||
<ListItemText
|
||||
primary='Pause notifications by schedule...'
|
||||
onClick={async () => {
|
||||
await window.service.window.open(WindowNames.preferences, { gotoTab: PreferenceSections.notifications });
|
||||
await window.service.window.open(WindowNames.preferences, { preferenceGotoTab: PreferenceSections.notifications });
|
||||
void window.remote.closeCurrentWindow();
|
||||
}}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ export default function Preferences(): JSX.Element {
|
|||
|
||||
// handle open preference from other window, and goto some tab
|
||||
useEffect(() => {
|
||||
const scrollTo = (window.meta as IPossibleWindowMeta<WindowMeta[WindowNames.preferences]>).gotoTab;
|
||||
const scrollTo = (window.meta() as IPossibleWindowMeta<WindowMeta[WindowNames.preferences]>).preferenceGotoTab;
|
||||
if (scrollTo === undefined) return;
|
||||
sections[scrollTo].ref?.current?.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
}, [sections]);
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ export function ViewLoadErrorMessages(props: IViewLoadErrorMessagesProps): JSX.E
|
|||
const { t } = useTranslation();
|
||||
const requestReload = useCallback(async (): Promise<void> => {
|
||||
await window.service.workspace.updateMetaData(props.activeWorkspace.id, { didFailLoadErrorMessage: null, isLoading: false });
|
||||
await window.service.window.reload(window.meta.windowName);
|
||||
await window.service.window.reload(window.meta().windowName);
|
||||
await window.service.view.removeAllViewOfWorkspace(props.activeWorkspace.id);
|
||||
await window.service.wiki.stopWiki(props.activeWorkspace.id);
|
||||
await window.service.workspaceView.initializeWorkspaceView(props.activeWorkspace);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ const SpellcheckLanguages = lazy(() => import('./SpellcheckLanguages'));
|
|||
export function Pages(): JSX.Element {
|
||||
const [, setLocation] = useLocation();
|
||||
useEffect(() => {
|
||||
setLocation(`/${window.meta.windowName}`);
|
||||
setLocation(`/${window.meta().windowName}`);
|
||||
}, [setLocation]);
|
||||
return (
|
||||
<Switch>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
/* eslint-disable @typescript-eslint/strict-boolean-expressions */
|
||||
// on production build, if we try to redirect to http://localhost:3012 , we will reach chrome-error://chromewebdata/ , but we can easily get back
|
||||
// this happens when we are redirected by OAuth login
|
||||
import { CreateWorkspaceTabs } from '@/pages/AddWorkspace/constants';
|
||||
import { PreferenceSections } from '@services/preferences/interface';
|
||||
import { SupportedStorageServices } from '@services/types';
|
||||
import { WindowNames } from '@services/windows/WindowProperties';
|
||||
import { WindowMeta, WindowNames } from '@services/windows/WindowProperties';
|
||||
import { windowName } from './browserViewMetaData';
|
||||
import { context, window as windowService } from './services';
|
||||
|
||||
|
|
@ -62,6 +64,13 @@ async function refresh(): Promise<void> {
|
|||
const { access_token: token } = await (response.json() as Promise<{ access_token: string }>);
|
||||
await window.service.auth.set(`${SupportedStorageServices.github}-token`, token);
|
||||
}
|
||||
await windowService.updateWindowMeta(
|
||||
windowName,
|
||||
{
|
||||
addWorkspaceTab: CreateWorkspaceTabs.CloneOnlineWiki,
|
||||
preferenceGotoTab: PreferenceSections.sync,
|
||||
} satisfies WindowMeta[WindowNames.addWorkspace] & WindowMeta[WindowNames.preferences],
|
||||
);
|
||||
await windowService.loadURL(windowName, MAIN_WINDOW_WEBPACK_ENTRY);
|
||||
} else if (window.location.href === CHROME_ERROR_PATH) {
|
||||
await windowService.loadURL(windowName, MAIN_WINDOW_WEBPACK_ENTRY);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { MetaDataChannel } from '@/constants/channels';
|
||||
import { WindowMeta, WindowNames } from '@services/windows/WindowProperties';
|
||||
import { IPossibleWindowMeta, WindowMeta, WindowNames } from '@services/windows/WindowProperties';
|
||||
import { contextBridge, ipcRenderer } from 'electron';
|
||||
|
||||
const metaDataArguments = process.argv
|
||||
|
|
@ -16,8 +16,14 @@ try {
|
|||
);
|
||||
}
|
||||
|
||||
export const browserViewMetaData = { windowName, ...extraMeta };
|
||||
contextBridge.exposeInMainWorld('meta', browserViewMetaData);
|
||||
export let browserViewMetaData = { windowName, ...extraMeta };
|
||||
contextBridge.exposeInMainWorld('meta', () => browserViewMetaData);
|
||||
ipcRenderer.on(MetaDataChannel.getViewMetaData, (event, payload?: { ipcToken: string }) => {
|
||||
ipcRenderer.send(`${MetaDataChannel.getViewMetaData}-${payload?.ipcToken ?? ''}`, browserViewMetaData);
|
||||
});
|
||||
/**
|
||||
* Receive update or windowMeta from server service.
|
||||
*/
|
||||
ipcRenderer.on(MetaDataChannel.pushViewMetaData, (event, payload?: IPossibleWindowMeta) => {
|
||||
browserViewMetaData = { ...browserViewMetaData, ...payload };
|
||||
});
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import { fixAlertConfirm } from './fixer/fixAlertConfirm';
|
|||
|
||||
declare global {
|
||||
interface Window {
|
||||
meta: IPossibleWindowMeta;
|
||||
meta: () => IPossibleWindowMeta;
|
||||
observables: IServicesWithOnlyObservables<typeof service>;
|
||||
service: IServicesWithoutObservables<typeof service>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ function getInfoTiddlerFields(updateInfoTiddlersCallback: (infos: Array<{ text:
|
|||
// Basics
|
||||
if (!$tw.browser || typeof window === 'undefined') return infoTiddlerFields;
|
||||
const isInTidGi = typeof document !== 'undefined' && document?.location?.protocol?.startsWith('tidgi');
|
||||
const workspaceID = (window.meta as WindowMeta[WindowNames.view] | undefined)?.workspaceID;
|
||||
const workspaceID = (window.meta() as WindowMeta[WindowNames.view] | undefined)?.workspaceID;
|
||||
infoTiddlerFields.push({ title: '$:/info/tidgi', text: mapBoolean(isInTidGi) });
|
||||
if (isInTidGi && workspaceID) {
|
||||
infoTiddlerFields.push({ title: '$:/info/tidgi/workspaceID', text: workspaceID });
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class TidGiIPCSyncAdaptor {
|
|||
this.isLoggedIn = false;
|
||||
this.isReadOnly = false;
|
||||
this.logoutIsAvailable = true;
|
||||
this.workspaceID = (window.meta as WindowMeta[WindowNames.view]).workspaceID!;
|
||||
this.workspaceID = (window.meta() as WindowMeta[WindowNames.view]).workspaceID!;
|
||||
if (window.observables?.wiki?.getWikiChangeObserver$ !== undefined) {
|
||||
// if install-electron-ipc-cat is faster than us, just subscribe to the observable. Otherwise we normally will wait for it to call us here.
|
||||
this.setupSSE();
|
||||
|
|
@ -336,7 +336,7 @@ class TidGiIPCSyncAdaptor {
|
|||
if ($tw.browser && typeof window !== 'undefined') {
|
||||
const isInTidGi = typeof document !== 'undefined' && document?.location?.protocol?.startsWith('tidgi');
|
||||
const servicesExposed = Boolean(window.service?.wiki);
|
||||
const hasWorkspaceIDinMeta = Boolean((window.meta as WindowMeta[WindowNames.view] | undefined)?.workspaceID);
|
||||
const hasWorkspaceIDinMeta = Boolean((window.meta() as WindowMeta[WindowNames.view] | undefined)?.workspaceID);
|
||||
if (isInTidGi && servicesExposed && hasWorkspaceIDinMeta) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
exports.adaptorClass = TidGiIPCSyncAdaptor;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import type { CreateWorkspaceTabs } from '@/pages/AddWorkspace/constants';
|
||||
import type { PreferenceSections } from '@services/preferences/interface';
|
||||
|
||||
export enum WindowNames {
|
||||
|
|
@ -84,7 +85,7 @@ export const windowDimension: Record<WindowNames, { height?: number; width?: num
|
|||
};
|
||||
|
||||
export interface IPreferenceWindowMeta {
|
||||
gotoTab?: PreferenceSections;
|
||||
preferenceGotoTab?: PreferenceSections;
|
||||
preventClosingWindow?: boolean;
|
||||
}
|
||||
|
||||
|
|
@ -94,8 +95,8 @@ export interface IPreferenceWindowMeta {
|
|||
*/
|
||||
export interface WindowMeta {
|
||||
[WindowNames.about]: undefined;
|
||||
[WindowNames.addWorkspace]: undefined;
|
||||
[WindowNames.any]: { uri: string };
|
||||
[WindowNames.addWorkspace]: { addWorkspaceTab?: CreateWorkspaceTabs };
|
||||
[WindowNames.any]: { uri?: string };
|
||||
[WindowNames.auth]: undefined;
|
||||
[WindowNames.editWorkspace]: { workspaceID?: string };
|
||||
[WindowNames.main]: { forceClose?: boolean };
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ export class Window implements IWindowService {
|
|||
config?: IWindowOpenConfig<N>,
|
||||
): Promise<BrowserWindow> {
|
||||
const newWindow = new BrowserWindow(windowConfig);
|
||||
const newWindowURL = windowMeta !== undefined && 'uri' in windowMeta ? windowMeta.uri : MAIN_WINDOW_WEBPACK_ENTRY;
|
||||
const newWindowURL = (windowMeta !== undefined && 'uri' in windowMeta ? windowMeta.uri : undefined) ?? MAIN_WINDOW_WEBPACK_ENTRY;
|
||||
if (config?.multiple !== true) {
|
||||
this.windows[windowName] = newWindow;
|
||||
}
|
||||
|
|
@ -303,13 +303,13 @@ export class Window implements IWindowService {
|
|||
newWindow.on('enter-full-screen', async () => {
|
||||
const mainWindow = this.get(windowName);
|
||||
if (mainWindow === undefined) return;
|
||||
mainWindow?.webContents.send('is-fullscreen-updated', true);
|
||||
mainWindow?.webContents?.send?.('is-fullscreen-updated', true);
|
||||
await this.workspaceViewService.realignActiveWorkspace();
|
||||
});
|
||||
newWindow.on('leave-full-screen', async () => {
|
||||
const mainWindow = this.get(windowName);
|
||||
if (mainWindow === undefined) return;
|
||||
mainWindow?.webContents.send('is-fullscreen-updated', false);
|
||||
mainWindow?.webContents?.send?.('is-fullscreen-updated', false);
|
||||
await this.workspaceViewService.realignActiveWorkspace();
|
||||
});
|
||||
}
|
||||
|
|
@ -323,13 +323,21 @@ export class Window implements IWindowService {
|
|||
}
|
||||
|
||||
public async updateWindowMeta<N extends WindowNames>(windowName: N, meta: WindowMeta[N]): Promise<void> {
|
||||
this.windowMeta[windowName] = { ...this.windowMeta[windowName], ...meta };
|
||||
const newMeta = { ...this.windowMeta[windowName], ...meta };
|
||||
this.windowMeta[windowName] = newMeta;
|
||||
}
|
||||
|
||||
public async getWindowMeta<N extends WindowNames>(windowName: N): Promise<WindowMeta[N] | undefined> {
|
||||
return this.windowMeta[windowName] as WindowMeta[N];
|
||||
}
|
||||
|
||||
/**
|
||||
* When using `loadURL`, window meta will be clear. And we can only append meta to a new window. So we need to push meta to window after `loadURL`.
|
||||
*/
|
||||
private async pushWindowMetaToWindow<N extends WindowNames>(win: BrowserWindow, meta: WindowMeta[N]): Promise<void> {
|
||||
win?.webContents?.send?.(MetaDataChannel.pushViewMetaData, meta);
|
||||
}
|
||||
|
||||
/**
|
||||
* BroadCast message to all opened windows, so we can sync state to redux and make them take effect immediately
|
||||
* @param channel ipc channel to send
|
||||
|
|
@ -375,12 +383,18 @@ export class Window implements IWindowService {
|
|||
|
||||
public async reload(windowName: WindowNames = WindowNames.main): Promise<void> {
|
||||
const win = this.get(windowName);
|
||||
win?.getBrowserView()?.webContents?.reload();
|
||||
if (win !== undefined) {
|
||||
win.getBrowserView()?.webContents?.reload?.();
|
||||
await this.pushWindowMetaToWindow(win, this.windowMeta[windowName]);
|
||||
}
|
||||
}
|
||||
|
||||
async loadURL(windowName: WindowNames, newUrl: string): Promise<void> {
|
||||
const win = this.get(windowName);
|
||||
await win?.loadURL(newUrl);
|
||||
if (win !== undefined) {
|
||||
await win.loadURL(newUrl);
|
||||
await this.pushWindowMetaToWindow(win, this.windowMeta[windowName]);
|
||||
}
|
||||
}
|
||||
|
||||
public async clearStorageData(windowName: WindowNames = WindowNames.main): Promise<void> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue