forked from webclipper/web-clipper
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c84eae1
commit 2f1a823
Showing
9 changed files
with
257 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { Form, Select } from 'antd'; | ||
import { FormComponentProps } from 'antd/lib/form'; | ||
import React, { Fragment } from 'react'; | ||
import backend from '../..'; | ||
import Dida365DocumentService from './service'; | ||
import locale from '@/common/locales'; | ||
import { useFetch } from '@shihengtech/hooks'; | ||
|
||
const HeaderForm: React.FC<FormComponentProps> = ({ form: { getFieldDecorator } }) => { | ||
const service = backend.getDocumentService() as Dida365DocumentService; | ||
const tagsResponse = useFetch(async () => service.getTags(), [service], { | ||
initialState: { | ||
data: [], | ||
}, | ||
}); | ||
|
||
return ( | ||
<Fragment> | ||
<Form.Item> | ||
{getFieldDecorator('tags', { | ||
initialValue: [], | ||
})( | ||
<Select | ||
mode="tags" | ||
maxTagCount={3} | ||
style={{ width: '100%' }} | ||
placeholder={locale.format({ | ||
id: 'backend.services.dida365.headerForm.applyTags', | ||
defaultMessage: 'Apply tags', | ||
})} | ||
loading={tagsResponse.loading} | ||
> | ||
{tagsResponse.data?.map(o => ( | ||
<Select.Option key={o} value={o} title={o}> | ||
{o} | ||
</Select.Option> | ||
))} | ||
</Select> | ||
)} | ||
</Form.Item> | ||
</Fragment> | ||
); | ||
}; | ||
|
||
export default HeaderForm; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import localeService from '@/common/locales'; | ||
import { ServiceMeta } from '@/common/backend'; | ||
import Service from './service'; | ||
import headerForm from './headerForm'; | ||
|
||
export default (): ServiceMeta => { | ||
return { | ||
name: localeService.format({ | ||
id: 'backend.services.ticktick.name', | ||
defaultMessage: 'TickTick', | ||
}), | ||
icon: 'dida365', | ||
type: 'ticktick', | ||
headerForm, | ||
service: Service, | ||
permission: { | ||
origins: ['https://api.ticktick.com/*'], | ||
permissions: ['webRequest', 'webRequestBlocking'], | ||
}, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
import { Container } from 'typedi'; | ||
import { generateUuid } from '@web-clipper/shared/lib/uuid'; | ||
import localeService from '@/common/locales'; | ||
import { IWebRequestService } from '@/service/common/webRequest'; | ||
import { | ||
CreateDocumentRequest, | ||
CompleteStatus, | ||
UnauthorizedError, | ||
Repository, | ||
} from '@/common/backend/services/interface'; | ||
import { DocumentService } from '@/common/backend/index'; | ||
import { extend, RequestMethod } from 'umi-request'; | ||
|
||
interface TickTickProfile { | ||
name: string; | ||
username: string; | ||
picture: string; | ||
} | ||
|
||
interface TickTickCheckResponse { | ||
projectProfiles: { | ||
id: string; | ||
name: string; | ||
isOwner: boolean; | ||
closed: boolean; | ||
groupId: string; | ||
}[]; | ||
projectGroups: { | ||
id: string; | ||
name: string; | ||
}[]; | ||
tags: { | ||
name: string; | ||
}[]; | ||
} | ||
interface TickTickCreateDocumentRequest extends CreateDocumentRequest { | ||
tags: string[]; | ||
} | ||
|
||
export default class TickTickDocumentService implements DocumentService { | ||
private request: RequestMethod; | ||
|
||
constructor() { | ||
const request = extend({ | ||
prefix: `https://api.ticktick.com/api/v2/`, | ||
}); | ||
request.interceptors.response.use( | ||
response => { | ||
if (response.clone().status === 401) { | ||
throw new UnauthorizedError( | ||
localeService.format({ | ||
id: 'backend.services.ticktick.unauthorizedErrorMessage', | ||
defaultMessage: 'Unauthorized! Please Login TickTick Web.', | ||
}) | ||
); | ||
} | ||
return response; | ||
}, | ||
{ global: false } | ||
); | ||
|
||
this.request = request; | ||
} | ||
|
||
getId = () => { | ||
return 'TickTick'; | ||
}; | ||
|
||
getUserInfo = async () => { | ||
const response = await this.request.get<TickTickProfile>('user/profile'); | ||
return { | ||
name: response.name, | ||
avatar: response.picture, | ||
homePage: '', | ||
description: response.username, | ||
}; | ||
}; | ||
|
||
getTags = async (): Promise<string[]> => { | ||
const TickTickCheckResponse = await this.request.get<TickTickCheckResponse>(`batch/check/0`); | ||
return TickTickCheckResponse.tags.map(o => o.name); | ||
}; | ||
|
||
getRepositories = async (): Promise<Repository[]> => { | ||
const TickTickCheckResponse = await this.request.get<TickTickCheckResponse>(`batch/check/0`); | ||
const groupMap = new Map<string, string>(); | ||
TickTickCheckResponse.projectGroups.forEach(group => { | ||
groupMap.set(group.id, group.name); | ||
}); | ||
return TickTickCheckResponse.projectProfiles | ||
.filter(o => !o.closed) | ||
.map(({ id, name, groupId }) => ({ | ||
id: id, | ||
name: name, | ||
groupId: groupId | ||
? groupId | ||
: localeService.format({ | ||
id: 'backend.services.ticktick.rootGroup', | ||
defaultMessage: 'Root', | ||
}), | ||
groupName: groupId | ||
? groupMap.get(groupId)! | ||
: localeService.format({ | ||
id: 'backend.services.ticktick.rootGroup', | ||
defaultMessage: 'Root', | ||
}), | ||
})); | ||
}; | ||
|
||
createDocument = async (request: TickTickCreateDocumentRequest): Promise<CompleteStatus> => { | ||
const webRequestService = Container.get(IWebRequestService); | ||
|
||
const header = await webRequestService.startChangeHeader({ | ||
urls: ['https://api.ticktick.com/*'], | ||
requestHeaders: [ | ||
{ | ||
name: 'origin', | ||
value: 'https://ticktick.com', | ||
}, | ||
], | ||
}); | ||
|
||
const settings = await this.request.get<{ timeZone: string }>( | ||
'user/preferences/settings?includeWeb=true' | ||
); | ||
|
||
const id = generateUuid() | ||
.replace(/-/g, '') | ||
.slice(0, 24); | ||
const data = { | ||
add: [ | ||
{ | ||
items: [], | ||
reminders: [], | ||
exDate: [], | ||
dueDate: null, | ||
priority: 0, | ||
progress: 0, | ||
assignee: null, | ||
sortOrder: -4611733297427382000, | ||
startDate: null, | ||
isFloating: false, | ||
status: 0, | ||
deleted: 0, | ||
tags: request.tags, | ||
projectId: request.repositoryId, | ||
title: request.title, | ||
content: request.content, | ||
timeZone: settings.timeZone, | ||
id: id, | ||
}, | ||
], | ||
update: [], | ||
delete: [], | ||
}; | ||
|
||
await this.request.post('batch/task', { | ||
data: data, | ||
headers: { | ||
[header.name]: header.value, | ||
}, | ||
}); | ||
|
||
await webRequestService.end(header); | ||
|
||
return { | ||
href: `https://ticktick.com/#p/${request.repositoryId}/tasks/${id}`, | ||
}; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters