Compare commits

..

No commits in common. "c75663bf9050735ffe5b8e1fe042db2b1095b47e" and "07013035632e0e6e30e175de21db5b58db5f9b4e" have entirely different histories.

11 changed files with 47 additions and 182 deletions

View File

@ -11,9 +11,7 @@ name: publish image
on:
push:
branches:
- release
- beta
branches: ['release']
env:
REGISTRY: ghcr.io
@ -30,15 +28,6 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
with:
image: tonistiigi/binfmt:latest
platforms: arm64
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Log in to the Container registry
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
with:
@ -57,6 +46,5 @@ jobs:
with:
context: .
push: true
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

View File

@ -14,12 +14,9 @@ COPY ./app/tsconfig.json ./
# Install Node.js dependencies
RUN npm install
COPY ./app/vite.config.js ./
# Copy public, and src directories
COPY ./app/public ./public
COPY ./app/src ./src
COPY ./app/index.html ./
# Set environment variables
ENV NODE_ENV=production
@ -32,6 +29,14 @@ FROM node:19-bullseye-slim AS server
# Set the working directory
WORKDIR /app
# Update the package index and install required dependencies
# RUN apt-get update && \
# apt-get install -y \
# curl \
# build-essential \
# libssl-dev \
# openssl
COPY ./server/package.json ./server/tsconfig.json ./
# Install Node.js dependencies from package.json
@ -40,7 +45,7 @@ RUN npm install
# Copy the rest of the application code into the working directory
COPY ./server/src ./src
RUN CI=true sh -c "cd /app && npm run start && rm -rf data"
RUN CI=true sh -c "cd /app && mkdir data && npm run start && rm -rf data"
COPY --from=build /app/build /app/public

View File

@ -3,24 +3,33 @@
<head>
<meta charset="utf-8" />
<link rel="dns-prefetch" href="https://fonts.googleapis.com">
<link rel="dns-prefetch" href="https://cdnjs.cloudflare.com">
<link rel="dns-prefetch" href="https://cdn.jsdelivr.net">
<link rel="preconnect" crossorigin="anonymous" href="https://fonts.googleapis.com">
<link rel="preconnect" crossorigin="anonymous" href="https://cdnjs.cloudflare.com">
<link rel="preconnect" crossorigin="anonymous" href="https://cdn.jsdelivr.net">
<link rel="icon" href="/favicon.ico" />
<!-- mobile app viewport -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="An open source ChatGPT app with a voice." />
<link rel="apple-touch-icon" href="/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="/manifest.json" />
<!--
Notice the use of in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>Chat with GPT | Unofficial ChatGPT app</title>
<link rel="stylesheet" crossorigin="anonymous" media="all" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/all.min.css" />
<link rel="stylesheet" crossorigin="anonymous" media="all" href="https://fonts.googleapis.com/css?family=Open+Sans:100,400,300,500,700,800" />
<link rel="stylesheet" crossorigin="anonymous" media="all" href="https://fonts.googleapis.com/css?family=Fira+Code:100,400,300,500,700,800" />
<link rel="stylesheet" crossorigin="anonymous" href="https://fonts.googleapis.com/css?family=Work+Sans:300,400,500,600,700&display=swap">
<link rel="stylesheet" crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.css" integrity="sha384-Xi8rHCmBmhbuyyhbI88391ZKP2dmfnOl4rT9ZfRI7mLTdk1wblIUnrIq35nqwEvC">
<link rel="stylesheet" media="all" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/all.min.css" />
<link rel="stylesheet" media="all" href="https://fonts.googleapis.com/css?family=Open+Sans:100,400,300,500,700,800" />
<link rel="stylesheet" media="all" href="https://fonts.googleapis.com/css?family=Fira+Code:100,400,300,500,700,800" />
<link href="https://fonts.googleapis.com/css?family=Work+Sans:300,400,500,600,700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.css"
integrity="sha384-Xi8rHCmBmhbuyyhbI88391ZKP2dmfnOl4rT9ZfRI7mLTdk1wblIUnrIq35nqwEvC" crossorigin="anonymous">
<link rel="stylesheet" href="/prose.css" />
<link rel="canonical" href="https://www.chatwithgpt.ai" />
<style>

View File

@ -69,8 +69,6 @@
"@vitejs/plugin-react": "^4.0.2",
"babel-plugin-formatjs": "^10.5.3",
"typescript": "^4.9.5",
"vite": "^4.4.1",
"vite-plugin-pwa": "^0.16.4",
"workbox-window": "^7.0.0"
"vite": "^4.4.1"
}
}

View File

@ -0,0 +1,8 @@
{
"short_name": "Chat with GPT",
"name": "Chat with GPT",
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

View File

@ -4,7 +4,6 @@ import { useChatSpotlightProps } from '../spotlight';
import { LoginModal, CreateAccountModal } from './auth-modals';
import Header, { HeaderProps, SubHeader } from './header';
import MessageInput from './input';
import { InstallUpdateNotification } from './pwa-notifications';
import SettingsDrawer from './settings';
import Sidebar from './sidebar';
import AudioControls from './tts-controls';
@ -91,7 +90,6 @@ export function Page(props: {
<SettingsDrawer />
<LoginModal />
<CreateAccountModal />
<InstallUpdateNotification />
</Main>
</Container>
</SpotlightProvider>;

View File

@ -1,37 +0,0 @@
import { Button, Notification } from "@mantine/core";
import { useCallback } from "react";
import { useRegisterSW } from "virtual:pwa-register/react";
export function InstallUpdateNotification() {
const {
offlineReady: [_, setOfflineReady],
needRefresh: [needRefresh, setNeedRefresh],
updateServiceWorker,
} = useRegisterSW({
onRegistered(r) {
console.log("SW Registered:", r);
},
onRegisterError(error) {
console.log("SW registration error", error);
},
});
const onClose = () => {
setOfflineReady(false);
setNeedRefresh(false);
};
const onUpdate = useCallback(async () => {
updateServiceWorker(true);
}, []);
return needRefresh ? (
<Notification title="Update available!" onClose={onClose}>
Click{" "}
<Button compact onClick={onUpdate}>
Update now
</Button>{" "}
to get the latest version.
</Notification>
) : null;
}

View File

@ -86,4 +86,4 @@ async function bootstrapApplication() {
);
}
bootstrapApplication();
bootstrapApplication();

View File

@ -1,20 +1,11 @@
import { configureStore } from '@reduxjs/toolkit';
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
import {
FLUSH,
PAUSE,
PERSIST,
PURGE,
REGISTER,
REHYDRATE,
persistReducer,
persistStore,
} from "redux-persist";
import storage from 'redux-persist/lib/storage';
import { persistReducer, persistStore } from 'redux-persist';
import messageReducer from './message';
import uiReducer from './ui';
import settingsUIReducer from './settings-ui';
import sidebarReducer from './sidebar';
import uiReducer from './ui';
const persistConfig = {
key: 'root',
@ -31,20 +22,16 @@ const persistMessageConfig = {
storage,
}
const store = configureStore({
reducer: {
message: persistReducer<ReturnType<typeof messageReducer>>(persistMessageConfig, messageReducer),
message: persistReducer(persistMessageConfig, messageReducer),
ui: uiReducer,
settingsUI: settingsUIReducer,
sidebar: persistReducer<ReturnType<typeof sidebarReducer>>(persistSidebarConfig, sidebarReducer),
sidebar: persistReducer(persistSidebarConfig, sidebarReducer),
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: {
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
},
}),
});
})
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

View File

@ -1,2 +1 @@
/// <reference types="vite-plugin-comlink/client" />
/// <reference types="vite-plugin-pwa/client" />

View File

@ -1,6 +1,5 @@
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";
import { VitePWA } from "vite-plugin-pwa";
export default defineConfig(() => {
return {
@ -15,11 +14,6 @@ export default defineConfig(() => {
},
build: {
outDir: "build",
target: "es2020",
sourcemap: true,
},
esbuild: {
target: "es2020",
},
resolve: {
alias: {
@ -40,90 +34,6 @@ export default defineConfig(() => {
],
},
}),
VitePWA({
registerType: "autoUpdate",
includeAssets: ["favicon.ico", "lang/*.json"],
manifest: {
short_name: "Chat with GPT",
name: "Chat with GPT",
start_url: ".",
display: "standalone",
theme_color: "#000000",
background_color: "#ffffff",
icons: [
{
src: "logo192.png",
type: "image/png",
sizes: "192x192",
},
{
src: "logo512.png",
type: "image/png",
sizes: "512x512",
},
],
},
workbox: {
runtimeCaching: [
{
urlPattern: /^https:\/\/fonts\.googleapis\.com\/.*/i,
handler: "CacheFirst",
options: {
cacheName: "google-fonts-cache",
expiration: {
maxEntries: 10,
maxAgeSeconds: 60 * 60 * 24 * 365,
},
cacheableResponse: {
statuses: [0, 200],
},
},
},
{
urlPattern: /^https:\/\/fonts\.gstatic\.com\/.*/i,
handler: "CacheFirst",
options: {
cacheName: "gstatic-fonts-cache",
expiration: {
maxEntries: 10,
maxAgeSeconds: 60 * 60 * 24 * 365,
},
cacheableResponse: {
statuses: [0, 200],
},
},
},
{
urlPattern: /^https:\/\/cdnjs\.cloudflare\.com\/.*/i,
handler: "CacheFirst",
options: {
cacheName: "cloudflare-js-cdn",
expiration: {
maxEntries: 10,
maxAgeSeconds: 60 * 60 * 24 * 365,
},
cacheableResponse: {
statuses: [0, 200],
},
},
},
{
urlPattern: /^https:\/\/cdn\.jsdelivr\.net\/.*/i,
handler: "CacheFirst",
options: {
cacheName: "jsdelivr-cdn",
expiration: {
maxEntries: 10,
maxAgeSeconds: 60 * 60 * 24 * 365,
},
cacheableResponse: {
statuses: [0, 200],
},
},
},
],
},
}),
],
};
});