diff --git a/package.json b/package.json index 43907f3e..30a317b2 100644 --- a/package.json +++ b/package.json @@ -24,11 +24,13 @@ "localforage": "^1.5.0", "object-path": "^0.11.3", "phoenix": "^1.3.0", + "popper.js": "^1.14.7", "sanitize-html": "^1.13.0", + "v-click-outside": "^2.1.1", "vue": "^2.5.13", "vue-chat-scroll": "^1.2.1", - "vue-compose": "^0.7.1", "vue-i18n": "^7.3.2", + "vue-popperjs": "^2.0.3", "vue-router": "^3.0.1", "vue-template-compiler": "^2.3.4", "vue-timeago": "^3.1.2", diff --git a/src/App.scss b/src/App.scss index 5fc0dd27..b1c65ade 100644 --- a/src/App.scss +++ b/src/App.scss @@ -101,6 +101,14 @@ button { background-color: $fallback--bg; background-color: var(--bg, $fallback--bg) } + + &.danger { + // TODO: add better color variable + color: $fallback--text; + color: var(--alertErrorPanelText, $fallback--text); + background-color: $fallback--alertError; + background-color: var(--alertError, $fallback--alertError); + } } label.select { diff --git a/src/boot/after_store.js b/src/boot/after_store.js index f2c1aa0f..603de348 100644 --- a/src/boot/after_store.js +++ b/src/boot/after_store.js @@ -171,9 +171,10 @@ const getCustomEmoji = async ({ store }) => { try { const res = await window.fetch('/api/pleroma/emoji.json') if (res.ok) { - const values = await res.json() + const result = await res.json() + const values = Array.isArray(result) ? Object.assign({}, ...result) : result const emoji = Object.keys(values).map((key) => { - return { shortcode: key, image_url: values[key] } + return { shortcode: key, image_url: values[key].image_url || values[key] } }) store.dispatch('setInstanceOption', { name: 'customEmoji', value: emoji }) store.dispatch('setInstanceOption', { name: 'pleromaBackend', value: true }) @@ -211,6 +212,7 @@ const getNodeInfo = async ({ store }) => { const frontendVersion = window.___pleromafe_commit_hash store.dispatch('setInstanceOption', { name: 'frontendVersion', value: frontendVersion }) + store.dispatch('setInstanceOption', { name: 'tagPolicyAvailable', value: metadata.federation.mrf_policies.includes('TagPolicy') }) } else { throw (res) } diff --git a/src/components/autosuggest/autosuggest.js b/src/components/autosuggest/autosuggest.js new file mode 100644 index 00000000..d4efe912 --- /dev/null +++ b/src/components/autosuggest/autosuggest.js @@ -0,0 +1,52 @@ +const debounceMilliseconds = 500 + +export default { + props: { + query: { // function to query results and return a promise + type: Function, + required: true + }, + filter: { // function to filter results in real time + type: Function + }, + placeholder: { + type: String, + default: 'Search...' + } + }, + data () { + return { + term: '', + timeout: null, + results: [], + resultsVisible: false + } + }, + computed: { + filtered () { + return this.filter ? this.filter(this.results) : this.results + } + }, + watch: { + term (val) { + this.fetchResults(val) + } + }, + methods: { + fetchResults (term) { + clearTimeout(this.timeout) + this.timeout = setTimeout(() => { + this.results = [] + if (term) { + this.query(term).then((results) => { this.results = results }) + } + }, debounceMilliseconds) + }, + onInputClick () { + this.resultsVisible = true + }, + onClickOutside () { + this.resultsVisible = false + } + } +} diff --git a/src/components/autosuggest/autosuggest.vue b/src/components/autosuggest/autosuggest.vue new file mode 100644 index 00000000..91657a2d --- /dev/null +++ b/src/components/autosuggest/autosuggest.vue @@ -0,0 +1,45 @@ + + + + + diff --git a/src/components/basic_user_card/basic_user_card.vue b/src/components/basic_user_card/basic_user_card.vue index 8afe8b44..48de6678 100644 --- a/src/components/basic_user_card/basic_user_card.vue +++ b/src/components/basic_user_card/basic_user_card.vue @@ -24,19 +24,11 @@ diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js index 69058bf6..30600f73 100644 --- a/src/components/conversation/conversation.js +++ b/src/components/conversation/conversation.js @@ -1,5 +1,4 @@ -import { reduce, filter, findIndex } from 'lodash' -import { set } from 'vue' +import { reduce, filter, findIndex, clone } from 'lodash' import Status from '../status/status.vue' const sortById = (a, b) => { @@ -36,8 +35,7 @@ const conversation = { data () { return { highlight: null, - expanded: false, - converationStatusIds: [] + expanded: false } }, props: [ @@ -54,15 +52,6 @@ const conversation = { status () { return this.statusoid }, - idsToShow () { - if (this.converationStatusIds.length > 0) { - return this.converationStatusIds - } else if (this.statusId) { - return [this.statusId] - } else { - return [] - } - }, statusId () { if (this.statusoid.retweeted_status) { return this.statusoid.retweeted_status.id @@ -70,6 +59,13 @@ const conversation = { return this.statusoid.id } }, + conversationId () { + if (this.statusoid.retweeted_status) { + return this.statusoid.retweeted_status.statusnet_conversation_id + } else { + return this.statusoid.statusnet_conversation_id + } + }, conversation () { if (!this.status) { return [] @@ -79,12 +75,7 @@ const conversation = { return [this.status] } - const statusesObject = this.$store.state.statuses.allStatusesObject - const conversation = this.idsToShow.reduce((acc, id) => { - acc.push(statusesObject[id]) - return acc - }, []) - + const conversation = clone(this.$store.state.statuses.conversationsObject[this.conversationId]) const statusIndex = findIndex(conversation, { id: this.statusId }) if (statusIndex !== -1) { conversation[statusIndex] = this.status @@ -131,10 +122,6 @@ const conversation = { .then(({ancestors, descendants}) => { this.$store.dispatch('addNewStatuses', { statuses: ancestors }) this.$store.dispatch('addNewStatuses', { statuses: descendants }) - set(this, 'converationStatusIds', [].concat( - ancestors.map(_ => _.id).filter(_ => _ !== this.statusId), - this.statusId, - descendants.map(_ => _.id).filter(_ => _ !== this.statusId))) }) .then(() => this.setHighlight(this.statusId)) } else { diff --git a/src/components/conversation/conversation.vue b/src/components/conversation/conversation.vue index c39a3ed9..c3bbb597 100644 --- a/src/components/conversation/conversation.vue +++ b/src/components/conversation/conversation.vue @@ -13,7 +13,7 @@ :key="status.id" :inlineExpanded="collapsable" :statusoid="status" - :expandable='!expanded' + :expandable='!isExpanded' :focused="focused(status.id)" :inConversation="isExpanded" :highlight="getHighlight()" diff --git a/src/components/delete_button/delete_button.js b/src/components/delete_button/delete_button.js index f2920666..22f24625 100644 --- a/src/components/delete_button/delete_button.js +++ b/src/components/delete_button/delete_button.js @@ -10,7 +10,11 @@ const DeleteButton = { }, computed: { currentUser () { return this.$store.state.users.currentUser }, - canDelete () { return this.currentUser && this.currentUser.rights.delete_others_notice || this.status.user.id === this.currentUser.id } + canDelete () { + if (!this.currentUser) { return } + const superuser = this.currentUser.rights.moderator || this.currentUser.rights.admin + return superuser || this.status.user.id === this.currentUser.id + } } } diff --git a/src/components/dialog_modal/dialog_modal.js b/src/components/dialog_modal/dialog_modal.js new file mode 100644 index 00000000..f14e3fe9 --- /dev/null +++ b/src/components/dialog_modal/dialog_modal.js @@ -0,0 +1,14 @@ +const DialogModal = { + props: { + darkOverlay: { + default: true, + type: Boolean + }, + onCancel: { + default: () => {}, + type: Function + } + } +} + +export default DialogModal diff --git a/src/components/dialog_modal/dialog_modal.vue b/src/components/dialog_modal/dialog_modal.vue new file mode 100644 index 00000000..7621fb20 --- /dev/null +++ b/src/components/dialog_modal/dialog_modal.vue @@ -0,0 +1,92 @@ + + + + + diff --git a/src/components/follow_card/follow_card.js b/src/components/follow_card/follow_card.js index ac4e265a..dc4a0d41 100644 --- a/src/components/follow_card/follow_card.js +++ b/src/components/follow_card/follow_card.js @@ -10,8 +10,7 @@ const FollowCard = { data () { return { inProgress: false, - requestSent: false, - updated: false + requestSent: false } }, components: { @@ -19,10 +18,8 @@ const FollowCard = { RemoteFollow }, computed: { - isMe () { return this.$store.state.users.currentUser.id === this.user.id }, - following () { return this.updated ? this.updated.following : this.user.following }, - showFollow () { - return !this.following || this.updated && !this.updated.following + isMe () { + return this.$store.state.users.currentUser.id === this.user.id }, loggedIn () { return this.$store.state.users.currentUser @@ -31,17 +28,15 @@ const FollowCard = { methods: { followUser () { this.inProgress = true - requestFollow(this.user, this.$store).then(({ sent, updated }) => { + requestFollow(this.user, this.$store).then(({ sent }) => { this.inProgress = false this.requestSent = sent - this.updated = updated }) }, unfollowUser () { this.inProgress = true - requestUnfollow(this.user, this.$store).then(({ updated }) => { + requestUnfollow(this.user, this.$store).then(() => { this.inProgress = false - this.updated = updated }) } } diff --git a/src/components/follow_card/follow_card.vue b/src/components/follow_card/follow_card.vue index 9f314fd3..94e2836f 100644 --- a/src/components/follow_card/follow_card.vue +++ b/src/components/follow_card/follow_card.vue @@ -4,34 +4,38 @@ {{ isMe ? $t('user_card.its_you') : $t('user_card.follows_you') }} -
- -
- - + + diff --git a/src/components/follow_requests/follow_requests.vue b/src/components/follow_requests/follow_requests.vue index b83c2d68..36901fb4 100644 --- a/src/components/follow_requests/follow_requests.vue +++ b/src/components/follow_requests/follow_requests.vue @@ -4,7 +4,7 @@ {{$t('nav.friend_requests')}}
- +
diff --git a/src/components/list/list.vue b/src/components/list/list.vue new file mode 100644 index 00000000..7136915b --- /dev/null +++ b/src/components/list/list.vue @@ -0,0 +1,42 @@ + + + + + diff --git a/src/components/login_form/login_form.js b/src/components/login_form/login_form.js index fb6dc651..dc917e47 100644 --- a/src/components/login_form/login_form.js +++ b/src/components/login_form/login_form.js @@ -31,15 +31,19 @@ const LoginForm = { username: this.user.username, password: this.user.password } - ).then((result) => { + ).then(async (result) => { if (result.error) { this.authError = result.error this.user.password = '' return } this.$store.commit('setToken', result.access_token) - this.$store.dispatch('loginUser', result.access_token) - this.$router.push({name: 'friends'}) + try { + await this.$store.dispatch('loginUser', result.access_token) + this.$router.push({name: 'friends'}) + } catch (e) { + console.log(e) + } }) }) }, diff --git a/src/components/moderation_tools/moderation_tools.js b/src/components/moderation_tools/moderation_tools.js new file mode 100644 index 00000000..3eedeaa1 --- /dev/null +++ b/src/components/moderation_tools/moderation_tools.js @@ -0,0 +1,106 @@ +import DialogModal from '../dialog_modal/dialog_modal.vue' +import Popper from 'vue-popperjs/src/component/popper.js.vue' + +const FORCE_NSFW = 'mrf_tag:media-force-nsfw' +const STRIP_MEDIA = 'mrf_tag:media-strip' +const FORCE_UNLISTED = 'mrf_tag:force-unlisted' +const DISABLE_REMOTE_SUBSCRIPTION = 'mrf_tag:disable-remote-subscription' +const DISABLE_ANY_SUBSCRIPTION = 'mrf_tag:disable-any-subscription' +const SANDBOX = 'mrf_tag:sandbox' +const QUARANTINE = 'mrf_tag:quarantine' + +const ModerationTools = { + props: [ + 'user' + ], + data () { + return { + showDropDown: false, + tags: { + FORCE_NSFW, + STRIP_MEDIA, + FORCE_UNLISTED, + DISABLE_REMOTE_SUBSCRIPTION, + DISABLE_ANY_SUBSCRIPTION, + SANDBOX, + QUARANTINE + }, + showDeleteUserDialog: false + } + }, + components: { + DialogModal, + Popper + }, + computed: { + tagsSet () { + return new Set(this.user.tags) + }, + hasTagPolicy () { + return this.$store.state.instance.tagPolicyAvailable + } + }, + methods: { + toggleMenu () { + this.showDropDown = !this.showDropDown + }, + hasTag (tagName) { + return this.tagsSet.has(tagName) + }, + toggleTag (tag) { + const store = this.$store + if (this.tagsSet.has(tag)) { + store.state.api.backendInteractor.untagUser(this.user, tag).then(response => { + if (!response.ok) { return } + store.commit('untagUser', {user: this.user, tag}) + }) + } else { + store.state.api.backendInteractor.tagUser(this.user, tag).then(response => { + if (!response.ok) { return } + store.commit('tagUser', {user: this.user, tag}) + }) + } + }, + toggleRight (right) { + const store = this.$store + if (this.user.rights[right]) { + store.state.api.backendInteractor.deleteRight(this.user, right).then(response => { + if (!response.ok) { return } + store.commit('updateRight', {user: this.user, right: right, value: false}) + }) + } else { + store.state.api.backendInteractor.addRight(this.user, right).then(response => { + if (!response.ok) { return } + store.commit('updateRight', {user: this.user, right: right, value: true}) + }) + } + }, + toggleActivationStatus () { + const store = this.$store + const status = !!this.user.deactivated + store.state.api.backendInteractor.setActivationStatus(this.user, status).then(response => { + if (!response.ok) { return } + store.commit('updateActivationStatus', {user: this.user, status: status}) + }) + }, + deleteUserDialog (show) { + this.showDeleteUserDialog = show + }, + deleteUser () { + const store = this.$store + const user = this.user + const {id, name} = user + store.state.api.backendInteractor.deleteUser(user) + .then(e => { + this.$store.dispatch('markStatusesAsDeleted', status => user.id === status.user.id) + const isProfile = this.$route.name === 'external-user-profile' || this.$route.name === 'user-profile' + const isTargetUser = this.$route.params.name === name || this.$route.params.id === id + if (isProfile && isTargetUser) { + window.history.back() + } + }) + } + } +} + +export default ModerationTools diff --git a/src/components/moderation_tools/moderation_tools.vue b/src/components/moderation_tools/moderation_tools.vue new file mode 100644 index 00000000..c24a2280 --- /dev/null +++ b/src/components/moderation_tools/moderation_tools.vue @@ -0,0 +1,158 @@ + + + + + diff --git a/src/components/notification/notification.js b/src/components/notification/notification.js index 42a48f3f..e59e7497 100644 --- a/src/components/notification/notification.js +++ b/src/components/notification/notification.js @@ -21,25 +21,28 @@ const Notification = { }, userProfileLink (user) { return generateProfileLink(user.id, user.screen_name, this.$store.state.instance.restrictedNicknames) + }, + getUser (notification) { + return this.$store.state.users.usersObject[notification.from_profile.id] } }, computed: { userClass () { - return highlightClass(this.notification.action.user) + return highlightClass(this.notification.from_profile) }, userStyle () { const highlight = this.$store.state.config.highlight - const user = this.notification.action.user + const user = this.notification.from_profile return highlightStyle(highlight[user.screen_name]) }, userInStore () { - return this.$store.getters.findUser(this.notification.action.user.id) + return this.$store.getters.findUser(this.notification.from_profile.id) }, user () { if (this.userInStore) { return this.userInStore } - return {} + return this.notification.from_profile } } } diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue index 8f532747..ae11d692 100644 --- a/src/components/notification/notification.vue +++ b/src/components/notification/notification.vue @@ -1,15 +1,20 @@ diff --git a/src/hocs/with_list/with_list.js b/src/hocs/with_list/with_list.js deleted file mode 100644 index 896f8fc8..00000000 --- a/src/hocs/with_list/with_list.js +++ /dev/null @@ -1,40 +0,0 @@ -import Vue from 'vue' -import map from 'lodash/map' -import isEmpty from 'lodash/isEmpty' -import './with_list.scss' - -const defaultEntryPropsGetter = entry => ({ entry }) -const defaultKeyGetter = entry => entry.id - -const withList = ({ - getEntryProps = defaultEntryPropsGetter, // function to accept entry and index values and return props to be passed into the item component - getKey = defaultKeyGetter // funciton to accept entry and index values and return key prop value -}) => (ItemComponent) => ( - Vue.component('withList', { - props: [ - 'entries', // array of entry - 'entryProps', // additional props to be passed into each entry - 'entryListeners' // additional event listeners to be passed into each entry - ], - render (createElement) { - return ( -
- {map(this.entries, (entry, index) => { - const props = { - key: getKey(entry, index), - props: { - ...this.$props.entryProps, - ...getEntryProps(entry, index) - }, - on: this.$props.entryListeners - } - return - })} - {isEmpty(this.entries) && this.$slots.empty &&
{this.$slots.empty}
} -
- ) - } - }) -) - -export default withList diff --git a/src/hocs/with_list/with_list.scss b/src/hocs/with_list/with_list.scss deleted file mode 100644 index c6e13d5b..00000000 --- a/src/hocs/with_list/with_list.scss +++ /dev/null @@ -1,6 +0,0 @@ -.with-list { - &-empty-content { - text-align: center; - padding: 10px; - } -} \ No newline at end of file diff --git a/src/hocs/with_load_more/with_load_more.scss b/src/hocs/with_load_more/with_load_more.scss index 1a0a9c40..4cefe2be 100644 --- a/src/hocs/with_load_more/with_load_more.scss +++ b/src/hocs/with_load_more/with_load_more.scss @@ -1,10 +1,16 @@ + +@import '../../_variables.scss'; + .with-load-more { &-footer { padding: 10px; text-align: center; + border-top: 1px solid; + border-top-color: $fallback--border; + border-top-color: var(--border, $fallback--border); .error { font-size: 14px; } } -} \ No newline at end of file +} diff --git a/src/i18n/cs.json b/src/i18n/cs.json index 020092a6..5f2f2b71 100644 --- a/src/i18n/cs.json +++ b/src/i18n/cs.json @@ -73,7 +73,8 @@ "content_type": { "text/plain": "Prostý text", "text/html": "HTML", - "text/markdown": "Markdown" + "text/markdown": "Markdown", + "text/bbcode": "BBCode" }, "content_warning": "Předmět (volitelný)", "default": "Právě jsem přistál v L.A.", diff --git a/src/i18n/en.json b/src/i18n/en.json index 1e82cd0a..711e8d31 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -22,7 +22,8 @@ "generic_error": "An error occured", "optional": "optional", "show_more": "Show more", - "show_less": "Show less" + "show_less": "Show less", + "cancel": "Cancel" }, "image_cropper": { "crop_picture": "Crop picture", @@ -76,7 +77,8 @@ "content_type": { "text/plain": "Plain text", "text/html": "HTML", - "text/markdown": "Markdown" + "text/markdown": "Markdown", + "text/bbcode": "BBCode" }, "content_warning": "Subject (optional)", "default": "Just landed in L.A.", @@ -111,6 +113,9 @@ "password_confirmation_match": "should be the same as password" } }, + "selectable_list": { + "select_all": "Select all" + }, "settings": { "app_name": "App name", "attachmentRadius": "Attachments", @@ -216,6 +221,8 @@ "reply_visibility_self": "Only show replies directed at me", "saving_err": "Error saving settings", "saving_ok": "Settings saved", + "search_user_to_block": "Search whom you want to block", + "search_user_to_mute": "Search whom you want to mute", "security_tab": "Security", "scope_copy": "Copy scope when replying (DMs are always copied)", "minimal_scopes_mode": "Minimize post scope selection options", @@ -403,7 +410,26 @@ "block_progress": "Blocking...", "unmute": "Unmute", "unmute_progress": "Unmuting...", - "mute_progress": "Muting..." + "mute_progress": "Muting...", + "admin_menu": { + "moderation": "Moderation", + "grant_admin": "Grant Admin", + "revoke_admin": "Revoke Admin", + "grant_moderator": "Grant Moderator", + "revoke_moderator": "Revoke Moderator", + "activate_account": "Activate account", + "deactivate_account": "Deactivate account", + "delete_account": "Delete account", + "force_nsfw": "Mark all posts as NSFW", + "strip_media": "Remove media from posts", + "force_unlisted": "Force posts to be unlisted", + "sandbox": "Force posts to be followers-only", + "disable_remote_subscription": "Disallow following user from remote instances", + "disable_any_subscription": "Disallow following user at all", + "quarantine": "Disallow user posts from federating", + "delete_user": "Delete user", + "delete_user_confirmation": "Are you absolutely sure? This action cannot be undone." + } }, "user_profile": { "timeline_title": "User Timeline", diff --git a/src/i18n/oc.json b/src/i18n/oc.json index 9214799d..a5826239 100644 --- a/src/i18n/oc.json +++ b/src/i18n/oc.json @@ -20,7 +20,10 @@ "submit": "Mandar", "more": "Mai", "generic_error": "Una error s’es producha", - "optional": "opcional" + "optional": "opcional", + "show_more": "Mostrar mai", + "show_less": "Mostrar mens", + "cancel": "Anullar" }, "image_cropper": { "crop_picture": "Talhar l’imatge", @@ -74,11 +77,13 @@ "content_type": { "text/plain": "Tèxte brut", "text/html": "HTML", - "text/markdown": "Markdown" + "text/markdown": "Markdown", + "text/bbcode": "BBCode" }, "content_warning": "Avís de contengut (opcional)", "default": "Escrivètz aquí vòstre estatut.", - "direct_warning": "Aquesta publicacion serà pas que visibla pels utilizaires mencionats.", + "direct_warning_to_all": "Aquesta publicacion serà pas que visibla pels utilizaires mencionats.", + "direct_warning_to_first_only": "Aquesta publicacion serà pas que visibla pels utilizaires mencionats a la debuta del messatge.", "posting": "Mandadís", "scope": { "direct": "Dirècte - Publicar pels utilizaires mencionats solament", @@ -108,6 +113,9 @@ "password_confirmation_match": "deu èsser lo meteis senhal" } }, + "selectable_list": { + "select_all": "O seleccionar tot" + }, "settings": { "app_name": "Nom de l’aplicacion", "attachmentRadius": "Pèças juntas", @@ -213,8 +221,11 @@ "reply_visibility_self": "Mostrar pas que las responsas que me son destinadas", "saving_err": "Error en enregistrant los paramètres", "saving_ok": "Paramètres enregistrats", - "scope_copy": "Copiar lo nivèl de confidencialitat per las responsas (Totjorn aissí pels Messatges Dirèctes)", + "search_user_to_block": "Cercatz qual volètz blocar", + "search_user_to_mute": "Cercatz qual volètz rescondre", "security_tab": "Seguretat", + "scope_copy": "Copiar lo nivèl de confidencialitat per las responsas (Totjorn aissí pels Messatges Dirèctes)", + "minimal_scopes_mode": "Minimizar lo nombre d’opcions per publicacion", "set_new_avatar": "Definir un nòu avatar", "set_new_profile_background": "Definir un nòu fons de perfil", "set_new_profile_banner": "Definir una nòva bandièra de perfil", @@ -349,6 +360,11 @@ "checkbox": "Ai legit los tèrmes e condicions d’utilizacion", "link": "un pichon ligam simpatic" } + }, + "version": { + "title": "Version", + "backend_version": "Version Backend", + "frontend_version": "Version Frontend" } }, "timeline": { @@ -394,7 +410,26 @@ "block_progress": "Blocatge...", "unmute": "Tornar mostrar", "unmute_progress": "Afichatge...", - "mute_progress": "A amagar..." + "mute_progress": "A amagar...", + "admin_menu": { + "moderation": "Moderacion", + "grant_admin": "Passar Admin", + "revoke_admin": "Revocar Admin", + "grant_moderator": "Passar Moderator", + "revoke_moderator": "Revocar Moderator", + "activate_account": "Activar lo compte", + "deactivate_account": "Desactivar lo compte", + "delete_account": "Suprimir lo compte", + "force_nsfw": "Marcar totas las publicacions coma sensiblas", + "strip_media": "Tirar los mèdias de las publicacions", + "force_unlisted": "Forçar las publicacions en pas-listadas", + "sandbox": "Forçar las publicacions en seguidors solament", + "disable_remote_subscription": "Desactivar lo seguiment d’utilizaire d’instàncias alonhadas", + "disable_any_subscription": "Desactivar tot seguiment", + "quarantine": "Defendre la federacion de las publicacions de l’utilizaire", + "delete_user": "Suprimir l’utilizaire", + "delete_user_confirmation": "Volètz vertadièrament far aquò ? Aquesta accion se pòt pas anullar." + } }, "user_profile": { "timeline_title": "Flux utilizaire", @@ -426,4 +461,4 @@ "TiB": "Tio" } } -} \ No newline at end of file +} diff --git a/src/i18n/pl.json b/src/i18n/pl.json index 8efce168..715e5d6e 100644 --- a/src/i18n/pl.json +++ b/src/i18n/pl.json @@ -74,7 +74,8 @@ "content_type": { "text/plain": "Czysty tekst", "text/html": "HTML", - "text/markdown": "Markdown" + "text/markdown": "Markdown", + "text/bbcode": "BBCode" }, "content_warning": "Temat (nieobowiązkowy)", "default": "Właśnie wróciłem z kościoła", @@ -431,4 +432,4 @@ "TiB": "TiB" } } -} \ No newline at end of file +} diff --git a/src/i18n/ru.json b/src/i18n/ru.json index 89aa43f4..5450f154 100644 --- a/src/i18n/ru.json +++ b/src/i18n/ru.json @@ -8,7 +8,8 @@ }, "general": { "apply": "Применить", - "submit": "Отправить" + "submit": "Отправить", + "cancel": "Отмена" }, "login": { "login": "Войти", @@ -311,7 +312,26 @@ "muted": "Игнорирую", "per_day": "в день", "remote_follow": "Читать удалённо", - "statuses": "Статусы" + "statuses": "Статусы", + "admin_menu": { + "moderation": "Опции модератора", + "grant_admin": "Сделать администратором", + "revoke_admin": "Забрать права администратора", + "grant_moderator": "Сделать модератором", + "revoke_moderator": "Забрать права модератора", + "activate_account": "Активировать аккаунт", + "deactivate_account": "Деактивировать аккаунт", + "delete_account": "Удалить аккаунт", + "force_nsfw": "Отмечать посты пользователя как NSFW", + "strip_media": "Убирать вложения из постов пользователя", + "force_unlisted": "Не добавлять посты в публичные ленты", + "sandbox": "Посты доступны только для подписчиков", + "disable_remote_subscription": "Запретить подписываться с удаленных серверов", + "disable_any_subscription": "Запретить подписываться на пользователя", + "quarantine": "Не федерировать посты пользователя", + "delete_user": "Удалить пользователя", + "delete_user_confirmation": "Вы уверены? Это действие нельзя отменить." + } }, "user_profile": { "timeline_title": "Лента пользователя" diff --git a/src/main.js b/src/main.js index 9ffc3727..725f5806 100644 --- a/src/main.js +++ b/src/main.js @@ -22,6 +22,7 @@ import pushNotifications from './lib/push_notifications_plugin.js' import messages from './i18n/messages.js' import VueChatScroll from 'vue-chat-scroll' +import VueClickOutside from 'v-click-outside' import afterStoreSetup from './boot/after_store.js' @@ -39,6 +40,7 @@ Vue.use(VueTimeago, { }) Vue.use(VueI18n) Vue.use(VueChatScroll) +Vue.use(VueClickOutside) const i18n = new VueI18n({ // By default, use the browser locale, we will update it if neccessary @@ -59,6 +61,11 @@ const persistedStateOptions = { const persistedState = await createPersistedState(persistedStateOptions) const store = new Vuex.Store({ modules: { + i18n: { + getters: { + i18n: () => i18n + } + }, interface: interfaceModule, instance: instanceModule, statuses: statusesModule, diff --git a/src/modules/api.js b/src/modules/api.js index 31cb55c6..7ed3edac 100644 --- a/src/modules/api.js +++ b/src/modules/api.js @@ -13,11 +13,11 @@ const api = { setBackendInteractor (state, backendInteractor) { state.backendInteractor = backendInteractor }, - addFetcher (state, {timeline, fetcher}) { - state.fetchers[timeline] = fetcher + addFetcher (state, { fetcherName, fetcher }) { + state.fetchers[fetcherName] = fetcher }, - removeFetcher (state, {timeline}) { - delete state.fetchers[timeline] + removeFetcher (state, { fetcherName }) { + delete state.fetchers[fetcherName] }, setWsToken (state, token) { state.wsToken = token @@ -33,17 +33,24 @@ const api = { } }, actions: { - startFetching (store, {timeline = 'friends', tag = false, userId = false}) { + startFetchingTimeline (store, { timeline = 'friends', tag = false, userId = false }) { // Don't start fetching if we already are. if (store.state.fetchers[timeline]) return - const fetcher = store.state.backendInteractor.startFetching({ timeline, store, userId, tag }) - store.commit('addFetcher', { timeline, fetcher }) + const fetcher = store.state.backendInteractor.startFetchingTimeline({ timeline, store, userId, tag }) + store.commit('addFetcher', { fetcherName: timeline, fetcher }) }, - stopFetching (store, timeline) { - const fetcher = store.state.fetchers[timeline] + startFetchingNotifications (store) { + // Don't start fetching if we already are. + if (store.state.fetchers['notifications']) return + + const fetcher = store.state.backendInteractor.startFetchingNotifications({ store }) + store.commit('addFetcher', { fetcherName: 'notifications', fetcher }) + }, + stopFetching (store, fetcherName) { + const fetcher = store.state.fetchers[fetcherName] window.clearInterval(fetcher) - store.commit('removeFetcher', {timeline}) + store.commit('removeFetcher', { fetcherName }) }, setWsToken (store, token) { store.commit('setWsToken', token) diff --git a/src/modules/interface.js b/src/modules/interface.js index 71554787..5b2762e5 100644 --- a/src/modules/interface.js +++ b/src/modules/interface.js @@ -48,7 +48,6 @@ const interfaceMod = { commit('setNotificationPermission', permission) }, setMobileLayout ({ commit }, value) { - console.log('setMobileLayout called') commit('setMobileLayout', value) } } diff --git a/src/modules/statuses.js b/src/modules/statuses.js index 8e0203e3..e70c2400 100644 --- a/src/modules/statuses.js +++ b/src/modules/statuses.js @@ -20,20 +20,22 @@ const emptyTl = (userId = 0) => ({ flushMarker: 0 }) +const emptyNotifications = () => ({ + desktopNotificationSilence: true, + maxId: 0, + minId: Number.POSITIVE_INFINITY, + data: [], + idStore: {}, + loading: false, + error: false +}) + export const defaultState = () => ({ allStatuses: [], allStatusesObject: {}, + conversationsObject: {}, maxId: 0, - notifications: { - desktopNotificationSilence: true, - maxId: 0, - minId: Number.POSITIVE_INFINITY, - data: [], - idStore: {}, - loading: false, - error: false, - fetcherId: null - }, + notifications: emptyNotifications(), favorites: new Set(), error: false, timelines: { @@ -111,6 +113,39 @@ const sortTimeline = (timeline) => { return timeline } +// Add status to the global storages (arrays and objects maintaining statuses) except timelines +const addStatusToGlobalStorage = (state, data) => { + const result = mergeOrAdd(state.allStatuses, state.allStatusesObject, data) + if (result.new) { + // Add to conversation + const status = result.item + const conversationsObject = state.conversationsObject + const conversationId = status.statusnet_conversation_id + if (conversationsObject[conversationId]) { + conversationsObject[conversationId].push(status) + } else { + set(conversationsObject, conversationId, [status]) + } + } + return result +} + +// Remove status from the global storages (arrays and objects maintaining statuses) except timelines +const removeStatusFromGlobalStorage = (state, status) => { + remove(state.allStatuses, { id: status.id }) + + // TODO: Need to remove from allStatusesObject? + + // Remove possible notification + remove(state.notifications.data, ({action: {id}}) => id === status.id) + + // Remove from conversation + const conversationId = status.statusnet_conversation_id + if (state.conversationsObject[conversationId]) { + remove(state.conversationsObject[conversationId], { id: status.id }) + } +} + const addNewStatuses = (state, { statuses, showImmediately = false, timeline, user = {}, noIdUpdate = false, userId }) => { // Sanity check if (!isArray(statuses)) { @@ -118,7 +153,6 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us } const allStatuses = state.allStatuses - const allStatusesObject = state.allStatusesObject const timelineObject = state.timelines[timeline] const maxNew = statuses.length > 0 ? maxBy(statuses, 'id').id : 0 @@ -141,7 +175,7 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us } const addStatus = (data, showImmediately, addToTimeline = true) => { - const result = mergeOrAdd(allStatuses, allStatusesObject, data) + const result = addStatusToGlobalStorage(state, data) const status = result.item if (result.new) { @@ -235,16 +269,13 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us }, 'deletion': (deletion) => { const uri = deletion.uri - - // Remove possible notification const status = find(allStatuses, {uri}) if (!status) { return } - remove(state.notifications.data, ({action: {id}}) => id === status.id) + removeStatusFromGlobalStorage(state, status) - remove(allStatuses, { uri }) if (timeline) { remove(timelineObject.statuses, { uri }) remove(timelineObject.visibleStatuses, { uri }) @@ -271,12 +302,12 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us } } -const addNewNotifications = (state, { dispatch, notifications, older, visibleNotificationTypes }) => { - const allStatuses = state.allStatuses - const allStatusesObject = state.allStatusesObject +const addNewNotifications = (state, { dispatch, notifications, older, visibleNotificationTypes, rootGetters }) => { each(notifications, (notification) => { - notification.action = mergeOrAdd(allStatuses, allStatusesObject, notification.action).item - notification.status = notification.status && mergeOrAdd(allStatuses, allStatusesObject, notification.status).item + if (notification.type !== 'follow') { + notification.action = addStatusToGlobalStorage(state, notification.action).item + notification.status = notification.status && addStatusToGlobalStorage(state, notification.status).item + } // Only add a new notification if we don't have one for the same action if (!state.notifications.idStore.hasOwnProperty(notification.id)) { @@ -292,15 +323,32 @@ const addNewNotifications = (state, { dispatch, notifications, older, visibleNot if ('Notification' in window && window.Notification.permission === 'granted') { const notifObj = {} - const action = notification.action - const title = action.user.name - notifObj.icon = action.user.profile_image_url - notifObj.body = action.text // there's a problem that it doesn't put a space before links tho + const status = notification.status + const title = notification.from_profile.name + notifObj.icon = notification.from_profile.profile_image_url + let i18nString + switch (notification.type) { + case 'like': + i18nString = 'favorited_you' + break + case 'repeat': + i18nString = 'repeated_you' + break + case 'follow': + i18nString = 'followed_you' + break + } + + if (i18nString) { + notifObj.body = rootGetters.i18n.t('notifications.' + i18nString) + } else { + notifObj.body = notification.status.text + } // Shows first attached non-nsfw image, if any. Should add configuration for this somehow... - if (action.attachments && action.attachments.length > 0 && !action.nsfw && - action.attachments[0].mimetype.startsWith('image/')) { - notifObj.image = action.attachments[0].url + if (status && status.attachments && status.attachments.length > 0 && !status.nsfw && + status.attachments[0].mimetype.startsWith('image/')) { + notifObj.image = status.attachments[0].url } if (!notification.seen && !state.notifications.desktopNotificationSilence && visibleNotificationTypes.includes(notification.type)) { @@ -340,9 +388,6 @@ export const mutations = { oldTimeline.visibleStatusesObject = {} each(oldTimeline.visibleStatuses, (status) => { oldTimeline.visibleStatusesObject[status.id] = status }) }, - setNotificationFetcher (state, { fetcherId }) { - state.notifications.fetcherId = fetcherId - }, resetStatuses (state) { const emptyState = defaultState() Object.entries(emptyState).forEach(([key, value]) => { @@ -352,6 +397,9 @@ export const mutations = { clearTimeline (state, { timeline }) { state.timelines[timeline] = emptyTl(state.timelines[timeline].userId) }, + clearNotifications (state) { + state.notifications = emptyNotifications() + }, setFavorited (state, { status, value }) { const newStatus = state.allStatusesObject[status.id] newStatus.favorited = value @@ -378,6 +426,13 @@ export const mutations = { const newStatus = state.allStatusesObject[status.id] newStatus.deleted = true }, + setManyDeleted (state, condition) { + Object.values(state.allStatusesObject).forEach(status => { + if (condition(status)) { + status.deleted = true + } + }) + }, setLoading (state, { timeline, value }) { state.timelines[timeline].loading = value }, @@ -413,8 +468,8 @@ const statuses = { addNewStatuses ({ rootState, commit }, { statuses, showImmediately = false, timeline = false, noIdUpdate = false, userId }) { commit('addNewStatuses', { statuses, showImmediately, timeline, noIdUpdate, user: rootState.users.currentUser, userId }) }, - addNewNotifications ({ rootState, commit, dispatch }, { notifications, older }) { - commit('addNewNotifications', { visibleNotificationTypes: visibleNotificationTypes(rootState), dispatch, notifications, older }) + addNewNotifications ({ rootState, commit, dispatch, rootGetters }, { notifications, older }) { + commit('addNewNotifications', { visibleNotificationTypes: visibleNotificationTypes(rootState), dispatch, notifications, older, rootGetters }) }, setError ({ rootState, commit }, { value }) { commit('setError', { value }) @@ -428,16 +483,13 @@ const statuses = { setNotificationsSilence ({ rootState, commit }, { value }) { commit('setNotificationsSilence', { value }) }, - stopFetchingNotifications ({ rootState, commit }) { - if (rootState.statuses.notifications.fetcherId) { - window.clearInterval(rootState.statuses.notifications.fetcherId) - } - commit('setNotificationFetcher', { fetcherId: null }) - }, deleteStatus ({ rootState, commit }, status) { commit('setDeleted', { status }) apiService.deleteStatus({ id: status.id, credentials: rootState.users.currentUser.credentials }) }, + markStatusesAsDeleted ({ commit }, condition) { + commit('setManyDeleted', condition) + }, favorite ({ rootState, commit }, status) { // Optimistic favoriting... commit('setFavorited', { status, value: true }) diff --git a/src/modules/users.js b/src/modules/users.js index 1a507d31..adcab233 100644 --- a/src/modules/users.js +++ b/src/modules/users.js @@ -1,5 +1,6 @@ import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js' -import { compact, map, each, merge, find, last } from 'lodash' +import userSearchApi from '../services/new_api/user_search.js' +import { compact, map, each, merge, last, concat, uniq } from 'lodash' import { set } from 'vue' import { registerPushNotifications, unregisterPushNotifications } from '../services/push/push.js' import oauthApi from '../services/new_api/oauth' @@ -32,11 +33,62 @@ const getNotificationPermission = () => { return Promise.resolve(Notification.permission) } +const blockUser = (store, id) => { + return store.rootState.api.backendInteractor.blockUser(id) + .then((relationship) => { + store.commit('updateUserRelationship', [relationship]) + store.commit('addBlockId', id) + store.commit('removeStatus', { timeline: 'friends', userId: id }) + store.commit('removeStatus', { timeline: 'public', userId: id }) + store.commit('removeStatus', { timeline: 'publicAndExternal', userId: id }) + }) +} + +const unblockUser = (store, id) => { + return store.rootState.api.backendInteractor.unblockUser(id) + .then((relationship) => store.commit('updateUserRelationship', [relationship])) +} + +const muteUser = (store, id) => { + return store.rootState.api.backendInteractor.muteUser(id) + .then((relationship) => { + store.commit('updateUserRelationship', [relationship]) + store.commit('addMuteId', id) + }) +} + +const unmuteUser = (store, id) => { + return store.rootState.api.backendInteractor.unmuteUser(id) + .then((relationship) => store.commit('updateUserRelationship', [relationship])) +} + export const mutations = { setMuted (state, { user: { id }, muted }) { const user = state.usersObject[id] set(user, 'muted', muted) }, + tagUser (state, { user: { id }, tag }) { + const user = state.usersObject[id] + const tags = user.tags || [] + const newTags = tags.concat([tag]) + set(user, 'tags', newTags) + }, + untagUser (state, { user: { id }, tag }) { + const user = state.usersObject[id] + const tags = user.tags || [] + const newTags = tags.filter(t => t !== tag) + set(user, 'tags', newTags) + }, + updateRight (state, { user: { id }, right, value }) { + const user = state.usersObject[id] + let newRights = user.rights + newRights[right] = value + set(user, 'rights', newRights) + }, + updateActivationStatus (state, { user: { id }, status }) { + const user = state.usersObject[id] + set(user, 'deactivated', !status) + }, setCurrentUser (state, user) { state.lastLoginName = user.screen_name state.currentUser = merge(state.currentUser || {}, user) @@ -51,42 +103,27 @@ export const mutations = { endLogin (state) { state.loggingIn = false }, - // TODO Clean after ourselves? - addFriends (state, { id, friends }) { + saveFriendIds (state, { id, friendIds }) { const user = state.usersObject[id] - each(friends, friend => { - if (!find(user.friends, { id: friend.id })) { - user.friends.push(friend) - } - }) - user.lastFriendId = last(friends).id + user.friendIds = uniq(concat(user.friendIds, friendIds)) }, - addFollowers (state, { id, followers }) { + saveFollowerIds (state, { id, followerIds }) { const user = state.usersObject[id] - each(followers, follower => { - if (!find(user.followers, { id: follower.id })) { - user.followers.push(follower) - } - }) - user.lastFollowerId = last(followers).id + user.followerIds = uniq(concat(user.followerIds, followerIds)) }, // Because frontend doesn't have a reason to keep these stuff in memory // outside of viewing someones user profile. clearFriends (state, userId) { const user = state.usersObject[userId] - if (!user) { - return + if (user) { + set(user, 'friendIds', []) } - user.friends = [] - user.lastFriendId = null }, clearFollowers (state, userId) { const user = state.usersObject[userId] - if (!user) { - return + if (user) { + set(user, 'followerIds', []) } - user.followers = [] - user.lastFollowerId = null }, addNewUsers (state, users) { each(users, (user) => mergeOrAdd(state.users, state.usersObject, user)) @@ -110,6 +147,11 @@ export const mutations = { saveBlockIds (state, blockIds) { state.currentUser.blockIds = blockIds }, + addBlockId (state, blockId) { + if (state.currentUser.blockIds.indexOf(blockId) === -1) { + state.currentUser.blockIds.push(blockId) + } + }, updateMutes (state, mutedUsers) { // Reset muted of all fetched users each(state.users, (user) => { user.muted = false }) @@ -118,12 +160,19 @@ export const mutations = { saveMuteIds (state, muteIds) { state.currentUser.muteIds = muteIds }, + addMuteId (state, muteId) { + if (state.currentUser.muteIds.indexOf(muteId) === -1) { + state.currentUser.muteIds.push(muteId) + } + }, setUserForStatus (state, status) { status.user = state.usersObject[status.user.id] }, setUserForNotification (state, notification) { - notification.action.user = state.usersObject[notification.action.user.id] - notification.from_profile = state.usersObject[notification.action.user.id] + if (notification.type !== 'follow') { + notification.action.user = state.usersObject[notification.action.user.id] + } + notification.from_profile = state.usersObject[notification.from_profile.id] }, setColor (state, { user: { id }, highlighted }) { const user = state.usersObject[id] @@ -176,8 +225,10 @@ const users = { }) }, fetchUserRelationship (store, id) { - return store.rootState.api.backendInteractor.fetchUserRelationship({ id }) - .then((relationships) => store.commit('updateUserRelationship', relationships)) + if (store.state.currentUser) { + store.rootState.api.backendInteractor.fetchUserRelationship({ id }) + .then((relationships) => store.commit('updateUserRelationship', relationships)) + } }, fetchBlocks (store) { return store.rootState.api.backendInteractor.fetchBlocks() @@ -187,18 +238,17 @@ const users = { return blocks }) }, - blockUser (store, userId) { - return store.rootState.api.backendInteractor.blockUser(userId) - .then((relationship) => { - store.commit('updateUserRelationship', [relationship]) - store.commit('removeStatus', { timeline: 'friends', userId }) - store.commit('removeStatus', { timeline: 'public', userId }) - store.commit('removeStatus', { timeline: 'publicAndExternal', userId }) - }) + blockUser (store, id) { + return blockUser(store, id) }, unblockUser (store, id) { - return store.rootState.api.backendInteractor.unblockUser(id) - .then((relationship) => store.commit('updateUserRelationship', [relationship])) + return unblockUser(store, id) + }, + blockUsers (store, ids = []) { + return Promise.all(ids.map(id => blockUser(store, id))) + }, + unblockUsers (store, ids = []) { + return Promise.all(ids.map(id => unblockUser(store, id))) }, fetchMutes (store) { return store.rootState.api.backendInteractor.fetchMutes() @@ -209,32 +259,34 @@ const users = { }) }, muteUser (store, id) { - return store.rootState.api.backendInteractor.muteUser(id) - .then((relationship) => store.commit('updateUserRelationship', [relationship])) + return muteUser(store, id) }, unmuteUser (store, id) { - return store.rootState.api.backendInteractor.unmuteUser(id) - .then((relationship) => store.commit('updateUserRelationship', [relationship])) + return unmuteUser(store, id) }, - addFriends ({ rootState, commit }, fetchBy) { - return new Promise((resolve, reject) => { - const user = rootState.users.usersObject[fetchBy] - const maxId = user.lastFriendId - rootState.api.backendInteractor.fetchFriends({ id: user.id, maxId }) - .then((friends) => { - commit('addFriends', { id: user.id, friends }) - resolve(friends) - }).catch(() => { - reject() - }) - }) + muteUsers (store, ids = []) { + return Promise.all(ids.map(id => muteUser(store, id))) }, - addFollowers ({ rootState, commit }, fetchBy) { - const user = rootState.users.usersObject[fetchBy] - const maxId = user.lastFollowerId - return rootState.api.backendInteractor.fetchFollowers({ id: user.id, maxId }) + unmuteUsers (store, ids = []) { + return Promise.all(ids.map(id => unmuteUser(store, id))) + }, + fetchFriends ({ rootState, commit }, id) { + const user = rootState.users.usersObject[id] + const maxId = last(user.friendIds) + return rootState.api.backendInteractor.fetchFriends({ id, maxId }) + .then((friends) => { + commit('addNewUsers', friends) + commit('saveFriendIds', { id, friendIds: map(friends, 'id') }) + return friends + }) + }, + fetchFollowers ({ rootState, commit }, id) { + const user = rootState.users.usersObject[id] + const maxId = last(user.followerIds) + return rootState.api.backendInteractor.fetchFollowers({ id, maxId }) .then((followers) => { - commit('addFollowers', { id: user.id, followers }) + commit('addNewUsers', followers) + commit('saveFollowerIds', { id, followerIds: map(followers, 'id') }) return followers }) }, @@ -257,6 +309,9 @@ const users = { unregisterPushNotifications(token) }, + addNewUsers ({ commit }, users) { + commit('addNewUsers', users) + }, addNewStatuses (store, { statuses }) { const users = map(statuses, 'user') const retweetedUsers = compact(map(statuses, 'retweeted_status.user')) @@ -287,6 +342,14 @@ const users = { store.commit('setUserForNotification', notification) }) }, + searchUsers (store, query) { + // TODO: Move userSearch api into api.service + return userSearchApi.search({query, store: { state: store.rootState }}) + .then((users) => { + store.commit('addNewUsers', users) + return users + }) + }, async signUp (store, userInfo) { store.commit('signUpPending') @@ -331,7 +394,8 @@ const users = { store.commit('setToken', false) store.dispatch('stopFetching', 'friends') store.commit('setBackendInteractor', backendInteractorService()) - store.dispatch('stopFetchingNotifications') + store.dispatch('stopFetching', 'notifications') + store.commit('clearNotifications') store.commit('resetStatuses') }, loginUser (store, accessToken) { @@ -363,7 +427,10 @@ const users = { } // Start getting fresh posts. - store.dispatch('startFetching', { timeline: 'friends' }) + store.dispatch('startFetchingTimeline', { timeline: 'friends' }) + + // Start fetching notifications + store.dispatch('startFetchingNotifications') // Get user mutes store.dispatch('fetchMutes') diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index 030c2f5e..6b255e9f 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -8,7 +8,6 @@ const BG_UPDATE_URL = '/api/qvitter/update_background_image.json' const BANNER_UPDATE_URL = '/api/account/update_profile_banner.json' const PROFILE_UPDATE_URL = '/api/account/update_profile.json' const EXTERNAL_PROFILE_URL = '/api/externalprofile/show.json' -const QVITTER_USER_NOTIFICATIONS_URL = '/api/qvitter/statuses/notifications.json' const QVITTER_USER_NOTIFICATIONS_READ_URL = '/api/qvitter/statuses/notifications/read.json' const FOLLOW_IMPORT_URL = '/api/pleroma/follow_import' const DELETE_ACCOUNT_URL = '/api/pleroma/delete_account' @@ -16,9 +15,14 @@ const CHANGE_PASSWORD_URL = '/api/pleroma/change_password' const FOLLOW_REQUESTS_URL = '/api/pleroma/friend_requests' const APPROVE_USER_URL = '/api/pleroma/friendships/approve' const DENY_USER_URL = '/api/pleroma/friendships/deny' +const TAG_USER_URL = '/api/pleroma/admin/users/tag' +const PERMISSION_GROUP_URL = '/api/pleroma/admin/permission_group' +const ACTIVATION_STATUS_URL = '/api/pleroma/admin/activation_status' +const ADMIN_USER_URL = '/api/pleroma/admin/user' const SUGGESTIONS_URL = '/api/v1/suggestions' const MASTODON_USER_FAVORITES_TIMELINE_URL = '/api/v1/favourites' +const MASTODON_USER_NOTIFICATIONS_URL = '/api/v1/notifications' const MASTODON_FAVORITE_URL = id => `/api/v1/statuses/${id}/favourite` const MASTODON_UNFAVORITE_URL = id => `/api/v1/statuses/${id}/unfavourite` const MASTODON_RETWEET_URL = id => `/api/v1/statuses/${id}/reblog` @@ -46,7 +50,7 @@ const MASTODON_UNMUTE_USER_URL = id => `/api/v1/accounts/${id}/unmute` const MASTODON_POST_STATUS_URL = '/api/v1/statuses' const MASTODON_MEDIA_UPLOAD_URL = '/api/v1/media' -import { each, map } from 'lodash' +import { each, map, concat, last } from 'lodash' import { parseStatus, parseUser, parseNotification, parseAttachment } from '../entity_normalizer/entity_normalizer.service.js' import 'whatwg-fetch' import { StatusCodeError } from '../errors/errors' @@ -290,10 +294,23 @@ const fetchFriends = ({id, maxId, sinceId, limit = 20, credentials}) => { } const exportFriends = ({id, credentials}) => { - let url = MASTODON_FOLLOWING_URL(id) + `?all=true` - return fetch(url, { headers: authHeaders(credentials) }) - .then((data) => data.json()) - .then((data) => data.map(parseUser)) + return new Promise(async (resolve, reject) => { + try { + let friends = [] + let more = true + while (more) { + const maxId = friends.length > 0 ? last(friends).id : undefined + const users = await fetchFriends({id, maxId, credentials}) + friends = concat(friends, users) + if (users.length === 0) { + more = false + } + } + resolve(friends) + } catch (err) { + reject(err) + } + }) } const fetchFollowers = ({id, maxId, sinceId, limit = 20, credentials}) => { @@ -352,13 +369,93 @@ const fetchStatus = ({id, credentials}) => { .then((data) => parseStatus(data)) } +const tagUser = ({tag, credentials, ...options}) => { + const screenName = options.screen_name + const form = { + nicknames: [screenName], + tags: [tag] + } + + const headers = authHeaders(credentials) + headers['Content-Type'] = 'application/json' + + return fetch(TAG_USER_URL, { + method: 'PUT', + headers: headers, + body: JSON.stringify(form) + }) +} + +const untagUser = ({tag, credentials, ...options}) => { + const screenName = options.screen_name + const body = { + nicknames: [screenName], + tags: [tag] + } + + const headers = authHeaders(credentials) + headers['Content-Type'] = 'application/json' + + return fetch(TAG_USER_URL, { + method: 'DELETE', + headers: headers, + body: JSON.stringify(body) + }) +} + +const addRight = ({right, credentials, ...user}) => { + const screenName = user.screen_name + + return fetch(`${PERMISSION_GROUP_URL}/${screenName}/${right}`, { + method: 'POST', + headers: authHeaders(credentials), + body: {} + }) +} + +const deleteRight = ({right, credentials, ...user}) => { + const screenName = user.screen_name + + return fetch(`${PERMISSION_GROUP_URL}/${screenName}/${right}`, { + method: 'DELETE', + headers: authHeaders(credentials), + body: {} + }) +} + +const setActivationStatus = ({status, credentials, ...user}) => { + const screenName = user.screen_name + const body = { + status: status + } + + const headers = authHeaders(credentials) + headers['Content-Type'] = 'application/json' + + return fetch(`${ACTIVATION_STATUS_URL}/${screenName}.json`, { + method: 'PUT', + headers: headers, + body: JSON.stringify(body) + }) +} + +const deleteUser = ({credentials, ...user}) => { + const screenName = user.screen_name + const headers = authHeaders(credentials) + + return fetch(`${ADMIN_USER_URL}.json?nickname=${screenName}`, { + method: 'DELETE', + headers: headers + }) +} + const fetchTimeline = ({timeline, credentials, since = false, until = false, userId = false, tag = false, withMuted = false}) => { const timelineUrls = { public: MASTODON_PUBLIC_TIMELINE, friends: MASTODON_USER_HOME_TIMELINE_URL, mentions: MENTIONS_URL, dms: MASTODON_DIRECT_MESSAGES_TIMELINE_URL, - notifications: QVITTER_USER_NOTIFICATIONS_URL, + notifications: MASTODON_USER_NOTIFICATIONS_URL, 'publicAndExternal': MASTODON_PUBLIC_TIMELINE, user: MASTODON_USER_TIMELINE_URL, media: MASTODON_USER_TIMELINE_URL, @@ -666,6 +763,12 @@ const apiService = { fetchBlocks, fetchOAuthTokens, revokeOAuthToken, + tagUser, + untagUser, + deleteUser, + addRight, + deleteRight, + setActivationStatus, register, getCaptcha, updateAvatar, diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js index 71e78d2f..75bba92b 100644 --- a/src/services/backend_interactor_service/backend_interactor_service.js +++ b/src/services/backend_interactor_service/backend_interactor_service.js @@ -1,5 +1,6 @@ import apiService from '../api/api.service.js' import timelineFetcherService from '../timeline_fetcher/timeline_fetcher.service.js' +import notificationsFetcher from '../notifications_fetcher/notifications_fetcher.service.js' const backendInteractorService = (credentials) => { const fetchStatus = ({id}) => { @@ -58,8 +59,36 @@ const backendInteractorService = (credentials) => { return apiService.denyUser({credentials, id}) } - const startFetching = ({timeline, store, userId = false, tag}) => { - return timelineFetcherService.startFetching({timeline, store, credentials, userId, tag}) + const startFetchingTimeline = ({ timeline, store, userId = false, tag }) => { + return timelineFetcherService.startFetching({ timeline, store, credentials, userId, tag }) + } + + const startFetchingNotifications = ({ store }) => { + return notificationsFetcher.startFetching({ store, credentials }) + } + + const tagUser = ({screen_name}, tag) => { + return apiService.tagUser({screen_name, tag, credentials}) + } + + const untagUser = ({screen_name}, tag) => { + return apiService.untagUser({screen_name, tag, credentials}) + } + + const addRight = ({screen_name}, right) => { + return apiService.addRight({screen_name, right, credentials}) + } + + const deleteRight = ({screen_name}, right) => { + return apiService.deleteRight({screen_name, right, credentials}) + } + + const setActivationStatus = ({screen_name}, status) => { + return apiService.setActivationStatus({screen_name, status, credentials}) + } + + const deleteUser = ({screen_name}) => { + return apiService.deleteUser({screen_name, credentials}) } const fetchMutes = () => apiService.fetchMutes({credentials}) @@ -97,13 +126,20 @@ const backendInteractorService = (credentials) => { fetchUserRelationship, fetchAllFollowing, verifyCredentials: apiService.verifyCredentials, - startFetching, + startFetchingTimeline, + startFetchingNotifications, fetchMutes, muteUser, unmuteUser, fetchBlocks, fetchOAuthTokens, revokeOAuthToken, + tagUser, + untagUser, + addRight, + deleteRight, + deleteUser, + setActivationStatus, register, getCaptcha, updateAvatar, diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js index ea57e6b2..e706e7d9 100644 --- a/src/services/entity_normalizer/entity_normalizer.service.js +++ b/src/services/entity_normalizer/entity_normalizer.service.js @@ -39,7 +39,7 @@ export const parseUser = (data) => { return output } - // output.name = ??? missing + output.name = data.display_name output.name_html = addEmojis(data.display_name, data.emojis) // output.description = ??? missing @@ -67,9 +67,14 @@ export const parseUser = (data) => { output.statusnet_blocking = relationship.blocking output.muted = relationship.muting } + + output.rights = { + moderator: data.pleroma.is_moderator, + admin: data.pleroma.is_admin + } } - // Missing, trying to recover + // TODO: handle is_local output.is_local = !output.screen_name.includes('@') } else { output.screen_name = data.screen_name @@ -103,7 +108,12 @@ export const parseUser = (data) => { // QVITTER ONLY FOR NOW // Really only applies to logged in user, really.. I THINK - output.rights = data.rights + if (data.rights) { + output.rights = { + moderator: data.rights.delete_others_notice, + admin: data.rights.admin + } + } output.no_rich_text = data.no_rich_text output.default_scope = data.default_scope output.hide_follows = data.hide_follows @@ -119,12 +129,19 @@ export const parseUser = (data) => { output.locked = data.locked output.followers_count = data.followers_count output.statuses_count = data.statuses_count - output.friends = [] - output.followers = [] + output.friendIds = [] + output.followerIds = [] if (data.pleroma) { output.follow_request_count = data.pleroma.follow_request_count } + if (data.pleroma) { + output.tags = data.pleroma.tags + output.deactivated = data.pleroma.deactivated + } + + output.tags = output.tags || [] + return output } @@ -172,28 +189,28 @@ export const parseStatus = (data) => { output.statusnet_html = addEmojis(data.content, data.emojis) - // Not exactly the same but works? - output.text = data.content + if (data.pleroma) { + const { pleroma } = data + output.text = pleroma.content ? data.pleroma.content['text/plain'] : data.content + output.summary = pleroma.spoiler_text ? data.pleroma.spoiler_text['text/plain'] : data.spoiler_text + output.statusnet_conversation_id = data.pleroma.conversation_id + output.is_local = pleroma.local + output.in_reply_to_screen_name = data.pleroma.in_reply_to_account_acct + } else { + output.text = data.content + output.summary = data.spoiler_text + } output.in_reply_to_status_id = data.in_reply_to_id output.in_reply_to_user_id = data.in_reply_to_account_id output.replies_count = data.replies_count - // Missing!! fix in UI? - // output.in_reply_to_screen_name = ??? - - // Not exactly the same but works - output.statusnet_conversation_id = data.id - if (output.type === 'retweet') { output.retweeted_status = parseStatus(data.reblog) } - output.summary = data.spoiler_text output.summary_html = addEmojis(data.spoiler_text, data.emojis) output.external_url = data.url - - // output.is_local = ??? missing } else { output.favorited = data.favorited output.fave_num = data.fave_num @@ -221,7 +238,6 @@ export const parseStatus = (data) => { output.in_reply_to_status_id = data.in_reply_to_status_id output.in_reply_to_user_id = data.in_reply_to_user_id output.in_reply_to_screen_name = data.in_reply_to_screen_name - output.statusnet_conversation_id = data.statusnet_conversation_id if (output.type === 'retweet') { @@ -272,9 +288,11 @@ export const parseNotification = (data) => { if (masto) { output.type = mastoDict[data.type] || data.type - // output.seen = ??? missing - output.status = parseStatus(data.status) - output.action = output.status // not sure + output.seen = data.pleroma.is_seen + output.status = output.type === 'follow' + ? null + : parseStatus(data.status) + output.action = output.status // TODO: Refactor, this is unneeded output.from_profile = parseUser(data.account) } else { const parsedNotice = parseStatus(data.notice) diff --git a/src/services/follow_manipulate/follow_manipulate.js b/src/services/follow_manipulate/follow_manipulate.js index 51dafe84..b2486e7c 100644 --- a/src/services/follow_manipulate/follow_manipulate.js +++ b/src/services/follow_manipulate/follow_manipulate.js @@ -23,18 +23,12 @@ export const requestFollow = (user, store) => new Promise((resolve, reject) => { // For locked users we just mark it that we sent the follow request if (updated.locked) { - resolve({ - sent: true, - updated - }) + resolve({ sent: true }) } if (updated.following) { // If we get result immediately, just stop. - resolve({ - sent: false, - updated - }) + resolve({ sent: false }) } // But usually we don't get result immediately, so we ask server @@ -48,16 +42,10 @@ export const requestFollow = (user, store) => new Promise((resolve, reject) => { .then((following) => { if (following) { // We confirmed and everything's good. - resolve({ - sent: false, - updated - }) + resolve({ sent: false }) } else { // If after all the tries, just treat it as if user is locked - resolve({ - sent: false, - updated - }) + resolve({ sent: false }) } }) }) diff --git a/src/services/notification_utils/notification_utils.js b/src/services/notification_utils/notification_utils.js index cd8f3f9e..8afd114e 100644 --- a/src/services/notification_utils/notification_utils.js +++ b/src/services/notification_utils/notification_utils.js @@ -10,8 +10,8 @@ export const visibleTypes = store => ([ ].filter(_ => _)) const sortById = (a, b) => { - const seqA = Number(a.action.id) - const seqB = Number(b.action.id) + const seqA = Number(a.id) + const seqB = Number(b.id) const isSeqA = !Number.isNaN(seqA) const isSeqB = !Number.isNaN(seqB) if (isSeqA && isSeqB) { @@ -21,7 +21,7 @@ const sortById = (a, b) => { } else if (!isSeqA && isSeqB) { return -1 } else { - return a.action.id > b.action.id ? -1 : 1 + return a.id > b.id ? -1 : 1 } } diff --git a/src/services/notifications_fetcher/notifications_fetcher.service.js b/src/services/notifications_fetcher/notifications_fetcher.service.js index 3ecdae6a..60c497ae 100644 --- a/src/services/notifications_fetcher/notifications_fetcher.service.js +++ b/src/services/notifications_fetcher/notifications_fetcher.service.js @@ -11,29 +11,35 @@ const fetchAndUpdate = ({store, credentials, older = false}) => { const rootState = store.rootState || store.state const timelineData = rootState.statuses.notifications + args['timeline'] = 'notifications' if (older) { if (timelineData.minId !== Number.POSITIVE_INFINITY) { args['until'] = timelineData.minId } + return fetchNotifications({ store, args, older }) } else { - // load unread notifications repeadedly to provide consistency between browser tabs + // fetch new notifications + if (timelineData.maxId !== Number.POSITIVE_INFINITY) { + args['since'] = timelineData.maxId + } + const result = fetchNotifications({ store, args, older }) + + // load unread notifications repeatedly to provide consistency between browser tabs const notifications = timelineData.data const unread = notifications.filter(n => !n.seen).map(n => n.id) - if (!unread.length) { - args['since'] = timelineData.maxId - } else { - args['since'] = Math.min(...unread) - 1 - if (timelineData.maxId !== Math.max(...unread)) { - args['until'] = Math.max(...unread, args['since'] + 20) - } + if (unread.length) { + args['since'] = Math.min(...unread) + fetchNotifications({ store, args, older }) } + + return result } +} - args['timeline'] = 'notifications' - +const fetchNotifications = ({ store, args, older }) => { return apiService.fetchTimeline(args) .then((notifications) => { - update({store, notifications, older}) + update({ store, notifications, older }) return notifications }, () => store.dispatch('setNotificationsError', { value: true })) .catch(() => store.dispatch('setNotificationsError', { value: true })) diff --git a/static/font/config.json b/static/font/config.json index 844853b3..b73f2ad4 100644 --- a/static/font/config.json +++ b/static/font/config.json @@ -245,6 +245,12 @@ "css": "bell-alt", "code": 61683, "src": "fontawesome" + }, + { + "uid": "5bb103cd29de77e0e06a52638527b575", + "css": "wrench", + "code": 59418, + "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 0b738b0c..b57c5620 100755 --- a/static/font/css/fontello-codes.css +++ b/static/font/css/fontello-codes.css @@ -24,6 +24,8 @@ .icon-adjust:before { content: '\e816'; } /* '' */ .icon-edit:before { content: '\e817'; } /* '' */ .icon-pencil:before { content: '\e818'; } /* '' */ +.icon-verified:before { content: '\e819'; } /* '' */ +.icon-wrench:before { content: '\e81a'; } /* '' */ .icon-spin3:before { content: '\e832'; } /* '' */ .icon-spin4:before { content: '\e834'; } /* '' */ .icon-link-ext:before { content: '\f08e'; } /* '' */ diff --git a/static/font/css/fontello-embedded.css b/static/font/css/fontello-embedded.css index d6960970..c69c8b9f 100755 --- 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?89861281'); - src: url('../font/fontello.eot?89861281#iefix') format('embedded-opentype'), - url('../font/fontello.svg?89861281#fontello') format('svg'); + src: url('../font/fontello.eot?54523265'); + src: url('../font/fontello.eot?54523265#iefix') format('embedded-opentype'), + url('../font/fontello.svg?54523265#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,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') 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?89861281#fontello') format('svg'); + src: url('../font/fontello.svg?54523265#fontello') format('svg'); } } */ @@ -77,6 +77,8 @@ .icon-adjust:before { content: '\e816'; } /* '' */ .icon-edit:before { content: '\e817'; } /* '' */ .icon-pencil:before { content: '\e818'; } /* '' */ +.icon-verified:before { content: '\e819'; } /* '' */ +.icon-wrench:before { content: '\e81a'; } /* '' */ .icon-spin3:before { content: '\e832'; } /* '' */ .icon-spin4:before { content: '\e834'; } /* '' */ .icon-link-ext:before { content: '\f08e'; } /* '' */ diff --git a/static/font/css/fontello-ie7-codes.css b/static/font/css/fontello-ie7-codes.css index 50273d32..981463a8 100755 --- a/static/font/css/fontello-ie7-codes.css +++ b/static/font/css/fontello-ie7-codes.css @@ -24,6 +24,8 @@ .icon-adjust { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } .icon-edit { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } .icon-pencil { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } +.icon-verified { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } +.icon-wrench { *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-link-ext { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } diff --git a/static/font/css/fontello-ie7.css b/static/font/css/fontello-ie7.css index adc56c4b..c2e8bc24 100755 --- a/static/font/css/fontello-ie7.css +++ b/static/font/css/fontello-ie7.css @@ -35,6 +35,8 @@ .icon-adjust { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } .icon-edit { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } .icon-pencil { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } +.icon-verified { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } +.icon-wrench { *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-link-ext { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } diff --git a/static/font/css/fontello.css b/static/font/css/fontello.css index 1cd1fd45..fc23c41a 100755 --- 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?72648396'); - src: url('../font/fontello.eot?72648396#iefix') format('embedded-opentype'), - url('../font/fontello.woff2?72648396') format('woff2'), - url('../font/fontello.woff?72648396') format('woff'), - url('../font/fontello.ttf?72648396') format('truetype'), - url('../font/fontello.svg?72648396#fontello') format('svg'); + src: url('../font/fontello.eot?11878820'); + src: url('../font/fontello.eot?11878820#iefix') format('embedded-opentype'), + url('../font/fontello.woff2?11878820') format('woff2'), + url('../font/fontello.woff?11878820') format('woff'), + url('../font/fontello.ttf?11878820') format('truetype'), + url('../font/fontello.svg?11878820#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?72648396#fontello') format('svg'); + src: url('../font/fontello.svg?11878820#fontello') format('svg'); } } */ @@ -80,6 +80,8 @@ .icon-adjust:before { content: '\e816'; } /* '' */ .icon-edit:before { content: '\e817'; } /* '' */ .icon-pencil:before { content: '\e818'; } /* '' */ +.icon-verified:before { content: '\e819'; } /* '' */ +.icon-wrench:before { content: '\e81a'; } /* '' */ .icon-spin3:before { content: '\e832'; } /* '' */ .icon-spin4:before { content: '\e834'; } /* '' */ .icon-link-ext:before { content: '\f08e'; } /* '' */ diff --git a/static/font/demo.html b/static/font/demo.html old mode 100644 new mode 100755 index 159dfd4a..1a1147af --- 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?23081587'); - src: url('./font/fontello.eot?23081587#iefix') format('embedded-opentype'), - url('./font/fontello.woff?23081587') format('woff'), - url('./font/fontello.ttf?23081587') format('truetype'), - url('./font/fontello.svg?23081587#fontello') format('svg'); + src: url('./font/fontello.eot?60799712'); + src: url('./font/fontello.eot?60799712#iefix') format('embedded-opentype'), + url('./font/fontello.woff?60799712') format('woff'), + url('./font/fontello.ttf?60799712') format('truetype'), + url('./font/fontello.svg?60799712#fontello') format('svg'); font-weight: normal; font-style: normal; } @@ -335,25 +335,29 @@ body {
icon-pencil0xe818
+
icon-verified0xe819
+
icon-wrench0xe81a
icon-spin30xe832
+
+
icon-spin40xe834
icon-link-ext0xf08e
-
-
icon-link-ext-alt0xf08f
icon-menu0xf0c9
+
+
icon-mail-alt0xf0e0
icon-comment-empty0xf0e5
-
-
icon-bell-alt0xf0f3
icon-plus-squared0xf0fe
-
icon-reply0xf112
-
icon-lock-open-alt0xf13e
+
icon-reply0xf112
+
icon-lock-open-alt0xf13e
icon-play-circled0xf144
icon-thumbs-up-alt0xf164
+
+
icon-binoculars0xf1e5
icon-user-plus0xf234
diff --git a/static/font/font/fontello.eot b/static/font/font/fontello.eot index 646a80b0..b9cdfcb5 100755 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 04869290..0e460ea5 100755 --- a/static/font/font/fontello.svg +++ b/static/font/font/fontello.svg @@ -56,6 +56,10 @@ + + + + diff --git a/static/font/font/fontello.ttf b/static/font/font/fontello.ttf index 90784968..f1b9f19d 100755 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 95077a64..141abc65 100755 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 7d9c653a..efed5cf7 100755 Binary files a/static/font/font/fontello.woff2 and b/static/font/font/fontello.woff2 differ diff --git a/test/fixtures/mastoapi.json b/test/fixtures/mastoapi.json index 858d7a0d..887fb83e 100644 --- a/test/fixtures/mastoapi.json +++ b/test/fixtures/mastoapi.json @@ -58,7 +58,10 @@ "tags": [], "uri": "https://shigusegubu.club/objects/16033fbb-97c0-4f0e-b834-7abb92fb8639", "url": "https://shigusegubu.club/objects/16033fbb-97c0-4f0e-b834-7abb92fb8639", - "visibility": "public" + "visibility": "public", + "pleroma": { + "local": true + } }, { "account": { "acct": "hj", @@ -127,7 +130,10 @@ "tags": [], "uri": "https://shigusegubu.club/objects/6634d32b-96a8-4852-a3db-ac8730715779", "url": "https://shigusegubu.club/objects/6634d32b-96a8-4852-a3db-ac8730715779", - "visibility": "public" + "visibility": "public", + "pleroma": { + "local": true + } }, { "account": { "acct": "hj", @@ -250,7 +256,10 @@ "tags": [], "uri": "https://pleroma.soykaf.com/objects/bf7e43d4-5048-4176-8519-58e3e1014f8b", "url": "https://pleroma.soykaf.com/objects/bf7e43d4-5048-4176-8519-58e3e1014f8b", - "visibility": "public" + "visibility": "public", + "pleroma": { + "local": true + } }, "reblogged": false, "reblogs_count": 0, @@ -260,7 +269,10 @@ "tags": [], "uri": "https://pleroma.soykaf.com/objects/bf7e43d4-5048-4176-8519-58e3e1014f8b", "url": "https://pleroma.soykaf.com/objects/bf7e43d4-5048-4176-8519-58e3e1014f8b", - "visibility": "public" + "visibility": "public", + "pleroma": { + "local": true + } }, { "account": { "acct": "hj", @@ -329,7 +341,10 @@ "tags": [], "uri": "https://shigusegubu.club/objects/0f963ca1-a263-41ca-a43c-b5d26d0a08e9", "url": "https://shigusegubu.club/objects/0f963ca1-a263-41ca-a43c-b5d26d0a08e9", - "visibility": "public" + "visibility": "public", + "pleroma": { + "local": true + } }, { "account": { "acct": "hj", @@ -390,7 +405,10 @@ "tags": [], "uri": "https://shigusegubu.club/objects/3f809bd8-656f-4a29-81d4-80eed6916eb0", "url": "https://shigusegubu.club/objects/3f809bd8-656f-4a29-81d4-80eed6916eb0", - "visibility": "public" + "visibility": "public", + "pleroma": { + "local": true + } }, { "account": { "acct": "hj", @@ -516,7 +534,10 @@ }], "uri": "tag:social.super-niche.club,2019-01-17:noticeId=2353002:objectType=note", "url": "https://social.super-niche.club/notice/2353002", - "visibility": "public" + "visibility": "public", + "pleroma": { + "local": true + } }, "reblogged": false, "reblogs_count": 0, @@ -529,7 +550,10 @@ }], "uri": "tag:social.super-niche.club,2019-01-17:noticeId=2353002:objectType=note", "url": "tag:social.super-niche.club,2019-01-17:noticeId=2353002:objectType=note", - "visibility": "public" + "visibility": "public", + "pleroma": { + "local": true + } }, { "account": { "acct": "hj", @@ -657,7 +681,10 @@ "tags": [], "uri": "https://miniwa.moe/objects/448e2944-0ecd-457f-92c3-cb454f2b0fab", "url": "https://miniwa.moe/objects/448e2944-0ecd-457f-92c3-cb454f2b0fab", - "visibility": "public" + "visibility": "public", + "pleroma": { + "local": true + } }, "reblogged": false, "reblogs_count": 0, @@ -667,7 +694,10 @@ "tags": [], "uri": "https://miniwa.moe/objects/448e2944-0ecd-457f-92c3-cb454f2b0fab", "url": "https://miniwa.moe/objects/448e2944-0ecd-457f-92c3-cb454f2b0fab", - "visibility": "public" + "visibility": "public", + "pleroma": { + "local": true + } }, { "account": { "acct": "hj", @@ -733,7 +763,10 @@ "tags": [], "uri": "https://shigusegubu.club/objects/38b1bc44-15d8-40dd-b1aa-937e0ff4a86d", "url": "https://shigusegubu.club/objects/38b1bc44-15d8-40dd-b1aa-937e0ff4a86d", - "visibility": "public" + "visibility": "public", + "pleroma": { + "local": true + } }, { "account": { "acct": "hj", @@ -794,7 +827,10 @@ "tags": [], "uri": "https://shigusegubu.club/objects/fbff5da4-a517-42a9-bca9-17cae8cf2542", "url": "https://shigusegubu.club/objects/fbff5da4-a517-42a9-bca9-17cae8cf2542", - "visibility": "public" + "visibility": "public", + "pleroma": { + "local": true + } }, { "account": { "acct": "hj", @@ -850,7 +886,10 @@ "tags": [], "uri": "https://shigusegubu.club/objects/4007d659-27c6-4577-be10-fd134f5e4e7e", "url": "https://shigusegubu.club/objects/4007d659-27c6-4577-be10-fd134f5e4e7e", - "visibility": "public" + "visibility": "public", + "pleroma": { + "local": true + } }, { "account": { "acct": "hj", @@ -906,7 +945,10 @@ "tags": [], "uri": "https://shigusegubu.club/objects/59912d51-1cc6-4dc7-828c-f167e6c8b391", "url": "https://shigusegubu.club/objects/59912d51-1cc6-4dc7-828c-f167e6c8b391", - "visibility": "public" + "visibility": "public", + "pleroma": { + "local": true + } }, { "account": { "acct": "hj", @@ -962,7 +1004,10 @@ "tags": [], "uri": "https://shigusegubu.club/objects/62690bce-3f49-4047-9c8e-8941f2f79e10", "url": "https://shigusegubu.club/objects/62690bce-3f49-4047-9c8e-8941f2f79e10", - "visibility": "public" + "visibility": "public", + "pleroma": { + "local": true + } }, { "account": { "acct": "hj", @@ -1023,7 +1068,10 @@ "tags": [], "uri": "https://shigusegubu.club/objects/818f3dd0-2ff8-4def-a170-e4d4c405f387", "url": "https://shigusegubu.club/objects/818f3dd0-2ff8-4def-a170-e4d4c405f387", - "visibility": "public" + "visibility": "public", + "pleroma": { + "local": true + } }, { "account": { "acct": "hj", @@ -1084,7 +1132,10 @@ "tags": [], "uri": "https://shigusegubu.club/objects/0783a193-c097-488d-8944-47df9372cd6e", "url": "https://shigusegubu.club/objects/0783a193-c097-488d-8944-47df9372cd6e", - "visibility": "public" + "visibility": "public", + "pleroma": { + "local": true + } }, { "account": { "acct": "hj", @@ -1145,7 +1196,10 @@ "tags": [], "uri": "https://shigusegubu.club/objects/145d5252-7b8e-467d-9f36-1db0818f452f", "url": "https://shigusegubu.club/objects/145d5252-7b8e-467d-9f36-1db0818f452f", - "visibility": "public" + "visibility": "public", + "pleroma": { + "local": true + } }, { "account": { "acct": "hj", @@ -1252,7 +1306,10 @@ "tags": [], "uri": "https://pleroma.site/objects/3076c055-0e34-4cf9-86ca-2d148b9b694a", "url": "https://pleroma.site/objects/3076c055-0e34-4cf9-86ca-2d148b9b694a", - "visibility": "public" + "visibility": "public", + "pleroma": { + "local": true + } }, "reblogged": false, "reblogs_count": 0, @@ -1262,7 +1319,10 @@ "tags": [], "uri": "https://pleroma.site/objects/3076c055-0e34-4cf9-86ca-2d148b9b694a", "url": "https://pleroma.site/objects/3076c055-0e34-4cf9-86ca-2d148b9b694a", - "visibility": "public" + "visibility": "public", + "pleroma": { + "local": true + } }, { "account": { "acct": "hj", @@ -1323,7 +1383,10 @@ "tags": [], "uri": "https://shigusegubu.club/objects/d4eb7c46-02f9-4b1f-83af-926cefa21f33", "url": "https://shigusegubu.club/objects/d4eb7c46-02f9-4b1f-83af-926cefa21f33", - "visibility": "public" + "visibility": "public", + "pleroma": { + "local": true + } }, { "account": { "acct": "hj", @@ -1446,7 +1509,10 @@ "tags": [], "uri": "https://pleroma.soykaf.com/objects/338b6bd2-3c2d-40fe-93a3-28b688782733", "url": "https://pleroma.soykaf.com/objects/338b6bd2-3c2d-40fe-93a3-28b688782733", - "visibility": "public" + "visibility": "public", + "pleroma": { + "local": true + } }, "reblogged": false, "reblogs_count": 0, @@ -1456,7 +1522,10 @@ "tags": [], "uri": "https://pleroma.soykaf.com/objects/338b6bd2-3c2d-40fe-93a3-28b688782733", "url": "https://pleroma.soykaf.com/objects/338b6bd2-3c2d-40fe-93a3-28b688782733", - "visibility": "public" + "visibility": "public", + "pleroma": { + "local": true + } }, { "account": { "acct": "hj", @@ -1517,7 +1586,10 @@ "tags": [], "uri": "https://shigusegubu.club/objects/f472f4ed-8b0b-492f-9d53-d69eda79629d", "url": "https://shigusegubu.club/objects/f472f4ed-8b0b-492f-9d53-d69eda79629d", - "visibility": "public" + "visibility": "public", + "pleroma": { + "local": true + } }, { "account": { "acct": "hj", @@ -1578,5 +1650,8 @@ "tags": [], "uri": "https://shigusegubu.club/objects/d6fb4fd2-1f6a-4446-a1a6-5edd34050096", "url": "https://shigusegubu.club/objects/d6fb4fd2-1f6a-4446-a1a6-5edd34050096", - "visibility": "public" + "visibility": "public", + "pleroma": { + "local": true + } }] diff --git a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js index 2b0b0d6d..bae890f8 100644 --- a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js +++ b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js @@ -129,7 +129,10 @@ const makeMockStatusMasto = (overrides = {}) => { tags: [], uri: 'https://shigusegubu.club/objects/16033fbb-97c0-4f0e-b834-7abb92fb8639', url: 'https://shigusegubu.club/objects/16033fbb-97c0-4f0e-b834-7abb92fb8639', - visibility: 'public' + visibility: 'public', + pleroma: { + local: true + } }, overrides) } diff --git a/test/unit/specs/services/notification_utils/notification_utils.spec.js b/test/unit/specs/services/notification_utils/notification_utils.spec.js index e945459e..1baa5fc9 100644 --- a/test/unit/specs/services/notification_utils/notification_utils.spec.js +++ b/test/unit/specs/services/notification_utils/notification_utils.spec.js @@ -9,14 +9,17 @@ describe('NotificationUtils', () => { notifications: { data: [ { + id: 1, action: { id: '1' }, type: 'like' }, { + id: 2, action: { id: '2' }, type: 'mention' }, { + id: 3, action: { id: '3' }, type: 'repeat' } @@ -35,10 +38,12 @@ describe('NotificationUtils', () => { const expected = [ { action: { id: '3' }, + id: 3, type: 'repeat' }, { action: { id: '1' }, + id: 1, type: 'like' } ] diff --git a/yarn.lock b/yarn.lock index 98992dba..489bd9f3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6097,6 +6097,10 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" +popper.js@^1.14.7: + version "1.14.7" + resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.14.7.tgz#e31ec06cfac6a97a53280c3e55e4e0c860e7738e" + posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" @@ -8068,6 +8072,10 @@ uuid@^3.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== +v-click-outside@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/v-click-outside/-/v-click-outside-2.1.1.tgz#5af80b68a1c82eac89c597890434fa3994b42ed1" + validate-npm-package-license@^3.0.1: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" @@ -8141,6 +8149,10 @@ vue-hot-reload-api@^2.2.0: resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.3.tgz#2756f46cb3258054c5f4723de8ae7e87302a1ccf" integrity sha512-KmvZVtmM26BQOMK1rwUZsrqxEGeKiYSZGA7SNWE6uExx8UX/cj9hq2MRV/wWC3Cq6AoeDGk57rL9YMFRel/q+g== +vue-hot-reload-api@^2.0.11: + version "2.3.1" + resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.1.tgz#b2d3d95402a811602380783ea4f566eb875569a2" + vue-i18n@^7.3.2: version "7.8.1" resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-7.8.1.tgz#2ce4b6efde679a1e05ddb5d907bfc1bc218803b2" @@ -8165,6 +8177,12 @@ vue-loader@^14.0.0: vue-style-loader "^4.0.1" vue-template-es2015-compiler "^1.6.0" +vue-popperjs@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/vue-popperjs/-/vue-popperjs-2.0.3.tgz#7c446d0ba7c63170ccb33a02669d0df4efc3d8cd" + dependencies: + popper.js "^1.14.7" + vue-router@^3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.0.2.tgz#dedc67afe6c4e2bc25682c8b1c2a8c0d7c7e56be"