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]
|
||||
|
||||
[options]
|
||||
module.name_mapper='^[~]\/\(.*\)$' -> '<PROJECT_ROOT>/app/src/\1'
|
||||
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'
|
||||
esproposal.optional_chaining=enable
|
||||
|
||||
[strict]
|
||||
|
|
|
|||
19
package-lock.json
generated
19
package-lock.json
generated
|
|
@ -7459,6 +7459,11 @@
|
|||
"integrity": "sha1-Y2jL20Cr8zc7UlrIfkomDDpwCRk=",
|
||||
"dev": true
|
||||
},
|
||||
"dequal": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/dequal/-/dequal-1.0.0.tgz",
|
||||
"integrity": "sha512-/Nd1EQbQbI9UbSHrMiKZjFLrXSnU328iQdZKPQf78XQI6C+gutkFUeoHpG5J08Ioa6HeRbRNFpSIclh1xyG0mw=="
|
||||
},
|
||||
"des.js": {
|
||||
"version": "1.0.1",
|
||||
"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": {
|
||||
"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",
|
||||
|
|
@ -10750,6 +10760,15 @@
|
|||
"resolved": "https://registry.npm.taobao.org/graceful-readlink/download/graceful-readlink-1.0.1.tgz",
|
||||
"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": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npm.taobao.org/growly/download/growly-1.3.0.tgz",
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
"electron-window-state": "5.0.3",
|
||||
"follow-redirects": "1.11.0",
|
||||
"fs-extra": "9.0.1",
|
||||
"graphql-hooks": "^4.5.0",
|
||||
"is-url": "1.2.4",
|
||||
"jimp": "0.13.0",
|
||||
"menubar": "8.0.2",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
// @flow
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styled from 'styled-components';
|
||||
import { GraphQLClient, ClientContext, useQuery } from 'graphql-hooks';
|
||||
|
||||
import Paper from '@material-ui/core/Paper';
|
||||
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 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 SearchRepo from './search-repo';
|
||||
|
||||
import connectComponent from '../../helpers/connect-component';
|
||||
import { updateForm, save, setWikiCreationMessage } from '../../state/dialog-add-workspace/actions';
|
||||
|
|
@ -23,17 +32,27 @@ import { updateForm, save, setWikiCreationMessage } from '../../state/dialog-add
|
|||
import {
|
||||
requestCopyWikiTemplate,
|
||||
requestCreateSubWiki,
|
||||
requestSetPreference,
|
||||
getPreference,
|
||||
getIconPath,
|
||||
getDesktopPath,
|
||||
getWorkspaces,
|
||||
countWorkspace,
|
||||
} from '../../senders';
|
||||
|
||||
const graphqlClient = new GraphQLClient({
|
||||
url: GITHUB_GRAPHQL_API,
|
||||
});
|
||||
|
||||
const Container = styled.main`
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
overflow: scroll;
|
||||
&::-webkit-scrollbar {
|
||||
width: 0;
|
||||
}
|
||||
padding-bottom: 35px;
|
||||
`;
|
||||
const Description = styled(Paper)`
|
||||
padding: 10px;
|
||||
|
|
@ -67,12 +86,29 @@ const SoftLinkToMainWikiSelectInputLabel = styled(InputLabel)`
|
|||
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 }) {
|
||||
const [isCreateMainWorkspace, isCreateMainWorkspaceSetter] = useState(countWorkspace() === 0);
|
||||
const [parentFolderLocation, parentFolderLocationSetter] = useState(getDesktopPath());
|
||||
const [wikiFolderLocation, wikiFolderLocationSetter] = useState('');
|
||||
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({});
|
||||
useEffect(() => {
|
||||
workspacesSetter(getWorkspaces());
|
||||
|
|
@ -91,115 +127,157 @@ function AddWorkspace({ wikiCreationMessage, onUpdateForm, onSave, onSetWikiCrea
|
|||
picturePath: getIconPath(),
|
||||
};
|
||||
return (
|
||||
<Container>
|
||||
<Description elevation={0} square>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Switch
|
||||
checked={isCreateMainWorkspace}
|
||||
onChange={event => isCreateMainWorkspaceSetter(event.target.checked)}
|
||||
<ClientContext.Provider value={graphqlClient}>
|
||||
<Container>
|
||||
<Description elevation={0} square>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Switch
|
||||
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}
|
||||
/>
|
||||
}
|
||||
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 => console.log(response)}
|
||||
onFailure={response => console.log(response)}
|
||||
/>
|
||||
</SyncContainer>
|
||||
|
||||
<CreateContainer elevation={2} square>
|
||||
<LocationPickerContainer>
|
||||
<LocationPickerInput
|
||||
<LocationPickerButton
|
||||
onClick={() => {
|
||||
const { remote } = window.require('electron');
|
||||
// eslint-disable-next-line promise/catch-or-return
|
||||
remote.dialog
|
||||
.showOpenDialog(remote.getCurrentWindow(), {
|
||||
properties: ['openDirectory'],
|
||||
})
|
||||
.then(({ canceled, filePaths }) => {
|
||||
// eslint-disable-next-line promise/always-return
|
||||
if (!canceled && filePaths.length > 0) {
|
||||
parentFolderLocationSetter(filePaths[0]);
|
||||
}
|
||||
});
|
||||
}}
|
||||
variant="outlined"
|
||||
color={parentFolderLocation ? 'default' : 'primary'}
|
||||
disableElevation
|
||||
endIcon={<FolderIcon />}
|
||||
>
|
||||
<Typography variant="button" display="inline">
|
||||
选择
|
||||
</Typography>
|
||||
</LocationPickerButton>
|
||||
</LocationPickerContainer>
|
||||
<LocationPickerInput
|
||||
error={!!wikiCreationMessage}
|
||||
helperText={wikiCreationMessage}
|
||||
fullWidth
|
||||
onChange={event => {
|
||||
parentFolderLocationSetter(event.target.value);
|
||||
wikiFolderNameSetter(event.target.value);
|
||||
onSetWikiCreationMessage('');
|
||||
}}
|
||||
label="知识库的父文件夹"
|
||||
value={parentFolderLocation}
|
||||
label="知识库文件夹名"
|
||||
value={wikiFolderName}
|
||||
/>
|
||||
<LocationPickerButton
|
||||
onClick={() => {
|
||||
const { remote } = window.require('electron');
|
||||
// eslint-disable-next-line promise/catch-or-return
|
||||
remote.dialog
|
||||
.showOpenDialog(remote.getCurrentWindow(), {
|
||||
properties: ['openDirectory'],
|
||||
})
|
||||
.then(({ canceled, filePaths }) => {
|
||||
// eslint-disable-next-line promise/always-return
|
||||
if (!canceled && filePaths.length > 0) {
|
||||
parentFolderLocationSetter(filePaths[0]);
|
||||
}
|
||||
});
|
||||
<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>
|
||||
<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">
|
||||
选择
|
||||
</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>
|
||||
{parentFolderLocation && (
|
||||
<>
|
||||
<Typography variant="body1" display="inline">
|
||||
子知识库将链接到
|
||||
在
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="body2"
|
||||
|
|
@ -208,89 +286,55 @@ function AddWorkspace({ wikiCreationMessage, onUpdateForm, onSave, onSetWikiCrea
|
|||
align="center"
|
||||
style={{ direction: 'rtl', textTransform: 'none' }}
|
||||
>
|
||||
{mainWikiToLink}/tiddlers/{wikiFolderName}
|
||||
{wikiFolderLocation}
|
||||
</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>
|
||||
|
||||
{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>
|
||||
</Container>
|
||||
</ClientContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
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_DOMAIN = 'tiddlygit-desktop.authing.cn'
|
||||
export const APP_ID = '5efdd30e56a87fb76b52809d';
|
||||
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');
|
||||
|
||||
export const requestCopyWikiTemplate = (newFolderPath, folderName) => ipcRenderer.invoke('copy-wiki-template', newFolderPath, folderName);
|
||||
export const requestCreateSubWiki = (newFolderPath, folderName, mainWikiToLink) => 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 requestCopyWikiTemplate = (newFolderPath, folderName) =>
|
||||
ipcRenderer.invoke('copy-wiki-template', newFolderPath, folderName);
|
||||
export const requestCreateSubWiki = (newFolderPath, folderName, mainWikiToLink) =>
|
||||
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 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 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 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 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 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 requestShowSpellcheckLanguagesWindow = () => ipcRenderer.send('request-show-spellcheck-languages-window');
|
||||
|
||||
// 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 getPauseNotificationsInfo = () => ipcRenderer.sendSync('get-pause-notifications-info');
|
||||
|
||||
// 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 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 requestShowRequireRestartDialog = () => ipcRenderer.send('request-show-require-restart-dialog');
|
||||
|
||||
// System Preferences
|
||||
export const getSystemPreference = (name) => ipcRenderer.sendSync('get-system-preference', name);
|
||||
export const getSystemPreferences = () => ipcRenderer.sendSync('get-system-preferences');
|
||||
export const requestSetSystemPreference = (name, value) =>
|
||||
export const getSystemPreference = (name: string): JsonValue => ipcRenderer.sendSync('get-system-preference', name);
|
||||
export const getSystemPreferences = (): JsonObject => ipcRenderer.sendSync('get-system-preferences');
|
||||
export const requestSetSystemPreference = (name: string, value: JsonValue) =>
|
||||
ipcRenderer.send('request-set-system-preference', name, value);
|
||||
|
||||
// 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 requestClearBrowsingData = () => ipcRenderer.send('request-clear-browsing-data');
|
||||
export const requestCreateWorkspace = (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 requestRealignActiveWorkspace = () => ipcRenderer.send('request-realign-active-workspace');
|
||||
export const requestRemoveWorkspace = (id) => ipcRenderer.send('request-remove-workspace', 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 requestRemoveWorkspace = id => ipcRenderer.send('request-remove-workspace', 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 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) =>
|
||||
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 getReactPath = () => ipcRenderer.sendSync('get-constant', 'REACT_PATH');
|
||||
export const getDesktopPath = () => ipcRenderer.sendSync('get-constant', 'DESKTOP_PATH');
|
||||
|
||||
// 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');
|
||||
|
||||
// Find In Page
|
||||
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
|
||||
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');
|
||||
|
||||
// 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