From 79efe0646cb6fc88952e33e13a8ce61205d3aad6 Mon Sep 17 00:00:00 2001 From: jared Date: Tue, 2 Apr 2019 10:53:33 -0400 Subject: [PATCH] merge develop --- BREAKING_CHANGES.md | 10 + README.md | 2 +- src/App.js | 27 +- src/App.scss | 32 -- src/App.vue | 11 +- src/boot/after_store.js | 50 ++- .../features_panel/features_panel.js | 2 +- .../features_panel/features_panel.vue | 2 +- src/components/mobile_nav/mobile_nav.js | 77 ++++ src/components/mobile_nav/mobile_nav.vue | 140 ++++++++ src/components/notification/notification.js | 9 + src/components/notification/notification.vue | 4 +- src/components/notifications/notifications.js | 3 + .../notifications/notifications.vue | 2 +- .../post_status_form/post_status_form.js | 25 +- .../post_status_form/post_status_form.vue | 12 +- .../scope_selector/scope_selector.js | 54 +++ .../scope_selector/scope_selector.vue | 30 ++ src/components/settings/settings.js | 10 +- src/components/settings/settings.vue | 6 + src/components/side_drawer/side_drawer.vue | 5 - src/components/status/status.js | 6 + src/components/status/status.vue | 14 +- src/components/user_profile/user_profile.js | 3 - src/components/user_settings/user_settings.js | 6 +- .../user_settings/user_settings.vue | 10 +- src/i18n/en.json | 5 +- src/i18n/oc.json | 2 + src/i18n/pl.json | 332 +++++++++++++++++- src/i18n/ru.json | 10 + src/modules/config.js | 3 +- src/modules/instance.js | 2 +- src/modules/interface.js | 10 +- src/modules/statuses.js | 11 +- .../user_profile_link_generator.js | 2 +- src/services/window_utils/window_utils.js | 5 + static/config.json | 4 +- static/font/LICENSE.txt | 0 static/font/README.txt | 0 static/font/config.json | 6 + static/font/css/fontello-codes.css | 1 + static/font/css/fontello-embedded.css | 13 +- static/font/css/fontello-ie7-codes.css | 1 + static/font/css/fontello-ie7.css | 1 + static/font/css/fontello.css | 15 +- static/font/demo.html | 15 +- static/font/font/fontello.eot | Bin 18372 -> 18720 bytes static/font/font/fontello.svg | 2 + static/font/font/fontello.ttf | Bin 18204 -> 18552 bytes static/font/font/fontello.woff | Bin 11180 -> 11296 bytes static/font/font/fontello.woff2 | Bin 9460 -> 9592 bytes 51 files changed, 835 insertions(+), 157 deletions(-) create mode 100644 BREAKING_CHANGES.md create mode 100644 src/components/mobile_nav/mobile_nav.js create mode 100644 src/components/mobile_nav/mobile_nav.vue create mode 100644 src/components/scope_selector/scope_selector.js create mode 100644 src/components/scope_selector/scope_selector.vue create mode 100644 src/services/window_utils/window_utils.js mode change 100755 => 100644 static/font/LICENSE.txt mode change 100755 => 100644 static/font/README.txt diff --git a/BREAKING_CHANGES.md b/BREAKING_CHANGES.md new file mode 100644 index 00000000..924c38da --- /dev/null +++ b/BREAKING_CHANGES.md @@ -0,0 +1,10 @@ +# v1.0 +## Removed features/radically changed behavior +### minimalScopesMode +As of !633, `scopeOptions` is no longer available and instead is changed for `minimalScopesMode` (default: `false`) + +Reasoning is that scopeOptions option originally existed mostly as a backwards-compatibility with GNU Social which only had `public` scope available and using scope selector would''t work. Since at some point we dropped GNU Social support, this option was mostly a nuisance (being default `false`'), however some people think scopes are an annoyance to a certain degree and want as less of that feature as possible. + +Solution - to only show minimal set among: *Direct*, *User default* and *Scope of post replying to*. This also makes it impossible to reply to a DM with a non-DM post from UI. + +*This setting is admin-default, user-configurable. Admin can choose different default for their instance but user can override it.* diff --git a/README.md b/README.md index 80938c45..889f0837 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ FE Build process also leaves current commit hash in global variable `___pleromaf # Configuration -Edit config.json for configuration. scopeOptionsEnabled gives you input fields for CWs and the scope settings. +Edit config.json for configuration. ## Options diff --git a/src/App.js b/src/App.js index 5c27a3df..46145b16 100644 --- a/src/App.js +++ b/src/App.js @@ -9,7 +9,8 @@ import ChatPanel from './components/chat_panel/chat_panel.vue' import MediaModal from './components/media_modal/media_modal.vue' import SideDrawer from './components/side_drawer/side_drawer.vue' import MobilePostStatusModal from './components/mobile_post_status_modal/mobile_post_status_modal.vue' -import { unseenNotificationsFromStore } from './services/notification_utils/notification_utils' +import MobileNav from './components/mobile_nav/mobile_nav.vue' +import { windowWidth } from './services/window_utils/window_utils' export default { name: 'app', @@ -24,7 +25,8 @@ export default { ChatPanel, MediaModal, SideDrawer, - MobilePostStatusModal + MobilePostStatusModal, + MobileNav }, data: () => ({ mobileActivePanel: 'timeline', @@ -40,6 +42,10 @@ export default { created () { // Load the locale from the storage this.$i18n.locale = this.$store.state.config.interfaceLanguage + window.addEventListener('resize', this.updateMobileState) + }, + destroyed () { + window.removeEventListener('resize', this.updateMobileState) }, computed: { currentUser () { return this.$store.state.users.currentUser }, @@ -82,13 +88,8 @@ export default { chat () { return this.$store.state.chat.channel.state === 'joined' }, suggestionsEnabled () { return this.$store.state.instance.suggestionsEnabled }, showInstanceSpecificPanel () { return this.$store.state.instance.showInstanceSpecificPanel }, - unseenNotifications () { - return unseenNotificationsFromStore(this.$store) - }, - unseenNotificationsCount () { - return this.unseenNotifications.length - }, - showFeaturesPanel () { return this.$store.state.instance.showFeaturesPanel } + showFeaturesPanel () { return this.$store.state.instance.showFeaturesPanel }, + isMobileLayout () { return this.$store.state.interface.mobileLayout } }, methods: { scrollToTop () { @@ -101,8 +102,12 @@ export default { onFinderToggled (hidden) { this.finderHidden = hidden }, - toggleMobileSidebar () { - this.$refs.sideDrawer.toggleDrawer() + updateMobileState () { + const mobileLayout = windowWidth() <= 800 + const changed = mobileLayout !== this.isMobileLayout + if (changed) { + this.$store.dispatch('setMobileLayout', mobileLayout) + } } } } diff --git a/src/App.scss b/src/App.scss index ae068e4f..5fc0dd27 100644 --- a/src/App.scss +++ b/src/App.scss @@ -484,24 +484,6 @@ nav { } } -.menu-button { - display: none; - position: relative; -} - -.alert-dot { - border-radius: 100%; - height: 8px; - width: 8px; - position: absolute; - left: calc(50% - 4px); - top: calc(50% - 4px); - margin-left: 6px; - margin-top: -6px; - background-color: $fallback--cRed; - background-color: var(--badgeNotification, $fallback--cRed); -} - .fade-enter-active, .fade-leave-active { transition: opacity .2s } @@ -530,20 +512,6 @@ nav { display: none; } -.panel-switcher { - display: none; - width: 100%; - height: 46px; - - button { - display: block; - flex: 1; - max-height: 32px; - margin: 0.5em; - padding: 0.5em; - } -} - @media all and (min-width: 800px) { body { overflow-y: scroll; diff --git a/src/App.vue b/src/App.vue index 4fff3d1d..3b8623ad 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,17 +1,14 @@ diff --git a/src/boot/after_store.js b/src/boot/after_store.js index f5add8ad..862a534d 100644 --- a/src/boot/after_store.js +++ b/src/boot/after_store.js @@ -1,8 +1,8 @@ import Vue from 'vue' import VueRouter from 'vue-router' import routes from './routes' - import App from '../App.vue' +import { windowWidth } from '../services/window_utils/window_utils' const getStatusnetConfig = async ({ store }) => { try { @@ -95,7 +95,7 @@ const setSettings = async ({ apiConfig, staticConfig, store }) => { copyInstanceOption('redirectRootNoLogin') copyInstanceOption('redirectRootLogin') copyInstanceOption('showInstanceSpecificPanel') - copyInstanceOption('scopeOptionsEnabled') + copyInstanceOption('minimalScopesMode') copyInstanceOption('formattingOptionsEnabled') copyInstanceOption('hideMutedPosts') copyInstanceOption('collapseMessageWithSubject') @@ -219,6 +219,28 @@ const getNodeInfo = async ({ store }) => { } } +const setConfig = async ({ store }) => { + // apiConfig, staticConfig + const configInfos = await Promise.all([getStatusnetConfig({ store }), getStaticConfig()]) + const apiConfig = configInfos[0] + const staticConfig = configInfos[1] + + await setSettings({ store, apiConfig, staticConfig }) +} + +const checkOAuthToken = async ({ store }) => { + return new Promise(async (resolve, reject) => { + if (store.state.oauth.token) { + try { + await store.dispatch('loginUser', store.state.oauth.token) + } catch (e) { + console.log(e) + } + } + resolve() + }) +} + const afterStoreSetup = async ({ store, i18n }) => { if (store.state.config.customTheme) { // This is a hack to deal with async loading of config.json and themes @@ -230,19 +252,19 @@ const afterStoreSetup = async ({ store, i18n }) => { }) } - const apiConfig = await getStatusnetConfig({ store }) - const staticConfig = await getStaticConfig() - await setSettings({ store, apiConfig, staticConfig }) - await getTOS({ store }) - await getInstancePanel({ store }) - await getStaticEmoji({ store }) - await getCustomEmoji({ store }) - await getNodeInfo({ store }) + const width = windowWidth() + store.dispatch('setMobileLayout', width <= 800) - // Now we have the server settings and can try logging in - if (store.state.oauth.token) { - await store.dispatch('loginUser', store.state.oauth.token) - } + // Now we can try getting the server settings and logging in + await Promise.all([ + checkOAuthToken({ store }), + setConfig({ store }), + getTOS({ store }), + getInstancePanel({ store }), + getStaticEmoji({ store }), + getCustomEmoji({ store }), + getNodeInfo({ store }) + ]) const router = new VueRouter({ mode: 'history', diff --git a/src/components/features_panel/features_panel.js b/src/components/features_panel/features_panel.js index e0b7a118..5f0b7b25 100644 --- a/src/components/features_panel/features_panel.js +++ b/src/components/features_panel/features_panel.js @@ -6,7 +6,7 @@ const FeaturesPanel = { gopher: function () { return this.$store.state.instance.gopherAvailable }, whoToFollow: function () { return this.$store.state.instance.suggestionsEnabled }, mediaProxy: function () { return this.$store.state.instance.mediaProxyAvailable }, - scopeOptions: function () { return this.$store.state.instance.scopeOptionsEnabled }, + minimalScopesMode: function () { return this.$store.state.instance.minimalScopesMode }, textlimit: function () { return this.$store.state.instance.textlimit } } } diff --git a/src/components/features_panel/features_panel.vue b/src/components/features_panel/features_panel.vue index 445143e9..7a263e01 100644 --- a/src/components/features_panel/features_panel.vue +++ b/src/components/features_panel/features_panel.vue @@ -12,7 +12,7 @@
  • {{$t('features_panel.gopher')}}
  • {{$t('features_panel.who_to_follow')}}
  • {{$t('features_panel.media_proxy')}}
  • -
  • {{$t('features_panel.scope_options')}}
  • +
  • {{$t('features_panel.scope_options')}}
  • {{$t('features_panel.text_limit')}} = {{textlimit}}
  • diff --git a/src/components/mobile_nav/mobile_nav.js b/src/components/mobile_nav/mobile_nav.js new file mode 100644 index 00000000..bc63d2ba --- /dev/null +++ b/src/components/mobile_nav/mobile_nav.js @@ -0,0 +1,77 @@ +import SideDrawer from '../side_drawer/side_drawer.vue' +import Notifications from '../notifications/notifications.vue' +import MobilePostStatusModal from '../mobile_post_status_modal/mobile_post_status_modal.vue' +import { unseenNotificationsFromStore } from '../../services/notification_utils/notification_utils' +import GestureService from '../../services/gesture_service/gesture_service' + +const MobileNav = { + components: { + SideDrawer, + Notifications, + MobilePostStatusModal + }, + data: () => ({ + notificationsCloseGesture: undefined, + notificationsOpen: false + }), + created () { + this.notificationsCloseGesture = GestureService.swipeGesture( + GestureService.DIRECTION_RIGHT, + this.closeMobileNotifications, + 50 + ) + }, + computed: { + currentUser () { + return this.$store.state.users.currentUser + }, + unseenNotifications () { + return unseenNotificationsFromStore(this.$store) + }, + unseenNotificationsCount () { + return this.unseenNotifications.length + }, + sitename () { return this.$store.state.instance.name } + }, + methods: { + toggleMobileSidebar () { + this.$refs.sideDrawer.toggleDrawer() + }, + openMobileNotifications () { + this.notificationsOpen = true + }, + closeMobileNotifications () { + if (this.notificationsOpen) { + // make sure to mark notifs seen only when the notifs were open and not + // from close-calls. + this.notificationsOpen = false + this.markNotificationsAsSeen() + } + }, + notificationsTouchStart (e) { + GestureService.beginSwipe(e, this.notificationsCloseGesture) + }, + notificationsTouchMove (e) { + GestureService.updateSwipe(e, this.notificationsCloseGesture) + }, + scrollToTop () { + window.scrollTo(0, 0) + }, + logout () { + this.$router.replace('/main/public') + this.$store.dispatch('logout') + }, + markNotificationsAsSeen () { + this.$refs.notifications.markAsSeen() + } + }, + watch: { + $route () { + // handles closing notificaitons when you press any router-link on the + // notifications. + this.closeMobileNotifications() + } + } +} + +export default MobileNav diff --git a/src/components/mobile_nav/mobile_nav.vue b/src/components/mobile_nav/mobile_nav.vue new file mode 100644 index 00000000..5fa41638 --- /dev/null +++ b/src/components/mobile_nav/mobile_nav.vue @@ -0,0 +1,140 @@ + + + + + diff --git a/src/components/notification/notification.js b/src/components/notification/notification.js index fe5b7018..42a48f3f 100644 --- a/src/components/notification/notification.js +++ b/src/components/notification/notification.js @@ -31,6 +31,15 @@ const Notification = { const highlight = this.$store.state.config.highlight const user = this.notification.action.user return highlightStyle(highlight[user.screen_name]) + }, + userInStore () { + return this.$store.getters.findUser(this.notification.action.user.id) + }, + user () { + if (this.userInStore) { + return this.userInStore + } + return {} } } } diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue index 5e9cef97..8f532747 100644 --- a/src/components/notification/notification.vue +++ b/src/components/notification/notification.vue @@ -1,11 +1,11 @@