Merge branch 'notifications' into shigusegubu
* notifications: error display removed style for rounding bottom part of notifications because there's now always "load more" footer fix custom emoji in username, fix gif avatar not being animated when hovering on the notification Hide initial desktop notifications spam when FE is opened and there's a lot of unseen notifications. Updated localization files Drop the entire thing about hidden "own" timeline since it doesn't necessarily contain all of the users posts (it doesn't contain DMs) even though it's "us". Since this is a workaround anyway just fetch home timeline instead. It could end up making more queries if user doesn't post that often.
This commit is contained in:
commit
83b2964f7c
9 changed files with 54 additions and 25 deletions
|
@ -14,6 +14,9 @@ const Notifications = {
|
|||
notifications () {
|
||||
return this.$store.state.statuses.notifications.data
|
||||
},
|
||||
error () {
|
||||
return this.$store.state.statuses.notifications.error
|
||||
},
|
||||
unseenNotifications () {
|
||||
return filter(this.notifications, ({seen}) => !seen)
|
||||
},
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
// a bit of a hack to allow scrolling below notifications
|
||||
padding-bottom: 15em;
|
||||
|
||||
.title {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.panel {
|
||||
background: $fallback--bg;
|
||||
background: var(--bg, $fallback--bg)
|
||||
|
@ -22,6 +26,8 @@
|
|||
background: var(--btn, $fallback--btn);
|
||||
color: $fallback--fg;
|
||||
color: var(--fg, $fallback--fg);
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
.read-button {
|
||||
position: absolute;
|
||||
right: 0.7em;
|
||||
|
@ -44,6 +50,19 @@
|
|||
line-height: 1.3em;
|
||||
}
|
||||
|
||||
.loadmore-error {
|
||||
position: absolute;
|
||||
right: 0.6em;
|
||||
font-size: 14px;
|
||||
min-width: 6em;
|
||||
font-family: sans-serif;
|
||||
text-align: center;
|
||||
padding: 0 0.25em 0 0.25em;
|
||||
margin: 0;
|
||||
color: $fallback--fg;
|
||||
color: var(--fg, $fallback--fg);
|
||||
}
|
||||
|
||||
.unseen {
|
||||
box-shadow: inset 4px 0 0 var(--cRed, $fallback--cRed);
|
||||
padding-left: 0;
|
||||
|
@ -79,7 +98,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
&:hover .animated.avatar {
|
||||
&:hover .animated.avatar-compact {
|
||||
canvas {
|
||||
display: none;
|
||||
}
|
||||
|
@ -155,6 +174,13 @@
|
|||
max-width: 100%;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
img {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
vertical-align: middle;
|
||||
object-fit: contain
|
||||
}
|
||||
}
|
||||
.timeago {
|
||||
float: right;
|
||||
|
@ -204,15 +230,4 @@
|
|||
margin-bottom: 0.3em;
|
||||
}
|
||||
}
|
||||
|
||||
// ugly as heck
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
border-radius: 0 0 $fallback--panelRadius $fallback--panelRadius;
|
||||
border-radius: 0 0 var(--panelRadius, $fallback--panelRadius) var(--panelRadius, $fallback--panelRadius);
|
||||
.status-el {
|
||||
border-radius: 0 0 $fallback--panelRadius $fallback--panelRadius;
|
||||
border-radius: 0 0 var(--panelRadius, $fallback--panelRadius) var(--panelRadius, $fallback--panelRadius);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,10 @@
|
|||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<span class="unseen-count" v-if="unseenCount">{{unseenCount}}</span>
|
||||
{{$t('notifications.notifications')}}
|
||||
<div class="title"> {{$t('notifications.notifications')}}</div>
|
||||
<div @click.prevent class="loadmore-error alert error" v-if="error">
|
||||
{{$t('timeline.error_fetching')}}
|
||||
</div>
|
||||
<button v-if="unseenCount" @click.prevent="markAsSeen" class="read-button">{{$t('notifications.read')}}</button>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
|
|
@ -355,7 +355,8 @@ const en = {
|
|||
followed_you: 'followed you',
|
||||
favorited_you: 'favorited your status',
|
||||
repeated_you: 'repeated your status',
|
||||
broken_favorite: 'Unknown status, searching for it...'
|
||||
broken_favorite: 'Unknown status, searching for it...',
|
||||
load_older: 'Load older notifications'
|
||||
},
|
||||
login: {
|
||||
login: 'Log in',
|
||||
|
@ -1650,7 +1651,8 @@ const ru = {
|
|||
followed_you: 'начал(а) читать вас',
|
||||
favorited_you: 'нравится ваш статус',
|
||||
repeated_you: 'повторил(а) ваш статус',
|
||||
broken_favorite: 'Неизвестный статус, ищем...'
|
||||
broken_favorite: 'Неизвестный статус, ищем...',
|
||||
load_older: 'Загрузить старые уведомления'
|
||||
},
|
||||
login: {
|
||||
login: 'Войти',
|
||||
|
|
|
@ -24,10 +24,12 @@ export const defaultState = {
|
|||
allStatusesObject: {},
|
||||
maxId: 0,
|
||||
notifications: {
|
||||
desktopNotificationSilence: true,
|
||||
maxId: 0,
|
||||
maxSavedId: 0,
|
||||
minId: Number.POSITIVE_INFINITY,
|
||||
data: [],
|
||||
error: false,
|
||||
brokenFavorites: {}
|
||||
},
|
||||
favorites: new Set(),
|
||||
|
@ -36,7 +38,6 @@ export const defaultState = {
|
|||
mentions: emptyTl(),
|
||||
public: emptyTl(),
|
||||
user: emptyTl(),
|
||||
own: emptyTl(),
|
||||
publicAndExternal: emptyTl(),
|
||||
friends: emptyTl(),
|
||||
tag: emptyTl()
|
||||
|
@ -315,7 +316,7 @@ const addNewNotifications = (state, { dispatch, notifications, older }) => {
|
|||
result.image = action.attachments[0].url
|
||||
}
|
||||
|
||||
if (fresh) {
|
||||
if (fresh && !state.notifications.desktopNotificationSilence) {
|
||||
let notification = new window.Notification(title, result)
|
||||
// Chrome is known for not closing notifications automatically
|
||||
// according to MDN, anyway.
|
||||
|
@ -364,7 +365,10 @@ export const mutations = {
|
|||
state.error = value
|
||||
},
|
||||
setNotificationsError (state, { value }) {
|
||||
state.notificationsError = value
|
||||
state.notifications.error = value
|
||||
},
|
||||
setNotificationsSilence (state, { value }) {
|
||||
state.notifications.desktopNotificationSilence = value
|
||||
},
|
||||
setProfileView (state, { v }) {
|
||||
// load followers / friends only when needed
|
||||
|
@ -402,6 +406,9 @@ const statuses = {
|
|||
setNotificationsError ({ rootState, commit }, { value }) {
|
||||
commit('setNotificationsError', { value })
|
||||
},
|
||||
setNotificationsSilence ({ rootState, commit }, { value }) {
|
||||
commit('setNotificationsSilence', { value })
|
||||
},
|
||||
addFriends ({ rootState, commit }, { friends }) {
|
||||
commit('addFriends', { friends })
|
||||
},
|
||||
|
|
|
@ -107,8 +107,6 @@ const users = {
|
|||
|
||||
// Start getting fresh tweets.
|
||||
store.dispatch('startFetching', 'friends')
|
||||
// Start getting our own posts, only really needed for mitigating broken favorites
|
||||
store.dispatch('startFetching', ['own', user.id])
|
||||
|
||||
// Get user mutes and follower info
|
||||
store.rootState.api.backendInteractor.fetchMutes().then((mutedUsers) => {
|
||||
|
|
|
@ -306,9 +306,6 @@ const fetchTimeline = ({timeline, credentials, since = false, until = false, use
|
|||
notifications: QVITTER_USER_NOTIFICATIONS_URL,
|
||||
'publicAndExternal': PUBLIC_AND_EXTERNAL_TIMELINE_URL,
|
||||
user: QVITTER_USER_TIMELINE_URL,
|
||||
// separate timeline for own posts, so it won't break due to user timeline bugs
|
||||
// really needed only for broken favorites
|
||||
own: QVITTER_USER_TIMELINE_URL,
|
||||
tag: TAG_TIMELINE_URL
|
||||
}
|
||||
|
||||
|
|
|
@ -54,11 +54,11 @@ const backendInteractorService = (credentials) => {
|
|||
return timelineFetcherService.startFetching({timeline, store, credentials, userId})
|
||||
}
|
||||
|
||||
const fetchOldPost = ({store, postId}) => {
|
||||
const fetchOldPost = ({store, postId, timeline = 'friends'}) => {
|
||||
return timelineFetcherService.fetchAndUpdate({
|
||||
store,
|
||||
credentials,
|
||||
timeline: 'own',
|
||||
timeline,
|
||||
older: true,
|
||||
until: postId + 1
|
||||
})
|
||||
|
|
|
@ -30,6 +30,10 @@ const fetchAndUpdate = ({store, credentials, older = false}) => {
|
|||
const startFetching = ({credentials, store}) => {
|
||||
fetchAndUpdate({ credentials, store })
|
||||
const boundFetchAndUpdate = () => fetchAndUpdate({ credentials, store })
|
||||
// Initially there's set flag to silence all desktop notifications so
|
||||
// that there won't spam of them when user just opened up the FE we
|
||||
// reset that flag after a while to show new notifications once again.
|
||||
setTimeout(() => store.dispatch('setNotificationsSilence', false), 10000)
|
||||
return setInterval(boundFetchAndUpdate, 10000)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue