Skip to content

Commit

Permalink
feat: 增加3.x的垫图、混图、识图和自定义反向代理支持
Browse files Browse the repository at this point in the history
  • Loading branch information
Licoy committed Oct 18, 2023
1 parent f73335f commit 7285331
Show file tree
Hide file tree
Showing 12 changed files with 247 additions and 70 deletions.
5 changes: 4 additions & 1 deletion .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,7 @@ HIDE_BALANCE_QUERY=

MJ_SERVER_ID=
MJ_CHANNEL_ID=
MJ_USER_TOKEN=
MJ_USER_TOKEN=
MJ_DISCORD_PROXY=
MJ_DISCORD_WSS_PROXY=
MJ_DISCORD_CDN_PROXY=
15 changes: 11 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@
- [x] Midjourney `Vary` 变化
- [x] Midjourney `Pan` 平移
- [x] Midjourney `Reroll` 重新生成
- [x] Midjourney `Describe` 识图(3.0待支持)
- [x] Midjourney `Blend` 混图(3.0待支持)
- [x] Midjourney 垫图(3.0待支持)
- [x] Midjourney `Describe` 识图
- [x] Midjourney `Blend` 混图
- [x] Midjourney 垫图
- [x] 绘图进度百分比、实时图像显示
- [x] 自定义Discord的API、CDN、Websocket支持
- [x] 自身内部支持 Midjourney 服务,无需任何第三方依赖

## 参数说明
Expand All @@ -38,6 +39,12 @@ Midjourney服务器ID
Midjourney频道ID
### MJ_USER_TOKEN
Midjourney用户Token
### MJ_DISCORD_PROXY
Discord代理域名,默认为:`https://discord.com`
### MJ_DISCORD_WSS_PROXY
Discord Websocket代理域名,默认为:`wss://gateway.discord.gg`
### MJ_DISCORD_WSS_PROXY
Discord CDN代理域名,默认为:`https://cdn.discordapp.com`
### CODE
(可选)设置页面中的访问密码
### 其余参数
Expand Down Expand Up @@ -71,7 +78,7 @@ npm run start // #或者开发模式启动: npm run dev
```
/mj a dog
```
### 混图、识图、垫图(3.0暂时不支持,陆续支持)
### 混图、识图、垫图
![mj-5](./docs/images/mj-5.png)
> 提示:垫图模式/识图(describe)模式只会使用第一张图片,混图(blend)模式会按顺序使用选中的两张图片(点击图片可以移除)
Expand Down
15 changes: 11 additions & 4 deletions README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ One-click free deployment of your private ChatGPT+Midjourney web application (ba
- [x] Midjourney `Vary` changes
- [x] Midjourney `Pan`
- [x] Midjourney `Reroll` respawn
- [x] Midjourney `Describe` image recognition (3.0 to be supported)
- [x] Midjourney `Blend` (3.0 to be supported)
- [x] Midjourney pad map (3.0 to be supported)
- [x] Midjourney `Describe` image recognition
- [x] Midjourney `Blend`
- [x] Midjourney pad map
- [x] Drawing progress percentage, real-time image display
- [x] Customized Discord API, CDN, and Websocket support
- [x] Support Midjourney service internally without any third-party dependencies

## Parameter Description
Expand All @@ -38,6 +39,12 @@ Midjourney server ID
MidjourneyChannelID
### MJ_USER_TOKEN
Midjourney User Token
### MJ_DISCORD_PROXY
Discord proxy domain, default to: `https://discord.com`
### MJ_DISCORD_WSS_PROXY
Discord Websocket proxy domain, default to: `wss://gateway.discord.gg`
### MJ_DISCORD_WSS_PROXY
Discord CDN proxy domain, default to: `https://cdn.discordapp.com`
### CODE
(Optional) Set the access password on the page to prevent others from easily using it to consume the balance
### Other Parameters
Expand Down Expand Up @@ -71,7 +78,7 @@ Enter your painting description starting with `/mj` in the input box to create a
```
/mj a dog
```
### Mixing images, recognizing images, and matting images (3.0 is not supported temporarily, and will be supported in succession)
### Mixing images, recognizing images, and matting images
![mj-5](./docs/images/mj-5.png)
> Tip: The pad mode/describe mode will only use the first picture, and the blend mode will use the two selected pictures in order (click the picture to remove it)
Expand Down
23 changes: 14 additions & 9 deletions app/api/midjourney/[...path]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,21 @@ async function handle(req: NextRequest, {params}: { params: { path: string[] } }
}
}
const path = params.path.join("/");
if (path == 'task/submit') {
let data: any = null
try {
data = await req.json()
} catch (e) {
return NextResponse.json({code: 1, status: 'FAIL', msg: '无效的请求数据'}, {status: 200});
try{
if (path == 'task/submit') {
let data: any = null
try {
data = await req.json()
} catch (e) {
return NextResponse.json({code: 1, status: 'FAIL', msg: '无效的请求数据'}, {status: 200});
}
const res = await api.submit(data)
return NextResponse.json(res, {status: 200});
} else if (path.startsWith('task/status') && params.path.length == 3) {
return NextResponse.json(api.status(params.path[2]), {status: 200});
}
return NextResponse.json(api.submit(data), {status: 200});
} else if (path.startsWith('task/status') && params.path.length == 3) {
return NextResponse.json(api.status(params.path[2]), {status: 200});
}catch (e:any) {
return NextResponse.json({code: 1, status: 'FAIL', msg: e.message || '未知错误,请查看服务端日志'}, {status: 200});
}
return NextResponse.json({code: 1, status: 'FAIL', msg: '无效操作'}, {status: 200});
}
Expand Down
7 changes: 4 additions & 3 deletions app/client/api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getClientConfig } from "../config/client";
import { ACCESS_CODE_PREFIX } from "../constant";
import { ChatMessage, ModelType, useAccessStore } from "../store";
import {ChatMessage, ModelType, useAccessStore, useAppConfig} from "../store";
import { ChatGPTApi } from "./platforms/openai";

export const ROLES = ["system", "user", "assistant"] as const;
Expand Down Expand Up @@ -151,8 +151,9 @@ export function getHeaders() {
}

export function useGetMidjourneySelfProxyUrl(url: string) {
const accessStore = useAccessStore.getState();
if (accessStore.useMjImgSelfProxy) {
const config = useAppConfig.getState();
if (config.useMjImgSelfProxy) {
const accessStore = useAccessStore.getState();
url = url.replace("https://cdn.discordapp.com", "/cdn/discordapp");
if (accessStore.accessCode) {
url +=
Expand Down
31 changes: 16 additions & 15 deletions app/components/chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import PinIcon from "../icons/pin.svg";
import EditIcon from "../icons/rename.svg";
import ConfirmIcon from "../icons/confirm.svg";
import CancelIcon from "../icons/cancel.svg";
import UploadIcon from "../icons/upload.svg";

import LightIcon from "../icons/light.svg";
import DarkIcon from "../icons/dark.svg";
Expand Down Expand Up @@ -542,20 +543,20 @@ export function ChatActions(props: {
icon={<RobotIcon/>}
/>

{/*<ChatAction*/}
{/* onClick={selectImage}*/}
{/* text="选择图片"*/}
{/* icon={<UploadIcon/>}*/}
{/* innerNode={*/}
{/* <input*/}
{/* type="file"*/}
{/* accept=".png,.jpg,.webp,.jpeg"*/}
{/* id="chat-image-file-select-upload"*/}
{/* style={{display: "none"}}*/}
{/* onChange={onImageSelected}*/}
{/* />*/}
{/* }*/}
{/*/>*/}
<ChatAction
onClick={selectImage}
text="选择图片"
icon={<UploadIcon/>}
innerNode={
<input
type="file"
accept=".png,.jpg,.webp,.jpeg"
id="chat-image-file-select-upload"
style={{display: "none"}}
onChange={onImageSelected}
/>
}
/>

{showModelSelector && (
<Selector
Expand Down Expand Up @@ -1352,7 +1353,7 @@ function _Chat() {
{useImages.length > 0 && (
<div className={styles["chat-select-images"]}>
{useImages.map((img: any, i) => (
<Image
<img
src={img.base64}
key={i}
onClick={() => {
Expand Down
2 changes: 1 addition & 1 deletion app/components/error.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export class ErrorBoundary extends React.Component<any, IErrorBoundaryState> {
try {
downloadAs(
JSON.stringify(localStorage),
"chatgpt-next-web-snapshot.json",
"chatgpt-midjourney-snapshot.json",
);
} finally {
localStorage.clear();
Expand Down
4 changes: 2 additions & 2 deletions app/components/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -604,11 +604,11 @@ export function Settings() {
>
<input
type="checkbox"
checked={accessStore.useMjImgSelfProxy}
checked={config.useMjImgSelfProxy}
onChange={(e) =>
updateConfig(
(config) =>
(accessStore.useMjImgSelfProxy = e.currentTarget.checked),
(config.useMjImgSelfProxy = e.currentTarget.checked),
)
}
></input>
Expand Down
Loading

0 comments on commit 7285331

Please sign in to comment.