From 1e14a1101933dcfec3f357c590a455649db375ff Mon Sep 17 00:00:00 2001 From: piotrruss Date: Sat, 4 Sep 2021 21:55:21 +0200 Subject: add mobile styles --- apps/Notes/components/Export.js | 4 +- apps/Notes/components/List.js | 70 +++++++++++++++++++-------------- apps/Notes/components/ListItem.js | 10 ++++- apps/Notes/components/NoteView.js | 12 +++--- apps/Notes/styles/_listItem.scss | 34 ++++++++++------ apps/Notes/styles/_noteView.scss | 4 +- apps/Notes/styles/_notesList.scss | 71 ++++++++++++++++++++++++++++++++++ components/App.js | 81 +++++++++++++++++++-------------------- components/Header.js | 62 +++++++++++++++++++----------- configs/translations.js | 14 +++++++ helpers/windowActions.js | 10 ++--- pages/index.js | 8 +++- styles/global.scss | 13 +++++++ styles/global/_themes.scss | 4 +- styles/global/_window.scss | 64 +++++++++++++++++++------------ styles/main/_header.scss | 74 +++++++++++++++++++++++++++++++---- 16 files changed, 378 insertions(+), 157 deletions(-) diff --git a/apps/Notes/components/Export.js b/apps/Notes/components/Export.js index 11aed5b..eeeab8f 100644 --- a/apps/Notes/components/Export.js +++ b/apps/Notes/components/Export.js @@ -15,7 +15,9 @@ const Export = ({setAction}) => { return (
-
{setAction('')}}>{t('back')}
+
+
{setAction('')}}>{t('back')}
+

{t('notes_click_to_export')}

diff --git a/apps/Notes/components/List.js b/apps/Notes/components/List.js index 5039061..238e305 100644 --- a/apps/Notes/components/List.js +++ b/apps/Notes/components/List.js @@ -12,6 +12,7 @@ const List = () => { const [fetchedNote, setFetchedNote] = useState() const [action, setAction] = useState('') const [loading, setLoading] = useState(false) + const [showSort, setShowSort] = useState(false) const {notes, error} = useNotes() const [sortedBy, sortBy, sortFn] = useSort(3) const {t} = useSettings() @@ -34,36 +35,47 @@ const List = () => { action === '' ? ( <>
-
setAction('addNote')}>{t('notes_new')}
-
setAction('importNotes')}>{t('import')}
-
setAction('exportNotes')}>{t('export')}
+
+
setAction('addNote')}>{t('notes_new')}
+
{setShowSort(s => !s)}}>{t('sort')}
+
setAction('importNotes')}>{t('import')}
+
setAction('exportNotes')}>{t('export')}
+
+
+
+ + + + + + + + + + + + + + + + { + notes.length > 0 + ? (notes.sort(sortFn).map(note => ( + + ))) : ( + + + + )} + +
{t('sort_by')}
sortBy(1)}>{t('title')} {sortedBy(1)} sortBy(2)}>{t('created')} {sortedBy(2)} sortBy(3)}>{t('modified')} {sortedBy(3)}
setShowSort(false)}>{t('close')}
{t('notes_list_empty')}
- - - - - - - - - - { - notes.length > 0 - ? (notes.sort(sortFn).map(note => ( - - ))) : ( - - - - )} - -
sortBy(1)}>{t('title')} {sortedBy(1)} sortBy(2)}>{t('created')} {sortedBy(2)} sortBy(3)}>{t('modified')} {sortedBy(3)}
{t('notes_list_empty')}
) : ( { - {datestring(note.created_at)} - {datestring(note.updated_at)} + + {t('created')}: + {datestring(note.created_at)} + + + {t('modified')}: + {datestring(note.updated_at)} + ) } diff --git a/apps/Notes/components/NoteView.js b/apps/Notes/components/NoteView.js index ccaf343..b92c7c7 100644 --- a/apps/Notes/components/NoteView.js +++ b/apps/Notes/components/NoteView.js @@ -23,11 +23,13 @@ const NoteView = ({fetchedNote, setFetchedNote, setAction}) => { return (
-
{setFetchedNote(); setAction('')}}>{t('back')}
-
copyToClipboard(content, t, setPopup)}>{t('copy')}
-
{setAction('editNote')}}>{t('edit')}
-
exportNote(fetchedNote)}>{t('export')}
-
{removeNote(e, _id, mutateNotes, t, setPopup, setAction)}}>{t('remove')}
+
+
{setFetchedNote(); setAction('')}}>{t('back')}
+
copyToClipboard(content, t, setPopup)}>{t('copy')}
+
{setAction('editNote')}}>{t('edit')}
+
exportNote(fetchedNote)}>{t('export')}
+
{removeNote(e, _id, mutateNotes, t, setPopup, setAction)}}>{t('remove')}
+
diff --git a/apps/Notes/styles/_listItem.scss b/apps/Notes/styles/_listItem.scss index 5e7376f..fcee9aa 100644 --- a/apps/Notes/styles/_listItem.scss +++ b/apps/Notes/styles/_listItem.scss @@ -23,24 +23,34 @@ opacity: 0; font-size: 80%; transition: .3s opacity linear .3s; + + @media(max-width: 40em) { + display: none; + } } } + + &:nth-of-type(n+2) span { + padding-right: .5em; + } } - &:hover { - background: var(--color-window-menu-alt); - border-radius: .5em; - // cursor: pointer; + @media(hover: hover) { + &:hover { + background: var(--color-window-menu-alt); + border-radius: .5em; + // cursor: pointer; - & > td:first-of-type > span:nth-child(n+2){ - color: var(--color-window-buttons); - visibility: visible; - opacity: 1; + & > td:first-of-type > span:nth-child(n+2){ + color: var(--color-window-buttons); + visibility: visible; + opacity: 1; + } } - } - & > td:first-of-type > span:nth-child(n+2):hover { - color: var(--color-text-alt); - background-color: var(--color-glass); + & > td:first-of-type > span:nth-child(n+2):hover { + color: var(--color-text-alt); + background-color: var(--color-glass); + } } } diff --git a/apps/Notes/styles/_noteView.scss b/apps/Notes/styles/_noteView.scss index cf6a080..63e3fa3 100644 --- a/apps/Notes/styles/_noteView.scss +++ b/apps/Notes/styles/_noteView.scss @@ -4,7 +4,6 @@ to {opacity: 1;} } - padding: 1rem; position: absolute; top: 0; right: 0; @@ -15,13 +14,12 @@ h2 { font-size: 1.25em; font-weight: 600; - padding: 1rem; user-select: text; } p { + padding-top: 1em; line-height: 1.33; - padding: 0 1rem 1rem; white-space: pre-line; user-select: text; } diff --git a/apps/Notes/styles/_notesList.scss b/apps/Notes/styles/_notesList.scss index f55757f..4580d62 100644 --- a/apps/Notes/styles/_notesList.scss +++ b/apps/Notes/styles/_notesList.scss @@ -40,4 +40,75 @@ animation: fade-in .3s; } } + + @media(max-width: 40em) { + thead { + display: flex; + + tr:first-of-type { + flex-shrink: 1; + } + } + + tr { + flex-direction: column; + } + + tbody { + tr { + padding-bottom: 1em; + } + + td:first-of-type { + font-weight: 600; + } + + td:nth-of-type(n+2) { + font-size: .8em; + padding-top: .5em; + color: var(--color-decor); + } + } + } +} + +.mobileSort { + @media(max-width: 40em) { + position: fixed; + display: flex; + flex-direction: column; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background: var(--color-window-popup); + border-radius: .5em; + border-bottom: 1px solid var(--color-window-border-bottom); + border-top: 1px solid var(--color-window-border-top); + padding: 1.5em; + width: 15em; + + tr:nth-of-type(1) > th { + font-weight: normal; + } + + tr:nth-of-type(2) { + padding-left: 1.5em; + + th { + padding: .75em; + + svg { + margin-left: .5em; + } + } + } + + tr:nth-of-type(3) { + text-align: center; + + & > td { + display: inline-block; + } + } + } } diff --git a/components/App.js b/components/App.js index b24aead..c539e72 100644 --- a/components/App.js +++ b/components/App.js @@ -1,7 +1,7 @@ import React, {useEffect, useRef} from 'react' import useSettings from 'hooks/useSettings' import useMediaQuery from 'hooks/useMediaQuery' -import {close, toggleMin, toggleMax, move} from 'helpers/windowActions' +import {close, toggleMin, toggleMax, move, focus} from 'helpers/windowActions' import {faArrowUp, faExpandAlt, faTimes, faCompressAlt} from '@fortawesome/free-solid-svg-icons' import {FontAwesomeIcon} from '@fortawesome/react-fontawesome' @@ -11,50 +11,49 @@ const App = ({children, app, setApps}) => { const forceMax = useMediaQuery(`(max-width: ${app.width}), (max-height: ${app.height})`); useEffect(() => { - move(app.name, winRef, setApps) + move(app, winRef, setApps) }, []) return ( - <> -
-

{t(app.name)}

-
{children}
-
- { app.buttons.includes('min') && ( - toggleMin(app.name, setApps)}> - - - )} - { app.buttons.includes('max') && !forceMax && ( - toggleMax(app.name, setApps)}> - - - )} - { app.buttons.includes('close') && ( - close(app.name, setApps)}> - - - )} -
+
{focus(app.name, setApps)}} + className={ + 'window' + + (app.min ? ' hidden' : '') + + (app.max || forceMax ? ' maximized' : '') + } + style={{ + height: app.height, + width: app.width, + ...app.pos.length + ? {top: app.pos[1], left: app.pos[0]} + : { + top: `calc((( 100vh - ${app.height} ) / 2) + 2em)`, + left: `calc(( 100vw - ${app.width} ) / 2)`, + } + }} + > +

{t(app.name)}

+
{children}
+
+ { app.buttons.includes('min') && ( + toggleMin(app.name, setApps)}> + + + )} + { app.buttons.includes('max') && !forceMax && ( + toggleMax(app.name, setApps)}> + + + )} + { app.buttons.includes('close') && ( + close(app.name, setApps)}> + + + )}
- +
) } diff --git a/components/Header.js b/components/Header.js index 9ff3d75..83f0ff9 100644 --- a/components/Header.js +++ b/components/Header.js @@ -5,12 +5,15 @@ import Link from 'next/link' import useUser from 'hooks/useUser' import fetchJson from 'helpers/fetchJson' import {focus, toggleMin} from 'helpers/windowActions' -import {open} from 'helpers/windowActions' +import {open, close} from 'helpers/windowActions' import appList from 'configs/appList' import useSettings from 'hooks/useSettings' +import {faTimes} from '@fortawesome/free-solid-svg-icons' +import {FontAwesomeIcon} from '@fortawesome/react-fontawesome' const Header = ({apps, setApps}) => { - const [userMenu, setUserMenu] = useState(false); + const [userMenu, setUserMenu] = useState(false) + const [showApps, setShowApps] = useState(false) const {user, mutateUser} = useUser() const {t} = useSettings() const router = useRouter() @@ -24,7 +27,6 @@ const Header = ({apps, setApps}) => { router.push('/login') } - const handleClick = (app, setApps) => { if (app.min) { toggleMin(app.name, setApps) @@ -35,25 +37,41 @@ const Header = ({apps, setApps}) => { return (
)) } - {apps && apps.map(app => { + {apps && apps.length > 0 && apps.map(app => { + if (!app) return null + const AppComponent = appList[app.name].component return ( diff --git a/styles/global.scss b/styles/global.scss index 0a542a9..04473b8 100644 --- a/styles/global.scss +++ b/styles/global.scss @@ -32,3 +32,16 @@ textarea, input { padding-right: 2rem; } +.mobile-only { + display: none!important; + + @media(max-width: 40em) { + display: inline-block!important; + } +} + +.desktop-only { + @media(max-width: 40em) { + display: none!important; + } +} diff --git a/styles/global/_themes.scss b/styles/global/_themes.scss index 9319fa5..e0b146f 100644 --- a/styles/global/_themes.scss +++ b/styles/global/_themes.scss @@ -13,7 +13,7 @@ --color-window-border-top: rgba(255,255,255,.7); --color-window-border-bottom: #ccc; --color-window-content: #fff; - --color-window-popup: #fff; + --color-window-popup: #eee; --color-window-buttons: #666; --color-window-buttons-alt: #222; --color-window-menu: #eee; @@ -42,7 +42,7 @@ --color-window-border-top: rgba(255,255,255,.7); --color-window-border-bottom: #ccc; --color-window-content: #fff; - --color-window-popup: #fff; + --color-window-popup: #eee; --color-window-buttons: #666; --color-window-buttons-alt: #222; --color-window-menu: #eee; diff --git a/styles/global/_window.scss b/styles/global/_window.scss index 08ddfaf..c489796 100644 --- a/styles/global/_window.scss +++ b/styles/global/_window.scss @@ -1,11 +1,14 @@ .window { position: absolute; - transition-property: opacity, visibility, transform, width, height, top, left; - transition-duration: .3s; box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px; border-radius: .5em; color: var(--color-text); + @media(min-width: 40em) { + transition-property: opacity, visibility, transform, width, height, top, left; + transition-duration: .3s; + } + &.moving { transition: none } @@ -29,19 +32,6 @@ height: 100%; width: 100%; } - // top: 50%; - // left: 50%; - - // @media (min-width: 80em) { - // width: 64em; - // left: calc((100vw - 64em) / 2) - // } - - // @media (min-height: 80em) { - // width: 64em; - // left: calc((100vh - 64em) / 2) - // } - // } &__title { position: absolute; @@ -86,6 +76,10 @@ color: var(--color-window-buttons-alt); } } + + @media(max-width: 40em) { + display: none; + } } &__content { @@ -96,7 +90,6 @@ right: 0; bottom: 0; left: 0; - padding: 1em; border-bottom-left-radius: .5em; border-bottom-right-radius: .5em; } @@ -109,18 +102,35 @@ .window__submenu { display: block; - margin: -1em -1em 1em; height: 2em; + width: 100%; background: var(--color-window-menu); - & > div { + & > div > div { // cursor: pointer; display: inline-block; padding: .5em; transition: .3s background; + white-space: nowrap; - &:hover { - background-color: var(--color-window-menu-alt); + @media(hover: hover) { + &:hover { + background-color: var(--color-window-menu-alt); + } + } + } + + + @media(max-width: 40em) { + height: 3em; + overflow: auto; + + & > div { + display: flex; + } + + & > div > div { + padding: 1em; } } } @@ -128,7 +138,7 @@ &__scroll { height: 100%; overflow: auto; - margin: -1em -1em 0; + padding: 1em; } &__buttons--popup { @@ -150,8 +160,10 @@ // cursor: pointer; transition: .3s background-color; - &:hover { - background-color: var(--color-button-alt); + @media(hover: hover) { + &:hover { + background-color: var(--color-button-alt); + } } } @@ -163,8 +175,10 @@ border-top: 1px solid var(--color-popup-error-border); border-bottom: 1px solid var(--color-popup-error-border); - &:hover { - background-color: var(--color-popup-error-button-alt); + @media(hover: hover) { + &:hover { + background-color: var(--color-popup-error-button-alt); + } } } } diff --git a/styles/main/_header.scss b/styles/main/_header.scss index 9fab16b..e6ac70f 100644 --- a/styles/main/_header.scss +++ b/styles/main/_header.scss @@ -6,34 +6,92 @@ nav { display: flex; - & > ul:first-of-type { + & > div { flex-grow: 1; - overflow: auto; + overflow-y: auto; + + & > span { + padding-left: .5em; + line-height: 2em; + font-weight: 600; + } + + & > ul { + display: flex; + } } - & > ul { + & > ul, + & > div > ul { display: block; & > li { display: inline-block; + & > span > span { + padding: .75em; + display: inline-block; + margin-left: .5em; + color: var(--color-error); + } + & > span, & > a { display: inline-block; color: var(--color-text); text-decoration: none; align-items: center; - padding: .25em .5em; - margin: .25em; border-radius: .5em; transition: .3s background, .3s color; + white-space: nowrap; + padding: .25em .5em; + margin: .25em; - &:hover { - background-color: var(--color-selected); - color: var(--color-text-alt); + @media(hover: hover) { + &:hover { + background-color: var(--color-selected); + color: var(--color-text-alt); + } } } } } } } + +.showMobileAppList { + @media(max-width: 40em) { + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background-color: var(--color-window-popup); + border-bottom: 1px solid var(--color-window-border-bottom); + border-top: 1px solid var(--color-window-border-top); + border-radius: .5em; + padding: 1em; + min-width: 13em; + + li { + width: 100%; + padding: 0; + margin: -.25em 0; + } + + & > li:first-of-type { + padding: .5em .5em 1em; + white-space: nowrap; + } + + & > li:last-of-type { + width: 100%; + padding-top: 1em; + text-align: center; + + span { + height: 2.1em; + padding: .5em .75em; + } + } + } +} -- cgit v1.2.3