mirror of
https://github.com/tiddly-gittly/TidGi-Desktop.git
synced 2025-12-06 02:30:47 -08:00
feat: use github token to load repo list
This commit is contained in:
parent
cb2428fb70
commit
758f10e469
7 changed files with 363 additions and 211 deletions
|
|
@ -7,9 +7,6 @@
|
||||||
[lints]
|
[lints]
|
||||||
|
|
||||||
[options]
|
[options]
|
||||||
module.name_mapper='^[~]\/\(.*\)$' -> '<PROJECT_ROOT>/app/src/\1'
|
esproposal.optional_chaining=enable
|
||||||
module.name_mapper='^constants\/\(.*\)$' -> '<PROJECT_ROOT>/app/src/constants/\1'
|
|
||||||
module.name_mapper='^components\/\(.*\)$' -> '<PROJECT_ROOT>/app/src/components/\1'
|
|
||||||
module.name_mapper='^libs\/\(.*\)$' -> '<PROJECT_ROOT>/app/libs/\1'
|
|
||||||
|
|
||||||
[strict]
|
[strict]
|
||||||
|
|
|
||||||
19
package-lock.json
generated
19
package-lock.json
generated
|
|
@ -7459,6 +7459,11 @@
|
||||||
"integrity": "sha1-Y2jL20Cr8zc7UlrIfkomDDpwCRk=",
|
"integrity": "sha1-Y2jL20Cr8zc7UlrIfkomDDpwCRk=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"dequal": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/dequal/-/dequal-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-/Nd1EQbQbI9UbSHrMiKZjFLrXSnU328iQdZKPQf78XQI6C+gutkFUeoHpG5J08Ioa6HeRbRNFpSIclh1xyG0mw=="
|
||||||
|
},
|
||||||
"des.js": {
|
"des.js": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npm.taobao.org/des.js/download/des.js-1.0.1.tgz",
|
"resolved": "https://registry.npm.taobao.org/des.js/download/des.js-1.0.1.tgz",
|
||||||
|
|
@ -9480,6 +9485,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"extract-files": {
|
||||||
|
"version": "8.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/extract-files/-/extract-files-8.1.0.tgz",
|
||||||
|
"integrity": "sha512-PTGtfthZK79WUMk+avLmwx3NGdU8+iVFXC2NMGxKsn0MnihOG2lvumj+AZo8CTwTrwjXDgZ5tztbRlEdRjBonQ=="
|
||||||
|
},
|
||||||
"extract-zip": {
|
"extract-zip": {
|
||||||
"version": "1.7.0",
|
"version": "1.7.0",
|
||||||
"resolved": "https://registry.npm.taobao.org/extract-zip/download/extract-zip-1.7.0.tgz?cache=0&sync_timestamp=1591773082587&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fextract-zip%2Fdownload%2Fextract-zip-1.7.0.tgz",
|
"resolved": "https://registry.npm.taobao.org/extract-zip/download/extract-zip-1.7.0.tgz?cache=0&sync_timestamp=1591773082587&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fextract-zip%2Fdownload%2Fextract-zip-1.7.0.tgz",
|
||||||
|
|
@ -10750,6 +10760,15 @@
|
||||||
"resolved": "https://registry.npm.taobao.org/graceful-readlink/download/graceful-readlink-1.0.1.tgz",
|
"resolved": "https://registry.npm.taobao.org/graceful-readlink/download/graceful-readlink-1.0.1.tgz",
|
||||||
"integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU="
|
"integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU="
|
||||||
},
|
},
|
||||||
|
"graphql-hooks": {
|
||||||
|
"version": "4.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/graphql-hooks/-/graphql-hooks-4.5.0.tgz",
|
||||||
|
"integrity": "sha512-xwOHJssNrcS9RWQz8nTEY2SBXzMWE6GcoAgN8A1tPwQI0VBFKcRtpK2XAm7+g34bF6uJuJl5QP9bSZy0F9BN6w==",
|
||||||
|
"requires": {
|
||||||
|
"dequal": "^1.0.0",
|
||||||
|
"extract-files": "^8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"growly": {
|
"growly": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npm.taobao.org/growly/download/growly-1.3.0.tgz",
|
"resolved": "https://registry.npm.taobao.org/growly/download/growly-1.3.0.tgz",
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@
|
||||||
"electron-window-state": "5.0.3",
|
"electron-window-state": "5.0.3",
|
||||||
"follow-redirects": "1.11.0",
|
"follow-redirects": "1.11.0",
|
||||||
"fs-extra": "9.0.1",
|
"fs-extra": "9.0.1",
|
||||||
|
"graphql-hooks": "^4.5.0",
|
||||||
"is-url": "1.2.4",
|
"is-url": "1.2.4",
|
||||||
"jimp": "0.13.0",
|
"jimp": "0.13.0",
|
||||||
"menubar": "8.0.2",
|
"menubar": "8.0.2",
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
// @flow
|
// @flow
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect, useCallback } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
import { GraphQLClient, ClientContext, useQuery } from 'graphql-hooks';
|
||||||
|
|
||||||
import Paper from '@material-ui/core/Paper';
|
import Paper from '@material-ui/core/Paper';
|
||||||
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
||||||
|
|
@ -15,7 +16,15 @@ import Select from '@material-ui/core/Select';
|
||||||
import MenuItem from '@material-ui/core/MenuItem';
|
import MenuItem from '@material-ui/core/MenuItem';
|
||||||
import FolderIcon from '@material-ui/icons/Folder';
|
import FolderIcon from '@material-ui/icons/Folder';
|
||||||
|
|
||||||
|
import List from '@material-ui/core/List';
|
||||||
|
import ListItem from '@material-ui/core/ListItem';
|
||||||
|
import ListItemIcon from '@material-ui/core/ListItemIcon';
|
||||||
|
import ListItemText from '@material-ui/core/ListItemText';
|
||||||
|
|
||||||
|
import { GITHUB_GRAPHQL_API } from '../../constants/auth';
|
||||||
|
|
||||||
import GitHubLogin from '../github-login';
|
import GitHubLogin from '../github-login';
|
||||||
|
import SearchRepo from './search-repo';
|
||||||
|
|
||||||
import connectComponent from '../../helpers/connect-component';
|
import connectComponent from '../../helpers/connect-component';
|
||||||
import { updateForm, save, setWikiCreationMessage } from '../../state/dialog-add-workspace/actions';
|
import { updateForm, save, setWikiCreationMessage } from '../../state/dialog-add-workspace/actions';
|
||||||
|
|
@ -23,17 +32,27 @@ import { updateForm, save, setWikiCreationMessage } from '../../state/dialog-add
|
||||||
import {
|
import {
|
||||||
requestCopyWikiTemplate,
|
requestCopyWikiTemplate,
|
||||||
requestCreateSubWiki,
|
requestCreateSubWiki,
|
||||||
|
requestSetPreference,
|
||||||
|
getPreference,
|
||||||
getIconPath,
|
getIconPath,
|
||||||
getDesktopPath,
|
getDesktopPath,
|
||||||
getWorkspaces,
|
getWorkspaces,
|
||||||
countWorkspace,
|
countWorkspace,
|
||||||
} from '../../senders';
|
} from '../../senders';
|
||||||
|
|
||||||
|
const graphqlClient = new GraphQLClient({
|
||||||
|
url: GITHUB_GRAPHQL_API,
|
||||||
|
});
|
||||||
|
|
||||||
const Container = styled.main`
|
const Container = styled.main`
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow: hidden;
|
overflow: scroll;
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
padding-bottom: 35px;
|
||||||
`;
|
`;
|
||||||
const Description = styled(Paper)`
|
const Description = styled(Paper)`
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
|
@ -67,12 +86,29 @@ const SoftLinkToMainWikiSelectInputLabel = styled(InputLabel)`
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const setGithubToken = (token: string) => requestSetPreference('github-token', token);
|
||||||
|
const getGithubToken = () => getPreference<string | null>('github-token');
|
||||||
|
const setGithubUsername = (username: string) => requestSetPreference('github-username', username);
|
||||||
|
const getGithubUsername = () => getPreference<string | null>('github-username');
|
||||||
|
|
||||||
function AddWorkspace({ wikiCreationMessage, onUpdateForm, onSave, onSetWikiCreationMessage }) {
|
function AddWorkspace({ wikiCreationMessage, onUpdateForm, onSave, onSetWikiCreationMessage }) {
|
||||||
const [isCreateMainWorkspace, isCreateMainWorkspaceSetter] = useState(countWorkspace() === 0);
|
const [isCreateMainWorkspace, isCreateMainWorkspaceSetter] = useState(countWorkspace() === 0);
|
||||||
const [parentFolderLocation, parentFolderLocationSetter] = useState(getDesktopPath());
|
const [parentFolderLocation, parentFolderLocationSetter] = useState(getDesktopPath());
|
||||||
const [wikiFolderLocation, wikiFolderLocationSetter] = useState('');
|
const [wikiFolderLocation, wikiFolderLocationSetter] = useState('');
|
||||||
const [wikiPort, wikiPortSetter] = useState(5212 + countWorkspace());
|
const [wikiPort, wikiPortSetter] = useState(5212 + countWorkspace());
|
||||||
|
|
||||||
|
// try get token from local storage, and set to state for gql to use
|
||||||
|
const setGraphqlClientHeader = useCallback((accessToken: string) => {
|
||||||
|
graphqlClient.setHeader('Authorization', `bearer ${accessToken}`);
|
||||||
|
setGithubToken(accessToken);
|
||||||
|
}, []);
|
||||||
|
useEffect(() => {
|
||||||
|
const accessToken = getGithubToken();
|
||||||
|
if (accessToken) {
|
||||||
|
setGraphqlClientHeader(accessToken);
|
||||||
|
}
|
||||||
|
}, [setGraphqlClientHeader]);
|
||||||
|
|
||||||
const [workspaces, workspacesSetter] = useState({});
|
const [workspaces, workspacesSetter] = useState({});
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
workspacesSetter(getWorkspaces());
|
workspacesSetter(getWorkspaces());
|
||||||
|
|
@ -91,115 +127,157 @@ function AddWorkspace({ wikiCreationMessage, onUpdateForm, onSave, onSetWikiCrea
|
||||||
picturePath: getIconPath(),
|
picturePath: getIconPath(),
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<Container>
|
<ClientContext.Provider value={graphqlClient}>
|
||||||
<Description elevation={0} square>
|
<Container>
|
||||||
<FormControlLabel
|
<Description elevation={0} square>
|
||||||
control={
|
<FormControlLabel
|
||||||
<Switch
|
control={
|
||||||
checked={isCreateMainWorkspace}
|
<Switch
|
||||||
onChange={event => isCreateMainWorkspaceSetter(event.target.checked)}
|
checked={isCreateMainWorkspace}
|
||||||
|
onChange={event => isCreateMainWorkspaceSetter(event.target.checked)}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label={`创建${isCreateMainWorkspace ? '主' : '子'}知识库`}
|
||||||
|
/>
|
||||||
|
<Typography variant="body2" display="inline">
|
||||||
|
{isCreateMainWorkspace
|
||||||
|
? '主知识库包含了TiddlyWiki的配置文件,以及发布为博客时的公开内容。'
|
||||||
|
: '子知识库必须依附于一个主知识库,可用于存放私有内容,同步到一个私有的Github仓库内,仅本人可读写。子知识库通过创建一个到主知识库的软链接(快捷方式)来生效,创建链接后主知识库内便可看到子知识库内的内容了。'}
|
||||||
|
</Typography>
|
||||||
|
</Description>
|
||||||
|
|
||||||
|
<SyncContainer elevation={2} square>
|
||||||
|
<Typography variant="subtitle1" align="center">
|
||||||
|
同步到云端
|
||||||
|
</Typography>
|
||||||
|
<GitHubLogin
|
||||||
|
clientId="7b6e0fc33f4afd71a4bb"
|
||||||
|
clientSecret="6015d1ca4ded86b4778ed39109193ff20c630bdd"
|
||||||
|
redirectUri="http://localhost"
|
||||||
|
scope="repo"
|
||||||
|
onSuccess={response => {
|
||||||
|
const accessToken = response?.userInfo?.thirdPartyIdentity?.accessToken;
|
||||||
|
if (accessToken) {
|
||||||
|
setGraphqlClientHeader(accessToken);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onFailure={response => console.log(response)}
|
||||||
|
/>
|
||||||
|
{Object.keys(graphqlClient.headers).length > 0 && <SearchRepo />}
|
||||||
|
</SyncContainer>
|
||||||
|
|
||||||
|
<CreateContainer elevation={2} square>
|
||||||
|
<LocationPickerContainer>
|
||||||
|
<LocationPickerInput
|
||||||
|
error={!!wikiCreationMessage}
|
||||||
|
helperText={wikiCreationMessage}
|
||||||
|
fullWidth
|
||||||
|
onChange={event => {
|
||||||
|
parentFolderLocationSetter(event.target.value);
|
||||||
|
onSetWikiCreationMessage('');
|
||||||
|
}}
|
||||||
|
label="知识库的父文件夹"
|
||||||
|
value={parentFolderLocation}
|
||||||
/>
|
/>
|
||||||
}
|
<LocationPickerButton
|
||||||
label={`创建${isCreateMainWorkspace ? '主' : '子'}知识库`}
|
onClick={() => {
|
||||||
/>
|
const { remote } = window.require('electron');
|
||||||
<Typography variant="body2" display="inline">
|
// eslint-disable-next-line promise/catch-or-return
|
||||||
{isCreateMainWorkspace
|
remote.dialog
|
||||||
? '主知识库包含了TiddlyWiki的配置文件,以及发布为博客时的公开内容。'
|
.showOpenDialog(remote.getCurrentWindow(), {
|
||||||
: '子知识库必须依附于一个主知识库,可用于存放私有内容,同步到一个私有的Github仓库内,仅本人可读写。子知识库通过创建一个到主知识库的软链接(快捷方式)来生效,创建链接后主知识库内便可看到子知识库内的内容了。'}
|
properties: ['openDirectory'],
|
||||||
</Typography>
|
})
|
||||||
</Description>
|
.then(({ canceled, filePaths }) => {
|
||||||
|
// eslint-disable-next-line promise/always-return
|
||||||
<SyncContainer elevation={2} square>
|
if (!canceled && filePaths.length > 0) {
|
||||||
<Typography variant="subtitle1" align="center">
|
parentFolderLocationSetter(filePaths[0]);
|
||||||
同步到云端
|
}
|
||||||
</Typography>
|
});
|
||||||
<GitHubLogin
|
}}
|
||||||
clientId="7b6e0fc33f4afd71a4bb"
|
variant="outlined"
|
||||||
clientSecret="6015d1ca4ded86b4778ed39109193ff20c630bdd"
|
color={parentFolderLocation ? 'default' : 'primary'}
|
||||||
redirectUri="http://localhost"
|
disableElevation
|
||||||
scope="repo"
|
endIcon={<FolderIcon />}
|
||||||
onSuccess={response => console.log(response)}
|
>
|
||||||
onFailure={response => console.log(response)}
|
<Typography variant="button" display="inline">
|
||||||
/>
|
选择
|
||||||
</SyncContainer>
|
</Typography>
|
||||||
|
</LocationPickerButton>
|
||||||
<CreateContainer elevation={2} square>
|
</LocationPickerContainer>
|
||||||
<LocationPickerContainer>
|
<LocationPickerInput
|
||||||
<LocationPickerInput
|
|
||||||
error={!!wikiCreationMessage}
|
error={!!wikiCreationMessage}
|
||||||
helperText={wikiCreationMessage}
|
|
||||||
fullWidth
|
fullWidth
|
||||||
onChange={event => {
|
onChange={event => {
|
||||||
parentFolderLocationSetter(event.target.value);
|
wikiFolderNameSetter(event.target.value);
|
||||||
onSetWikiCreationMessage('');
|
onSetWikiCreationMessage('');
|
||||||
}}
|
}}
|
||||||
label="知识库的父文件夹"
|
label="知识库文件夹名"
|
||||||
value={parentFolderLocation}
|
value={wikiFolderName}
|
||||||
/>
|
/>
|
||||||
<LocationPickerButton
|
<LocationPickerInput
|
||||||
onClick={() => {
|
fullWidth
|
||||||
const { remote } = window.require('electron');
|
onChange={event => {
|
||||||
// eslint-disable-next-line promise/catch-or-return
|
wikiPortSetter(event.target.value);
|
||||||
remote.dialog
|
}}
|
||||||
.showOpenDialog(remote.getCurrentWindow(), {
|
label="WIKI服务器端口号(出现冲突再改,一般默认即可)"
|
||||||
properties: ['openDirectory'],
|
value={wikiPort}
|
||||||
})
|
/>
|
||||||
.then(({ canceled, filePaths }) => {
|
{!isCreateMainWorkspace && (
|
||||||
// eslint-disable-next-line promise/always-return
|
<>
|
||||||
if (!canceled && filePaths.length > 0) {
|
<SoftLinkToMainWikiSelectInputLabel id="main-wiki-select-label">
|
||||||
parentFolderLocationSetter(filePaths[0]);
|
主知识库位置
|
||||||
}
|
</SoftLinkToMainWikiSelectInputLabel>
|
||||||
});
|
<SoftLinkToMainWikiSelect
|
||||||
|
labelId="main-wiki-select-label"
|
||||||
|
id="main-wiki-select"
|
||||||
|
value={mainWikiToLink}
|
||||||
|
onChange={event => mainWikiToLinkSetter(event.target.value)}
|
||||||
|
>
|
||||||
|
{Object.keys(workspaces).map(workspaceID => (
|
||||||
|
<MenuItem key={workspaceID} value={workspaces[workspaceID].name}>
|
||||||
|
{workspaces[workspaceID].name}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</SoftLinkToMainWikiSelect>
|
||||||
|
{mainWikiToLink && (
|
||||||
|
<FormHelperText>
|
||||||
|
<Typography variant="body1" display="inline">
|
||||||
|
子知识库将链接到
|
||||||
|
</Typography>
|
||||||
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
noWrap
|
||||||
|
display="inline"
|
||||||
|
align="center"
|
||||||
|
style={{ direction: 'rtl', textTransform: 'none' }}
|
||||||
|
>
|
||||||
|
{mainWikiToLink}/tiddlers/{wikiFolderName}
|
||||||
|
</Typography>
|
||||||
|
</FormHelperText>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</CreateContainer>
|
||||||
|
|
||||||
|
{isCreateMainWorkspace ? (
|
||||||
|
<CloseButton
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
disabled={!parentFolderLocation}
|
||||||
|
onClick={async () => {
|
||||||
|
onUpdateForm(workspaceFormData);
|
||||||
|
const creationError = await requestCopyWikiTemplate(parentFolderLocation, wikiFolderName);
|
||||||
|
if (creationError) {
|
||||||
|
onSetWikiCreationMessage(creationError);
|
||||||
|
} else {
|
||||||
|
onSave();
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
variant="outlined"
|
|
||||||
color={parentFolderLocation ? 'default' : 'primary'}
|
|
||||||
disableElevation
|
|
||||||
endIcon={<FolderIcon />}
|
|
||||||
>
|
>
|
||||||
<Typography variant="button" display="inline">
|
{parentFolderLocation && (
|
||||||
选择
|
<>
|
||||||
</Typography>
|
|
||||||
</LocationPickerButton>
|
|
||||||
</LocationPickerContainer>
|
|
||||||
<LocationPickerInput
|
|
||||||
error={!!wikiCreationMessage}
|
|
||||||
fullWidth
|
|
||||||
onChange={event => {
|
|
||||||
wikiFolderNameSetter(event.target.value);
|
|
||||||
onSetWikiCreationMessage('');
|
|
||||||
}}
|
|
||||||
label="知识库文件夹名"
|
|
||||||
value={wikiFolderName}
|
|
||||||
/>
|
|
||||||
<LocationPickerInput
|
|
||||||
fullWidth
|
|
||||||
onChange={event => {
|
|
||||||
wikiPortSetter(event.target.value);
|
|
||||||
}}
|
|
||||||
label="WIKI服务器端口号(出现冲突再改,一般默认即可)"
|
|
||||||
value={wikiPort}
|
|
||||||
/>
|
|
||||||
{!isCreateMainWorkspace && (
|
|
||||||
<>
|
|
||||||
<SoftLinkToMainWikiSelectInputLabel id="main-wiki-select-label">
|
|
||||||
主知识库位置
|
|
||||||
</SoftLinkToMainWikiSelectInputLabel>
|
|
||||||
<SoftLinkToMainWikiSelect
|
|
||||||
labelId="main-wiki-select-label"
|
|
||||||
id="main-wiki-select"
|
|
||||||
value={mainWikiToLink}
|
|
||||||
onChange={event => mainWikiToLinkSetter(event.target.value)}
|
|
||||||
>
|
|
||||||
{Object.keys(workspaces).map(workspaceID => (
|
|
||||||
<MenuItem key={workspaceID} value={workspaces[workspaceID].name}>
|
|
||||||
{workspaces[workspaceID].name}
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</SoftLinkToMainWikiSelect>
|
|
||||||
{mainWikiToLink && (
|
|
||||||
<FormHelperText>
|
|
||||||
<Typography variant="body1" display="inline">
|
<Typography variant="body1" display="inline">
|
||||||
子知识库将链接到
|
在
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography
|
<Typography
|
||||||
variant="body2"
|
variant="body2"
|
||||||
|
|
@ -208,89 +286,55 @@ function AddWorkspace({ wikiCreationMessage, onUpdateForm, onSave, onSetWikiCrea
|
||||||
align="center"
|
align="center"
|
||||||
style={{ direction: 'rtl', textTransform: 'none' }}
|
style={{ direction: 'rtl', textTransform: 'none' }}
|
||||||
>
|
>
|
||||||
{mainWikiToLink}/tiddlers/{wikiFolderName}
|
{wikiFolderLocation}
|
||||||
</Typography>
|
</Typography>
|
||||||
</FormHelperText>
|
</>
|
||||||
)}
|
)}
|
||||||
</>
|
<Typography variant="body1" display="inline">
|
||||||
|
创建WIKI
|
||||||
|
</Typography>
|
||||||
|
</CloseButton>
|
||||||
|
) : (
|
||||||
|
<CloseButton
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
disabled={!parentFolderLocation || !mainWikiToLink}
|
||||||
|
onClick={async () => {
|
||||||
|
onUpdateForm(workspaceFormData);
|
||||||
|
const creationError = await requestCreateSubWiki(parentFolderLocation, wikiFolderName, mainWikiToLink);
|
||||||
|
if (creationError) {
|
||||||
|
onSetWikiCreationMessage(creationError);
|
||||||
|
} else {
|
||||||
|
onSave();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{parentFolderLocation && (
|
||||||
|
<>
|
||||||
|
<Typography variant="body1" display="inline">
|
||||||
|
在
|
||||||
|
</Typography>
|
||||||
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
noWrap
|
||||||
|
display="inline"
|
||||||
|
align="center"
|
||||||
|
style={{ direction: 'rtl', textTransform: 'none' }}
|
||||||
|
>
|
||||||
|
{wikiFolderLocation}
|
||||||
|
</Typography>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
<Typography variant="body1" display="inline">
|
||||||
|
创建WIKI
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body1" display="inline">
|
||||||
|
并链接到主知识库
|
||||||
|
</Typography>
|
||||||
|
</CloseButton>
|
||||||
)}
|
)}
|
||||||
</CreateContainer>
|
</Container>
|
||||||
|
</ClientContext.Provider>
|
||||||
{isCreateMainWorkspace ? (
|
|
||||||
<CloseButton
|
|
||||||
variant="contained"
|
|
||||||
color="secondary"
|
|
||||||
disabled={!parentFolderLocation}
|
|
||||||
onClick={async () => {
|
|
||||||
onUpdateForm(workspaceFormData);
|
|
||||||
const creationError = await requestCopyWikiTemplate(parentFolderLocation, wikiFolderName);
|
|
||||||
if (creationError) {
|
|
||||||
onSetWikiCreationMessage(creationError);
|
|
||||||
} else {
|
|
||||||
onSave();
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{parentFolderLocation && (
|
|
||||||
<>
|
|
||||||
<Typography variant="body1" display="inline">
|
|
||||||
在
|
|
||||||
</Typography>
|
|
||||||
<Typography
|
|
||||||
variant="body2"
|
|
||||||
noWrap
|
|
||||||
display="inline-block"
|
|
||||||
align="center"
|
|
||||||
style={{ direction: 'rtl', textTransform: 'none' }}
|
|
||||||
>
|
|
||||||
{wikiFolderLocation}
|
|
||||||
</Typography>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
<Typography variant="body1" display="inline">
|
|
||||||
创建WIKI
|
|
||||||
</Typography>
|
|
||||||
</CloseButton>
|
|
||||||
) : (
|
|
||||||
<CloseButton
|
|
||||||
variant="contained"
|
|
||||||
color="secondary"
|
|
||||||
disabled={!parentFolderLocation || !mainWikiToLink}
|
|
||||||
onClick={async () => {
|
|
||||||
onUpdateForm(workspaceFormData);
|
|
||||||
const creationError = await requestCreateSubWiki(parentFolderLocation, wikiFolderName, mainWikiToLink);
|
|
||||||
if (creationError) {
|
|
||||||
onSetWikiCreationMessage(creationError);
|
|
||||||
} else {
|
|
||||||
onSave();
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{parentFolderLocation && (
|
|
||||||
<>
|
|
||||||
<Typography variant="body1" display="inline">
|
|
||||||
在
|
|
||||||
</Typography>
|
|
||||||
<Typography
|
|
||||||
variant="body2"
|
|
||||||
noWrap
|
|
||||||
display="inline-block"
|
|
||||||
align="center"
|
|
||||||
style={{ direction: 'rtl', textTransform: 'none' }}
|
|
||||||
>
|
|
||||||
{wikiFolderLocation}
|
|
||||||
</Typography>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
<Typography variant="body1" display="inline">
|
|
||||||
创建WIKI
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="body1" display="inline">
|
|
||||||
并链接到主知识库
|
|
||||||
</Typography>
|
|
||||||
</CloseButton>
|
|
||||||
)}
|
|
||||||
</Container>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
77
src/components/dialog-add-workspace/search-repo.js
Normal file
77
src/components/dialog-add-workspace/search-repo.js
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
// @flow
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import { useQuery } from 'graphql-hooks';
|
||||||
|
|
||||||
|
import TextField from '@material-ui/core/TextField';
|
||||||
|
import FolderIcon from '@material-ui/icons/Folder';
|
||||||
|
import LinearProgress from '@material-ui/core/LinearProgress';
|
||||||
|
import List from '@material-ui/core/List';
|
||||||
|
import ListItem from '@material-ui/core/ListItem';
|
||||||
|
import ListItemIcon from '@material-ui/core/ListItemIcon';
|
||||||
|
import ListItemText from '@material-ui/core/ListItemText';
|
||||||
|
|
||||||
|
const RepoSearchInput = styled(TextField)``;
|
||||||
|
|
||||||
|
const SEARCH_REPO_QUERY = `
|
||||||
|
query SearchRepo($queryString: String!) {
|
||||||
|
search(query: $queryString, type: REPOSITORY, first: 10) {
|
||||||
|
repositoryCount
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
... on Repository {
|
||||||
|
name
|
||||||
|
url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
export default function SearchRepo() {
|
||||||
|
const [githubRepoSearchString, githubRepoSearchStringSetter] = useState('wiki');
|
||||||
|
const loadCount = 10;
|
||||||
|
const { loading, error, data } = useQuery(SEARCH_REPO_QUERY, {
|
||||||
|
variables: {
|
||||||
|
first: loadCount,
|
||||||
|
queryString: `user:linonetwo ${githubRepoSearchString}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const repositoryCount = data?.search?.repositoryCount;
|
||||||
|
let repoList = [];
|
||||||
|
if (repositoryCount) {
|
||||||
|
repoList = data.search.edges.map(({ node }) => node);
|
||||||
|
}
|
||||||
|
let helperText = '';
|
||||||
|
if (error) {
|
||||||
|
helperText = '无法加载仓库列表,网络不佳';
|
||||||
|
}
|
||||||
|
if (repositoryCount > loadCount) {
|
||||||
|
helperText = `仅展示前${loadCount}个结果`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<RepoSearchInput
|
||||||
|
fullWidth
|
||||||
|
onChange={event => {
|
||||||
|
githubRepoSearchStringSetter(event.target.value);
|
||||||
|
}}
|
||||||
|
label="搜索Github仓库名"
|
||||||
|
value={githubRepoSearchString}
|
||||||
|
helperText={helperText}
|
||||||
|
/>
|
||||||
|
{loading && <LinearProgress variant="query" />}
|
||||||
|
<List component="nav" aria-label="main mailbox folders">
|
||||||
|
{repoList.map(({ name, url }) => (
|
||||||
|
<ListItem button key={url}>
|
||||||
|
<ListItemIcon>
|
||||||
|
<FolderIcon />
|
||||||
|
</ListItemIcon>
|
||||||
|
<ListItemText primary={name} />
|
||||||
|
</ListItem>
|
||||||
|
))}
|
||||||
|
</List>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
export const APP_ID = '5efdd30e56a87fb76b52809d'
|
export const APP_ID = '5efdd30e56a87fb76b52809d';
|
||||||
export const APP_DOMAIN = 'tiddlygit-desktop.authing.cn'
|
export const APP_DOMAIN = 'tiddlygit-desktop.authing.cn';
|
||||||
|
export const GITHUB_GRAPHQL_API = 'https://api.github.com/graphql';
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,13 @@
|
||||||
|
// @flow
|
||||||
const { ipcRenderer } = window.require('electron');
|
const { ipcRenderer } = window.require('electron');
|
||||||
|
|
||||||
export const requestCopyWikiTemplate = (newFolderPath, folderName) => ipcRenderer.invoke('copy-wiki-template', newFolderPath, folderName);
|
export const requestCopyWikiTemplate = (newFolderPath, folderName) =>
|
||||||
export const requestCreateSubWiki = (newFolderPath, folderName, mainWikiToLink) => ipcRenderer.invoke('create-sub-wiki', newFolderPath, folderName, mainWikiToLink);
|
ipcRenderer.invoke('copy-wiki-template', newFolderPath, folderName);
|
||||||
export const requestStartTiddlyWiki = (wikiPath, port, userName) => ipcRenderer.send('request-start-tiddlywiki', wikiPath, port, userName);
|
export const requestCreateSubWiki = (newFolderPath, folderName, mainWikiToLink) =>
|
||||||
export const requestOpenInBrowser = (url) => ipcRenderer.send('request-open-in-browser', url);
|
ipcRenderer.invoke('create-sub-wiki', newFolderPath, folderName, mainWikiToLink);
|
||||||
|
export const requestStartTiddlyWiki = (wikiPath, port, userName) =>
|
||||||
|
ipcRenderer.send('request-start-tiddlywiki', wikiPath, port, userName);
|
||||||
|
export const requestOpenInBrowser = url => ipcRenderer.send('request-open-in-browser', url);
|
||||||
export const requestShowMessageBox = (message, type) => ipcRenderer.send('request-show-message-box', message, type);
|
export const requestShowMessageBox = (message, type) => ipcRenderer.send('request-show-message-box', message, type);
|
||||||
export const requestLoadUrl = (url, id) => ipcRenderer.send('request-load-url', url, id);
|
export const requestLoadUrl = (url, id) => ipcRenderer.send('request-load-url', url, id);
|
||||||
|
|
||||||
|
|
@ -13,67 +17,76 @@ export const requestGoForward = () => ipcRenderer.send('request-go-forward');
|
||||||
export const requestReload = () => ipcRenderer.send('request-reload');
|
export const requestReload = () => ipcRenderer.send('request-reload');
|
||||||
|
|
||||||
export const requestQuit = () => ipcRenderer.send('request-quit');
|
export const requestQuit = () => ipcRenderer.send('request-quit');
|
||||||
export const requestCheckForUpdates = (isSilent) => ipcRenderer.send('request-check-for-updates', isSilent);
|
export const requestCheckForUpdates = isSilent => ipcRenderer.send('request-check-for-updates', isSilent);
|
||||||
|
|
||||||
export const requestShowAboutWindow = () => ipcRenderer.send('request-show-about-window');
|
export const requestShowAboutWindow = () => ipcRenderer.send('request-show-about-window');
|
||||||
export const requestShowAddWorkspaceWindow = () => ipcRenderer.send('request-show-add-workspace-window');
|
export const requestShowAddWorkspaceWindow = () => ipcRenderer.send('request-show-add-workspace-window');
|
||||||
export const requestShowCodeInjectionWindow = (type) => ipcRenderer.send('request-show-code-injection-window', type);
|
export const requestShowCodeInjectionWindow = type => ipcRenderer.send('request-show-code-injection-window', type);
|
||||||
export const requestShowCustomUserAgentWindow = () => ipcRenderer.send('request-show-custom-user-agent-window');
|
export const requestShowCustomUserAgentWindow = () => ipcRenderer.send('request-show-custom-user-agent-window');
|
||||||
export const requestShowEditWorkspaceWindow = (id) => ipcRenderer.send('request-show-edit-workspace-window', id);
|
export const requestShowEditWorkspaceWindow = id => ipcRenderer.send('request-show-edit-workspace-window', id);
|
||||||
export const requestShowLicenseRegistrationWindow = () => ipcRenderer.send('request-show-license-registration-window');
|
export const requestShowLicenseRegistrationWindow = () => ipcRenderer.send('request-show-license-registration-window');
|
||||||
export const requestShowNotificationsWindow = () => ipcRenderer.send('request-show-notifications-window');
|
export const requestShowNotificationsWindow = () => ipcRenderer.send('request-show-notifications-window');
|
||||||
export const requestShowPreferencesWindow = (scrollTo) => ipcRenderer.send('request-show-preferences-window', scrollTo);
|
export const requestShowPreferencesWindow = scrollTo => ipcRenderer.send('request-show-preferences-window', scrollTo);
|
||||||
export const requestShowProxyWindow = () => ipcRenderer.send('request-show-proxy-window');
|
export const requestShowProxyWindow = () => ipcRenderer.send('request-show-proxy-window');
|
||||||
export const requestShowSpellcheckLanguagesWindow = () => ipcRenderer.send('request-show-spellcheck-languages-window');
|
export const requestShowSpellcheckLanguagesWindow = () => ipcRenderer.send('request-show-spellcheck-languages-window');
|
||||||
|
|
||||||
// Notifications
|
// Notifications
|
||||||
export const requestShowNotification = (opts) => ipcRenderer.send('request-show-notification', opts);
|
export const requestShowNotification = opts => ipcRenderer.send('request-show-notification', opts);
|
||||||
export const requestUpdatePauseNotificationsInfo = () => ipcRenderer.send('request-update-pause-notifications-info');
|
export const requestUpdatePauseNotificationsInfo = () => ipcRenderer.send('request-update-pause-notifications-info');
|
||||||
export const getPauseNotificationsInfo = () => ipcRenderer.sendSync('get-pause-notifications-info');
|
export const getPauseNotificationsInfo = () => ipcRenderer.sendSync('get-pause-notifications-info');
|
||||||
|
|
||||||
// Preferences
|
// Preferences
|
||||||
export const getPreference = (name) => ipcRenderer.sendSync('get-preference', name);
|
// eslint-disable-next-line no-use-before-define
|
||||||
|
type JsonValue = string | number | boolean | null | JsonArray | JsonObject;
|
||||||
|
interface JsonObject {
|
||||||
|
[x: string]: JsonValue;
|
||||||
|
}
|
||||||
|
interface JsonArray extends Array<JsonValue> {} // tslint:disable-line no-empty-interface
|
||||||
|
export function getPreference<T=JsonValue>(name: string): T {
|
||||||
|
return ipcRenderer.sendSync('get-preference', name);
|
||||||
|
}
|
||||||
export const getPreferences = () => ipcRenderer.sendSync('get-preferences');
|
export const getPreferences = () => ipcRenderer.sendSync('get-preferences');
|
||||||
export const requestSetPreference = (name, value) => ipcRenderer.send('request-set-preference', name, value);
|
export const requestSetPreference = (name: string, value: JsonValue) =>
|
||||||
|
ipcRenderer.send('request-set-preference', name, value);
|
||||||
export const requestResetPreferences = () => ipcRenderer.send('request-reset-preferences');
|
export const requestResetPreferences = () => ipcRenderer.send('request-reset-preferences');
|
||||||
export const requestShowRequireRestartDialog = () => ipcRenderer.send('request-show-require-restart-dialog');
|
export const requestShowRequireRestartDialog = () => ipcRenderer.send('request-show-require-restart-dialog');
|
||||||
|
|
||||||
// System Preferences
|
// System Preferences
|
||||||
export const getSystemPreference = (name) => ipcRenderer.sendSync('get-system-preference', name);
|
export const getSystemPreference = (name: string): JsonValue => ipcRenderer.sendSync('get-system-preference', name);
|
||||||
export const getSystemPreferences = () => ipcRenderer.sendSync('get-system-preferences');
|
export const getSystemPreferences = (): JsonObject => ipcRenderer.sendSync('get-system-preferences');
|
||||||
export const requestSetSystemPreference = (name, value) =>
|
export const requestSetSystemPreference = (name: string, value: JsonValue) =>
|
||||||
ipcRenderer.send('request-set-system-preference', name, value);
|
ipcRenderer.send('request-set-system-preference', name, value);
|
||||||
|
|
||||||
// Workspace
|
// Workspace
|
||||||
export const countWorkspace = () => ipcRenderer.sendSync('count-workspace');
|
export const countWorkspace = () => ipcRenderer.sendSync('count-workspace');
|
||||||
export const getWorkspace = (id) => ipcRenderer.sendSync('get-workspace', id);
|
export const getWorkspace = (id: string) => ipcRenderer.sendSync('get-workspace', id);
|
||||||
export const getWorkspaces = () => ipcRenderer.sendSync('get-workspaces');
|
export const getWorkspaces = () => ipcRenderer.sendSync('get-workspaces');
|
||||||
export const requestClearBrowsingData = () => ipcRenderer.send('request-clear-browsing-data');
|
export const requestClearBrowsingData = () => ipcRenderer.send('request-clear-browsing-data');
|
||||||
export const requestCreateWorkspace = (name, isSubWiki, port, homeUrl, picture, transparentBackground) =>
|
export const requestCreateWorkspace = (name, isSubWiki, port, homeUrl, picture, transparentBackground) =>
|
||||||
ipcRenderer.send('request-create-workspace', name, isSubWiki, port, homeUrl, picture, transparentBackground);
|
ipcRenderer.send('request-create-workspace', name, isSubWiki, port, homeUrl, picture, transparentBackground);
|
||||||
export const requestHibernateWorkspace = (id) => ipcRenderer.send('request-hibernate-workspace', id);
|
export const requestHibernateWorkspace = id => ipcRenderer.send('request-hibernate-workspace', id);
|
||||||
export const requestOpenUrlInWorkspace = (url, id) => ipcRenderer.send('request-open-url-in-workspace', url, id);
|
export const requestOpenUrlInWorkspace = (url, id) => ipcRenderer.send('request-open-url-in-workspace', url, id);
|
||||||
export const requestRealignActiveWorkspace = () => ipcRenderer.send('request-realign-active-workspace');
|
export const requestRealignActiveWorkspace = () => ipcRenderer.send('request-realign-active-workspace');
|
||||||
export const requestRemoveWorkspace = (id) => ipcRenderer.send('request-remove-workspace', id);
|
export const requestRemoveWorkspace = id => ipcRenderer.send('request-remove-workspace', id);
|
||||||
export const requestRemoveWorkspacePicture = (id) => ipcRenderer.send('request-remove-workspace-picture', id);
|
export const requestRemoveWorkspacePicture = id => ipcRenderer.send('request-remove-workspace-picture', id);
|
||||||
export const requestSetActiveWorkspace = (id) => ipcRenderer.send('request-set-active-workspace', id);
|
export const requestSetActiveWorkspace = id => ipcRenderer.send('request-set-active-workspace', id);
|
||||||
export const requestSetWorkspace = (id, opts) => ipcRenderer.send('request-set-workspace', id, opts);
|
export const requestSetWorkspace = (id, opts) => ipcRenderer.send('request-set-workspace', id, opts);
|
||||||
export const requestSetWorkspaces = (workspaces) => ipcRenderer.send('request-set-workspaces', workspaces);
|
export const requestSetWorkspaces = workspaces => ipcRenderer.send('request-set-workspaces', workspaces);
|
||||||
export const requestSetWorkspacePicture = (id, picturePath) =>
|
export const requestSetWorkspacePicture = (id, picturePath) =>
|
||||||
ipcRenderer.send('request-set-workspace-picture', id, picturePath);
|
ipcRenderer.send('request-set-workspace-picture', id, picturePath);
|
||||||
export const requestWakeUpWorkspace = (id) => ipcRenderer.send('request-wake-up-workspace', id);
|
export const requestWakeUpWorkspace = id => ipcRenderer.send('request-wake-up-workspace', id);
|
||||||
|
|
||||||
export const getIconPath = () => ipcRenderer.sendSync('get-constant', 'ICON_PATH');
|
export const getIconPath = () => ipcRenderer.sendSync('get-constant', 'ICON_PATH');
|
||||||
export const getReactPath = () => ipcRenderer.sendSync('get-constant', 'REACT_PATH');
|
export const getReactPath = () => ipcRenderer.sendSync('get-constant', 'REACT_PATH');
|
||||||
export const getDesktopPath = () => ipcRenderer.sendSync('get-constant', 'DESKTOP_PATH');
|
export const getDesktopPath = () => ipcRenderer.sendSync('get-constant', 'DESKTOP_PATH');
|
||||||
|
|
||||||
// Workspace Meta
|
// Workspace Meta
|
||||||
export const getWorkspaceMeta = (id) => ipcRenderer.sendSync('get-workspace-meta', id);
|
export const getWorkspaceMeta = id => ipcRenderer.sendSync('get-workspace-meta', id);
|
||||||
export const getWorkspaceMetas = () => ipcRenderer.sendSync('get-workspace-metas');
|
export const getWorkspaceMetas = () => ipcRenderer.sendSync('get-workspace-metas');
|
||||||
|
|
||||||
// Find In Page
|
// Find In Page
|
||||||
export const requestFindInPage = (text, forward) => ipcRenderer.send('request-find-in-page', text, forward);
|
export const requestFindInPage = (text, forward) => ipcRenderer.send('request-find-in-page', text, forward);
|
||||||
export const requestStopFindInPage = (close) => ipcRenderer.send('request-stop-find-in-page', close);
|
export const requestStopFindInPage = close => ipcRenderer.send('request-stop-find-in-page', close);
|
||||||
|
|
||||||
// Auth
|
// Auth
|
||||||
export const requestValidateAuthIdentity = (windowId, username, password) =>
|
export const requestValidateAuthIdentity = (windowId, username, password) =>
|
||||||
|
|
@ -83,4 +96,4 @@ export const requestValidateAuthIdentity = (windowId, username, password) =>
|
||||||
export const getShouldUseDarkColors = () => ipcRenderer.sendSync('get-should-use-dark-colors');
|
export const getShouldUseDarkColors = () => ipcRenderer.sendSync('get-should-use-dark-colors');
|
||||||
|
|
||||||
// Online Status
|
// Online Status
|
||||||
export const signalOnlineStatusChanged = (online) => ipcRenderer.send('online-status-changed', online);
|
export const signalOnlineStatusChanged = online => ipcRenderer.send('online-status-changed', online);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue