├── .husky
├── .gitignore
└── pre-commit
├── .gitignore
├── src
├── options
│ ├── types
│ │ ├── index.ts
│ │ └── settings.ts
│ ├── setting-form
│ │ ├── block.tsx
│ │ ├── instructions
│ │ │ ├── actions
│ │ │ │ ├── add.tsx
│ │ │ │ ├── export.tsx
│ │ │ │ └── import.tsx
│ │ │ ├── modal-state.tsx
│ │ │ ├── emoji.tsx
│ │ │ ├── index.tsx
│ │ │ ├── instruction-modal.tsx
│ │ │ └── list.tsx
│ │ ├── system.tsx
│ │ ├── custom-list.tsx
│ │ ├── index.tsx
│ │ ├── provider.tsx
│ │ └── open-api.tsx
│ ├── index.tsx
│ ├── index.html
│ ├── app.tsx
│ └── index.css
├── popup
│ ├── index.css
│ ├── index.tsx
│ ├── index.html
│ └── app.tsx
├── assets
│ ├── icon.png
│ └── icon.svg
├── global.d.ts
├── common
│ ├── types.d.ts
│ ├── langs.tsx
│ ├── file.tsx
│ ├── antd-theme.ts
│ ├── browser.ts
│ ├── locale
│ │ ├── en-US.json
│ │ └── zh-CN.json
│ ├── debug.ts
│ ├── i18n.ts
│ ├── event-name.ts
│ ├── api
│ │ ├── writely.ts
│ │ ├── openai-request.ts
│ │ ├── chatgpt-web.ts
│ │ ├── instructions.ts
│ │ └── openai.ts
│ ├── parse-stream.ts
│ └── store
│ │ └── settings.ts
├── content
│ ├── container
│ │ ├── ask-writely
│ │ │ ├── result-panel
│ │ │ │ ├── actions
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── replay.tsx
│ │ │ │ │ ├── replace.tsx
│ │ │ │ │ ├── update.tsx
│ │ │ │ │ ├── copy.tsx
│ │ │ │ │ └── base-action.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── login-instruction.tsx
│ │ │ │ ├── header.tsx
│ │ │ │ └── content.tsx
│ │ │ ├── content
│ │ │ │ ├── quick-prompt.tsx
│ │ │ │ ├── list.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── index.tsx
│ │ │ └── prompts.tsx
│ │ ├── store
│ │ │ ├── instruction.ts
│ │ │ ├── selection.ts
│ │ │ ├── result-panel.ts
│ │ │ └── view.ts
│ │ └── index.tsx
│ ├── utils
│ │ ├── selection
│ │ │ ├── highlight.ts
│ │ │ └── index.ts
│ │ └── edit-detector.ts
│ ├── index.tsx
│ ├── app.tsx
│ ├── shadow-dom.ts
│ └── index.css
├── components
│ ├── icon
│ │ ├── index.ts
│ │ ├── send.tsx
│ │ ├── update.tsx
│ │ ├── up.tsx
│ │ ├── drag.tsx
│ │ ├── return.tsx
│ │ ├── back.tsx
│ │ ├── delete.tsx
│ │ ├── close.tsx
│ │ ├── heart.tsx
│ │ ├── right.tsx
│ │ ├── write.tsx
│ │ ├── link.tsx
│ │ ├── replay.tsx
│ │ ├── copy.tsx
│ │ ├── edit.tsx
│ │ ├── replace.tsx
│ │ ├── insert.tsx
│ │ ├── more.tsx
│ │ ├── stop.tsx
│ │ ├── checked.tsx
│ │ ├── setting.tsx
│ │ ├── feedback.tsx
│ │ ├── chatgpt.tsx
│ │ ├── writely.tsx
│ │ ├── github.tsx
│ │ ├── logo.tsx
│ │ ├── open-ai.tsx
│ │ └── prompt-icons.tsx
│ └── icon-btn.tsx
└── background
│ ├── openai-request.ts
│ ├── index.ts
│ └── chatgpt-web.ts
├── assets
├── demo.gif
├── logo.png
├── config.png
├── notion-demo.gif
└── screen-shot.md
├── postcss.config.js
├── .prettierrc
├── index.html
├── tsconfig.json
├── DEMO.md
├── patches
├── antd+5.24.0.patch
└── openai+4.85.3.patch
├── LICENSE
├── manifest.json
├── manifest.firefox.json
├── README-CN.md
├── package.json
├── .github
└── workflows
│ └── release.yml
├── tsup.config.ts
├── tailwind.config.cjs
└── README.md
/.husky/.gitignore:
--------------------------------------------------------------------------------
1 | _
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | node_modules
3 | *.log
4 | *.lock
--------------------------------------------------------------------------------
/src/options/types/index.ts:
--------------------------------------------------------------------------------
1 | export * from './settings';
2 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 |
4 | npx lint-staged
5 |
--------------------------------------------------------------------------------
/assets/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/code/app-extension-writely/main/assets/demo.gif
--------------------------------------------------------------------------------
/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/code/app-extension-writely/main/assets/logo.png
--------------------------------------------------------------------------------
/src/popup/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
--------------------------------------------------------------------------------
/assets/config.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/code/app-extension-writely/main/assets/config.png
--------------------------------------------------------------------------------
/src/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/code/app-extension-writely/main/src/assets/icon.png
--------------------------------------------------------------------------------
/assets/notion-demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/code/app-extension-writely/main/assets/notion-demo.gif
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: [require('tailwindcss')(), require('autoprefixer')()],
3 | }
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "es5",
3 | "tabWidth": 2,
4 | "semi": false,
5 | "singleQuote": true
6 | }
--------------------------------------------------------------------------------
/src/global.d.ts:
--------------------------------------------------------------------------------
1 | import { Browser } from 'webextension-polyfill'
2 |
3 | declare global {
4 | var browser: Browser
5 | }
6 |
7 | declare module '*.png'
8 |
--------------------------------------------------------------------------------
/assets/screen-shot.md:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/popup/index.tsx:
--------------------------------------------------------------------------------
1 | import { createRoot } from 'react-dom/client'
2 | import { App } from './app'
3 |
4 | createRoot(document.getElementById('app')).render(
7 |
8 |
9 |
10 |
11 |
40 |
41 |
42 | 3. 进行配置。
43 |
44 |
45 |
46 | 4. 将鼠标滑动到任何网页上的单词上,一个“W”图标将出现在鼠标附近,单击以使用。
47 |
48 | 
49 |
50 | ## 更多演示
51 |
52 | [演示文档](./DEMO.md)
53 |
--------------------------------------------------------------------------------
/src/assets/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
31 |
--------------------------------------------------------------------------------
/src/components/icon/chatgpt.tsx:
--------------------------------------------------------------------------------
1 | import { SVGProps } from 'react'
2 |
3 | export const ChatGPTIcon: React.FC
8 |
9 |
10 |
11 |
12 |
13 |
53 |
54 | 3. Perform configuration.
55 |
56 |
57 |
58 | 4. After sliding the word on any webpage, a "W" icon will appear near the mouse, click to use.
59 |
60 | 
61 | 
62 |
63 | ## More demos [Demos](./DEMO.md)
64 |
65 | ## Star History
66 |
67 | [](https://star-history.com/#anc95/writely&Date)
68 |
--------------------------------------------------------------------------------
/src/content/container/ask-writely/content/list.tsx:
--------------------------------------------------------------------------------
1 | import { MaterialSymbolsMoreHoriz } from '@/components/icon/more'
2 | import { Popover } from 'antd'
3 | import i18next from 'i18next'
4 | import React, { useCallback, useRef } from 'react'
5 | import { RightArrowIcon } from '../../../../components/icon'
6 |
7 | export type ListProps = {
8 | items: {
9 | label: React.ReactNode
10 | children: ListProps['items']
11 | icon: React.ReactNode
12 | instruction: string
13 | }[]
14 | onClick?: (item: ListProps['items'][number]) => void
15 | max?: number
16 | }
17 |
18 | export const List: React.FC