Page MenuHomePhorge

No OneTemporary

Authored By
Unknown
Size
9 KB
Referenced Files
None
Subscribers
None
diff --git a/changelog.d/modals-mobile.change b/changelog.d/modals-mobile.change
new file mode 100644
index 0000000000..e6a768c573
--- /dev/null
+++ b/changelog.d/modals-mobile.change
@@ -0,0 +1 @@
+modal layout for mobile has new layout to make it easy to use
diff --git a/changelog.d/modals.fix b/changelog.d/modals.fix
new file mode 100644
index 0000000000..68278bfc05
--- /dev/null
+++ b/changelog.d/modals.fix
@@ -0,0 +1 @@
+fixed modals buttons overflow
diff --git a/src/App.js b/src/App.js
index befcece800..3142d06292 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,160 +1,164 @@
import UserPanel from './components/user_panel/user_panel.vue'
import NavPanel from './components/nav_panel/nav_panel.vue'
import InstanceSpecificPanel from './components/instance_specific_panel/instance_specific_panel.vue'
import FeaturesPanel from './components/features_panel/features_panel.vue'
import WhoToFollowPanel from './components/who_to_follow_panel/who_to_follow_panel.vue'
import ShoutPanel from './components/shout_panel/shout_panel.vue'
import MediaModal from './components/media_modal/media_modal.vue'
import SideDrawer from './components/side_drawer/side_drawer.vue'
import MobilePostStatusButton from './components/mobile_post_status_button/mobile_post_status_button.vue'
import MobileNav from './components/mobile_nav/mobile_nav.vue'
import DesktopNav from './components/desktop_nav/desktop_nav.vue'
import UserReportingModal from './components/user_reporting_modal/user_reporting_modal.vue'
import EditStatusModal from './components/edit_status_modal/edit_status_modal.vue'
import PostStatusModal from './components/post_status_modal/post_status_modal.vue'
import StatusHistoryModal from './components/status_history_modal/status_history_modal.vue'
import GlobalNoticeList from './components/global_notice_list/global_notice_list.vue'
import { windowWidth, windowHeight } from './services/window_utils/window_utils'
import { mapGetters } from 'vuex'
import { defineAsyncComponent } from 'vue'
export default {
name: 'app',
components: {
UserPanel,
NavPanel,
Notifications: defineAsyncComponent(() => import('./components/notifications/notifications.vue')),
InstanceSpecificPanel,
FeaturesPanel,
WhoToFollowPanel,
ShoutPanel,
MediaModal,
SideDrawer,
MobilePostStatusButton,
MobileNav,
DesktopNav,
SettingsModal: defineAsyncComponent(() => import('./components/settings_modal/settings_modal.vue')),
UpdateNotification: defineAsyncComponent(() => import('./components/update_notification/update_notification.vue')),
UserReportingModal,
PostStatusModal,
EditStatusModal,
StatusHistoryModal,
GlobalNoticeList
},
data: () => ({
mobileActivePanel: 'timeline'
}),
watch: {
themeApplied (value) {
this.removeSplash()
+ },
+ layoutType (value) {
+ document.getElementById('modal').classList = ['-' + this.layoutType]
}
},
created () {
// Load the locale from the storage
const val = this.$store.getters.mergedConfig.interfaceLanguage
this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val })
window.addEventListener('resize', this.updateMobileState)
+ document.getElementById('modal').classList = ['-' + this.layoutType]
},
mounted () {
if (this.$store.state.interface.themeApplied) {
this.removeSplash()
}
},
unmounted () {
window.removeEventListener('resize', this.updateMobileState)
},
computed: {
themeApplied () {
return this.$store.state.interface.themeApplied
},
layoutModalClass () {
return '-' + this.layoutType
},
classes () {
return [
{
'-reverse': this.reverseLayout,
'-no-sticky-headers': this.noSticky,
'-has-new-post-button': this.newPostButtonShown
},
'-' + this.layoutType
]
},
navClasses () {
const { navbarColumnStretch } = this.$store.getters.mergedConfig
return [
'-' + this.layoutType,
...(navbarColumnStretch ? ['-column-stretch'] : [])
]
},
currentUser () { return this.$store.state.users.currentUser },
userBackground () { return this.currentUser.background_image },
instanceBackground () {
return this.mergedConfig.hideInstanceWallpaper
? null
: this.$store.state.instance.background
},
background () { return this.userBackground || this.instanceBackground },
bgStyle () {
if (this.background) {
return {
'--body-background-image': `url(${this.background})`
}
}
},
shout () { return this.$store.state.shout.joined },
suggestionsEnabled () { return this.$store.state.instance.suggestionsEnabled },
showInstanceSpecificPanel () {
return this.$store.state.instance.showInstanceSpecificPanel &&
!this.$store.getters.mergedConfig.hideISP &&
this.$store.state.instance.instanceSpecificPanelContent
},
isChats () {
return this.$route.name === 'chat' || this.$route.name === 'chats'
},
isListEdit () {
return this.$route.name === 'lists-edit'
},
newPostButtonShown () {
if (this.isChats) return false
if (this.isListEdit) return false
return this.$store.getters.mergedConfig.alwaysShowNewPostButton || this.layoutType === 'mobile'
},
showFeaturesPanel () { return this.$store.state.instance.showFeaturesPanel },
editingAvailable () { return this.$store.state.instance.editingAvailable },
shoutboxPosition () {
return this.$store.getters.mergedConfig.alwaysShowNewPostButton || false
},
hideShoutbox () {
return this.$store.getters.mergedConfig.hideShoutbox
},
layoutType () { return this.$store.state.interface.layoutType },
privateMode () { return this.$store.state.instance.private },
reverseLayout () {
const { thirdColumnMode, sidebarRight: reverseSetting } = this.$store.getters.mergedConfig
if (this.layoutType !== 'wide') {
return reverseSetting
} else {
return thirdColumnMode === 'notifications' ? reverseSetting : !reverseSetting
}
},
noSticky () { return this.$store.getters.mergedConfig.disableStickyHeaders },
showScrollbars () { return this.$store.getters.mergedConfig.showScrollbars },
...mapGetters(['mergedConfig'])
},
methods: {
updateMobileState () {
this.$store.dispatch('setLayoutWidth', windowWidth())
this.$store.dispatch('setLayoutHeight', windowHeight())
},
removeSplash () {
document.querySelector('#status').textContent = this.$t('splash.fun_' + Math.ceil(Math.random() * 4))
const splashscreenRoot = document.querySelector('#splash')
splashscreenRoot.addEventListener('transitionend', () => {
splashscreenRoot.remove()
})
splashscreenRoot.classList.add('hidden')
document.querySelector('#app').classList.remove('hidden')
}
}
}
diff --git a/src/components/dialog_modal/dialog_modal.vue b/src/components/dialog_modal/dialog_modal.vue
index 93b8ac0fab..096c8ac8c7 100644
--- a/src/components/dialog_modal/dialog_modal.vue
+++ b/src/components/dialog_modal/dialog_modal.vue
@@ -1,82 +1,123 @@
<template>
<span
+ class="dialog-container"
:class="{ 'dark-overlay': darkOverlay }"
@click.self.stop="onCancel()"
>
<div
class="dialog-modal panel panel-default"
@click.stop=""
>
<div class="panel-heading dialog-modal-heading">
<h1 class="title">
<slot name="header" />
</h1>
</div>
<div class="panel-body dialog-modal-content">
<slot name="default" />
</div>
<div class="dialog-modal-footer user-interactions panel-footer">
<slot name="footer" />
</div>
</div>
</span>
</template>
<script src="./dialog_modal.js"></script>
<style lang="scss">
// TODO: unify with other modals.
.dark-overlay {
&::before {
bottom: 0;
content: " ";
display: block;
cursor: default;
left: 0;
position: fixed;
right: 0;
top: 0;
background: rgb(27 31 35 / 50%);
z-index: 2000;
}
}
-.dialog-modal.panel {
+.dialog-container {
+ display: grid;
+ position: fixed;
top: 0;
- left: 50%;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ justify-content: center;
+ align-items: center;
+ justify-items: center;
+}
+
+.dialog-modal.panel {
max-height: 80vh;
max-width: 90vw;
- margin: 15vh auto;
- position: fixed;
- transform: translateX(-50%);
z-index: 2001;
cursor: default;
display: block;
.dialog-modal-heading {
.title {
text-align: center;
}
}
.dialog-modal-content {
margin: 0;
padding: 1rem;
white-space: normal;
+ text-align: center;
}
.dialog-modal-footer {
margin: 0;
padding: 0.5em;
border-top: 1px solid var(--border);
- display: flex;
- justify-content: flex-end;
+ display: grid;
+ grid-gap: 0.5em;
+ grid-template-columns: min-content;
+ grid-auto-columns: min-content;
+ grid-auto-flow: column dense;
+ height: auto;
button {
width: auto;
- margin-left: 0.5rem;
+ white-space: nowrap;
+ padding-left: 2em;
+ padding-right: 2em;
+ }
+ }
+}
+
+#modal.-mobile {
+ .dialog-container {
+ justify-content: stretch;
+ align-items: end;
+ justify-items: stretch;
+ }
+
+ .dialog-modal.panel {
+ min-width: 100vw;
+ }
+
+ .dialog-modal-footer {
+ flex-direction: column;
+ justify-content: flex-end;
+ grid-template-columns: 1fr;
+ grid-auto-columns: none;
+ grid-auto-rows: auto;
+ grid-auto-flow: row dense;
+
+ button {
+ grid-column: 1;
+ height: 3em;
}
}
}
</style>

File Metadata

Mime Type
text/x-diff
Expires
Thu, Oct 29, 9:10 PM (1 d, 17 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1798658
Default Alt Text
(9 KB)

Event Timeline