Add mobile support
This commit is contained in:
parent
df89356dc0
commit
4c685e1a1e
|
@ -8,6 +8,8 @@
|
||||||
"name": "chatgpt-web",
|
"name": "chatgpt-web",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@fortawesome/free-brands-svg-icons": "^6.4.0",
|
||||||
|
"@fortawesome/free-regular-svg-icons": "^6.4.0",
|
||||||
"@fortawesome/free-solid-svg-icons": "^6.4.0",
|
"@fortawesome/free-solid-svg-icons": "^6.4.0",
|
||||||
"@fullhuman/postcss-purgecss": "^5.0.0",
|
"@fullhuman/postcss-purgecss": "^5.0.0",
|
||||||
"@microsoft/fetch-event-source": "^2.0.1",
|
"@microsoft/fetch-event-source": "^2.0.1",
|
||||||
|
@ -462,6 +464,32 @@
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@fortawesome/free-brands-svg-icons": {
|
||||||
|
"version": "6.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.4.0.tgz",
|
||||||
|
"integrity": "sha512-qvxTCo0FQ5k2N+VCXb/PZQ+QMhqRVM4OORiO6MXdG6bKolIojGU/srQ1ptvKk0JTbRgaJOfL2qMqGvBEZG7Z6g==",
|
||||||
|
"dev": true,
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@fortawesome/fontawesome-common-types": "6.4.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@fortawesome/free-regular-svg-icons": {
|
||||||
|
"version": "6.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.4.0.tgz",
|
||||||
|
"integrity": "sha512-ZfycI7D0KWPZtf7wtMFnQxs8qjBXArRzczABuMQqecA/nXohquJ5J/RCR77PmY5qGWkxAZDxpnUFVXKwtY/jPw==",
|
||||||
|
"dev": true,
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@fortawesome/fontawesome-common-types": "6.4.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@fortawesome/free-solid-svg-icons": {
|
"node_modules/@fortawesome/free-solid-svg-icons": {
|
||||||
"version": "6.4.0",
|
"version": "6.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.4.0.tgz",
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
"lint": "eslint . --fix"
|
"lint": "eslint . --fix"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@fortawesome/free-brands-svg-icons": "^6.4.0",
|
||||||
|
"@fortawesome/free-regular-svg-icons": "^6.4.0",
|
||||||
"@fortawesome/free-solid-svg-icons": "^6.4.0",
|
"@fortawesome/free-solid-svg-icons": "^6.4.0",
|
||||||
"@fullhuman/postcss-purgecss": "^5.0.0",
|
"@fullhuman/postcss-purgecss": "^5.0.0",
|
||||||
"@microsoft/fetch-event-source": "^2.0.1",
|
"@microsoft/fetch-event-source": "^2.0.1",
|
||||||
|
|
|
@ -34,14 +34,14 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<!-- <Navbar /> -->
|
<Navbar />
|
||||||
<section class="section">
|
<section class="section">
|
||||||
<div class="container is-fullhd">
|
<div class="container is-fullhd">
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
<div class="column is-one-fifth">
|
<div class="column is-one-fifth side-bar-column">
|
||||||
<Sidebar />
|
<Sidebar />
|
||||||
</div>
|
</div>
|
||||||
<div class="column is-four-fifths" id="content">
|
<div class="column is-four-fifths main-content-column" id="content">
|
||||||
{#key $location}
|
{#key $location}
|
||||||
<Router {routes} on:conditionsFailed={() => replace('/')}/>
|
<Router {routes} on:conditionsFailed={() => replace('/')}/>
|
||||||
{/key}
|
{/key}
|
||||||
|
|
154
src/app.scss
154
src/app.scss
|
@ -1,3 +1,81 @@
|
||||||
|
html {
|
||||||
|
/* Scrollbar */
|
||||||
|
--scrollbarBG: transparent;
|
||||||
|
--thumbBG: hsl(0, 0%, 60%); /* scollbar color light */
|
||||||
|
/* Back-ground */
|
||||||
|
--BgColorDark: hsl(228, 10%, 10%);
|
||||||
|
--BgColorLight: hsl(0, 0%, 100%);
|
||||||
|
// --BgColorSidebarDark: rgb(28, 30, 36);
|
||||||
|
--BgColorSidebarDark: rgb(16, 17, 22);
|
||||||
|
--BgColorSidebarLight: hsla(0, 0%, 93%, 0.354);
|
||||||
|
|
||||||
|
/* Sizes */
|
||||||
|
--sidebarTop: 0px;
|
||||||
|
--sidebarWidth: max(300px, 20%);
|
||||||
|
--mainContentWidth: calc(100% - var(--sidebarWidth));
|
||||||
|
|
||||||
|
--sectionPaddingTop: 0px;
|
||||||
|
|
||||||
|
--chatContentPaddingTop: 20px;
|
||||||
|
--chatContentPaddingRight: 40px;
|
||||||
|
--chatContentPaddingBottom: 120px;
|
||||||
|
--chatContentPaddingLeft: 40px;
|
||||||
|
|
||||||
|
--chatInputPaddingTop: 0px;
|
||||||
|
--chatInputPaddingRight: 60px;
|
||||||
|
--chatInputPaddingBottom: 10px;
|
||||||
|
--chatInputPaddingLeft: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
html {
|
||||||
|
--thumbBG: #3f3f3f; /* scrollbar color dark */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 900px) {
|
||||||
|
html {
|
||||||
|
--sidebarWidth: max(250px, 20%);
|
||||||
|
|
||||||
|
--chatContentPaddingTop: 50px;
|
||||||
|
--chatContentPaddingRight: 20px;
|
||||||
|
--chatContentPaddingLeft: 20px;
|
||||||
|
|
||||||
|
--chatInputPaddingRight: 30px;
|
||||||
|
--chatInputPaddingLeft: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 768px) {
|
||||||
|
.navbar {
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
|
html {
|
||||||
|
--BgColorSidebarLight: hsl(210, 12%, 97%);
|
||||||
|
// --BgColorSidebarDark: rgb(22, 24, 30);
|
||||||
|
--sidebarWidth: max(300px, 20%);
|
||||||
|
--mainContentWidth: calc(100%);
|
||||||
|
--sidebarTop: 56px;
|
||||||
|
--chatInputPaddingRight: 20px;
|
||||||
|
--chatInputPaddingLeft: 20px;
|
||||||
|
}
|
||||||
|
.main-menu .gpt-logo {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.main-menu .level-right {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.main-menu .level-item {
|
||||||
|
margin-bottom: inherit !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@keyframes rotating {
|
@keyframes rotating {
|
||||||
from {
|
from {
|
||||||
transform: rotate(0deg);
|
transform: rotate(0deg);
|
||||||
|
@ -155,8 +233,7 @@ $modal-background-background-color-dark: rgba($dark, 0.86) !default; // remove t
|
||||||
.dropdown.is-fullwidth {
|
.dropdown.is-fullwidth {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
.dropdown-trigger,
|
.dropdown-trigger, .dropdown-menu {
|
||||||
.dropdown-menu {
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,6 +259,18 @@ $modal-background-background-color-dark: rgba($dark, 0.86) !default; // remove t
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 768px) {
|
||||||
|
.main-menu .dropdown-menu .dropdown-content {
|
||||||
|
max-height: calc(100vh - 112px);
|
||||||
|
}
|
||||||
|
.main-menu {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.main-menu.pinned {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.chat-menu-item {
|
.chat-menu-item {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
@ -200,15 +289,25 @@ $modal-background-background-color-dark: rgba($dark, 0.86) !default; // remove t
|
||||||
|
|
||||||
/* Overrides for main layout */
|
/* Overrides for main layout */
|
||||||
|
|
||||||
|
.column.side-bar-column {
|
||||||
|
width: var(--sidebarWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
.column.main-content-column {
|
||||||
|
width: var(--mainContentWidth)
|
||||||
|
}
|
||||||
|
|
||||||
section.section {
|
section.section {
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
|
padding-top: var(--sectionPaddingTop);
|
||||||
}
|
}
|
||||||
|
|
||||||
aside.menu.main-menu {
|
aside.menu.main-menu {
|
||||||
|
z-index:1;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
width: 20%;
|
width: var(--sidebarWidth);
|
||||||
padding-right: 20px;
|
padding-right: 20px;
|
||||||
top: 0px;
|
top: var(--sidebarTop);
|
||||||
bottom:0px;
|
bottom:0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,8 +315,8 @@ aside.menu.main-menu .menu-expanse {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column;
|
flex-flow: column;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: hsla(0, 0%, 60%, 0.208);
|
background-color: var(--BgColorSidebarLight);
|
||||||
box-shadow: 5px 0px 1px hsla(0, 0%, 60%, 0.208);
|
box-shadow: 5px 0px 0px var(--BgColorSidebarLight);
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-expanse
|
.menu-expanse
|
||||||
|
@ -236,34 +335,26 @@ aside.menu.main-menu .menu-expanse {
|
||||||
color: hsl(0, 0%, 21%) !important;
|
color: hsl(0, 0%, 21%) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
html {
|
|
||||||
--scrollbarBG: $body-background-color;
|
|
||||||
--thumbBG: #999999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.lower-mask {
|
.lower-mask {
|
||||||
display: block;
|
display: block;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-image: linear-gradient(180deg,hsla(0,0%,100%,0) 13.94%,#fff 54.73%);
|
background-image: linear-gradient(180deg,hsla(0,0%,100%,0) 13.94%, var(--BgColorLight) 54.73%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
html {
|
|
||||||
--thumbBG: #3f3f3f;
|
|
||||||
}
|
|
||||||
.default-text {
|
.default-text {
|
||||||
color: rgb(181, 181, 181) !important;
|
color: rgb(181, 181, 181) !important;
|
||||||
}
|
}
|
||||||
.lower-mask {
|
.lower-mask {
|
||||||
background-image: linear-gradient(180deg,hsla(0,0%,100%,0) 13.94%,#17181c 54.73%);
|
background-image: linear-gradient(180deg,hsla(0,0%,100%,0) 13.94%, var(--BgColorDark) 54.73%);
|
||||||
}
|
}
|
||||||
aside.menu.main-menu .menu-expanse {
|
aside.menu.main-menu .menu-expanse {
|
||||||
background-color: hsla(0, 0%, 19%, 0.371);
|
background-color: var(--BgColorSidebarDark);
|
||||||
box-shadow: 5px 0px 1px hsla(0, 0%, 19%, 0.371);
|
box-shadow: 5px 0px 0px var(--BgColorSidebarDark);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*::-webkit-scrollbar {
|
*::-webkit-scrollbar {
|
||||||
|
@ -283,23 +374,32 @@ html {
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-content {
|
.chat-content {
|
||||||
padding-left: 20px;
|
padding:
|
||||||
padding-top: 40px;
|
var(--chatContentPaddingTop)
|
||||||
padding-right: 40px;
|
var(--chatContentPaddingRight)
|
||||||
padding-bottom: 120px;
|
var(--chatContentPaddingBottom)
|
||||||
|
var(--chatContentPaddingLeft) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-focus-point {
|
.chat-focus-point {
|
||||||
width:100%;
|
width: 100%;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
margin-bottom: -.75rem;;
|
/* Bulma does something strange where scrolling to the end of the body
|
||||||
|
or html doesn't actually scroll to the bottom of the page
|
||||||
|
this -.75rem, then scroll to the bottom of this works, but I don't like it.*/
|
||||||
|
margin-bottom: -.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.prompt-input-container {
|
.prompt-input-container {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
width: 80%;
|
width: var(--mainContentWidth);
|
||||||
padding: 0px 40px 10px 40px;
|
|
||||||
|
padding:
|
||||||
|
var(--chatInputPaddingTop)
|
||||||
|
var(--chatInputPaddingRight)
|
||||||
|
var(--chatInputPaddingBottom)
|
||||||
|
var(--chatInputPaddingLeft);
|
||||||
}
|
}
|
||||||
|
|
||||||
.running-total-container {
|
.running-total-container {
|
||||||
|
@ -319,3 +419,5 @@ html {
|
||||||
margin-left: 8px;
|
margin-left: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,7 @@
|
||||||
</a>
|
</a>
|
||||||
<hr class="dropdown-divider">
|
<hr class="dropdown-divider">
|
||||||
<a href={'#/'} class="dropdown-item" on:click={close}>
|
<a href={'#/'} class="dropdown-item" on:click={close}>
|
||||||
<span><Fa icon={faKey}/></span> API Key
|
<span class="menu-icon"><Fa icon={faKey}/></span> API Key
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,21 +1,38 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { params } from 'svelte-spa-router'
|
// import { params } from 'svelte-spa-router'
|
||||||
import logo from '../assets/logo.svg'
|
import { pinMainMenu } from './Storage.svelte'
|
||||||
import ChatOptionMenu from './ChatOptionMenu.svelte'
|
import logo from '../assets/logo.svg'
|
||||||
let showChatMenu
|
// import ChatOptionMenu from './ChatOptionMenu.svelte'
|
||||||
|
import Fa from 'svelte-fa/src/fa.svelte';
|
||||||
|
import { faBars, faXmark } from '@fortawesome/free-solid-svg-icons/index'
|
||||||
|
|
||||||
$: activeChatId = $params && $params.chatId ? parseInt($params.chatId) : undefined
|
// $: activeChatId = $params && $params.chatId ? parseInt($params.chatId) : undefined
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<nav class="navbar is-fixed-top" aria-label="main navigation">
|
<nav class="navbar is-fixed-top" aria-label="main navigation">
|
||||||
<div class="navbar-brand">
|
<div class="navbar-brand">
|
||||||
<a class="navbar-item" href={'#/'}>
|
<div class="navbar-item">
|
||||||
<img src={logo} alt="ChatGPT-web" width="28" height="28" />
|
|
||||||
<p class="ml-2 is-size-4 has-text-weight-bold">ChatGPT-web</p>
|
{#if $pinMainMenu}
|
||||||
</a>
|
<button class="button" on:click|stopPropagation={()=>{$pinMainMenu=false}}>
|
||||||
|
<span class="icon">
|
||||||
<div class="chat-option-menu navbar-item is-pulled-right">
|
<Fa icon={faXmark} />
|
||||||
<ChatOptionMenu bind:show={showChatMenu} bind:chatId={activeChatId} />
|
</span>
|
||||||
|
</button>
|
||||||
|
{:else}
|
||||||
|
<button class="button" on:click|stopPropagation={()=>{$pinMainMenu=true}}>
|
||||||
|
<span class="icon">
|
||||||
|
<Fa icon={faBars} />
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
<a class="navbar-item" href={'#/'}>
|
||||||
|
<img src={logo} alt="ChatGPT-web" width="24" height="24" />
|
||||||
|
<p class="ml-2 is-size-6 has-text-weight-bold">ChatGPT-web</p>
|
||||||
|
</a>
|
||||||
|
<!-- <div class="chat-option-menu navbar-item is-pulled-right">
|
||||||
|
<ChatOptionMenu bind:chatId={activeChatId} />
|
||||||
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { params } from 'svelte-spa-router'
|
import { params } from 'svelte-spa-router'
|
||||||
import ChatMenuItem from './ChatMenuItem.svelte'
|
import ChatMenuItem from './ChatMenuItem.svelte'
|
||||||
import { apiKeyStorage, chatsStorage } from './Storage.svelte'
|
import { apiKeyStorage, chatsStorage, pinMainMenu } from './Storage.svelte'
|
||||||
import Fa from 'svelte-fa/src/fa.svelte'
|
import Fa from 'svelte-fa/src/fa.svelte'
|
||||||
import { faSquarePlus, faKey } from '@fortawesome/free-solid-svg-icons/index'
|
import { faSquarePlus, faKey } from '@fortawesome/free-solid-svg-icons/index'
|
||||||
import ChatOptionMenu from './ChatOptionMenu.svelte';
|
import ChatOptionMenu from './ChatOptionMenu.svelte';
|
||||||
import logo from '../assets/logo.svg'
|
import logo from '../assets/logo.svg'
|
||||||
|
import { clickOutside } from 'svelte-use-click-outside';
|
||||||
|
|
||||||
$: sortedChats = $chatsStorage.sort((a, b) => b.id - a.id)
|
$: sortedChats = $chatsStorage.sort((a, b) => b.id - a.id)
|
||||||
|
|
||||||
|
@ -13,12 +14,12 @@
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<aside class="menu main-menu">
|
<aside class="menu main-menu" class:pinned={$pinMainMenu} use:clickOutside={() => { $pinMainMenu = false }}>
|
||||||
<div class="menu-expanse">
|
<div class="menu-expanse">
|
||||||
<div class="menu-label gpt-logo navbar-brand">
|
<div class="gpt-logo navbar-brand">
|
||||||
<a class="navbar-item" href={'#/'}>
|
<a class="navbar-item" href={'#/'}>
|
||||||
<img src={logo} alt="ChatGPT-web" width="28" height="28" />
|
<img src={logo} alt="ChatGPT-web" width="24" height="24" />
|
||||||
<p class="ml-2 is-size-4 has-text-weight-bold">ChatGPT-web</p>
|
<p class="ml-2 is-size-5 has-text-weight-bold">ChatGPT-web</p>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<ul class="menu-list menu-expansion-list">
|
<ul class="menu-list menu-expansion-list">
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
export let checkStateChange = writable(0) // Trigger for Chat
|
export let checkStateChange = writable(0) // Trigger for Chat
|
||||||
export let showSetChatSettings = writable(false) //
|
export let showSetChatSettings = writable(false) //
|
||||||
export let submitExitingPromptsNow = writable(false) // for them to go now. Will not submit anything in the input
|
export let submitExitingPromptsNow = writable(false) // for them to go now. Will not submit anything in the input
|
||||||
|
export let pinMainMenu = writable(false) // for them to go now. Will not submit anything in the input
|
||||||
|
|
||||||
const chatDefaults = getChatDefaults()
|
const chatDefaults = getChatDefaults()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue