Add mobile support
This commit is contained in:
parent
df89356dc0
commit
4c685e1a1e
|
@ -8,6 +8,8 @@
|
|||
"name": "chatgpt-web",
|
||||
"version": "0.0.0",
|
||||
"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",
|
||||
"@fullhuman/postcss-purgecss": "^5.0.0",
|
||||
"@microsoft/fetch-event-source": "^2.0.1",
|
||||
|
@ -462,6 +464,32 @@
|
|||
"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": {
|
||||
"version": "6.4.0",
|
||||
"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"
|
||||
},
|
||||
"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",
|
||||
"@fullhuman/postcss-purgecss": "^5.0.0",
|
||||
"@microsoft/fetch-event-source": "^2.0.1",
|
||||
|
|
|
@ -34,14 +34,14 @@
|
|||
</script>
|
||||
|
||||
|
||||
<!-- <Navbar /> -->
|
||||
<Navbar />
|
||||
<section class="section">
|
||||
<div class="container is-fullhd">
|
||||
<div class="columns">
|
||||
<div class="column is-one-fifth">
|
||||
<div class="column is-one-fifth side-bar-column">
|
||||
<Sidebar />
|
||||
</div>
|
||||
<div class="column is-four-fifths" id="content">
|
||||
<div class="column is-four-fifths main-content-column" id="content">
|
||||
{#key $location}
|
||||
<Router {routes} on:conditionsFailed={() => replace('/')}/>
|
||||
{/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 {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
|
@ -155,8 +233,7 @@ $modal-background-background-color-dark: rgba($dark, 0.86) !default; // remove t
|
|||
.dropdown.is-fullwidth {
|
||||
display: flex;
|
||||
|
||||
.dropdown-trigger,
|
||||
.dropdown-menu {
|
||||
.dropdown-trigger, .dropdown-menu {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
@ -182,6 +259,18 @@ $modal-background-background-color-dark: rgba($dark, 0.86) !default; // remove t
|
|||
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 {
|
||||
position: relative;
|
||||
}
|
||||
|
@ -200,15 +289,25 @@ $modal-background-background-color-dark: rgba($dark, 0.86) !default; // remove t
|
|||
|
||||
/* Overrides for main layout */
|
||||
|
||||
.column.side-bar-column {
|
||||
width: var(--sidebarWidth);
|
||||
}
|
||||
|
||||
.column.main-content-column {
|
||||
width: var(--mainContentWidth)
|
||||
}
|
||||
|
||||
section.section {
|
||||
padding: 0px;
|
||||
padding-top: var(--sectionPaddingTop);
|
||||
}
|
||||
|
||||
aside.menu.main-menu {
|
||||
z-index:1;
|
||||
position: fixed;
|
||||
width: 20%;
|
||||
width: var(--sidebarWidth);
|
||||
padding-right: 20px;
|
||||
top: 0px;
|
||||
top: var(--sidebarTop);
|
||||
bottom:0px;
|
||||
}
|
||||
|
||||
|
@ -216,8 +315,8 @@ aside.menu.main-menu .menu-expanse {
|
|||
display: flex;
|
||||
flex-flow: column;
|
||||
height: 100%;
|
||||
background-color: hsla(0, 0%, 60%, 0.208);
|
||||
box-shadow: 5px 0px 1px hsla(0, 0%, 60%, 0.208);
|
||||
background-color: var(--BgColorSidebarLight);
|
||||
box-shadow: 5px 0px 0px var(--BgColorSidebarLight);
|
||||
}
|
||||
|
||||
.menu-expanse
|
||||
|
@ -236,34 +335,26 @@ aside.menu.main-menu .menu-expanse {
|
|||
color: hsl(0, 0%, 21%) !important;
|
||||
}
|
||||
|
||||
html {
|
||||
--scrollbarBG: $body-background-color;
|
||||
--thumbBG: #999999;
|
||||
}
|
||||
|
||||
.lower-mask {
|
||||
display: block;
|
||||
position: fixed;
|
||||
bottom: 0px;
|
||||
height: 100px;
|
||||
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) {
|
||||
html {
|
||||
--thumbBG: #3f3f3f;
|
||||
}
|
||||
.default-text {
|
||||
color: rgb(181, 181, 181) !important;
|
||||
}
|
||||
.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 {
|
||||
background-color: hsla(0, 0%, 19%, 0.371);
|
||||
box-shadow: 5px 0px 1px hsla(0, 0%, 19%, 0.371);
|
||||
background-color: var(--BgColorSidebarDark);
|
||||
box-shadow: 5px 0px 0px var(--BgColorSidebarDark);
|
||||
}
|
||||
}
|
||||
*::-webkit-scrollbar {
|
||||
|
@ -283,23 +374,32 @@ html {
|
|||
}
|
||||
|
||||
.chat-content {
|
||||
padding-left: 20px;
|
||||
padding-top: 40px;
|
||||
padding-right: 40px;
|
||||
padding-bottom: 120px;
|
||||
padding:
|
||||
var(--chatContentPaddingTop)
|
||||
var(--chatContentPaddingRight)
|
||||
var(--chatContentPaddingBottom)
|
||||
var(--chatContentPaddingLeft) ;
|
||||
}
|
||||
|
||||
.chat-focus-point {
|
||||
width:100%;
|
||||
width: 100%;
|
||||
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 {
|
||||
position: fixed;
|
||||
bottom: 0px;
|
||||
width: 80%;
|
||||
padding: 0px 40px 10px 40px;
|
||||
width: var(--mainContentWidth);
|
||||
|
||||
padding:
|
||||
var(--chatInputPaddingTop)
|
||||
var(--chatInputPaddingRight)
|
||||
var(--chatInputPaddingBottom)
|
||||
var(--chatInputPaddingLeft);
|
||||
}
|
||||
|
||||
.running-total-container {
|
||||
|
@ -319,3 +419,5 @@ html {
|
|||
margin-left: 8px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -131,7 +131,7 @@
|
|||
</a>
|
||||
<hr class="dropdown-divider">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,21 +1,38 @@
|
|||
<script lang="ts">
|
||||
import { params } from 'svelte-spa-router'
|
||||
import logo from '../assets/logo.svg'
|
||||
import ChatOptionMenu from './ChatOptionMenu.svelte'
|
||||
let showChatMenu
|
||||
// import { params } from 'svelte-spa-router'
|
||||
import { pinMainMenu } from './Storage.svelte'
|
||||
import logo from '../assets/logo.svg'
|
||||
// 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>
|
||||
|
||||
<nav class="navbar is-fixed-top" aria-label="main navigation">
|
||||
<div class="navbar-brand">
|
||||
<a class="navbar-item" href={'#/'}>
|
||||
<img src={logo} alt="ChatGPT-web" width="28" height="28" />
|
||||
<p class="ml-2 is-size-4 has-text-weight-bold">ChatGPT-web</p>
|
||||
</a>
|
||||
<div class="navbar-item">
|
||||
|
||||
<div class="chat-option-menu navbar-item is-pulled-right">
|
||||
<ChatOptionMenu bind:show={showChatMenu} bind:chatId={activeChatId} />
|
||||
{#if $pinMainMenu}
|
||||
<button class="button" on:click|stopPropagation={()=>{$pinMainMenu=false}}>
|
||||
<span class="icon">
|
||||
<Fa icon={faXmark} />
|
||||
</span>
|
||||
</button>
|
||||
{:else}
|
||||
<button class="button" on:click|stopPropagation={()=>{$pinMainMenu=true}}>
|
||||
<span class="icon">
|
||||
<Fa icon={faBars} />
|
||||
</span>
|
||||
</button>
|
||||
{/if}
|
||||
</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>
|
||||
</nav>
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
<script lang="ts">
|
||||
import { params } from 'svelte-spa-router'
|
||||
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 { faSquarePlus, faKey } from '@fortawesome/free-solid-svg-icons/index'
|
||||
import ChatOptionMenu from './ChatOptionMenu.svelte';
|
||||
import logo from '../assets/logo.svg'
|
||||
import { clickOutside } from 'svelte-use-click-outside';
|
||||
|
||||
$: sortedChats = $chatsStorage.sort((a, b) => b.id - a.id)
|
||||
|
||||
|
@ -13,12 +14,12 @@
|
|||
|
||||
</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-label gpt-logo navbar-brand">
|
||||
<div class="gpt-logo navbar-brand">
|
||||
<a class="navbar-item" href={'#/'}>
|
||||
<img src={logo} alt="ChatGPT-web" width="28" height="28" />
|
||||
<p class="ml-2 is-size-4 has-text-weight-bold">ChatGPT-web</p>
|
||||
<img src={logo} alt="ChatGPT-web" width="24" height="24" />
|
||||
<p class="ml-2 is-size-5 has-text-weight-bold">ChatGPT-web</p>
|
||||
</a>
|
||||
</div>
|
||||
<ul class="menu-list menu-expansion-list">
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
export let checkStateChange = writable(0) // Trigger for Chat
|
||||
export let showSetChatSettings = writable(false) //
|
||||
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()
|
||||
|
||||
|
|
Loading…
Reference in New Issue