Add mobile support

This commit is contained in:
Webifi 2023-05-31 07:51:03 -05:00
parent df89356dc0
commit 4c685e1a1e
8 changed files with 198 additions and 47 deletions

28
package-lock.json generated
View File

@ -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",

View File

@ -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",

View File

@ -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}

View File

@ -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;
} }

View File

@ -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>

View File

@ -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>

View File

@ -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">

View File

@ -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()