Skip to content

Commit

Permalink
Merge branch 'Yidadaa:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
aizpy authored Jun 15, 2023
2 parents 5b8d303 + 9d1a848 commit 7aae655
Show file tree
Hide file tree
Showing 39 changed files with 500 additions and 70 deletions.
86 changes: 86 additions & 0 deletions .github/workflows/app.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: Release App

on:
workflow_dispatch:
release:
types: [published]

jobs:
create-release:
permissions:
contents: write
runs-on: ubuntu-20.04
outputs:
release_id: ${{ steps.create-release.outputs.result }}

steps:
- uses: actions/checkout@v3
- name: setup node
uses: actions/setup-node@v3
with:
node-version: 16
- name: get version
run: echo "PACKAGE_VERSION=$(node -p "require('./src-tauri/tauri.conf.json').package.version")" >> $GITHUB_ENV
- name: create release
id: create-release
uses: actions/github-script@v6
with:
script: |
const { data } = await github.rest.repos.getLatestRelease({
owner: context.repo.owner,
repo: context.repo.repo,
})
return data.id
build-tauri:
needs: create-release
permissions:
contents: write
strategy:
fail-fast: false
matrix:
platform: [macos-latest, ubuntu-20.04, windows-latest]

runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v3
- name: setup node
uses: actions/setup-node@v3
with:
node-version: 16
- name: install Rust stable
uses: dtolnay/rust-toolchain@stable
- name: install dependencies (ubuntu only)
if: matrix.platform == 'ubuntu-20.04'
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf
- name: install frontend dependencies
run: yarn install # change this to npm or pnpm depending on which one you use
- uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
releaseId: ${{ needs.create-release.outputs.release_id }}

publish-release:
permissions:
contents: write
runs-on: ubuntu-20.04
needs: [create-release, build-tauri]

steps:
- name: publish release
id: publish-release
uses: actions/github-script@v6
env:
release_id: ${{ needs.create-release.outputs.release_id }}
with:
script: |
github.rest.repos.updateRelease({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: process.env.release_id,
draft: false,
prerelease: false
})
4 changes: 2 additions & 2 deletions .github/workflows/sync.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@ jobs:
- name: Sync check
if: failure()
run: |
echo "::error::由于权限不足,导致同步失败(这是预期的行为),请前往仓库首页手动执行[Sync fork]。"
echo "::error::Due to insufficient permissions, synchronization failed (as expected). Please go to the repository homepage and manually perform [Sync fork]."
echo "[Error] 由于上游仓库的 workflow 文件变更,导致 GitHub 自动暂停了本次自动更新,你需要手动 Sync Fork 一次,详细教程请查看:https://github.com/Yidadaa/ChatGPT-Next-Web/blob/main/README_CN.md#%E6%89%93%E5%BC%80%E8%87%AA%E5%8A%A8%E6%9B%B4%E6%96%B0"
echo "[Error] Due to a change in the workflow file of the upstream repository, GitHub has automatically suspended the scheduled automatic update. You need to manually sync your fork. Please refer to the detailed tutorial for instructions: https://github.com/Yidadaa/ChatGPT-Next-Web#enable-automatic-updates"
exit 1
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,9 @@ Before starting development, you must create a new `.env.local` file at project

```
OPENAI_API_KEY=<your api key here>
# if you are not able to access openai service, use this BASE_URL
BASE_URL=https://chatgpt1.nextweb.fun/api/proxy
```

### Local Development
Expand Down
5 changes: 3 additions & 2 deletions README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,6 @@ OpenAI 接口代理 URL,如果你手动配置了 openai 接口代理,请填

## 开发

> 强烈不建议在本地进行开发或者部署,由于一些技术原因,很难在本地配置好 OpenAI API 代理,除非你能保证可以直连 OpenAI 服务器。
点击下方按钮,开始二次开发:

[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/Yidadaa/ChatGPT-Next-Web)
Expand All @@ -110,6 +108,9 @@ OpenAI 接口代理 URL,如果你手动配置了 openai 接口代理,请填

```
OPENAI_API_KEY=<your api key here>
# 中国大陆用户,可以使用本项目自带的代理进行开发,你也可以自由选择其他代理地址
BASE_URL=https://chatgpt1.nextweb.fun/api/proxy
```

### 本地开发
Expand Down
1 change: 0 additions & 1 deletion app/api/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { NextRequest } from "next/server";
import { getServerSideConfig } from "../config/server";
import md5 from "spark-md5";
import { ACCESS_CODE_PREFIX } from "../constant";
import { OPENAI_URL } from "./common";

function getIP(req: NextRequest) {
let ip = req.ip ?? req.headers.get("x-real-ip");
Expand Down
4 changes: 4 additions & 0 deletions app/api/openai/[...path]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ async function handle(
) {
console.log("[OpenAI Route] params ", params);

if (req.method === "OPTIONS") {
return NextResponse.json({ body: "OK" }, { status: 200 });
}

const subpath = params.path.join("/");

if (!ALLOWD_PATH.has(subpath)) {
Expand Down
15 changes: 13 additions & 2 deletions app/components/chat.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { useDebouncedCallback } from "use-debounce";
import React, { useState, useRef, useEffect, useLayoutEffect } from "react";
import React, {
useState,
useRef,
useEffect,
useLayoutEffect,
useMemo,
} from "react";

import SendWhiteIcon from "../icons/send-white.svg";
import BrainIcon from "../icons/brain.svg";
Expand Down Expand Up @@ -61,6 +67,7 @@ import { useMaskStore } from "../store/mask";
import { useCommand } from "../command";
import { prettyObject } from "../utils/format";
import { ExportMessageModal } from "./exporter";
import { getClientConfig } from "../config/client";

const Markdown = dynamic(async () => (await import("./markdown")).Markdown, {
loading: () => <LoadingIcon />,
Expand Down Expand Up @@ -704,9 +711,13 @@ export function Chat() {
}
};

const clientConfig = useMemo(() => getClientConfig(), []);

const location = useLocation();
const isChat = location.pathname === Path.Chat;

const autoFocus = !isMobileScreen || isChat; // only focus in chat page
const showMaxIcon = !isMobileScreen && !clientConfig?.isApp;

useCommand({
fill: setUserInput,
Expand Down Expand Up @@ -755,7 +766,7 @@ export function Chat() {
}}
/>
</div>
{!isMobileScreen && (
{showMaxIcon && (
<div className="window-action-button">
<IconButton
icon={config.tightBorder ? <MinIcon /> : <MaxIcon />}
Expand Down
7 changes: 6 additions & 1 deletion app/components/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,14 @@ const useHasHydrated = () => {

const loadAsyncGoogleFont = () => {
const linkEl = document.createElement("link");
const proxyFontUrl = "/google-fonts";
const remoteFontUrl = "https://fonts.googleapis.com";
const googleFontUrl =
getClientConfig()?.buildMode === "export" ? remoteFontUrl : proxyFontUrl;
linkEl.rel = "stylesheet";
linkEl.href =
"/google-fonts/css2?family=Noto+Sans+SC:wght@300;400;700;900&display=swap";
googleFontUrl +
"/css2?family=Noto+Sans+SC:wght@300;400;700;900&display=swap";
document.head.appendChild(linkEl);
};

Expand Down
71 changes: 43 additions & 28 deletions app/components/markdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import mermaid from "mermaid";

import LoadingIcon from "../icons/three-dots.svg";
import React from "react";
import { useThrottledCallback } from "use-debounce";

export function Mermaid(props: { code: string; onError: () => void }) {
const ref = useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -127,43 +128,57 @@ export function Markdown(
) {
const mdRef = useRef<HTMLDivElement>(null);
const renderedHeight = useRef(0);
const renderedWidth = useRef(0);
const inView = useRef(!!props.defaultShow);
const [_, triggerRender] = useState(0);
const checkInView = useThrottledCallback(
() => {
const parent = props.parentRef?.current;
const md = mdRef.current;
if (parent && md && !props.defaultShow) {
const parentBounds = parent.getBoundingClientRect();
const twoScreenHeight = Math.max(500, parentBounds.height * 2);
const mdBounds = md.getBoundingClientRect();
const parentTop = parentBounds.top - twoScreenHeight;
const parentBottom = parentBounds.bottom + twoScreenHeight;
const isOverlap =
Math.max(parentTop, mdBounds.top) <=
Math.min(parentBottom, mdBounds.bottom);
inView.current = isOverlap;
triggerRender(Date.now());
}

if (inView.current && md) {
const rect = md.getBoundingClientRect();
renderedHeight.current = Math.max(renderedHeight.current, rect.height);
renderedWidth.current = Math.max(renderedWidth.current, rect.width);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
},
300,
{
leading: true,
trailing: true,
},
);

const parent = props.parentRef?.current;
const md = mdRef.current;

const checkInView = () => {
if (parent && md) {
const parentBounds = parent.getBoundingClientRect();
const twoScreenHeight = Math.max(500, parentBounds.height * 2);
const mdBounds = md.getBoundingClientRect();
const parentTop = parentBounds.top - twoScreenHeight;
const parentBottom = parentBounds.bottom + twoScreenHeight;
const isOverlap =
Math.max(parentTop, mdBounds.top) <=
Math.min(parentBottom, mdBounds.bottom);
inView.current = isOverlap;
}

if (inView.current && md) {
renderedHeight.current = Math.max(
renderedHeight.current,
md.getBoundingClientRect().height,
);
}
};
useEffect(() => {
props.parentRef?.current?.addEventListener("scroll", checkInView);
checkInView();
return () =>
props.parentRef?.current?.removeEventListener("scroll", checkInView);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

setTimeout(() => checkInView(), 1);
const getSize = (x: number) => (!inView.current && x > 0 ? x : "auto");

return (
<div
className="markdown-body"
style={{
fontSize: `${props.fontSize ?? 14}px`,
height:
!inView.current && renderedHeight.current > 0
? renderedHeight.current
: "auto",
height: getSize(renderedHeight.current),
width: getSize(renderedWidth.current),
}}
ref={mdRef}
onContextMenu={props.onContextMenu}
Expand Down
7 changes: 6 additions & 1 deletion app/components/mask.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,12 @@ function ContextPromptItem(props: {
className={chatStyle["context-content"]}
rows={focusingInput ? 5 : 1}
onFocus={() => setFocusingInput(true)}
onBlur={() => setFocusingInput(false)}
onBlur={() => {
setFocusingInput(false);
// If the selection is not removed when the user loses focus, some
// extensions like "Translate" will always display a floating bar
window?.getSelection()?.removeAllRanges();
}}
onInput={(e) =>
props.update({
...props.prompt,
Expand Down
5 changes: 4 additions & 1 deletion app/components/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,9 @@ export function Settings() {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

const clientConfig = useMemo(() => getClientConfig(), []);
const showAccessCode = enabledAccessControl && !clientConfig?.isApp;

return (
<ErrorBoundary>
<div className="window-header">
Expand Down Expand Up @@ -485,7 +488,7 @@ export function Settings() {
</List>

<List>
{enabledAccessControl ? (
{showAccessCode ? (
<ListItem
title={Locale.Settings.AccessCode.Title}
subTitle={Locale.Settings.AccessCode.SubTitle}
Expand Down
1 change: 1 addition & 0 deletions app/config/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const getBuildConfig = () => {
return {
commitId: COMMIT_ID,
buildMode: process.env.BUILD_MODE ?? "standalone",
isApp: !!process.env.BUILD_APP,
};
};

Expand Down
1 change: 1 addition & 0 deletions app/config/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ declare global {
HIDE_USER_API_KEY?: string; // disable user's api key input
DISABLE_GPT4?: string; // allow user to use gpt-4 or not
BUILD_MODE?: "standalone" | "export";
BUILD_APP?: string; // is building desktop app
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion app/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const UPDATE_URL = `${REPO_URL}#keep-updated`;
export const FETCH_COMMIT_URL = `https://api.github.com/repos/${OWNER}/${REPO}/commits?per_page=1`;
export const FETCH_TAG_URL = `https://api.github.com/repos/${OWNER}/${REPO}/tags?per_page=1`;
export const RUNTIME_CONFIG_DOM = "danger-runtime-config";
export const DEFAULT_API_HOST = "https://chatgpt.nextweb.fun/api/proxy";
export const DEFAULT_API_HOST = "https://chatgpt1.nextweb.fun/api/proxy";

export enum Path {
Home = "/",
Expand Down
1 change: 0 additions & 1 deletion app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import "./styles/globals.scss";
import "./styles/markdown.scss";
import "./styles/highlight.scss";
import { getBuildConfig } from "./config/build";
import { getClientConfig } from "./config/client";

export const metadata = {
Expand Down
2 changes: 1 addition & 1 deletion app/store/access.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const useAccessStore = create<AccessControlStore>()(
);
},
fetch() {
if (fetchState > 0) return;
if (fetchState > 0 || getClientConfig()?.buildMode === "export") return;
fetchState = 1;
fetch("/api/config", {
method: "post",
Expand Down
Loading

0 comments on commit 7aae655

Please sign in to comment.