mirror of
https://github.com/tiddly-gittly/TidGi-Desktop.git
synced 2025-12-06 02:30:47 -08:00
feat: better doc sites list
This commit is contained in:
parent
5be3fb6e7b
commit
b06fd5e5b4
7 changed files with 222 additions and 75 deletions
|
|
@ -464,6 +464,9 @@
|
|||
"Edit": "Edit",
|
||||
"Open": "Open",
|
||||
"Help": {
|
||||
"Alternatives": "Alternatives"
|
||||
"Alternatives": "Alternatives",
|
||||
"Description": "Clicking the \"Open\" button will open the page in a new window. The page needs to be loaded from the Internet for the first time (5s - 1min), so it is not available when the network is disconnected. \nYou can modify the content of the opened page at will as a sandbox playground to try out the learned features. If you want to save the modified results, you can click Tiddlywiki's save button to save it as a single-page wiki in HTML format.",
|
||||
"List": "Helps List",
|
||||
"Contribute": "Contribute to this site"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -464,6 +464,9 @@
|
|||
"GenerationTimeout": "模型生成超时,已中止。"
|
||||
},
|
||||
"Help": {
|
||||
"Alternatives": "其它源"
|
||||
"Alternatives": "其它源",
|
||||
"Description": "点击「打开」按钮会在新窗口打开页面,页面初次打开需要5秒到1分钟时间从互联网加载,断网不可用。你可以随意修改打开的页面的内容,作为沙箱游乐场随意尝试学到的功能,如果想保存修改的结果,可以点击太微的保存按钮,保存为HTML格式的单页面维基。",
|
||||
"List": "帮助列表",
|
||||
"Contribute": "向此网站贡献内容"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,47 +1,61 @@
|
|||
/* eslint-disable @typescript-eslint/strict-boolean-expressions */
|
||||
/* eslint-disable unicorn/no-null */
|
||||
import { Button, Menu, MenuItem } from '@mui/material';
|
||||
import AccessibilityNewIcon from '@mui/icons-material/AccessibilityNew';
|
||||
import AltRouteIcon from '@mui/icons-material/AltRoute';
|
||||
import OpenInBrowserIcon from '@mui/icons-material/OpenInBrowser';
|
||||
import OpenInNewIcon from '@mui/icons-material/OpenInNew';
|
||||
import { Button, Card, CardActions, CardContent, ListItemIcon, ListItemText, Menu, MenuItem } from '@mui/material';
|
||||
import { WindowNames } from '@services/windows/WindowProperties';
|
||||
import React, { useState } from 'react';
|
||||
import { styled } from 'styled-components';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { styled } from 'styled-components';
|
||||
import { type useLoadHelpPagesList } from './useLoadHelpPagesList';
|
||||
|
||||
const StyledGridItem = styled.div`
|
||||
// Add styles for your grid item here
|
||||
const StyledCard = styled(Card)`
|
||||
`;
|
||||
|
||||
interface HelpWebsiteItemProps {
|
||||
item: {
|
||||
description: string;
|
||||
fallbackUrls: string[];
|
||||
title: string;
|
||||
url: string;
|
||||
};
|
||||
item: ReturnType<typeof useLoadHelpPagesList>[number];
|
||||
}
|
||||
|
||||
export const HelpWebsiteItem: React.FC<HelpWebsiteItemProps> = ({ item }) => {
|
||||
const { t } = useTranslation();
|
||||
const [anchorElement, setAnchorElement] = useState<null | HTMLElement>(null);
|
||||
|
||||
const openExternalLink = (uri: string) => {
|
||||
void window.service.window.open(WindowNames.any, { uri });
|
||||
const [sourceAnchorElement, setSourceAnchorElement] = useState<null | HTMLElement>(null);
|
||||
const handleOpenSourcesMenu = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||
setSourceAnchorElement(event.currentTarget);
|
||||
};
|
||||
|
||||
const handleOpenMenu = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||
setAnchorElement(event.currentTarget);
|
||||
const [moreAnchorElement, setMoreAnchorElement] = useState<null | HTMLElement>(null);
|
||||
const handleOpenMoreMenu = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||
setMoreAnchorElement(event.currentTarget);
|
||||
};
|
||||
|
||||
const handleCloseMenu = () => {
|
||||
setAnchorElement(null);
|
||||
setSourceAnchorElement(null);
|
||||
setMoreAnchorElement(null);
|
||||
};
|
||||
|
||||
const openExternalLinkInApp = (uri: string) => {
|
||||
void window.service.window.open(WindowNames.any, { uri });
|
||||
};
|
||||
const openExternalLinkInBrowser = (uri: string) => {
|
||||
void window.service.native.open(uri);
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledGridItem>
|
||||
<StyledCard>
|
||||
<CardContent>
|
||||
<h3>{item.title}</h3>
|
||||
<p>{item.description}</p>
|
||||
</CardContent>
|
||||
<CardActions>
|
||||
<Button
|
||||
onClick={() => {
|
||||
openExternalLink(item.url);
|
||||
openExternalLinkInApp(item.url);
|
||||
}}
|
||||
variant='contained'
|
||||
startIcon={<OpenInNewIcon />}
|
||||
>
|
||||
{t('Open')}
|
||||
</Button>
|
||||
|
|
@ -50,30 +64,72 @@ export const HelpWebsiteItem: React.FC<HelpWebsiteItemProps> = ({ item }) => {
|
|||
<Button
|
||||
aria-controls='fallback-menu'
|
||||
aria-haspopup='true'
|
||||
onClick={handleOpenMenu}
|
||||
onClick={handleOpenSourcesMenu}
|
||||
variant='contained'
|
||||
startIcon={<AltRouteIcon />}
|
||||
>
|
||||
{t('Help.Alternatives')}
|
||||
</Button>
|
||||
<Menu
|
||||
id='fallback-menu'
|
||||
anchorEl={anchorElement}
|
||||
anchorEl={sourceAnchorElement}
|
||||
keepMounted
|
||||
open={Boolean(anchorElement)}
|
||||
open={Boolean(sourceAnchorElement)}
|
||||
onClose={handleCloseMenu}
|
||||
>
|
||||
{item.fallbackUrls.map((url, index) => (
|
||||
<MenuItem
|
||||
key={index}
|
||||
onClick={() => {
|
||||
openExternalLink(url);
|
||||
openExternalLinkInApp(url);
|
||||
}}
|
||||
>
|
||||
{new URL(url).hostname}
|
||||
<ListItemIcon>
|
||||
<OpenInNewIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText>{new URL(url).hostname}</ListItemText>
|
||||
</MenuItem>
|
||||
))}
|
||||
</Menu>
|
||||
</>
|
||||
)}
|
||||
</StyledGridItem>
|
||||
<Menu
|
||||
id='more-menu'
|
||||
anchorEl={moreAnchorElement}
|
||||
keepMounted
|
||||
open={Boolean(moreAnchorElement)}
|
||||
onClose={handleCloseMenu}
|
||||
>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
openExternalLinkInBrowser(item.url);
|
||||
}}
|
||||
>
|
||||
<ListItemIcon>
|
||||
<OpenInBrowserIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText>{t('ContextMenu.OpenLinkInBrowser')}</ListItemText>
|
||||
</MenuItem>
|
||||
{item.contribute && (
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
openExternalLinkInBrowser(item.contribute);
|
||||
}}
|
||||
>
|
||||
<ListItemIcon>
|
||||
<AccessibilityNewIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText>{t('Help.Contribute')}</ListItemText>
|
||||
</MenuItem>
|
||||
)}
|
||||
</Menu>
|
||||
<Button
|
||||
onClick={handleOpenMoreMenu}
|
||||
variant='outlined'
|
||||
>
|
||||
{t('ContextMenu.More')}
|
||||
</Button>
|
||||
</CardActions>
|
||||
</StyledCard>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,10 +1,68 @@
|
|||
{
|
||||
"onlineSources": [
|
||||
"tidgi.fun/recipes/default/tiddlers.json?filter=[tag[HelpPage]]"
|
||||
"https://tidgi.fun/recipes/default/tiddlers.json?filter=[tag[HelpPage]]"
|
||||
],
|
||||
"default": [
|
||||
{"title":"Tiddlywiki XP", "description": "「一个快速体验太微的机会」—— 非常全面、易读,包括了很多非常基础的操作,例如「如何新建第一个笔记」","tags":"Intro","url":"https://keatonlao.gitee.io/tiddlywiki-xp/", "fallbackUrls": "https://keatonlao.github.io/tiddlywiki-xp/", "language": "zh-Hans"},
|
||||
{"title":"Grok TiddlyWiki", "description": "Build a deep, lasting understanding of TiddlyWiki","tags":"Intro FAQ","url":"https://groktiddlywiki.com/read/", "language": "en-GB"},
|
||||
{"title":"太微中文教程", "description": "中文社区共建的TiddlyWiki教程,体验从入门到知识管理大师之路","tags":"Intro","url":"https://tw-cn.netlify.app/", "fallbackUrls": "https://tw-cn.cpolar.top/ https://tiddly-wiki-chinese-tutorial.vercel.app/ https://tiddly-gittly.github.io/TiddlyWiki-Chinese-Tutorial/", "language": "zh-Hans"}
|
||||
{
|
||||
"title": "太记手册",
|
||||
"description": "太记桌面版的用法(不包含中文教程和XP里已写的内容)",
|
||||
"tags": "Intro",
|
||||
"url": "https://tidgi.fun/#TidGi-Handbook:TidGi-Handbook%20Index",
|
||||
"contribute": "https://github.com/tiddly-gittly/TidGi-Official-Website",
|
||||
"fallbackUrls": "https://tiddly-gittly.github.io/TidGi-Official-Website/#TidGi-Handbook:TidGi-Handbook%20Index",
|
||||
"language": "zh_CN"
|
||||
},
|
||||
{
|
||||
"title": "TidGi Handbook",
|
||||
"description": "Usage of TidGi Desktop app (Not including content already in Grok and official tw doc)",
|
||||
"tags": "Intro",
|
||||
"url": "https://tidgi.fun/#TidGi-Handbook:TidGi-Handbook%20Index",
|
||||
"contribute": "https://github.com/tiddly-gittly/TidGi-Official-Website",
|
||||
"fallbackUrls": "https://tiddly-gittly.github.io/TidGi-Official-Website/#TidGi-Handbook:TidGi-Handbook%20Index",
|
||||
"language": "en"
|
||||
},
|
||||
{
|
||||
"title": "Tiddlywiki XP",
|
||||
"description": "「一个快速体验太微的机会」—— 非常全面、易读,包括了很多非常基础的操作,例如「如何新建第一个笔记」",
|
||||
"tags": "Intro",
|
||||
"url": "https://keatonlao.gitee.io/tiddlywiki-xp/",
|
||||
"contribute": "https://github.com/keatonlao/tiddlywiki-xp",
|
||||
"fallbackUrls": "https://keatonlao.github.io/tiddlywiki-xp/",
|
||||
"language": "zh_CN"
|
||||
},
|
||||
{
|
||||
"title": "Grok TiddlyWiki",
|
||||
"description": "Build a deep, lasting understanding of TiddlyWiki",
|
||||
"tags": "Intro FAQ",
|
||||
"url": "https://groktiddlywiki.com/read/",
|
||||
"contribute": "https://groktiddlywiki.com/donate/",
|
||||
"language": "en"
|
||||
},
|
||||
{
|
||||
"title": "太微中文教程",
|
||||
"description": "中文社区共建的TiddlyWiki教程,体验从入门到知识管理大师之路",
|
||||
"tags": "Intro",
|
||||
"url": "https://tw-cn.netlify.app/",
|
||||
"contribute": "https://github.com/tiddly-gittly/TiddlyWiki-Chinese-Tutorial",
|
||||
"fallbackUrls": "https://tw-cn.cpolar.top/ https://tiddly-wiki-chinese-tutorial.vercel.app/ https://tiddly-gittly.github.io/TiddlyWiki-Chinese-Tutorial/",
|
||||
"language": "zh_CN"
|
||||
},
|
||||
{
|
||||
"title": "太微官方文档(中文版)",
|
||||
"description": "TiddlyWiki 舞 - 基础文档简体中文版",
|
||||
"tags": "Doc",
|
||||
"url": "https://tw-cn-doc.cpolar.top/",
|
||||
"contribute": "https://github.com/BramChen/tw5-docs",
|
||||
"fallbackUrls": "https://bramchen.github.io/tw5-docs/zh_CN/",
|
||||
"language": "zh_CN"
|
||||
},
|
||||
{
|
||||
"title": "TiddlyWiki",
|
||||
"description": "Official Document",
|
||||
"tags": "Doc",
|
||||
"url": "https://tiddlywiki.com/",
|
||||
"contribute": "https://github.com/Jermolene/TiddlyWiki5/tree/master/editions/tw5.com",
|
||||
"language": "en"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,10 +1,33 @@
|
|||
import { Grid } from '@mui/material';
|
||||
import { Divider, Grid, Typography } from '@mui/material';
|
||||
import { usePreferenceObservable } from '@services/preferences/hooks';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { styled } from 'styled-components';
|
||||
import { Languages } from '../Preferences/sections/Languages';
|
||||
import { HelpWebsiteItem } from './HelpWebsiteItem';
|
||||
import { useLoadHelpPagesList } from './useLoadHelpPagesList';
|
||||
|
||||
const InnerContentRoot = styled.div`
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
justify-content: flex-start;
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
`;
|
||||
|
||||
export function Help(): JSX.Element {
|
||||
const items = useLoadHelpPagesList();
|
||||
const { t } = useTranslation();
|
||||
const preference = usePreferenceObservable();
|
||||
const items = useLoadHelpPagesList(preference?.language);
|
||||
return (
|
||||
<>
|
||||
<Languages languageSelectorOnly />
|
||||
<InnerContentRoot>
|
||||
<Typography>{t('Help.Description')}</Typography>
|
||||
<Divider>{t('Help.List')}</Divider>
|
||||
<Grid container spacing={2}>
|
||||
{items.map((item, index) => (
|
||||
<Grid key={index} item xs={12} sm={6} md={4}>
|
||||
|
|
@ -12,5 +35,7 @@ export function Help(): JSX.Element {
|
|||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
</InnerContentRoot>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,13 @@ import { useEffect, useState } from 'react';
|
|||
import { LastArrayElement } from 'type-fest';
|
||||
import helpPages from './helpPages.json';
|
||||
|
||||
function makeFallbackUrlsArray(item: LastArrayElement<typeof helpPages.default>): Omit<LastArrayElement<typeof helpPages.default>, 'fallbackUrls'> & { fallbackUrls: string[] } {
|
||||
return { ...item, fallbackUrls: item?.fallbackUrls?.split(' ') ?? [] };
|
||||
function makeFallbackUrlsArray(
|
||||
item: LastArrayElement<typeof helpPages.default>,
|
||||
): Omit<LastArrayElement<typeof helpPages.default>, 'fallbackUrls' | 'language'> & { fallbackUrls: string[]; language: string[] } {
|
||||
return { ...item, fallbackUrls: item?.fallbackUrls?.split(' ') ?? [], language: item?.language?.split(' ') ?? [] };
|
||||
}
|
||||
|
||||
export function useLoadHelpPagesList() {
|
||||
export function useLoadHelpPagesList(language = 'en-GB') {
|
||||
const [items, setItems] = useState(helpPages.default.map(makeFallbackUrlsArray));
|
||||
useEffect(() => {
|
||||
const loadMoreItems = async () => {
|
||||
|
|
@ -34,5 +36,5 @@ export function useLoadHelpPagesList() {
|
|||
void loadMoreItems();
|
||||
}, []);
|
||||
|
||||
return items;
|
||||
return items.filter(item => item.language.includes(language));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ exports.startup = function() {
|
|||
// call setupSSE in `src/services/wiki/plugin/ipcSyncAdaptor/ipc-syncadaptor.ts` of TidGi-Desktop
|
||||
if (typeof $tw !== 'undefined') {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
||||
$tw.syncadaptor?.setupSSE();
|
||||
$tw.syncadaptor?.setupSSE?.();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue