Merge branch 'Yidadaa:main' into main

This commit is contained in:
IMGSS 2023-03-31 11:57:48 +08:00 committed by GitHub
commit 5c87607b30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 102 additions and 87 deletions

View File

@ -43,10 +43,10 @@ jobs:
uses: docker/build-push-action@v4
with:
context: .
platforms: linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8
platforms: linux/amd64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

16
.github/workflows/sync.yml vendored Normal file
View File

@ -0,0 +1,16 @@
# .github/workflows/sync.yml
name: Sync Fork
on:
schedule:
- cron: "0 8 * * *" # 每天0点触发
jobs:
repo-sync:
runs-on: ubuntu-latest
steps:
- uses: TG908/fork-sync@v1.1
with:
github_token: ${{ secrets.GITHUB_TOKEN }} # 这个 token action 会默认配置, 这里只需这样写就行
owner: Yidadaa # fork 上游项目 owner
head: main # fork 上游项目需要同步的分支
base: main # 需要同步到本项目的目标分支

View File

@ -6,13 +6,9 @@ RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json yarn.lock* package-lock.json* ./
COPY package.json yarn.lock ./
RUN \
if [ -f yarn.lock ]; then yarn install --frozen-lockfile --network-timeout 100000; \
elif [ -f package-lock.json ]; then npm ci; \
else echo "Lockfile not found." && exit 1; \
fi
RUN yarn install
FROM base AS builder

View File

@ -191,4 +191,4 @@ docker run -d -p 3000:3000 -e OPENAI_API_KEY="" -e CODE="" yidadaa/chatgpt-next-
## LICENSE
- [Anti 996 License](https://github.com/kattgu7/Anti-996-License/blob/master/LICENSE_CN_EN)
[Anti 996 License](https://github.com/kattgu7/Anti-996-License/blob/master/LICENSE_CN_EN)

View File

@ -26,13 +26,13 @@
@media only screen and (min-width: 600px) {
.tight-container {
--window-width: 100vw;
--window-height: 100vh;
--window-height: var(--full-height);
--window-content-width: calc(100% - var(--sidebar-width));
@include container();
max-width: 100vw;
max-height: 100vh;
max-height: var(--full-height);
border-radius: 0;
}
@ -74,7 +74,7 @@
position: absolute;
left: -100%;
z-index: 999;
height: 100vh;
height: var(--full-height);
transition: all ease 0.3s;
box-shadow: none;
}

View File

@ -24,7 +24,13 @@ import DownloadIcon from "../icons/download.svg";
import { Message, SubmitKey, useChatStore, ChatSession } from "../store";
import { showModal, showToast } from "./ui-lib";
import { copyToClipboard, downloadAs, isIOS, selectOrCopy } from "../utils";
import {
copyToClipboard,
downloadAs,
isIOS,
isMobileScreen,
selectOrCopy,
} from "../utils";
import Locale from "../locales";
import dynamic from "next/dynamic";
@ -285,9 +291,7 @@ export function Chat(props: {
// for auto-scroll
const latestMessageRef = useRef<HTMLDivElement>(null);
// wont scroll while hovering messages
const [autoScroll, setAutoScroll] = useState(false);
const [autoScroll, setAutoScroll] = useState(true);
// preview messages
const messages = (session.messages as RenderMessage[])
@ -320,7 +324,17 @@ export function Chat(props: {
useLayoutEffect(() => {
setTimeout(() => {
const dom = latestMessageRef.current;
if (dom && !isIOS() && autoScroll) {
const inputDom = inputRef.current;
// only scroll when input overlaped message body
let shouldScroll = true;
if (dom && inputDom) {
const domRect = dom.getBoundingClientRect();
const inputRect = inputDom.getBoundingClientRect();
shouldScroll = domRect.top > inputRect.top;
}
if (dom && autoScroll && shouldScroll) {
dom.scrollIntoView({
block: "end",
});
@ -476,7 +490,7 @@ export function Chat(props: {
onFocus={() => setAutoScroll(true)}
onBlur={() => {
setAutoScroll(false);
setTimeout(() => setPromptHints([]), 100);
setTimeout(() => setPromptHints([]), 500);
}}
autoFocus={!props?.sideBarShowing}
/>
@ -618,7 +632,9 @@ export function Home() {
return (
<div
className={`${
config.tightBorder ? styles["tight-container"] : styles.container
config.tightBorder && !isMobileScreen()
? styles["tight-container"]
: styles.container
}`}
>
<div

View File

@ -23,7 +23,7 @@ import {
import { Avatar, PromptHints } from "./home";
import Locale, { AllLangs, changeLang, getLang } from "../locales";
import { getCurrentCommitId } from "../utils";
import { getCurrentVersion } from "../utils";
import Link from "next/link";
import { UPDATE_URL } from "../constant";
import { SearchService, usePromptStore } from "../store/prompt";
@ -60,7 +60,7 @@ export function Settings(props: { closeSettings: () => void }) {
const updateStore = useUpdateStore();
const [checkingUpdate, setCheckingUpdate] = useState(false);
const currentId = getCurrentCommitId();
const currentId = getCurrentVersion();
const remoteId = updateStore.remoteId;
const hasNewVersion = currentId !== remoteId;
@ -267,19 +267,17 @@ export function Settings(props: { closeSettings: () => void }) {
></input>
</SettingItem>
<div className="no-mobile">
<SettingItem title={Locale.Settings.TightBorder}>
<input
type="checkbox"
checked={config.tightBorder}
onChange={(e) =>
updateConfig(
(config) => (config.tightBorder = e.currentTarget.checked),
)
}
></input>
</SettingItem>
</div>
<SettingItem title={Locale.Settings.TightBorder}>
<input
type="checkbox"
checked={config.tightBorder}
onChange={(e) =>
updateConfig(
(config) => (config.tightBorder = e.currentTarget.checked),
)
}
></input>
</SettingItem>
</List>
<List>
<SettingItem
@ -375,7 +373,7 @@ export function Settings(props: { closeSettings: () => void }) {
type="range"
title={config.historyMessageCount.toString()}
value={config.historyMessageCount}
min="2"
min="0"
max="25"
step="2"
onChange={(e) =>

View File

@ -3,3 +3,4 @@ export const REPO = "ChatGPT-Next-Web";
export const REPO_URL = `https://github.com/${OWNER}/${REPO}`;
export const UPDATE_URL = `${REPO_URL}#%E4%BF%9D%E6%8C%81%E6%9B%B4%E6%96%B0-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`;

View File

@ -8,11 +8,12 @@ import { ACCESS_CODES, IS_IN_DOCKER } from "./api/access";
let COMMIT_ID: string | undefined;
try {
COMMIT_ID = process
// .execSync("git describe --tags --abbrev=0")
.execSync("git rev-parse --short HEAD")
.toString()
.trim();
} catch (e) {
console.error("No git or not from git repo.")
console.error("No git or not from git repo.");
}
export const metadata = {
@ -22,13 +23,13 @@ export const metadata = {
title: "ChatGPT Next Web",
statusBarStyle: "black-translucent",
},
themeColor: "#fafafa"
themeColor: "#fafafa",
};
function Meta() {
const metas = {
version: COMMIT_ID ?? "unknown",
access: (ACCESS_CODES.size > 0 || IS_IN_DOCKER) ? "enabled" : "disabled",
access: ACCESS_CODES.size > 0 || IS_IN_DOCKER ? "enabled" : "disabled",
};
return (

View File

@ -89,7 +89,9 @@ export function isValidNumber(x: number, min: number, max: number) {
return typeof x === "number" && x <= max && x >= min;
}
export function filterConfig(config: ModelConfig): Partial<ModelConfig> {
export function filterConfig(oldConfig: ModelConfig): Partial<ModelConfig> {
const config = Object.assign({}, oldConfig);
const validator: {
[k in keyof ModelConfig]: (x: ModelConfig[keyof ModelConfig]) => boolean;
} = {
@ -103,7 +105,7 @@ export function filterConfig(config: ModelConfig): Partial<ModelConfig> {
return isValidNumber(x as number, -2, 2);
},
temperature(x) {
return isValidNumber(x as number, 0, 1);
return isValidNumber(x as number, 0, 2);
},
};

View File

@ -1,7 +1,7 @@
import { create } from "zustand";
import { persist } from "zustand/middleware";
import { FETCH_COMMIT_URL } from "../constant";
import { getCurrentCommitId } from "../utils";
import { FETCH_COMMIT_URL, FETCH_TAG_URL } from "../constant";
import { getCurrentVersion } from "../utils";
export interface UpdateStore {
lastUpdate: number;
@ -19,16 +19,17 @@ export const useUpdateStore = create<UpdateStore>()(
remoteId: "",
async getLatestCommitId(force = false) {
const overOneHour = Date.now() - get().lastUpdate > 3600 * 1000;
const shouldFetch = force || overOneHour;
const overTenMins = Date.now() - get().lastUpdate > 10 * 60 * 1000;
const shouldFetch = force || overTenMins;
if (!shouldFetch) {
return getCurrentCommitId();
return getCurrentVersion();
}
try {
// const data = await (await fetch(FETCH_TAG_URL)).json();
// const remoteId = data[0].name as string;
const data = await (await fetch(FETCH_COMMIT_URL)).json();
const sha = data[0].sha as string;
const remoteId = sha.substring(0, 7);
const remoteId = (data[0].sha as string).substring(0, 7);
set(() => ({
lastUpdate: Date.now(),
remoteId,
@ -37,13 +38,13 @@ export const useUpdateStore = create<UpdateStore>()(
return remoteId;
} catch (error) {
console.error("[Fetch Upstream Commit Id]", error);
return getCurrentCommitId();
return getCurrentVersion();
}
},
}),
{
name: UPDATE_KEY,
version: 1,
}
)
},
),
);

View File

@ -53,12 +53,13 @@
--sidebar-width: 300px;
--window-content-width: calc(100% - var(--sidebar-width));
--message-max-width: 80%;
--full-height: 100vh;
}
@media only screen and (max-width: 600px) {
:root {
--window-width: 100vw;
--window-height: 100vh;
--window-height: var(--full-height);
--sidebar-width: 100vw;
--window-content-width: var(--window-width);
--message-max-width: 100%;
@ -80,14 +81,14 @@ body {
color: var(--black);
margin: 0;
padding: 0;
height: 100vh;
height: var(--full-height);
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
user-select: none;
font-family: "Noto Sans SC", "SF Pro SC", "SF Pro Text", "SF Pro Icons",
"PingFang SC", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
"PingFang SC", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
@media only screen and (max-width: 600px) {
background-color: var(--second);
@ -119,6 +120,11 @@ select {
cursor: pointer;
background-color: var(--white);
color: var(--black);
text-align: center;
}
input {
text-align: center;
}
input[type="checkbox"] {
@ -196,7 +202,7 @@ div.math {
position: fixed;
top: 0;
left: 0;
height: 100vh;
height: var(--full-height);
width: 100vw;
background-color: rgba($color: #000000, $alpha: 0.5);
display: flex;

View File

@ -120,33 +120,3 @@
cursor: help;
}
}
@mixin light {
.markdown-body pre {
filter: invert(1) hue-rotate(90deg) brightness(1.3);
}
}
@mixin dark {
.markdown-body pre {
filter: none;
}
}
:root {
@include light();
}
.light {
@include light();
}
.dark {
@include dark();
}
@media (prefers-color-scheme: dark) {
:root {
@include dark();
}
}

View File

@ -45,6 +45,10 @@ export function isIOS() {
return /iphone|ipad|ipod/.test(userAgent);
}
export function isMobileScreen() {
return window.innerWidth <= 600;
}
export function selectOrCopy(el: HTMLElement, content: string) {
const currentSelection = window.getSelection();
@ -72,7 +76,7 @@ export function queryMeta(key: string, defaultValue?: string): string {
}
let currentId: string;
export function getCurrentCommitId() {
export function getCurrentVersion() {
if (currentId) {
return currentId;
}

View File

@ -1,10 +1,14 @@
import fetch from "node-fetch";
import fs from "fs/promises";
const CN_URL =
const RAW_CN_URL =
"https://raw.githubusercontent.com/PlexPt/awesome-chatgpt-prompts-zh/main/prompts-zh.json";
const EN_URL =
const CN_URL =
"https://cdn.jsdelivr.net/gh/PlexPt/awesome-chatgpt-prompts-zh@main/prompts-zh.json";
const RAW_EN_URL =
"https://raw.githubusercontent.com/f/awesome-chatgpt-prompts/main/prompts.csv";
const EN_URL =
"https://cdn.jsdelivr.net/gh/f/awesome-chatgpt-prompts@main/prompts.csv";
const FILE = "./public/prompts.json";
async function fetchCN() {