* Fix some mobile layout issues

* More hacks to fix scrolling a bit
This commit is contained in:
styppo 2023-01-01 20:53:16 +00:00
parent 342764c458
commit bef9fad696
No known key found for this signature in database
GPG Key ID: 3AAA685C50724C28
7 changed files with 100 additions and 73 deletions

View File

@ -44,10 +44,12 @@
</div>
</div>
<ProfilePopup v-if="$store.getters.isSignedIn" />
<div v-else class="sign-in" @click="signIn">
<q-icon class="icon" name="login" size="sm" />
<div class="label">Log in</div>
<div style="position: sticky; bottom: 0">
<ProfilePopup v-if="$store.getters.isSignedIn" />
<div v-else class="sign-in" @click="signIn">
<q-icon class="icon" name="login" size="sm" />
<div class="label">Log in</div>
</div>
</div>
<div
@ -116,11 +118,11 @@ menu {
margin: 0;
padding-inline-start: 0;
.menu {
height: 100%;
&-nav {
position: relative;
padding: 0 1rem;
}
height: 100%;
&-logo {
margin: 1rem 0;
svg, img {

View File

@ -14,9 +14,9 @@
<div class="addon">
<slot />
</div>
<div class="logo">
<router-link class="logo" to="/">
<Logo />
</div>
</router-link>
</div>
</template>
@ -107,6 +107,7 @@ export default defineComponent({
@media screen and (max-width: $phone) {
.page-header {
padding: .4rem 1rem;
.logo {
display: block;
position: absolute;

View File

@ -127,8 +127,8 @@ export default {
},
},
methods: {
formatPostDate(ts) {
const date = new Date(ts)
formatPostDate(timestamp) {
const date = new Date(timestamp)
const month = this.$t(MONTHS[date.getMonth()])
const sameYear = date.getFullYear() === (new Date().getFullYear())
@ -136,8 +136,8 @@ export default {
return `${date.getDate()} ${month}${year}`
},
formatPostTime(ts) {
const date = new Date(ts)
formatPostTime(timestamp) {
const date = new Date(timestamp)
return `${date.getHours()}:${date.getMinutes()}`
}
}

View File

@ -18,16 +18,14 @@
<p>
<BaseUserName :pubkey="post.author" @click.stop />
<span>&#183;</span>
<span class="created-at">{{ moment(post.createdAt).fromNow() }}</span>
<span class="created-at">{{ formatPostDate(post.createdAt) }}</span>
</p>
<p v-if="ancestor" class="in-reply-to">
Replying to <a @click.stop="toEvent(ancestor)">{{ shorten(ancestor) }}</a>
</p>
</div>
<div class="post-content-body">
<p>
<BaseMarkdown :content="post.content" />
</p>
<BaseMarkdown :content="post.content" />
</div>
<div v-if="actions" class="post-content-actions">
<div class="action-item comment" @click.stop="$store.dispatch('createPost', {replyTo})">
@ -135,7 +133,23 @@ export default {
},
},
methods: {
moment,
formatPostDate(timestamp) {
return this.$q.screen.lt.md
? this.shortDateFromNow(timestamp)
: moment(timestamp).fromNow()
},
shortDateFromNow(timestamp) {
const now = Date.now()
const diff = Math.round(Math.max(now - timestamp, 0) / 1000)
const formatDiff = (div, offset) => Math.max(Math.floor((diff + offset) / div), 1)
if (diff < 45) return `${formatDiff(1, 0)}s`
if (diff < 60 * 45) return `${formatDiff(60, 15)}m`
if (diff < 60 * 60 * 22) return `${formatDiff(60 * 60, 60 * 15)}h`
if (diff < 60 * 60 * 24 * 26) return `${formatDiff(60 * 60 * 24, 60 * 60 * 2)}d`
if (diff < 60 * 60 * 24 * 30 * 320) return `${formatDiff(60 * 60 * 24 * 30, 60 * 60 * 24 * 4)}mo`
return `${formatDiff(60 * 60 * 24 * 30 * 365, 60 * 60 * 24 * 45)}y`
}
},
}
</script>
@ -175,10 +189,13 @@ export default {
}
&-content {
margin-left: 12px;
padding: 1rem 0;
padding: 1rem 0 .4rem;
flex-grow: 1;
max-width: 570px;
&-header {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
.in-reply-to {
color: $color-dark-gray;
a {
@ -212,25 +229,7 @@ export default {
}
&-body {
color: #fff;
&-images {
&-wrapper {
border-radius: 10px;
overflow: hidden;
border: $border-light;
display: flex;
.post-content-image-item {
cursor: zoom-in;
& + .post-content-image-item {
border-left: $border-light;
}
flex-grow: 1;
img {
vertical-align: middle;
width: 100%;
}
}
}
}
margin-bottom: 1rem;
}
&-actions {
display: flex;
@ -287,18 +286,11 @@ export default {
}
}
}
@media screen and (max-width: $phone) {
.post{
.post {
&-content {
&-header {
span{
display: none;
}
.created-at {
display: block;
color: rgba($color: $color-dark-gray, $alpha: 0.5);
margin: 5px 0;
}
.nip05 {
display: unset;
color: $color-dark-gray;

View File

@ -10,7 +10,7 @@
<div class="layout-flow">
<q-page-container ref="pageContainer">
<router-view v-slot="{ Component }">
<keep-alive :include="['Feed', 'Messages', 'Notifications']">
<keep-alive :include="cachedPages">
<component :is="Component" :key="$route.path" @scroll-to-rect="scrollToRect" />
</keep-alive>
</router-view>
@ -31,6 +31,7 @@
>
<BaseIcon icon="hamburger" />
</div>
<div v-if="mobileMenuOpen" class="mobile-menu-backdrop fixed-full" v-close-popup></div>
</div>
<SignInDialog />
@ -66,14 +67,19 @@ export default defineComponent({
setup () {
const $q = useQuasar()
// const cachedPages = ref(['feed', 'notifications', 'messages'])
$q.screen.setSizes({
// FIXME Needs to be in sync with assets/variables.scss
sm: 414,
md: 755,
lg: 1113,
xl: 1310,
})
return $q
},
data() {
return {
cachedPages: ['Feed', 'Notifications', 'Messages'],
cachedPages: ['Feed', 'Notifications', 'Messages', 'Inbox', 'Settings', 'DevTools'],
middlePagePos: {},
broadcastChannel: new BroadcastChannel('hamstr'),
activeWindow: false,
@ -118,8 +124,8 @@ export default defineComponent({
// setup scrolling
// document.querySelector('#left-drawer').addEventListener('wheel', this.redirectScroll)
this.$router.beforeEach((to, from) => { this.preserveScrollPos(to, from) })
this.$router.afterEach((to, from) => { this.restoreScrollPos(to, from) })
// this.$router.beforeEach((to, from) => { this.preserveScrollPos(to, from) })
// this.$router.afterEach((to, from) => { this.restoreScrollPos(to, from) })
// destroy streams before unloading window
window.onbeforeunload = async () => {
@ -147,7 +153,7 @@ export default defineComponent({
},
scrollToRect(rect) {
let offset = Math.max(rect.top, 0) - 78
let offset = Math.max(rect.top, 0)
setVerticalScrollPosition(this.scrollingContainer, offset, 0)
},
@ -355,6 +361,12 @@ export default defineComponent({
fill: #fff;
}
}
.mobile-menu-backdrop {
z-index: 750;
pointer-events: all;
outline: 0;
background: rgba(0, 0, 0, 0.4);
}
}
}
</style>

View File

@ -1,24 +1,28 @@
<template>
<q-page>
<PageHeader>
<div class="addon-menu">
<div class="addon-menu-icon">
<q-icon name="more_vert" size="sm" />
</div>
<q-menu target=".addon-menu-icon" anchor="top left" self="top right" class="addon-menu-popup">
<div>
<div v-for="tabName in availableTabs" :key="tabName" class="popup-header" @click="tab = tabName" v-close-popup>
<p>{{ tabName }}</p>
<div class="more" v-if="tab === tabName">
<BaseIcon icon="tick" />
<div class="page-header-container">
<PageHeader>
<div class="addon-menu">
<div class="addon-menu-icon">
<q-icon name="more_vert" size="sm" />
</div>
<q-menu target=".addon-menu-icon" anchor="top left" self="top right" class="addon-menu-popup">
<div>
<div v-for="tabName in availableTabs" :key="tabName" class="popup-header" @click="tab = tabName" v-close-popup>
<p>{{ tabName }}</p>
<div class="more" v-if="tab === tabName">
<BaseIcon icon="tick" />
</div>
</div>
</div>
</div>
</q-menu>
</div>
</PageHeader>
</q-menu>
</div>
</PageHeader>
</div>
<PostEditor class="post-editor" v-if="$store.getters.isSignedIn" />
<div class="post-editor" v-if="$store.getters.isSignedIn">
<PostEditor />
</div>
<div class="feed-tabs">
<q-tabs
@ -42,7 +46,7 @@
</div>
<div class="feed">
<div class="load-more-container">
<div class="load-more-container" :class="{'more-available': unreadFeed[tab].length}">
<BaseButtonLoadMore
v-if="unreadFeed[tab].length"
:loading="loadingUnread"
@ -342,9 +346,21 @@ export default defineComponent({
}
@media screen and (max-width: $phone) {
.page-header-container {
border-bottom: $border-dark;
}
.post-editor {
display: none;
}
.feed {
.load-more-container {
border: 0;
min-height: 0;
&.more-available {
border-bottom: $border-dark;
}
}
}
}
</style>

View File

@ -23,8 +23,8 @@
:connector="ancestorsCompiled.length > 0"
@add-event="processChildEvent"
/>
<div v-else>
{{ $t('event') }} {{ $route.params.eventId }}
<div v-else style="padding-left: 1.5rem">
<q-spinner size="sm" style="margin-right: .5rem"/> Loading...
</div>
</q-item>
@ -106,6 +106,8 @@ export default defineComponent({
this.scrollToMainEvent()
})
this.resizeObserver.observe(this.$refs.page.$el)
setTimeout(() => this.resizeObserver.disconnect(), 2000)
},
beforeUnmount() {
@ -200,12 +202,14 @@ export default defineComponent({
const el = this.$refs.main?.$el
if (!el) return
const offset = Math.max(el.offsetTop - 78, 0)
// TODO Clean up
const offset = this.$q.screen.xs ? 61 : 78
const position = Math.max(el.offsetTop - offset, 0)
if (this.scrollTimeout) {
clearTimeout(this.scrollTimeout)
}
this.scrollTimeout = setTimeout(() => window.scrollTo(0, offset), 100)
this.scrollTimeout = setTimeout(() => window.scrollTo(0, position), 100)
},
addEventAncestors(event) {