aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/App.js23
-rw-r--r--src/App.scss7
-rw-r--r--src/App.vue2
-rw-r--r--src/components/settings/settings.js4
-rw-r--r--src/components/settings/settings.vue4
-rw-r--r--src/components/status/status.vue16
-rw-r--r--src/components/timeline/timeline.js24
-rw-r--r--src/i18n/messages.js2
-rw-r--r--src/modules/config.js1
-rw-r--r--src/modules/statuses.js8
10 files changed, 84 insertions, 7 deletions
diff --git a/src/App.js b/src/App.js
index 1da3ff7c..3823bd03 100644
--- a/src/App.js
+++ b/src/App.js
@@ -23,6 +23,18 @@ export default {
style () { return { 'background-image': `url(${this.background})` } },
sitename () { return this.$store.state.config.name }
},
+ created () {
+ // this is to detect user zooming mostly
+ window.addEventListener('resize', this.fixSidebarWidth)
+ },
+ mounted () {
+ // for some reason, at least in dev mode, dom is not ready enough at this point
+ // in theory calling the function directly here should be enough, but it's not
+ setTimeout(() => { this.fixSidebarWidth() }, 500)
+ },
+ destroyed () {
+ window.removeEventListener('resize', this.fixSidebarWidth)
+ },
methods: {
activatePanel (panelName) {
this.mobileActivePanel = panelName
@@ -32,6 +44,17 @@ export default {
},
logout () {
this.$store.dispatch('logout')
+ },
+ fixSidebarWidth () {
+ // firefox
+ let barwidth = window.innerWidth - document.body.offsetWidth
+ if (document.body.offsetWidth <= 0) {
+ // chromium
+ barwidth = window.innerWidth - document.body.scrollWidth
+ }
+ // adjust the sidebar size to fit the scrollbar width to keep the gap consistently sized
+ document.getElementById('sidebar-container').style.width = `${345 + barwidth}px`
+ document.getElementById('sidebar-container').style.paddingRight = `${barwidth}px`
}
}
}
diff --git a/src/App.scss b/src/App.scss
index f10c3d65..c3c9013e 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -219,16 +219,19 @@ nav {
}
@media all and (min-width: 960px) {
+ body {
+ overflow-y: scroll;
+ }
.sidebar {
overflow: hidden;
max-height: 100vh;
- width: 350px;
+ width: 345px;
position: fixed;
margin-top: -10px;
.sidebar-container {
height: 96vh;
- width: 362px;
+ width: 365px;
padding-top: 10px;
padding-right: 20px;
overflow-x: hidden;
diff --git a/src/App.vue b/src/App.vue
index 8e802a02..59cfcaa6 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -19,7 +19,7 @@
</div>
<div class="sidebar-flexer" :class="{ 'mobile-hidden': mobileActivePanel != 'sidebar'}">
<div class="sidebar" :class="{ 'mobile-hidden': mobileActivePanel != 'sidebar' }">
- <div class="sidebar-container">
+ <div class="sidebar-container" id="sidebar-container">
<user-panel></user-panel>
<nav-panel></nav-panel>
<notifications v-if="currentUser"></notifications>
diff --git a/src/components/settings/settings.js b/src/components/settings/settings.js
index b3bb8290..b88937bb 100644
--- a/src/components/settings/settings.js
+++ b/src/components/settings/settings.js
@@ -9,6 +9,7 @@ const settings = {
hideNsfwLocal: this.$store.state.config.hideNsfw,
muteWordsString: this.$store.state.config.muteWords.join('\n'),
autoLoadLocal: this.$store.state.config.autoLoad,
+ streamingLocal: this.$store.state.config.streaming,
hoverPreviewLocal: this.$store.state.config.hoverPreview
}
},
@@ -33,6 +34,9 @@ const settings = {
autoLoadLocal (value) {
this.$store.dispatch('setOption', { name: 'autoLoad', value })
},
+ streamingLocal (value) {
+ this.$store.dispatch('setOption', { name: 'streaming', value })
+ },
hoverPreviewLocal (value) {
this.$store.dispatch('setOption', { name: 'hoverPreview', value })
},
diff --git a/src/components/settings/settings.vue b/src/components/settings/settings.vue
index 5978e4ed..6a311d55 100644
--- a/src/components/settings/settings.vue
+++ b/src/components/settings/settings.vue
@@ -33,6 +33,10 @@
<label for="autoLoad">{{$t('settings.autoload')}}</label>
</li>
<li>
+ <input type="checkbox" id="streaming" v-model="streamingLocal">
+ <label for="streaming">{{$t('settings.streaming')}}</label>
+ </li>
+ <li>
<input type="checkbox" id="hoverPreview" v-model="hoverPreviewLocal">
<label for="hoverPreview">{{$t('settings.reply_link_preview')}}</label>
</li>
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index 8d6dce67..84397bfa 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -14,7 +14,7 @@
</div>
<post-status-form class="reply-body" :reply-to="status.id" :attentions="status.attentions" :repliedUser="status.user" v-on:posted="toggleReplying" v-if="replying"/>
</div>
- <div class="status-el base00-background base03-border" v-else-if="!status.deleted" v-bind:class="[{ 'base01-background': isFocused }, { 'status-conversation': inConversation }]" >
+ <div class="status-el base00-background base03-border status-fadein" v-else-if="!status.deleted" v-bind:class="[{ 'base01-background': isFocused }, { 'status-conversation': inConversation }]" >
<template v-if="muted">
<div class="media status container muted">
<small><router-link :to="{ name: 'user-profile', params: { id: status.user.id } }">{{status.user.screen_name}}</router-link></small>
@@ -232,6 +232,20 @@
}
}
+ .status-fadein {
+ animation-duration: 0.5s;
+ animation-name: fadein;
+ }
+
+ @keyframes fadein {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+ }
+
.greentext {
color: green;
}
diff --git a/src/components/timeline/timeline.js b/src/components/timeline/timeline.js
index 6968bc6f..613b8a34 100644
--- a/src/components/timeline/timeline.js
+++ b/src/components/timeline/timeline.js
@@ -11,6 +11,11 @@ const Timeline = {
'userId',
'tag'
],
+ data () {
+ return {
+ paused: false
+ }
+ },
computed: {
timelineError () { return this.$store.state.statuses.error },
followers () {
@@ -21,6 +26,9 @@ const Timeline = {
},
viewing () {
return this.timeline.viewing
+ },
+ newStatusCount () {
+ return this.timeline.newStatusCount
}
},
components: {
@@ -56,6 +64,7 @@ const Timeline = {
methods: {
showNewStatuses () {
this.$store.commit('showNewStatuses', { timeline: this.timelineName })
+ this.paused = false
},
fetchOlderStatuses () {
const store = this.$store
@@ -90,6 +99,21 @@ const Timeline = {
this.fetchOlderStatuses()
}
}
+ },
+ watch: {
+ newStatusCount (count) {
+ if (!this.$store.state.config.streaming) {
+ return
+ }
+ if (count > 0) {
+ // only 'stream' them when you're scrolled to the top
+ if (window.pageYOffset < 15 && !this.paused) {
+ this.showNewStatuses()
+ } else {
+ this.paused = true
+ }
+ }
+ }
}
}
diff --git a/src/i18n/messages.js b/src/i18n/messages.js
index b9a4f756..cedb7fd7 100644
--- a/src/i18n/messages.js
+++ b/src/i18n/messages.js
@@ -103,6 +103,7 @@ const fi = {
hide_attachments_in_convo: 'Piilota liitteet keskusteluissa',
nsfw_clickthrough: 'Piilota NSFW liitteet klikkauksen taakse.',
autoload: 'Lataa vanhempia viestejä automaattisesti ruudun pohjalla',
+ streaming: 'Näytä uudet viestit automaattisesti ollessasi ruudun huipulla',
reply_link_preview: 'Keskusteluiden vastauslinkkien esikatselu'
},
notifications: {
@@ -186,6 +187,7 @@ const en = {
hide_attachments_in_convo: 'Hide attachments in conversations',
nsfw_clickthrough: 'Enable clickthrough NSFW attachment hiding',
autoload: 'Enable automatic loading when scrolled to the bottom',
+ streaming: 'Enable automatic streaming of new posts when scrolled to the top',
reply_link_preview: 'Enable reply-link preview on mouse hover'
},
notifications: {
diff --git a/src/modules/config.js b/src/modules/config.js
index f7d6e9c8..ac17747e 100644
--- a/src/modules/config.js
+++ b/src/modules/config.js
@@ -8,6 +8,7 @@ const defaultState = {
hideAttachmentsInConv: false,
hideNsfw: true,
autoLoad: true,
+ streaming: false,
hoverPreview: true,
muteWords: []
}
diff --git a/src/modules/statuses.js b/src/modules/statuses.js
index 884ba0ef..6d4b4843 100644
--- a/src/modules/statuses.js
+++ b/src/modules/statuses.js
@@ -131,7 +131,7 @@ export const statusType = (status) => {
return 'favorite'
}
- if (status.text.match(/deleted notice {{tag/)) {
+ if (status.text.match(/deleted notice {{tag/) || status.qvitter_delete_notice) {
return 'deletion'
}
@@ -211,8 +211,10 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
sortTimeline(mentions)
}
-
- addNotification({ type: 'mention', status, action: status })
+ // Don't add notification for self-mention
+ if (status.user.id !== user.id) {
+ addNotification({ type: 'mention', status, action: status })
+ }
}
}