diff --git a/README.md b/README.md index bdab5251..114228d8 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ > A Qvitter-style frontend for certain GS servers. -![screenshot](http://i.imgur.com/3q30Zxt.jpg) +![screenshot](https://my.mixtape.moe/kjzioz.PNG) # FOR ADMINS diff --git a/index.html b/index.html index 668b21bb..b7654cc1 100644 --- a/index.html +++ b/index.html @@ -1,5 +1,5 @@ - + diff --git a/package.json b/package.json index 669a5932..d04c3e22 100644 --- a/package.json +++ b/package.json @@ -23,11 +23,11 @@ "object-path": "^0.11.3", "sanitize-html": "^1.13.0", "sass-loader": "^4.0.2", - "vue": "^2.1.0", - "vue-router": "^2.2.0", - "vue-template-compiler": "^2.1.10", + "vue": "^2.3.4", + "vue-router": "^2.5.3", + "vue-template-compiler": "^2.3.4", "vue-timeago": "^3.1.2", - "vuex": "^2.1.0" + "vuex": "^2.3.1" }, "devDependencies": { "autoprefixer": "^6.4.0", diff --git a/src/App.js b/src/App.js index 2a00b369..a2d891f7 100644 --- a/src/App.js +++ b/src/App.js @@ -1,13 +1,15 @@ import UserPanel from './components/user_panel/user_panel.vue' import NavPanel from './components/nav_panel/nav_panel.vue' import Notifications from './components/notifications/notifications.vue' +import UserFinder from './components/user_finder/user_finder.vue' export default { name: 'app', components: { UserPanel, NavPanel, - Notifications + Notifications, + UserFinder }, data: () => ({ mobileActivePanel: 'timeline' diff --git a/src/App.scss b/src/App.scss index 8a1942c6..a5f190cb 100644 --- a/src/App.scss +++ b/src/App.scss @@ -52,6 +52,8 @@ button{ .item { flex: 1; + line-height: 21px; + height: 21px; } .gaps > .item { @@ -134,11 +136,6 @@ main-router { background-color: rgba(0,0,0,0.1); } -.media-body { - flex: 1; - padding-left: 0.5em; -} - .container > * { min-width: 0px; } @@ -147,60 +144,6 @@ main-router { color: grey; } -.status-actions { - width: 50%; - display: flex; - - div, favorite-button { - flex: 1; - } -} - -status-text-container { - display: block; -} - -.status-el { - line-height: 18px; - - .notify { - .avatar { - border-width: 3px; - border-style: solid; - } - } - - .media-left { - img { - margin-top: 0.2em; - float: right; - margin-right: 0.3em; - border-radius: 5px; - } - } - - .retweet-info { - padding: 0.7em 0 0 0.6em; - - .media-left { - display: flex; - - i { - align-self: center; - text-align: right; - flex: 1; - padding-right: 0.3em; - } - } - } - - .media-heading { - small { - font-weight: lighter; - } - margin-bottom: 0.3em; - } -} nav { z-index: 1000; } @@ -213,13 +156,20 @@ nav { } .main { - flex: 1; - flex-basis: 65%; + flex-basis: 60%; + flex-grow: 1; + flex-shrink: 1; } .sidebar { - flex: 1; - flex-basis: 35%; + flex: 0; + flex-basis: 35%; +} + +.sidebar-flexer { + flex: 1; + flex-basis: 345px; + width: 365px; } .mobile-shown { @@ -238,6 +188,30 @@ nav { } } +@media all and (min-width: 960px) { + .sidebar { + overflow: hidden; + max-height: 100vh; + width: 350px; + position: fixed; + margin-top: -10px; + + .sidebar-container { + height: 96vh; + width: 362px; + padding-top: 10px; + padding-right: 20px; + overflow-x: hidden; + overflow-y: scroll; + } + } + .sidebar-flexer { + max-height: 96vh; + flex-shrink: 0; + flex-grow: 0; + } +} + @media all and (max-width: 959px) { .mobile-hidden { display: none; diff --git a/src/App.vue b/src/App.vue index c4b3cb13..b2d8df8b 100644 --- a/src/App.vue +++ b/src/App.vue @@ -6,6 +6,7 @@ {{sitename}}
+
@@ -15,10 +16,14 @@ - @@ -21,4 +31,30 @@ border-bottom-style: solid; border-bottom-width: 1px; } + + .status-preview { + position: absolute; + max-width: 35em; + padding: 0.5em; + display: flex; + border-color: inherit; + border-style: solid; + border-width: 1px; + border-radius: 4px; + box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5); + .avatar { + width: 32px; + height: 32px; + border-radius: 50%; + } + .text { + h4 { + margin-bottom: 0.4em; + small { + font-weight: lighter; + } + } + padding: 0 0.5em 0.5em 0.5em; + } + } diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js index c8d5e212..c0c86c68 100644 --- a/src/components/notifications/notifications.js +++ b/src/components/notifications/notifications.js @@ -1,3 +1,5 @@ +import Status from '../status/status.vue' + import { sortBy, take, filter } from 'lodash' const Notifications = { @@ -23,6 +25,9 @@ const Notifications = { return this.unseenNotifications.length } }, + components: { + Status + }, watch: { unseenCount (count) { if (count > 0) { diff --git a/src/components/notifications/notifications.scss b/src/components/notifications/notifications.scss index 9bc2a5ec..f02ced8d 100644 --- a/src/components/notifications/notifications.scss +++ b/src/components/notifications/notifications.scss @@ -1,6 +1,8 @@ @import '../../_variables.scss'; .notifications { + // a bit of a hack to allow scrolling below notifications + padding-bottom: 15em; .panel-heading { // force the text to stay centered, while keeping @@ -43,19 +45,23 @@ word-wrap: break-word; line-height:18px; - .icon-retweet { + .icon-retweet.lit { color: $green; } - .icon-reply { + .icon-reply.lit { color: $blue; } h1 { + word-break: break-all; margin: 0 0 0.3em; padding: 0; font-size: 1em; line-height:20px; + small { + font-weight: lighter; + } } padding: 0.3em 0.8em 0.5em; diff --git a/src/components/notifications/notifications.vue b/src/components/notifications/notifications.vue index 661d842c..f5950ac9 100644 --- a/src/components/notifications/notifications.vue +++ b/src/components/notifications/notifications.vue @@ -7,23 +7,34 @@
-
+
-
- +
-

{{ notification.action.user.name }}
favorited your status

-

{{ notification.status.text }}

+

+ {{ notification.action.user.name }} + + +

+
-

{{ notification.action.user.name }}
repeated your status

-

{{ notification.status.text }}

+

+ {{ notification.action.user.name }} + + +

+
-

{{ notification.action.user.name }}
mentioned you

-

{{ notification.status.text }}

+

+ {{ notification.action.user.name }} + + +

+
diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index 797fcdbb..881a9d1c 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -5,6 +5,7 @@ import Completion from '../../services/completion/completion.js' import { take, filter, reject, map, uniqBy } from 'lodash' + const buildMentionsString = ({user, attentions}, currentUser) => { let allAttentions = [...attentions] @@ -87,6 +88,8 @@ const PostStatusForm = { files: [] } this.$emit('posted') + let el = this.$el.querySelector('textarea') + el.style.height = '16px' }, addMediaFile (fileInfo) { this.newStatus.files.push(fileInfo) @@ -113,6 +116,13 @@ const PostStatusForm = { }, fileDrag (e) { e.dataTransfer.dropEffect = 'copy' + }, + resize (e) { + e.target.style.height = 'auto' + e.target.style.height = `${e.target.scrollHeight - 10}px` + if (e.target.value === '') { + e.target.style.height = '16px' + } } } } diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index 12a9c88a..4f6d4565 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -1,17 +1,8 @@ @@ -51,14 +51,20 @@ .form-bottom { display: flex; padding: 0.5em; + height: 32px; button { - flex: 2; + width: 10em; } } .attachments { - padding: 0.5em; + padding: 0 0.5em; + + .attachment { + position: relative; + margin: 0.5em 0.8em 0.2em 0; + } i { position: absolute; @@ -86,11 +92,16 @@ form textarea { border: solid; border-width: 1px; - border-color: silver; + border-color: inherit; border-radius: 5px; line-height:16px; padding: 5px; - resize: vertical; + resize: none; + overflow: hidden; + } + + form textarea:focus { + min-height: 48px; } .btn { diff --git a/src/components/settings/settings.js b/src/components/settings/settings.js index 3d373283..998aa354 100644 --- a/src/components/settings/settings.js +++ b/src/components/settings/settings.js @@ -1,11 +1,15 @@ import StyleSwitcher from '../style_switcher/style_switcher.vue' +import { filter, trim } from 'lodash' const settings = { data () { return { hideAttachmentsLocal: this.$store.state.config.hideAttachments, hideAttachmentsInConvLocal: this.$store.state.config.hideAttachmentsInConv, - hideNsfwLocal: this.$store.state.config.hideNsfw + hideNsfwLocal: this.$store.state.config.hideNsfw, + autoLoadLocal: this.$store.state.config.autoLoad, + hoverPreviewLocal: this.$store.state.config.hoverPreview, + muteWordsString: this.$store.state.config.muteWords.join('\n') } }, components: { @@ -20,6 +24,16 @@ const settings = { }, hideNsfwLocal (value) { this.$store.dispatch('setOption', { name: 'hideNsfw', value }) + }, + autoLoadLocal (value) { + this.$store.dispatch('setOption', { name: 'autoLoad', value }) + }, + hoverPreviewLocal (value) { + this.$store.dispatch('setOption', { name: 'hoverPreview', value }) + }, + muteWordsString (value) { + value = filter(value.split('\n'), (word) => trim(word).length > 0) + this.$store.dispatch('setOption', { name: 'muteWords', value }) } } } diff --git a/src/components/settings/settings.vue b/src/components/settings/settings.vue index 478d761a..af0242c4 100644 --- a/src/components/settings/settings.vue +++ b/src/components/settings/settings.vue @@ -8,6 +8,11 @@

Theme

+
+

Filtering

+

All notices containing these words will be muted, one per line

+ +

Attachments

    @@ -23,6 +28,14 @@ +
  • + + +
  • +
  • + + +
@@ -32,9 +45,13 @@ - diff --git a/src/components/timeline/timeline.js b/src/components/timeline/timeline.js index d5a9adcc..3dc07f9e 100644 --- a/src/components/timeline/timeline.js +++ b/src/components/timeline/timeline.js @@ -6,7 +6,8 @@ const Timeline = { props: [ 'timeline', 'timelineName', - 'title' + 'title', + 'userId' ], computed: { timelineError () { return this.$store.state.statuses.error } @@ -20,11 +21,14 @@ const Timeline = { const credentials = store.state.users.currentUser.credentials const showImmediately = this.timeline.visibleStatuses.length === 0 + window.onscroll = this.scrollLoad + timelineFetcher.fetchAndUpdate({ store, credentials, timeline: this.timelineName, - showImmediately + showImmediately, + userId: this.userId }) }, methods: { @@ -40,8 +44,15 @@ const Timeline = { credentials, timeline: this.timelineName, older: true, - showImmediately: true + showImmediately: true, + userId: this.userId }).then(() => store.commit('setLoading', { timeline: this.timelineName, value: false })) + }, + scrollLoad (e) { + let height = Math.max(document.body.offsetHeight, document.body.scrollHeight) + if (this.timeline.loading === false && this.$store.state.config.autoLoad && (window.innerHeight + window.pageYOffset) >= (height - 750)) { + this.fetchOlderStatuses() + } } } } diff --git a/src/components/user_card_content/user_card_content.vue b/src/components/user_card_content/user_card_content.vue index 8c971d53..ff1b108c 100644 --- a/src/components/user_card_content/user_card_content.vue +++ b/src/components/user_card_content/user_card_content.vue @@ -61,10 +61,13 @@ props: [ 'user' ], computed: { headingStyle () { - let rgb = this.$store.state.config.colors['base00'].match(/\d+/g) - return { - backgroundColor: `rgb(${Math.floor(rgb[0] * 0.53)}, ${Math.floor(rgb[1] * 0.56)}, ${Math.floor(rgb[2] * 0.59)})`, - backgroundImage: `url(${this.user.cover_photo})` + let color = this.$store.state.config.colors['base00'] + if (color) { + let rgb = this.$store.state.config.colors['base00'].match(/\d+/g) + return { + backgroundColor: `rgb(${Math.floor(rgb[0] * 0.53)}, ${Math.floor(rgb[1] * 0.56)}, ${Math.floor(rgb[2] * 0.59)})`, + backgroundImage: `url(${this.user.cover_photo})` + } } }, bodyStyle () { @@ -79,9 +82,8 @@ return this.$store.state.users.currentUser }, dailyAvg () { - return Math.round( - this.user.statuses_count / ((new Date() - new Date(this.user.created_at)) / (60 * 60 * 24 * 1000)) - ) + const days = Math.ceil((new Date() - new Date(this.user.created_at)) / (60 * 60 * 24 * 1000)) + return Math.round(this.user.statuses_count / days) } }, methods: { @@ -117,7 +119,6 @@ } .profile-panel-body { - padding-top: 0em; top: -0em; padding-top: 4em; } diff --git a/src/components/user_finder/user_finder.js b/src/components/user_finder/user_finder.js new file mode 100644 index 00000000..03205382 --- /dev/null +++ b/src/components/user_finder/user_finder.js @@ -0,0 +1,22 @@ +const UserFinder = { + data: () => ({ + username: undefined, + hidden: true + }), + methods: { + findUser (username) { + this.$store.state.api.backendInteractor.externalProfile(username) + .then((user) => { + if (!user.error) { + this.$store.commit('addNewUsers', [user]) + this.$router.push({name: 'user-profile', params: {id: user.id}}) + } + }) + }, + toggleHidden () { + this.hidden = !this.hidden + } + } +} + +export default UserFinder diff --git a/src/components/user_finder/user_finder.vue b/src/components/user_finder/user_finder.vue new file mode 100644 index 00000000..c23d8ee0 --- /dev/null +++ b/src/components/user_finder/user_finder.vue @@ -0,0 +1,23 @@ + + + + + diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js index 4d52bc95..5f9d4d08 100644 --- a/src/components/user_profile/user_profile.js +++ b/src/components/user_profile/user_profile.js @@ -1,16 +1,30 @@ import UserCardContent from '../user_card_content/user_card_content.vue' -import { find } from 'lodash' +import Timeline from '../timeline/timeline.vue' const UserProfile = { + created () { + this.$store.commit('clearTimeline', { timeline: 'user' }) + this.$store.dispatch('startFetching', ['user', this.userId]) + }, + destroyed () { + this.$store.dispatch('stopFetching', 'user') + }, computed: { + timeline () { return this.$store.state.statuses.timelines.user }, + userId () { + return this.$route.params.id + }, user () { - const id = this.$route.params.id - const user = find(this.$store.state.users.users, {id}) - return user + if (this.timeline.statuses[0]) { + return this.timeline.statuses[0].user + } else { + return false + } } }, components: { - UserCardContent + UserCardContent, + Timeline } } diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue index 11a61bfc..9241c469 100644 --- a/src/components/user_profile/user_profile.vue +++ b/src/components/user_profile/user_profile.vue @@ -1,6 +1,9 @@ diff --git a/src/lib/persisted_state.js b/src/lib/persisted_state.js index a47ad7d5..02349e13 100644 --- a/src/lib/persisted_state.js +++ b/src/lib/persisted_state.js @@ -3,6 +3,8 @@ import objectPath from 'object-path' import localforage from 'localforage' import { throttle, each } from 'lodash' +let loaded = false + const defaultReducer = (state, paths) => ( paths.length === 0 ? state : paths.reduce((substate, path) => { objectPath.set(substate, path, objectPath.get(state, path)) @@ -15,7 +17,11 @@ const defaultStorage = (() => { })() const defaultSetState = (key, state, storage) => { - return storage.setItem(key, state) + if (!loaded) { + console.log('waiting for old state to be loaded...') + } else { + return storage.setItem(key, state) + } } export default function createPersistedState ({ @@ -32,17 +38,23 @@ export default function createPersistedState ({ } = {}) { return store => { getState(key, storage).then((savedState) => { - if (typeof savedState === 'object') { - // build user cache - const usersState = savedState.users || {} - usersState.usersObject = {} - const users = usersState.users || [] - each(users, (user) => { usersState.usersObject[user.id] = user }) - savedState.users = usersState + try { + if (typeof savedState === 'object') { + // build user cache + const usersState = savedState.users || {} + usersState.usersObject = {} + const users = usersState.users || [] + each(users, (user) => { usersState.usersObject[user.id] = user }) + savedState.users = usersState - store.replaceState( - merge({}, store.state, savedState) - ) + store.replaceState( + merge({}, store.state, savedState) + ) + } + loaded = true + } catch (e) { + console.log("Couldn't load state") + loaded = true } }) diff --git a/src/main.js b/src/main.js index ab0fd6c0..e5ecf228 100644 --- a/src/main.js +++ b/src/main.js @@ -24,7 +24,7 @@ Vue.use(VueRouter) Vue.use(VueTimeago, { locale: 'en-US', locales: { - 'en-US': require('vue-timeago/locales/en-US.json') + 'en-US': require('../static/timeago.json') } }) @@ -33,6 +33,9 @@ const persistedStateOptions = { 'config.hideAttachments', 'config.hideAttachmentsInConv', 'config.hideNsfw', + 'config.autoLoad', + 'config.hoverPreview', + 'config.muteWords', 'statuses.notifications', 'users.users' ] diff --git a/src/modules/api.js b/src/modules/api.js index a32adfde..e61382eb 100644 --- a/src/modules/api.js +++ b/src/modules/api.js @@ -1,4 +1,5 @@ import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js' +import {isArray} from 'lodash' const api = { state: { @@ -18,9 +19,17 @@ const api = { }, actions: { startFetching (store, timeline) { + let userId = false + + // This is for user timelines + if (isArray(timeline)) { + userId = timeline[1] + timeline = timeline[0] + } + // Don't start fetching if we already are. if (!store.state.fetchers[timeline]) { - const fetcher = store.state.backendInteractor.startFetching({timeline, store}) + const fetcher = store.state.backendInteractor.startFetching({timeline, store, userId}) store.commit('addFetcher', {timeline, fetcher}) } }, diff --git a/src/modules/config.js b/src/modules/config.js index 05b4ab3b..f7d6e9c8 100644 --- a/src/modules/config.js +++ b/src/modules/config.js @@ -6,7 +6,10 @@ const defaultState = { colors: {}, hideAttachments: false, hideAttachmentsInConv: false, - hideNsfw: true + hideNsfw: true, + autoLoad: true, + hoverPreview: true, + muteWords: [] } const config = { diff --git a/src/modules/statuses.js b/src/modules/statuses.js index 051ec71b..c3753c5a 100644 --- a/src/modules/statuses.js +++ b/src/modules/statuses.js @@ -32,6 +32,17 @@ export const defaultState = { minVisibleId: 0, loading: false }, + user: { + statuses: [], + statusesObject: {}, + faves: [], + visibleStatuses: [], + visibleStatusesObject: {}, + newStatusCount: 0, + maxId: 0, + minVisibleId: 0, + loading: false + }, publicAndExternal: { statuses: [], statusesObject: {}, @@ -242,6 +253,14 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us const uri = deletion.uri updateMaxId(deletion) + // Remove possible notification + const status = find(allStatuses, {uri}) + if (!status) { + return + } + + remove(state.notifications, ({action: {id}}) => id === status.id) + remove(allStatuses, { uri }) if (timeline) { remove(timelineObject.statuses, { uri }) @@ -276,6 +295,21 @@ export const mutations = { oldTimeline.visibleStatusesObject = {} each(oldTimeline.visibleStatuses, (status) => { oldTimeline.visibleStatusesObject[status.id] = status }) }, + clearTimeline (state, { timeline }) { + const emptyTimeline = { + statuses: [], + statusesObject: {}, + faves: [], + visibleStatuses: [], + visibleStatusesObject: {}, + newStatusCount: 0, + maxId: 0, + minVisibleId: 0, + loading: false + } + + state.timelines[timeline] = emptyTimeline + }, setFavorited (state, { status, value }) { const newStatus = state.allStatusesObject[status.id] newStatus.favorited = value diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index 4dfc0a02..59e3a1c3 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -17,10 +17,14 @@ const FRIENDS_URL = '/api/statuses/friends.json' const FOLLOWING_URL = '/api/friendships/create.json' const UNFOLLOWING_URL = '/api/friendships/destroy.json' const QVITTER_USER_PREF_URL = '/api/qvitter/set_profile_pref.json' +const EXTERNAL_PROFILE_URL = '/api/externalprofile/show.json' +const QVITTER_USER_TIMELINE_URL = '/api/qvitter/statuses/user_timeline.json' // const USER_URL = '/api/users/show.json' const oldfetch = window.fetch +import { map } from 'lodash' + let fetch = (url, options) => { const baseUrl = '' const fullUrl = baseUrl + url @@ -35,6 +39,13 @@ const authHeaders = (user) => { } } +const externalProfile = (profileUrl) => { + let url = `${EXTERNAL_PROFILE_URL}?profileurl=${profileUrl}` + return fetch(url, { + method: 'GET' + }).then((data) => data.json()) +} + const followUser = ({id, credentials}) => { let url = `${FOLLOWING_URL}?user_id=${id}` return fetch(url, { @@ -90,24 +101,34 @@ const setUserMute = ({id, credentials, muted = true}) => { }) } -const fetchTimeline = ({timeline, credentials, since = false, until = false}) => { +const fetchTimeline = ({timeline, credentials, since = false, until = false, userId = false}) => { const timelineUrls = { public: PUBLIC_TIMELINE_URL, friends: FRIENDS_TIMELINE_URL, mentions: MENTIONS_URL, - 'publicAndExternal': PUBLIC_AND_EXTERNAL_TIMELINE_URL + 'publicAndExternal': PUBLIC_AND_EXTERNAL_TIMELINE_URL, + user: QVITTER_USER_TIMELINE_URL } let url = timelineUrls[timeline] + let params = [] + if (since) { - url += `?since_id=${since}` + params.push(['since_id', since]) } if (until) { - url += `?max_id=${until}` + params.push(['max_id', until]) } + if (userId) { + params.push(['user_id', userId]) + } + + const queryString = map(params, (param) => `${param[0]}=${param[1]}`).join('&') + url += `?${queryString}` + return fetch(url, { headers: authHeaders(credentials) }).then((data) => data.json()) } @@ -198,7 +219,8 @@ const apiService = { uploadMedia, fetchAllFollowing, setUserMute, - fetchMutes + fetchMutes, + externalProfile } export default apiService diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js index bc68d02c..f2d01c70 100644 --- a/src/services/backend_interactor_service/backend_interactor_service.js +++ b/src/services/backend_interactor_service/backend_interactor_service.js @@ -26,8 +26,8 @@ const backendInteractorService = (credentials) => { return apiService.unfollowUser({credentials, id}) } - const startFetching = ({timeline, store}) => { - return timelineFetcherService.startFetching({timeline, store, credentials}) + const startFetching = ({timeline, store, userId = false}) => { + return timelineFetcherService.startFetching({timeline, store, credentials, userId}) } const setUserMute = ({id, muted = true}) => { @@ -36,6 +36,8 @@ const backendInteractorService = (credentials) => { const fetchMutes = () => apiService.fetchMutes({credentials}) + const externalProfile = (profileUrl) => apiService.externalProfile(profileUrl) + const backendInteractorServiceInstance = { fetchStatus, fetchConversation, @@ -46,7 +48,8 @@ const backendInteractorService = (credentials) => { verifyCredentials: apiService.verifyCredentials, startFetching, setUserMute, - fetchMutes + fetchMutes, + externalProfile } return backendInteractorServiceInstance diff --git a/src/services/timeline_fetcher/timeline_fetcher.service.js b/src/services/timeline_fetcher/timeline_fetcher.service.js index 24aef069..b28de9e7 100644 --- a/src/services/timeline_fetcher/timeline_fetcher.service.js +++ b/src/services/timeline_fetcher/timeline_fetcher.service.js @@ -14,7 +14,7 @@ const update = ({store, statuses, timeline, showImmediately}) => { }) } -const fetchAndUpdate = ({store, credentials, timeline = 'friends', older = false, showImmediately = false}) => { +const fetchAndUpdate = ({store, credentials, timeline = 'friends', older = false, showImmediately = false, userId = false}) => { const args = { timeline, credentials } const rootState = store.rootState || store.state const timelineData = rootState.statuses.timelines[camelCase(timeline)] @@ -25,14 +25,16 @@ const fetchAndUpdate = ({store, credentials, timeline = 'friends', older = false args['since'] = timelineData.maxId } + args['userId'] = userId + return apiService.fetchTimeline(args) .then((statuses) => update({store, statuses, timeline, showImmediately}), () => store.dispatch('setError', { value: true })) } -const startFetching = ({ timeline = 'friends', credentials, store }) => { - fetchAndUpdate({timeline, credentials, store, showImmediately: true}) - const boundFetchAndUpdate = () => fetchAndUpdate({ timeline, credentials, store }) +const startFetching = ({timeline = 'friends', credentials, store, userId = false}) => { + fetchAndUpdate({timeline, credentials, store, showImmediately: true, userId}) + const boundFetchAndUpdate = () => fetchAndUpdate({ timeline, credentials, store, userId }) return setInterval(boundFetchAndUpdate, 10000) } const timelineFetcher = { diff --git a/static/config.json b/static/config.json index fb8d4015..3b6d56c4 100644 --- a/static/config.json +++ b/static/config.json @@ -1,6 +1,6 @@ { "name": "Pleroma FE", - "theme": "base16-ashes.css", + "theme": "base16-pleroma-dark.css", "background": "/static/bg.jpg", "logo": "/static/logo.png" } diff --git a/static/css/base16-pleroma-dark.css b/static/css/base16-pleroma-dark.css new file mode 100644 index 00000000..8190d2a7 --- /dev/null +++ b/static/css/base16-pleroma-dark.css @@ -0,0 +1,33 @@ +.base00-background { background-color: #161c20; } +.base01-background { background-color: #282e32; } +.base02-background { background-color: #343a3f; } +.base03-background { background-color: #4e5256; } +.base04-background { background-color: #ababab; } +.base05-background { background-color: #b9b9b9; } +.base06-background { background-color: #d0d0d0; } +.base07-background { background-color: #e7e7e7; } +.base08-background { background-color: #baaa9c; } +.base09-background { background-color: #999999; } +.base0A-background { background-color: #a0a0a0; } +.base0B-background { background-color: #8e8e8e; } +.base0C-background { background-color: #868686; } +.base0D-background { background-color: #686868; } +.base0E-background { background-color: #747474; } +.base0F-background { background-color: #5e5e5e; } + +.base00 { color: #161c20; } +.base01 { color: #282e32; } +.base02 { color: #36393e; } +.base03 { color: #4e5256; } +.base04 { color: #ababab; } +.base05 { color: #b9b9b9; } +.base06 { color: #d0d0d0; } +.base07 { color: #e7e7e7; } +.base08 { color: #baaa9c; } +.base09 { color: #999999; } +.base0A { color: #a0a0a0; } +.base0B { color: #8e8e8e; } +.base0C { color: #868686; } +.base0D { color: #686868; } +.base0E { color: #747474; } +.base0F { color: #5e5e5e; } diff --git a/static/css/base16-pleroma-light.css b/static/css/base16-pleroma-light.css new file mode 100644 index 00000000..1a85689a --- /dev/null +++ b/static/css/base16-pleroma-light.css @@ -0,0 +1,33 @@ +.base00-background { background-color: #f2f4f6; } +.base01-background { background-color: #dde2e6; } +.base02-background { background-color: #c0c6cb; } +.base03-background { background-color: #a4a4a4; } +.base04-background { background-color: #545454; } +.base05-background { background-color: #304055; } +.base06-background { background-color: #040404; } +.base07-background { background-color: #000000; } +.base08-background { background-color: #e92f2f; } +.base09-background { background-color: #e09448; } +.base0A-background { background-color: #dddd13; } +.base0B-background { background-color: #0ed839; } +.base0C-background { background-color: #23edda; } +.base0D-background { background-color: #3b48e3; } +.base0E-background { background-color: #f996e2; } +.base0F-background { background-color: #69542d; } + +.base00 { color: #f2f4f6; } +.base01 { color: #dde2e6; } +.base02 { color: #c0c6cb; } +.base03 { color: #a4a4a4; } +.base04 { color: #545454; } +.base05 { color: #304055; } +.base06 { color: #040404; } +.base07 { color: #000000; } +.base08 { color: #e46f0f; } +.base09 { color: #e09448; } +.base0A { color: #dddd13; } +.base0B { color: #0ed839; } +.base0C { color: #23edda; } +.base0D { color: #3b48e3; } +.base0E { color: #f996e2; } +.base0F { color: #69542d; } diff --git a/static/css/themes.json b/static/css/themes.json index e3c35d6d..ea8e5a0c 100644 --- a/static/css/themes.json +++ b/static/css/themes.json @@ -1,4 +1,6 @@ [ +"base16-pleroma-dark.css", +"base16-pleroma-light.css", "base16-3024.css", "base16-apathy.css", "base16-ashes.css", diff --git a/static/font/config.json b/static/font/config.json index 58eb1943..7c58cada 100644 --- a/static/font/config.json +++ b/static/font/config.json @@ -77,6 +77,18 @@ "css": "cog", "code": 59399, "src": "fontawesome" + }, + { + "uid": "1bafeeb1808a5fe24484c7890096901a", + "css": "user-plus", + "code": 62004, + "src": "fontawesome" + }, + { + "uid": "559647a6f430b3aeadbecd67194451dd", + "css": "menu", + "code": 61641, + "src": "fontawesome" } ] } \ No newline at end of file diff --git a/static/font/css/fontello-codes.css b/static/font/css/fontello-codes.css index 3658db77..3e658de9 100644 --- a/static/font/css/fontello-codes.css +++ b/static/font/css/fontello-codes.css @@ -9,5 +9,7 @@ .icon-cog:before { content: '\e807'; } /* '' */ .icon-spin3:before { content: '\e832'; } /* '' */ .icon-spin4:before { content: '\e834'; } /* '' */ +.icon-menu:before { content: '\f0c9'; } /* '' */ .icon-reply:before { content: '\f112'; } /* '' */ -.icon-binoculars:before { content: '\f1e5'; } /* '' */ \ No newline at end of file +.icon-binoculars:before { content: '\f1e5'; } /* '' */ +.icon-user-plus:before { content: '\f234'; } /* '' */ \ No newline at end of file diff --git a/static/font/css/fontello-embedded.css b/static/font/css/fontello-embedded.css index 360bf238..7dedc03f 100644 --- a/static/font/css/fontello-embedded.css +++ b/static/font/css/fontello-embedded.css @@ -1,15 +1,15 @@ @font-face { font-family: 'fontello'; - src: url('../font/fontello.eot?36468641'); - src: url('../font/fontello.eot?36468641#iefix') format('embedded-opentype'), - url('../font/fontello.svg?36468641#fontello') format('svg'); + src: url('../font/fontello.eot?46746090'); + src: url('../font/fontello.eot?46746090#iefix') format('embedded-opentype'), + url('../font/fontello.svg?46746090#fontello') format('svg'); font-weight: normal; font-style: normal; } @font-face { font-family: 'fontello'; - src: url('data:application/octet-stream;base64,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') format('woff'), - url('data:application/octet-stream;base64,AAEAAAAPAIAAAwBwR1NVQiCMJXkAAAD8AAAAVE9TLzI+L1MmAAABUAAAAFZjbWFwg8ihQQAAAagAAAIqY3Z0IAbV/uYAABQsAAAAIGZwZ22KkZBZAAAUTAAAC3BnYXNwAAAAEAAAFCQAAAAIZ2x5ZvRAK38AAAPUAAAMGGhlYWQM49T0AAAP7AAAADZoaGVhB4IDpAAAECQAAAAkaG10eDAL//wAABBIAAAANGxvY2EQahP0AAAQfAAAABxtYXhwARgMBwAAEJgAAAAgbmFtZcydHR8AABC4AAACzXBvc3SiSezdAAATiAAAAJtwcmVw5UErvAAAH7wAAACGAAEAAAAKADAAPgACbGF0bgAOREZMVAAaAAQAAAAAAAAAAQAAAAQAAAAAAAAAAQAAAAFsaWdhAAgAAAABAAAAAQAEAAQAAAABAAgAAQAGAAAAAQAAAAEDsgGQAAUAAAJ6ArwAAACMAnoCvAAAAeAAMQECAAACAAUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBmRWQAQOgA8eUDUv9qAFoDUgClAAAAAQAAAAAAAAAAAAUAAAADAAAALAAAAAQAAAGKAAEAAAAAAIQAAwABAAAALAADAAoAAAGKAAQAWAAAAAwACAACAAToB+gy6DTxEvHl//8AAOgA6DLoNPES8eX//wAAAAAAAAAAAAAAAQAMABoAGgAaABoAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAAAAQYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAoAAAAAAAAAAMAADoAAAA6AAAAAABAADoAQAA6AEAAAACAADoAgAA6AIAAAADAADoAwAA6AMAAAAEAADoBAAA6AQAAAAFAADoBQAA6AUAAAAGAADoBgAA6AYAAAAHAADoBwAA6AcAAAAIAADoMgAA6DIAAAAJAADoNAAA6DQAAAAKAADxEgAA8RIAAAALAADx5QAA8eUAAAAMAAAAAQAA/+8C1AKGACQAHkAbIhkQBwQAAgFHAwECAAJvAQEAAGYUHBQUBAUYKyUUDwEGIi8BBwYiLwEmND8BJyY0PwE2Mh8BNzYyHwEWFA8BFxYC1A9MECwQpKQQLBBMEBCkpBAQTBAsEKSkECwQTA8PpKQPcBYQTA8PpaUPD0wQLBCkpBAsEEwQEKSkEBBMDy4PpKQPAAQAAP+xA6EDLgAIABEAKQBAAEZAQzUBBwYJAAICAAJHAAkGCW8IAQYHBm8ABwMHbwAEAAIEVAUBAwEBAAIDAGAABAQCWAACBAJMPTwjMyMiMiU5GBIKBR0rJTQmDgIeATY3NCYOAh4BNjcVFAYjISImJzU0NhczHgE7ATI2NzMyFgMGKwEVFAYHIyImJzUjIiY/ATYyHwEWAsoUHhQCGBoYjRQgEgIWHBhGIBb8yxceASAW7gw2I48iNg3uFiC2CRiPFA+PDxQBjxcTEfoKHgr6Eh0OFgISIBIEGgwOFgISIBIEGomzFiAgFrMWIAEfKCgfHgFSFvoPFAEWDvosEfoKCvoRAAAAAAEAAP/KA6EDQAAfADVAChIPCgQDBQACAUdLsBxQWEAMAQEAAgBwAAICDAJJG0AKAAIAAm8BAQAAZlm1HRQXAwUXKwEUDwETFRQOAS8BBwYiJjU0NxMnJjU0NyU3NjIfAQUWA6EPyjAMFQz7+gwWDAEwyw4fARh+CyAMfQEYIAHpDA/F/ukMCxABB4SEBxIKBAgBF8UPDBUFKP4XF/4oBQACAAD/ygOhA0AACQApAEBAERwZFA4NCQgHBgUDAQwAAgFHS7AcUFhADAEBAAIAcAACAgwCSRtACgACAAJvAQEAAGZZQAklJBcWEhADBRQrATcvAQ8BFwc3FxMUDwETFRQjIi8BBwYiJjU0NxMnJjU0NyU3NjIfAQUWAnuq62pp7Ksp09P+D8owFwoM+/oMFgwBMMsOHwEYfgsgDH0BGCABIqYi1dUiputvbwGyDA/F/ukMHAeEhAcSCgQIARfFDwwVBSj+Fxf+KAUAAAACAAD/+AQwAnwAIQBDAEJAPyIBBAYBRwMBAQcGBwEGbQkBBgQHBgRrCAECAAcBAgdgAAQAAARUAAQEAFgFAQAEAExCQBYhJRghFhUoEwoFHSslFAYnISImLwEuATMRIyIuAT8BNjIfARYUBgcjFSEyHwEWJRQPAQYiLwEmNDY7ATUhIi8BJjQ2NyEyFh8BHgEVETMyFgLKCgj96QUGAgMBAgFrDxQBCLMLIAyyCRYOawFBCQVZBAFlCLIMIAuzCBYOa/6+CQVZBAoIAhgEBgIDAQJrDhYLBwwBAgMEAQwBTxYbCtYMDNYKHBQB1gZsBeINCtYNDdYKGxbWB2sFDQoBAgMFAggD/rIWAAAABQAA/8MD6AKxAAkAGgA+AEQAVwBXQFQ0GwIABFMGAgIAUkMCAQJQQiknCAEGBgEERwAFBAVvAAIAAQACAW0AAQYAAQZrAAYDAAYDawADA24ABAAABFQABAQAWAAABABMTEsTLhkkFB0HBRorJTcuATc0NwYHFgE0JgciBhUUFjI2NTQ2MzI2NxQVBgIPAQYjIicmNTQ3LgEnJjQ3PgEzMhc3NjMyFh8BFgcWExQGBxMWFxQHBgcOASM3PgE3Jic3HgEXFgE2KzA4ASKAVV4BahALRmQQFhBEMAsQyjvqOxwFCgdECRlQhjILC1b8lzIyHwUKAw4LJAsBCRVYSZ0E+gsWJ1TcfCl3yEVBXSM1YiALaU8jaj1DOkGEkAFnCxABZEULEBALMEQQdQQBaf5aaTIJJwYKByokeE0RKhKDmAo2CQYGFAYBBf79ToAbARgZXhMTJC1gakoKhGlkQD8kYjYTAAACAAD/zgMgAu4ADwAbAElARgQBAgMFAwIFbQkHAgUGAwUGawgBAAADAgADXgAGAQEGUgAGBgFYAAEGAUwQEAEAEBsQGxoZGBcWFRQTEhEJBgAPAQ4KBRQrATIWFREUBiMhIiY1ETQ2MwE1IzUjFSMVMxUzNQK8Kjo6Kv2oKDw8KAImyGTIyGQC7joq/agoPDwoAlgqOv4+ZMjIZMjIAAAAAgAA/7EDWgMLAAgAagBFQEJlWUxBBAAEOwoCAQA0KBsQBAMBA0cABQQFbwYBBAAEbwAAAQBvAAEDAW8AAwIDbwACAmZcW1NRSUgrKiIgExIHBRYrATQmIg4BFjI2JRUUBg8BBgcWFxYUBw4BJyIvAQYHBgcGKwEiJjUnJicHBiInJicmNDc+ATcmLwEuASc1NDY/ATY3JicmNDc+ATMyHwE2NzY3NjsBMhYfARYXNzYyFxYXFhQHDgEHFh8BHgECO1J4UgJWdFYBHAgHaAoLEygGBQ9QDQcHTRkaCQcEEHwIDBAbF08GEAZGFgQFCCgKDwhmBwgBCgVoCA4XJQYFD1ANBwhNGBoJCAMRfAcMAQ8cF08FDwdIFAQECSgKDwhmBwoBXjtUVHZUVHh8BwwBEB4VGzIGDgYVUAEFPA0ITBwQCgdnCQw8BQZAHgUOBgwyDxwbDwEMB3wHDAEQGRogLQcMBxRQBTwNCEwcEAoHZwkLOwUFQxwFDgYMMg8cGhABDAAAAAL//f9qA+sDUgAnAFAAfkAOJBYGAwECTEI0AwQDAkdLsCFQWEAmAAECAwIBA20HAQMEAgMEawACAgBYBgEAAAxIAAQEBVgABQUNBUkbQCMAAQIDAgEDbQcBAwQCAwRrAAQABQQFXAACAgBYBgEAAAwCSVlAFykoAQBHRTEvKFApUBQSDAoAJwEnCAUUKwEiBwYHBgcUFh8BMzI1Njc2NzYzMhYXBwYWHwEWPgEvAS4BDwEmJyYBIhUGBwYHBiMiJyYnNzYmLwEmDgEfAR4BPwEWFxYzMjc2NzY3NCYvAQHug3FtQ0UFBQQEVBMFNTNTV2NPjjQ6CQIM9wsUCgQ6AhIJQURaXAEzEwU1M1NWY1BIRTU7CAIL+AsUCgQ6AhIKQERaXWaCcW5CRQUFBAQDUkA+a26BCAkCARJiU1EvMT44OQkTAzIDCRYQ4wgLBjxGJij+BBJiU1EvMSAeODkJEwMyAwkWEOMICwY8RiYoQD5rboIICAIBAAAC////WwPqA1IAHwBBAC1AKgQBAgABRzEBAUQAAgABAAIBbQABAW4DAQAADABJAQAhIBQTAB8BHwQFFCsBIgcGBzE2NzYXFhcWFxYGBwYXHgE3PgE3NiYnLgEnJgEiBwYHBgcGFhcWFxYXFjc2NzEGBwYnJicmJyY2NzYmJyYB8ldRVERWbGpnak9CISEGJQ4aEDMRAwoCIwElJpBeW/4FGA8EBAYBJAIkJkhbe3d5fWFWbGpna09CISAFJQgGDhIDUh0eOUUVFB4gT0JWU7NRKRsQAREDDwZaw1ldkCYl/u4QBAYIBlrDWV1IWyQiGBlRRRUUHiBPQlZTs1EVIQ4SAAAAAAEAAP+xA+gDLgArAClAJiYBBAMBRwADBANvAAQBBG8AAQIBbwACAAJvAAAAZiMXEz0XBQUZKyUUBw4CBwYiJjU0Njc2NTQuBSsBFRQGIicBJjQ3ATYyFgcVMyAXFgPoRwEKBAUHEQoCAQMUIjg+VlY3fRQgCf7jCwsBHQscGAJ9AY5aHuFdnwQSEAQKDAgFFAMmHzhaQDAeEgaPDhYLAR4KHgoBHgoUD4/hSwAFAAD/agPoA1IAEAAUACUALwA5AKBAFzMpAgcIIQEFAh0VDQwEAAUDRwQBBQFGS7AhUFhALQYMAwsEAQcCBwECbQACBQcCBWsABQAHBQBrCQEHBwhYCgEICAxIBAEAAA0ASRtALAYMAwsEAQcCBwECbQACBQcCBWsABQAHBQBrBAEAAG4JAQcHCFgKAQgIDAdJWUAgEREAADc1MjEtKygnJCIfHhsZERQRFBMSABAADzcNBRUrAREUBgcRFAYHISImJxETNjMhESMRAREUBgchIiYnESImJxEzMhclFSM1NDY7ATIWBRUjNTQ2OwEyFgGJFg4UEP7jDxQBiwQNAZ+OAjsWDv7jDxQBDxQB7Q0E/j7FCgihCAoBd8UKCKEICgKf/lQPFAH+vw8UARYOAR0B6Az+eAGI/gz+4w8UARYOAUEWDgGsDK19fQgKCgh9fQgKCgAAAQAAAAEAAJf0bOpfDzz1AAsD6AAAAADUy8ixAAAAANTLyLH//f9bBDADUgAAAAgAAgAAAAAAAAABAAADUv9qAAAEL//9//0EMAABAAAAAAAAAAAAAAAAAAAADQPoAAADEQAAA6AAAAOgAAADoAAABC8AAAPoAAADIAAAA1kAAAPo//0D6f//A+gAAAPoAAAAAAAAAEoAzgEeAYQCCgK8AwwDzgSKBQwFYgYMAAEAAAANAGsABQAAAAAAAgAaACoAcwAAAHgLcAAAAAAAAAASAN4AAQAAAAAAAAA1AAAAAQAAAAAAAQAIADUAAQAAAAAAAgAHAD0AAQAAAAAAAwAIAEQAAQAAAAAABAAIAEwAAQAAAAAABQALAFQAAQAAAAAABgAIAF8AAQAAAAAACgArAGcAAQAAAAAACwATAJIAAwABBAkAAABqAKUAAwABBAkAAQAQAQ8AAwABBAkAAgAOAR8AAwABBAkAAwAQAS0AAwABBAkABAAQAT0AAwABBAkABQAWAU0AAwABBAkABgAQAWMAAwABBAkACgBWAXMAAwABBAkACwAmAclDb3B5cmlnaHQgKEMpIDIwMTcgYnkgb3JpZ2luYWwgYXV0aG9ycyBAIGZvbnRlbGxvLmNvbWZvbnRlbGxvUmVndWxhcmZvbnRlbGxvZm9udGVsbG9WZXJzaW9uIDEuMGZvbnRlbGxvR2VuZXJhdGVkIGJ5IHN2ZzJ0dGYgZnJvbSBGb250ZWxsbyBwcm9qZWN0Lmh0dHA6Ly9mb250ZWxsby5jb20AQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgADIAMAAxADcAIABiAHkAIABvAHIAaQBnAGkAbgBhAGwAIABhAHUAdABoAG8AcgBzACAAQAAgAGYAbwBuAHQAZQBsAGwAbwAuAGMAbwBtAGYAbwBuAHQAZQBsAGwAbwBSAGUAZwB1AGwAYQByAGYAbwBuAHQAZQBsAGwAbwBmAG8AbgB0AGUAbABsAG8AVgBlAHIAcwBpAG8AbgAgADEALgAwAGYAbwBuAHQAZQBsAGwAbwBHAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAHMAdgBnADIAdAB0AGYAIABmAHIAbwBtACAARgBvAG4AdABlAGwAbABvACAAcAByAG8AagBlAGMAdAAuAGgAdAB0AHAAOgAvAC8AZgBvAG4AdABlAGwAbABvAC4AYwBvAG0AAAAAAgAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANAQIBAwEEAQUBBgEHAQgBCQEKAQsBDAENAQ4ABmNhbmNlbAZ1cGxvYWQEc3RhcgpzdGFyLWVtcHR5B3JldHdlZXQHZXllLW9mZgxwbHVzLXNxdWFyZWQDY29nBXNwaW4zBXNwaW40BXJlcGx5CmJpbm9jdWxhcnMAAAAAAQAB//8ADwAAAAAAAAAAAAAAAAAAAAAAGAAYABgAGANS/1sDUv9bsAAsILAAVVhFWSAgS7gADlFLsAZTWliwNBuwKFlgZiCKVViwAiVhuQgACABjYyNiGyEhsABZsABDI0SyAAEAQ2BCLbABLLAgYGYtsAIsIGQgsMBQsAQmWrIoAQpDRWNFUltYISMhG4pYILBQUFghsEBZGyCwOFBYIbA4WVkgsQEKQ0VjRWFksChQWCGxAQpDRWNFILAwUFghsDBZGyCwwFBYIGYgiophILAKUFhgGyCwIFBYIbAKYBsgsDZQWCGwNmAbYFlZWRuwAStZWSOwAFBYZVlZLbADLCBFILAEJWFkILAFQ1BYsAUjQrAGI0IbISFZsAFgLbAELCMhIyEgZLEFYkIgsAYjQrEBCkNFY7EBCkOwAWBFY7ADKiEgsAZDIIogirABK7EwBSWwBCZRWGBQG2FSWVgjWSEgsEBTWLABKxshsEBZI7AAUFhlWS2wBSywB0MrsgACAENgQi2wBiywByNCIyCwACNCYbACYmawAWOwAWCwBSotsAcsICBFILALQ2O4BABiILAAUFiwQGBZZrABY2BEsAFgLbAILLIHCwBDRUIqIbIAAQBDYEItsAkssABDI0SyAAEAQ2BCLbAKLCAgRSCwASsjsABDsAQlYCBFiiNhIGQgsCBQWCGwABuwMFBYsCAbsEBZWSOwAFBYZVmwAyUjYUREsAFgLbALLCAgRSCwASsjsABDsAQlYCBFiiNhIGSwJFBYsAAbsEBZI7AAUFhlWbADJSNhRESwAWAtsAwsILAAI0KyCwoDRVghGyMhWSohLbANLLECAkWwZGFELbAOLLABYCAgsAxDSrAAUFggsAwjQlmwDUNKsABSWCCwDSNCWS2wDywgsBBiZrABYyC4BABjiiNhsA5DYCCKYCCwDiNCIy2wECxLVFixBGREWSSwDWUjeC2wESxLUVhLU1ixBGREWRshWSSwE2UjeC2wEiyxAA9DVVixDw9DsAFhQrAPK1mwAEOwAiVCsQwCJUKxDQIlQrABFiMgsAMlUFixAQBDYLAEJUKKiiCKI2GwDiohI7ABYSCKI2GwDiohG7EBAENgsAIlQrACJWGwDiohWbAMQ0ewDUNHYLACYiCwAFBYsEBgWWawAWMgsAtDY7gEAGIgsABQWLBAYFlmsAFjYLEAABMjRLABQ7AAPrIBAQFDYEItsBMsALEAAkVUWLAPI0IgRbALI0KwCiOwAWBCIGCwAWG1EBABAA4AQkKKYLESBiuwcisbIlktsBQssQATKy2wFSyxARMrLbAWLLECEystsBcssQMTKy2wGCyxBBMrLbAZLLEFEystsBossQYTKy2wGyyxBxMrLbAcLLEIEystsB0ssQkTKy2wHiwAsA0rsQACRVRYsA8jQiBFsAsjQrAKI7ABYEIgYLABYbUQEAEADgBCQopgsRIGK7ByKxsiWS2wHyyxAB4rLbAgLLEBHistsCEssQIeKy2wIiyxAx4rLbAjLLEEHistsCQssQUeKy2wJSyxBh4rLbAmLLEHHistsCcssQgeKy2wKCyxCR4rLbApLCA8sAFgLbAqLCBgsBBgIEMjsAFgQ7ACJWGwAWCwKSohLbArLLAqK7AqKi2wLCwgIEcgILALQ2O4BABiILAAUFiwQGBZZrABY2AjYTgjIIpVWCBHICCwC0NjuAQAYiCwAFBYsEBgWWawAWNgI2E4GyFZLbAtLACxAAJFVFiwARawLCqwARUwGyJZLbAuLACwDSuxAAJFVFiwARawLCqwARUwGyJZLbAvLCA1sAFgLbAwLACwAUVjuAQAYiCwAFBYsEBgWWawAWOwASuwC0NjuAQAYiCwAFBYsEBgWWawAWOwASuwABa0AAAAAABEPiM4sS8BFSotsDEsIDwgRyCwC0NjuAQAYiCwAFBYsEBgWWawAWNgsABDYTgtsDIsLhc8LbAzLCA8IEcgsAtDY7gEAGIgsABQWLBAYFlmsAFjYLAAQ2GwAUNjOC2wNCyxAgAWJSAuIEewACNCsAIlSYqKRyNHI2EgWGIbIVmwASNCsjMBARUUKi2wNSywABawBCWwBCVHI0cjYbAJQytlii4jICA8ijgtsDYssAAWsAQlsAQlIC5HI0cjYSCwBCNCsAlDKyCwYFBYILBAUVizAiADIBuzAiYDGllCQiMgsAhDIIojRyNHI2EjRmCwBEOwAmIgsABQWLBAYFlmsAFjYCCwASsgiophILACQ2BkI7ADQ2FkUFiwAkNhG7ADQ2BZsAMlsAJiILAAUFiwQGBZZrABY2EjICCwBCYjRmE4GyOwCENGsAIlsAhDRyNHI2FgILAEQ7ACYiCwAFBYsEBgWWawAWNgIyCwASsjsARDYLABK7AFJWGwBSWwAmIgsABQWLBAYFlmsAFjsAQmYSCwBCVgZCOwAyVgZFBYIRsjIVkjICCwBCYjRmE4WS2wNyywABYgICCwBSYgLkcjRyNhIzw4LbA4LLAAFiCwCCNCICAgRiNHsAErI2E4LbA5LLAAFrADJbACJUcjRyNhsABUWC4gPCMhG7ACJbACJUcjRyNhILAFJbAEJUcjRyNhsAYlsAUlSbACJWG5CAAIAGNjIyBYYhshWWO4BABiILAAUFiwQGBZZrABY2AjLiMgIDyKOCMhWS2wOiywABYgsAhDIC5HI0cjYSBgsCBgZrACYiCwAFBYsEBgWWawAWMjICA8ijgtsDssIyAuRrACJUZSWCA8WS6xKwEUKy2wPCwjIC5GsAIlRlBYIDxZLrErARQrLbA9LCMgLkawAiVGUlggPFkjIC5GsAIlRlBYIDxZLrErARQrLbA+LLA1KyMgLkawAiVGUlggPFkusSsBFCstsD8ssDYriiAgPLAEI0KKOCMgLkawAiVGUlggPFkusSsBFCuwBEMusCsrLbBALLAAFrAEJbAEJiAuRyNHI2GwCUMrIyA8IC4jOLErARQrLbBBLLEIBCVCsAAWsAQlsAQlIC5HI0cjYSCwBCNCsAlDKyCwYFBYILBAUVizAiADIBuzAiYDGllCQiMgR7AEQ7ACYiCwAFBYsEBgWWawAWNgILABKyCKimEgsAJDYGQjsANDYWRQWLACQ2EbsANDYFmwAyWwAmIgsABQWLBAYFlmsAFjYbACJUZhOCMgPCM4GyEgIEYjR7ABKyNhOCFZsSsBFCstsEIssDUrLrErARQrLbBDLLA2KyEjICA8sAQjQiM4sSsBFCuwBEMusCsrLbBELLAAFSBHsAAjQrIAAQEVFBMusDEqLbBFLLAAFSBHsAAjQrIAAQEVFBMusDEqLbBGLLEAARQTsDIqLbBHLLA0Ki2wSCywABZFIyAuIEaKI2E4sSsBFCstsEkssAgjQrBIKy2wSiyyAABBKy2wSyyyAAFBKy2wTCyyAQBBKy2wTSyyAQFBKy2wTiyyAABCKy2wTyyyAAFCKy2wUCyyAQBCKy2wUSyyAQFCKy2wUiyyAAA+Ky2wUyyyAAE+Ky2wVCyyAQA+Ky2wVSyyAQE+Ky2wViyyAABAKy2wVyyyAAFAKy2wWCyyAQBAKy2wWSyyAQFAKy2wWiyyAABDKy2wWyyyAAFDKy2wXCyyAQBDKy2wXSyyAQFDKy2wXiyyAAA/Ky2wXyyyAAE/Ky2wYCyyAQA/Ky2wYSyyAQE/Ky2wYiywNysusSsBFCstsGMssDcrsDsrLbBkLLA3K7A8Ky2wZSywABawNyuwPSstsGYssDgrLrErARQrLbBnLLA4K7A7Ky2waCywOCuwPCstsGkssDgrsD0rLbBqLLA5Ky6xKwEUKy2wayywOSuwOystsGwssDkrsDwrLbBtLLA5K7A9Ky2wbiywOisusSsBFCstsG8ssDorsDsrLbBwLLA6K7A8Ky2wcSywOiuwPSstsHIsswkEAgNFWCEbIyFZQiuwCGWwAyRQeLABFTAtAEu4AMhSWLEBAY5ZsAG5CAAIAGNwsQAFQrIAAQAqsQAFQrMKAgEIKrEABUKzDgABCCqxAAZCugLAAAEACSqxAAdCugBAAAEACSqxAwBEsSQBiFFYsECIWLEDZESxJgGIUVi6CIAAAQRAiGNUWLEDAERZWVlZswwCAQwquAH/hbAEjbECAEQAAA==') format('truetype'); + src: url('data:application/octet-stream;base64,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') format('woff'), + url('data:application/octet-stream;base64,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') format('truetype'); } /* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */ /* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */ @@ -17,7 +17,7 @@ @media screen and (-webkit-min-device-pixel-ratio:0) { @font-face { font-family: 'fontello'; - src: url('../font/fontello.svg?36468641#fontello') format('svg'); + src: url('../font/fontello.svg?46746090#fontello') format('svg'); } } */ @@ -62,5 +62,7 @@ .icon-cog:before { content: '\e807'; } /* '' */ .icon-spin3:before { content: '\e832'; } /* '' */ .icon-spin4:before { content: '\e834'; } /* '' */ +.icon-menu:before { content: '\f0c9'; } /* '' */ .icon-reply:before { content: '\f112'; } /* '' */ -.icon-binoculars:before { content: '\f1e5'; } /* '' */ \ No newline at end of file +.icon-binoculars:before { content: '\f1e5'; } /* '' */ +.icon-user-plus:before { content: '\f234'; } /* '' */ \ No newline at end of file diff --git a/static/font/css/fontello-ie7-codes.css b/static/font/css/fontello-ie7-codes.css index 9bd3bc9e..dfab853a 100644 --- a/static/font/css/fontello-ie7-codes.css +++ b/static/font/css/fontello-ie7-codes.css @@ -9,5 +9,7 @@ .icon-cog { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } .icon-spin3 { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } .icon-spin4 { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } +.icon-menu { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } .icon-reply { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } -.icon-binoculars { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } \ No newline at end of file +.icon-binoculars { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } +.icon-user-plus { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } \ No newline at end of file diff --git a/static/font/css/fontello-ie7.css b/static/font/css/fontello-ie7.css index a5745239..3e93ecd2 100644 --- a/static/font/css/fontello-ie7.css +++ b/static/font/css/fontello-ie7.css @@ -20,5 +20,7 @@ .icon-cog { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } .icon-spin3 { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } .icon-spin4 { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } +.icon-menu { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } .icon-reply { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } -.icon-binoculars { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } \ No newline at end of file +.icon-binoculars { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } +.icon-user-plus { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } \ No newline at end of file diff --git a/static/font/css/fontello.css b/static/font/css/fontello.css index 7b1fbd0c..81250ae3 100644 --- a/static/font/css/fontello.css +++ b/static/font/css/fontello.css @@ -1,11 +1,11 @@ @font-face { font-family: 'fontello'; - src: url('../font/fontello.eot?90538621'); - src: url('../font/fontello.eot?90538621#iefix') format('embedded-opentype'), - url('../font/fontello.woff2?90538621') format('woff2'), - url('../font/fontello.woff?90538621') format('woff'), - url('../font/fontello.ttf?90538621') format('truetype'), - url('../font/fontello.svg?90538621#fontello') format('svg'); + src: url('../font/fontello.eot?79576261'); + src: url('../font/fontello.eot?79576261#iefix') format('embedded-opentype'), + url('../font/fontello.woff2?79576261') format('woff2'), + url('../font/fontello.woff?79576261') format('woff'), + url('../font/fontello.ttf?79576261') format('truetype'), + url('../font/fontello.svg?79576261#fontello') format('svg'); font-weight: normal; font-style: normal; } @@ -15,7 +15,7 @@ @media screen and (-webkit-min-device-pixel-ratio:0) { @font-face { font-family: 'fontello'; - src: url('../font/fontello.svg?90538621#fontello') format('svg'); + src: url('../font/fontello.svg?79576261#fontello') format('svg'); } } */ @@ -65,5 +65,7 @@ .icon-cog:before { content: '\e807'; } /* '' */ .icon-spin3:before { content: '\e832'; } /* '' */ .icon-spin4:before { content: '\e834'; } /* '' */ +.icon-menu:before { content: '\f0c9'; } /* '' */ .icon-reply:before { content: '\f112'; } /* '' */ -.icon-binoculars:before { content: '\f1e5'; } /* '' */ \ No newline at end of file +.icon-binoculars:before { content: '\f1e5'; } /* '' */ +.icon-user-plus:before { content: '\f234'; } /* '' */ \ No newline at end of file diff --git a/static/font/demo.html b/static/font/demo.html index 98b49a84..02fb5d79 100644 --- a/static/font/demo.html +++ b/static/font/demo.html @@ -229,11 +229,11 @@ body { } @font-face { font-family: 'fontello'; - src: url('./font/fontello.eot?15442171'); - src: url('./font/fontello.eot?15442171#iefix') format('embedded-opentype'), - url('./font/fontello.woff?15442171') format('woff'), - url('./font/fontello.ttf?15442171') format('truetype'), - url('./font/fontello.svg?15442171#fontello') format('svg'); + src: url('./font/fontello.eot?13861244'); + src: url('./font/fontello.eot?13861244#iefix') format('embedded-opentype'), + url('./font/fontello.woff?13861244') format('woff'), + url('./font/fontello.ttf?13861244') format('truetype'), + url('./font/fontello.svg?13861244#fontello') format('svg'); font-weight: normal; font-style: normal; } @@ -315,8 +315,12 @@ body {
icon-spin30xe832
icon-spin40xe834
+
icon-menu0xf0c9
icon-reply0xf112
+
+
icon-binoculars0xf1e5
+
icon-user-plus0xf234
diff --git a/static/font/font/fontello.eot b/static/font/font/fontello.eot index 4050fa3b..4573d823 100644 Binary files a/static/font/font/fontello.eot and b/static/font/font/fontello.eot differ diff --git a/static/font/font/fontello.svg b/static/font/font/fontello.svg index f1e8b9fc..98105a87 100644 --- a/static/font/font/fontello.svg +++ b/static/font/font/fontello.svg @@ -26,9 +26,13 @@ + + + + \ No newline at end of file diff --git a/static/font/font/fontello.ttf b/static/font/font/fontello.ttf index bec32f07..c3bfb92a 100644 Binary files a/static/font/font/fontello.ttf and b/static/font/font/fontello.ttf differ diff --git a/static/font/font/fontello.woff b/static/font/font/fontello.woff index 245e1d2f..dced1f8c 100644 Binary files a/static/font/font/fontello.woff and b/static/font/font/fontello.woff differ diff --git a/static/font/font/fontello.woff2 b/static/font/font/fontello.woff2 index 9ec54aa4..b91fcbd7 100644 Binary files a/static/font/font/fontello.woff2 and b/static/font/font/fontello.woff2 differ diff --git a/static/timeago.json b/static/timeago.json new file mode 100644 index 00000000..b6f669c2 --- /dev/null +++ b/static/timeago.json @@ -0,0 +1,10 @@ +[ + "now", + ["%ss", "%ss"], + ["%smin", "%smin"], + ["%sh", "%sh"], + ["%sd", "%sd"], + ["%sw", "%sw"], + ["%sm", "%sm"], + ["%sy", "%sy"] +] diff --git a/test/unit/specs/modules/statuses.spec.js b/test/unit/specs/modules/statuses.spec.js index 891423ca..d25cc108 100644 --- a/test/unit/specs/modules/statuses.spec.js +++ b/test/unit/specs/modules/statuses.spec.js @@ -125,18 +125,19 @@ describe('The Statuses module', () => { it('removes statuses by tag on deletion', () => { const state = cloneDeep(defaultState) const status = makeMockStatus({id: 1}) + const otherStatus = makeMockStatus({id: 3}) status.uri = 'xxx' const deletion = makeMockStatus({id: 2, is_post_verb: false}) deletion.text = 'Dolus deleted notice {{tag:gs.smuglo.li,2016-11-18:noticeId=1038007:objectType=note}}.' deletion.uri = 'xxx' - mutations.addNewStatuses(state, { statuses: [status], showImmediately: true, timeline: 'public' }) + mutations.addNewStatuses(state, { statuses: [status, otherStatus], showImmediately: true, timeline: 'public' }) mutations.addNewStatuses(state, { statuses: [deletion], showImmediately: true, timeline: 'public' }) - expect(state.allStatuses).to.eql([]) - expect(state.timelines.public.statuses).to.eql([]) - expect(state.timelines.public.visibleStatuses).to.eql([]) - expect(state.timelines.public.maxId).to.eql(2) + expect(state.allStatuses).to.eql([otherStatus]) + expect(state.timelines.public.statuses).to.eql([otherStatus]) + expect(state.timelines.public.visibleStatuses).to.eql([otherStatus]) + expect(state.timelines.public.maxId).to.eql(3) }) it('does not update the maxId when the noIdUpdate flag is set', () => { @@ -319,6 +320,36 @@ describe('The Statuses module', () => { expect(state.notifications[0].type).to.eql('mention') }) + it('removes a notification when the notice gets removed', () => { + const user = { id: 1 } + const state = cloneDeep(defaultState) + const status = makeMockStatus({id: 1}) + const otherStatus = makeMockStatus({id: 3}) + const mentionedStatus = makeMockStatus({id: 2}) + mentionedStatus.attentions = [user] + mentionedStatus.uri = 'xxx' + otherStatus.attentions = [user] + + const deletion = makeMockStatus({id: 4, is_post_verb: false}) + deletion.text = 'Dolus deleted notice {{tag:gs.smuglo.li,2016-11-18:noticeId=1038007:objectType=note}}.' + deletion.uri = 'xxx' + + mutations.addNewStatuses(state, { statuses: [status, otherStatus], user }) + + expect(state.notifications.length).to.eql(1) + + mutations.addNewStatuses(state, { statuses: [mentionedStatus], user }) + expect(state.allStatuses.length).to.eql(3) + expect(state.notifications.length).to.eql(2) + expect(state.notifications[1].status).to.eql(mentionedStatus) + expect(state.notifications[1].action).to.eql(mentionedStatus) + expect(state.notifications[1].type).to.eql('mention') + + mutations.addNewStatuses(state, { statuses: [deletion], user }) + expect(state.allStatuses.length).to.eql(2) + expect(state.notifications.length).to.eql(1) + }) + it('adds the message to mentions when you are mentioned', () => { const user = { id: 1 } const state = cloneDeep(defaultState) diff --git a/yarn.lock b/yarn.lock index 6249966e..b0c3e63e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5713,9 +5713,9 @@ vue-loader@^11.1.0: vue-style-loader "^2.0.0" vue-template-es2015-compiler "^1.2.2" -vue-router@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-2.2.1.tgz#b027f9fac2cf13462725e843d6dc631b6aa077f6" +vue-router@^2.5.3: + version "2.5.3" + resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-2.5.3.tgz#073783f564b6aece6c8a59c63e298dc2aabfb51b" vue-style-loader@^2.0.0: version "2.0.0" @@ -5724,9 +5724,9 @@ vue-style-loader@^2.0.0: hash-sum "^1.0.2" loader-utils "^0.2.7" -vue-template-compiler@^2.1.10: - version "2.1.10" - resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.1.10.tgz#cb89643adc395e97435585522e43d0a9b1913257" +vue-template-compiler@^2.3.4: + version "2.3.4" + resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.3.4.tgz#5a88ac2c5e4d5d6218e6aa80e7e221fb7e67894c" dependencies: de-indent "^1.0.2" he "^1.1.0" @@ -5739,13 +5739,13 @@ vue-timeago@^3.1.2: version "3.2.0" resolved "https://registry.yarnpkg.com/vue-timeago/-/vue-timeago-3.2.0.tgz#73fd0635de6ea4ecfbbce035b2e44035d806fba1" -vue@^2.1.0: - version "2.1.10" - resolved "https://registry.yarnpkg.com/vue/-/vue-2.1.10.tgz#c9235ca48c7925137be5807832ac4e3ac180427b" +vue@^2.3.4: + version "2.3.4" + resolved "https://registry.yarnpkg.com/vue/-/vue-2.3.4.tgz#5ec3b87a191da8090bbef56b7cfabd4158038171" -vuex@^2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/vuex/-/vuex-2.1.2.tgz#15d2da62dd6ff59c071f0a91cd4f434eacf6ca6c" +vuex@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/vuex/-/vuex-2.3.1.tgz#cde8e997c1f9957719bc7dea154f9aa691d981a6" watchpack@^0.2.1: version "0.2.9"