Merge remote-tracking branch 'upstream/develop' into shigusegubu
* upstream/develop: (29 commits) update api services use native scrollbar refactor using List component remove transition css update api endpoint url rewrite checkbox component fix panel title overflow issue in mobile fix double scrollbar display bug in mobile prevent parent scroll use custom scrollbar modal style improvements Update promisedRequest helper to support json payload Improve mobile layout Add a css class to the checkbox indicator update copy update generic error message add translations add error message reset modal state if api request is completed add processing state and close modal after api request is completed ...
This commit is contained in:
commit
680cb7eda7
26 changed files with 552 additions and 77 deletions
|
@ -10,6 +10,7 @@ import MediaModal from './components/media_modal/media_modal.vue'
|
|||
import SideDrawer from './components/side_drawer/side_drawer.vue'
|
||||
import MobilePostStatusModal from './components/mobile_post_status_modal/mobile_post_status_modal.vue'
|
||||
import MobileNav from './components/mobile_nav/mobile_nav.vue'
|
||||
import UserReportingModal from './components/user_reporting_modal/user_reporting_modal.vue'
|
||||
import { windowWidth } from './services/window_utils/window_utils'
|
||||
|
||||
export default {
|
||||
|
@ -26,7 +27,8 @@ export default {
|
|||
MediaModal,
|
||||
SideDrawer,
|
||||
MobilePostStatusModal,
|
||||
MobileNav
|
||||
MobileNav,
|
||||
UserReportingModal
|
||||
},
|
||||
data: () => ({
|
||||
mobileActivePanel: 'timeline',
|
||||
|
|
|
@ -379,6 +379,7 @@ main-router {
|
|||
|
||||
.panel-heading {
|
||||
display: flex;
|
||||
flex: none;
|
||||
border-radius: $fallback--panelRadius $fallback--panelRadius 0 0;
|
||||
border-radius: var(--panelRadius, $fallback--panelRadius) var(--panelRadius, $fallback--panelRadius) 0 0;
|
||||
background-size: cover;
|
||||
|
@ -793,4 +794,4 @@ nav {
|
|||
background-color: var(--lightBg, $fallback--fg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
<media-modal></media-modal>
|
||||
</div>
|
||||
<chat-panel :floating="true" v-if="currentUser && chat" class="floating-chat mobile-hidden"></chat-panel>
|
||||
<UserReportingModal />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import UserAvatar from '../user_avatar/user_avatar.vue'
|
||||
|
||||
const AvatarList = {
|
||||
props: ['avatars'],
|
||||
props: ['users'],
|
||||
computed: {
|
||||
slicedAvatars () {
|
||||
return this.avatars ? this.avatars.slice(0, 15) : []
|
||||
slicedUsers () {
|
||||
return this.users ? this.users.slice(0, 15) : []
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="avatars">
|
||||
<div class="avatars-item" v-for="avatar in slicedAvatars">
|
||||
<UserAvatar :src="avatar.profile_image_url" class="avatar-small" />
|
||||
<div class="avatars-item" v-for="user in slicedUsers">
|
||||
<UserAvatar :user="user" class="avatar-small" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
<template>
|
||||
<div class="basic-user-card">
|
||||
<router-link :to="userProfileLink(user)">
|
||||
<UserAvatar class="avatar" @click.prevent.native="toggleUserExpanded" :src="user.profile_image_url"/>
|
||||
<UserAvatar
|
||||
class="avatar"
|
||||
:user="user"
|
||||
@click.prevent.native="toggleUserExpanded"
|
||||
/>
|
||||
</router-link>
|
||||
<div class="basic-user-card-expanded-content" v-if="userExpanded">
|
||||
<UserCard :user="user" :rounded="true" :bordered="true"/>
|
||||
|
|
|
@ -63,6 +63,11 @@ const MobileNav = {
|
|||
},
|
||||
markNotificationsAsSeen () {
|
||||
this.$refs.notifications.markAsSeen()
|
||||
},
|
||||
onScroll ({ target: { scrollTop, clientHeight, scrollHeight } }) {
|
||||
if (this.$store.state.config.autoLoad && scrollTop + clientHeight >= scrollHeight) {
|
||||
this.$refs.notifications.fetchOlderNotifications()
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
|
|
@ -1,25 +1,26 @@
|
|||
<template>
|
||||
<nav class='nav-bar container' id="nav">
|
||||
<div class='mobile-inner-nav' @click="scrollToTop()">
|
||||
<div class='item'>
|
||||
<a href="#" class="mobile-nav-button" @click.stop.prevent="toggleMobileSidebar()">
|
||||
<i class="button-icon icon-menu"></i>
|
||||
</a>
|
||||
<router-link class="site-name" :to="{ name: 'root' }" active-class="home">{{sitename}}</router-link>
|
||||
<div>
|
||||
<nav class='nav-bar container' id="nav">
|
||||
<div class='mobile-inner-nav' @click="scrollToTop()">
|
||||
<div class='item'>
|
||||
<a href="#" class="mobile-nav-button" @click.stop.prevent="toggleMobileSidebar()">
|
||||
<i class="button-icon icon-menu"></i>
|
||||
</a>
|
||||
<router-link class="site-name" :to="{ name: 'root' }" active-class="home">{{sitename}}</router-link>
|
||||
</div>
|
||||
<div class='item right'>
|
||||
<a class="mobile-nav-button" v-if="currentUser" href="#" @click.stop.prevent="openMobileNotifications()">
|
||||
<i class="button-icon icon-bell-alt"></i>
|
||||
<div class="alert-dot" v-if="unseenNotificationsCount"></div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class='item right'>
|
||||
<a class="mobile-nav-button" v-if="currentUser" href="#" @click.stop.prevent="openMobileNotifications()">
|
||||
<i class="button-icon icon-bell-alt"></i>
|
||||
<div class="alert-dot" v-if="unseenNotificationsCount"></div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<SideDrawer ref="sideDrawer" :logout="logout"/>
|
||||
</nav>
|
||||
<div v-if="currentUser"
|
||||
class="mobile-notifications-drawer"
|
||||
:class="{ 'closed': !notificationsOpen }"
|
||||
@touchstart="notificationsTouchStart"
|
||||
@touchmove="notificationsTouchMove"
|
||||
@touchstart.stop="notificationsTouchStart"
|
||||
@touchmove.stop="notificationsTouchMove"
|
||||
>
|
||||
<div class="mobile-notifications-header">
|
||||
<span class="title">{{$t('notifications.notifications')}}</span>
|
||||
|
@ -27,12 +28,13 @@
|
|||
<i class="button-icon icon-cancel"/>
|
||||
</a>
|
||||
</div>
|
||||
<div v-if="currentUser" class="mobile-notifications">
|
||||
<div class="mobile-notifications" @scroll="onScroll">
|
||||
<Notifications ref="notifications" noHeading="true"/>
|
||||
</div>
|
||||
</div>
|
||||
<SideDrawer ref="sideDrawer" :logout="logout"/>
|
||||
<MobilePostStatusModal />
|
||||
</nav>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="./mobile_nav.js"></script>
|
||||
|
@ -79,6 +81,8 @@
|
|||
transition-property: transform;
|
||||
transition-duration: 0.25s;
|
||||
transform: translateX(0);
|
||||
z-index: 1001;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
|
||||
&.closed {
|
||||
transform: translateX(100%);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
</status>
|
||||
<div class="non-mention" :class="[userClass, { highlighted: userStyle }]" :style="[ userStyle ]" v-else>
|
||||
<a class='avatar-container' :href="notification.from_profile.statusnet_profile_url" @click.stop.prevent.capture="toggleUserExpanded">
|
||||
<UserAvatar :compact="true" :betterShadow="betterShadow" :src="notification.from_profile.profile_image_url_original" />
|
||||
<UserAvatar :compact="true" :betterShadow="betterShadow" :user="notification.from_profile"/>
|
||||
</a>
|
||||
<div class='notification-right'>
|
||||
<UserCard :user="getUser(notification)" :rounded="true" :bordered="true" v-if="userExpanded" />
|
||||
|
|
|
@ -52,6 +52,10 @@ const Notifications = {
|
|||
this.$store.dispatch('markNotificationsAsSeen')
|
||||
},
|
||||
fetchOlderNotifications () {
|
||||
if (this.loading) {
|
||||
return
|
||||
}
|
||||
|
||||
const store = this.$store
|
||||
const credentials = store.state.users.currentUser.credentials
|
||||
store.commit('setNotificationsLoading', { value: true })
|
||||
|
|
|
@ -263,13 +263,13 @@ const Status = {
|
|||
}
|
||||
return this.status.summary_html + '<br />' + this.status.statusnet_html
|
||||
},
|
||||
combinedFavsAndRepeatsAvatars () {
|
||||
combinedFavsAndRepeatsUsers () {
|
||||
// Use the status from the global status repository since favs and repeats are saved in it
|
||||
const combinedAvatars = [].concat(
|
||||
const combinedUsers = [].concat(
|
||||
this.statusFromGlobalRepository.favoritedBy,
|
||||
this.statusFromGlobalRepository.rebloggedBy
|
||||
)
|
||||
return uniqBy(combinedAvatars, 'id')
|
||||
return uniqBy(combinedUsers, 'id')
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
</template>
|
||||
<template v-else>
|
||||
<div v-if="retweet && !noHeading && !inConversation" :class="[repeaterClass, { highlighted: repeaterStyle }]" :style="[repeaterStyle]" class="media container retweet-info">
|
||||
<UserAvatar class="media-left" v-if="retweet" :betterShadow="betterShadow" :src="statusoid.user.profile_image_url_original"/>
|
||||
<UserAvatar class="media-left" v-if="retweet" :betterShadow="betterShadow" :user="statusoid.user"/>
|
||||
<div class="media-body faint">
|
||||
<span class="user-name">
|
||||
<router-link v-if="retweeterHtml" :to="retweeterProfileLink" v-html="retweeterHtml"/>
|
||||
|
@ -27,7 +27,7 @@
|
|||
<div :class="[userClass, { highlighted: userStyle, 'is-retweet': retweet && !inConversation }]" :style="[ userStyle ]" class="media status">
|
||||
<div v-if="!noHeading" class="media-left">
|
||||
<router-link :to="userProfileLink" @click.stop.prevent.capture.native="toggleUserExpanded">
|
||||
<UserAvatar :compact="compact" :betterShadow="betterShadow" :src="status.user.profile_image_url_original"/>
|
||||
<UserAvatar :compact="compact" :betterShadow="betterShadow" :user="status.user"/>
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="status-body">
|
||||
|
@ -91,8 +91,13 @@
|
|||
</div>
|
||||
|
||||
<div v-if="showPreview" class="status-preview-container">
|
||||
<status class="status-preview" v-if="preview" :isPreview="true" :statusoid="preview" :compact=true></status>
|
||||
<div class="status-preview status-preview-loading" v-else>
|
||||
<status class="status-preview"
|
||||
v-if="preview"
|
||||
:isPreview="true"
|
||||
:statusoid="preview"
|
||||
:compact=true
|
||||
/>
|
||||
<div v-else class="status-preview status-preview-loading">
|
||||
<i class="icon-spin4 animate-spin"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -134,7 +139,7 @@
|
|||
</div>
|
||||
|
||||
<transition name="fade">
|
||||
<div class="favs-repeated-users" v-if="combinedFavsAndRepeatsAvatars.length > 0 && isFocused">
|
||||
<div class="favs-repeated-users" v-if="combinedFavsAndRepeatsUsers.length > 0 && isFocused">
|
||||
<div class="stats">
|
||||
<div class="stat-count" v-if="statusFromGlobalRepository.rebloggedBy && statusFromGlobalRepository.rebloggedBy.length > 0">
|
||||
<a class="stat-title">{{ $t('status.repeats') }}</a>
|
||||
|
@ -145,7 +150,7 @@
|
|||
<div class="stat-number">{{ statusFromGlobalRepository.favoritedBy.length }}</div>
|
||||
</div>
|
||||
<div class="avatar-row">
|
||||
<AvatarList :avatars='combinedFavsAndRepeatsAvatars'></AvatarList>
|
||||
<AvatarList :users="combinedFavsAndRepeatsUsers"></AvatarList>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -2,7 +2,7 @@ import StillImage from '../still-image/still-image.vue'
|
|||
|
||||
const UserAvatar = {
|
||||
props: [
|
||||
'src',
|
||||
'user',
|
||||
'betterShadow',
|
||||
'compact'
|
||||
],
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
<template>
|
||||
<StillImage
|
||||
class="avatar"
|
||||
:alt="user.screen_name"
|
||||
:title="user.screen_name"
|
||||
:src="user.profile_image_url_original"
|
||||
:class="{ 'avatar-compact': compact, 'better-shadow': betterShadow }"
|
||||
:src="imgSrc"
|
||||
:imageLoadError="imageLoadError"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
@ -151,6 +151,9 @@ export default {
|
|||
},
|
||||
userProfileLink (user) {
|
||||
return generateProfileLink(user.id, user.screen_name, this.$store.state.instance.restrictedNicknames)
|
||||
},
|
||||
reportUser () {
|
||||
this.$store.dispatch('openUserReportingModal', this.user.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<div class='user-info'>
|
||||
<div class='container'>
|
||||
<router-link :to="userProfileLink(user)">
|
||||
<UserAvatar :betterShadow="betterShadow" :src="user.profile_image_url_original"/>
|
||||
<UserAvatar :betterShadow="betterShadow" :user="user"/>
|
||||
</router-link>
|
||||
<div class="name-and-screen-name">
|
||||
<div class="top-line">
|
||||
|
@ -99,8 +99,14 @@
|
|||
</button>
|
||||
</span>
|
||||
</div>
|
||||
<ModerationTools :user='user' v-if='loggedIn.role === "admin"'>
|
||||
</ModerationTools>
|
||||
<div class='block' v-if='isOtherUser && loggedIn'>
|
||||
<span>
|
||||
<button @click="reportUser">
|
||||
{{ $t('user_card.report') }}
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
<ModerationTools :user='user' v-if='loggedIn.role === "admin"'/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
106
src/components/user_reporting_modal/user_reporting_modal.js
Normal file
106
src/components/user_reporting_modal/user_reporting_modal.js
Normal file
|
@ -0,0 +1,106 @@
|
|||
|
||||
import Status from '../status/status.vue'
|
||||
import List from '../list/list.vue'
|
||||
import Checkbox from '../checkbox/checkbox.vue'
|
||||
|
||||
const UserReportingModal = {
|
||||
components: {
|
||||
Status,
|
||||
List,
|
||||
Checkbox
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
comment: '',
|
||||
forward: false,
|
||||
statusIdsToReport: [],
|
||||
processing: false,
|
||||
error: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isLoggedIn () {
|
||||
return !!this.$store.state.users.currentUser
|
||||
},
|
||||
isOpen () {
|
||||
return this.isLoggedIn && this.$store.state.reports.modalActivated
|
||||
},
|
||||
userId () {
|
||||
return this.$store.state.reports.userId
|
||||
},
|
||||
user () {
|
||||
return this.$store.getters.findUser(this.userId)
|
||||
},
|
||||
remoteInstance () {
|
||||
return !this.user.is_local && this.user.screen_name.substr(this.user.screen_name.indexOf('@') + 1)
|
||||
},
|
||||
statuses () {
|
||||
return this.$store.state.reports.statuses
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
userId: 'resetState'
|
||||
},
|
||||
methods: {
|
||||
resetState () {
|
||||
// Reset state
|
||||
this.comment = ''
|
||||
this.forward = false
|
||||
this.statusIdsToReport = []
|
||||
this.processing = false
|
||||
this.error = false
|
||||
},
|
||||
closeModal () {
|
||||
this.$store.dispatch('closeUserReportingModal')
|
||||
},
|
||||
reportUser () {
|
||||
this.processing = true
|
||||
this.error = false
|
||||
const params = {
|
||||
userId: this.userId,
|
||||
comment: this.comment,
|
||||
forward: this.forward,
|
||||
statusIds: this.statusIdsToReport
|
||||
}
|
||||
this.$store.state.api.backendInteractor.reportUser(params)
|
||||
.then(() => {
|
||||
this.processing = false
|
||||
this.resetState()
|
||||
this.closeModal()
|
||||
})
|
||||
.catch(() => {
|
||||
this.processing = false
|
||||
this.error = true
|
||||
})
|
||||
},
|
||||
clearError () {
|
||||
this.error = false
|
||||
},
|
||||
isChecked (statusId) {
|
||||
return this.statusIdsToReport.indexOf(statusId) !== -1
|
||||
},
|
||||
toggleStatus (checked, statusId) {
|
||||
if (checked === this.isChecked(statusId)) {
|
||||
return
|
||||
}
|
||||
|
||||
if (checked) {
|
||||
this.statusIdsToReport.push(statusId)
|
||||
} else {
|
||||
this.statusIdsToReport.splice(this.statusIdsToReport.indexOf(statusId), 1)
|
||||
}
|
||||
},
|
||||
resize (e) {
|
||||
const target = e.target || e
|
||||
if (!(target instanceof window.Element)) { return }
|
||||
// Auto is needed to make textbox shrink when removing lines
|
||||
target.style.height = 'auto'
|
||||
target.style.height = `${target.scrollHeight}px`
|
||||
if (target.value === '') {
|
||||
target.style.height = null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default UserReportingModal
|
157
src/components/user_reporting_modal/user_reporting_modal.vue
Normal file
157
src/components/user_reporting_modal/user_reporting_modal.vue
Normal file
|
@ -0,0 +1,157 @@
|
|||
<template>
|
||||
<div class="modal-view" @click="closeModal" v-if="isOpen">
|
||||
<div class="user-reporting-panel panel" @click.stop="">
|
||||
<div class="panel-heading">
|
||||
<div class="title">{{$t('user_reporting.title', [user.screen_name])}}</div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="user-reporting-panel-left">
|
||||
<div>
|
||||
<p>{{$t('user_reporting.add_comment_description')}}</p>
|
||||
<textarea
|
||||
v-model="comment"
|
||||
class="form-control"
|
||||
:placeholder="$t('user_reporting.additional_comments')"
|
||||
rows="1"
|
||||
@input="resize"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="!user.is_local">
|
||||
<p>{{$t('user_reporting.forward_description')}}</p>
|
||||
<Checkbox v-model="forward">{{$t('user_reporting.forward_to', [remoteInstance])}}</Checkbox>
|
||||
</div>
|
||||
<div>
|
||||
<button class="btn btn-default" @click="reportUser" :disabled="processing">{{$t('user_reporting.submit')}}</button>
|
||||
<div class="alert error" v-if="error">
|
||||
{{$t('user_reporting.generic_error')}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-reporting-panel-right">
|
||||
<List :items="statuses">
|
||||
<template slot="item" slot-scope="{item}">
|
||||
<div class="status-fadein user-reporting-panel-sitem">
|
||||
<Status :inConversation="false" :focused="false" :statusoid="item" />
|
||||
<Checkbox :checked="isChecked(item.id)" @change="checked => toggleStatus(checked, item.id)" />
|
||||
</div>
|
||||
</template>
|
||||
</List>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="./user_reporting_modal.js"></script>
|
||||
|
||||
<style lang="scss">
|
||||
@import '../../_variables.scss';
|
||||
|
||||
.user-reporting-panel {
|
||||
width: 90vw;
|
||||
max-width: 700px;
|
||||
min-height: 20vh;
|
||||
max-height: 80vh;
|
||||
|
||||
.panel-heading {
|
||||
.title {
|
||||
text-align: center;
|
||||
// TODO: Consider making these as default of panel
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.panel-body {
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
border-top: 1px solid;
|
||||
border-color: $fallback--border;
|
||||
border-color: var(--border, $fallback--border);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&-left {
|
||||
padding: 1.1em 0.7em 0.7em;
|
||||
line-height: 1.4em;
|
||||
box-sizing: border-box;
|
||||
|
||||
> div {
|
||||
margin-bottom: 1em;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
textarea.form-control {
|
||||
line-height: 16px;
|
||||
resize: none;
|
||||
overflow: hidden;
|
||||
transition: min-height 200ms 100ms;
|
||||
min-height: 44px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.btn {
|
||||
min-width: 10em;
|
||||
padding: 0 2em;
|
||||
}
|
||||
|
||||
.alert {
|
||||
margin: 1em 0 0 0;
|
||||
line-height: 1.3em;
|
||||
}
|
||||
}
|
||||
|
||||
&-right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
&-sitem {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
> .status-el {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
> .checkbox {
|
||||
margin: 0.75em;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (min-width: 801px) {
|
||||
.panel-body {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
&-left {
|
||||
width: 50%;
|
||||
max-width: 320px;
|
||||
border-right: 1px solid;
|
||||
border-color: $fallback--border;
|
||||
border-color: var(--border, $fallback--border);
|
||||
padding: 1.1em;
|
||||
|
||||
> div {
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
}
|
||||
|
||||
&-right {
|
||||
width: 50%;
|
||||
flex: 1 1 auto;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -420,6 +420,7 @@
|
|||
"muted": "Muted",
|
||||
"per_day": "per day",
|
||||
"remote_follow": "Remote follow",
|
||||
"report": "Report",
|
||||
"statuses": "Statuses",
|
||||
"unblock": "Unblock",
|
||||
"unblock_progress": "Unblocking...",
|
||||
|
@ -452,6 +453,15 @@
|
|||
"profile_does_not_exist": "Sorry, this profile does not exist.",
|
||||
"profile_loading_error": "Sorry, there was an error loading this profile."
|
||||
},
|
||||
"user_reporting": {
|
||||
"title": "Reporting {0}",
|
||||
"add_comment_description": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
|
||||
"additional_comments": "Additional comments",
|
||||
"forward_description": "The account is from another server. Send a copy of the report there as well?",
|
||||
"forward_to": "Forward to {0}",
|
||||
"submit": "Submit",
|
||||
"generic_error": "An error occurred while processing your request."
|
||||
},
|
||||
"who_to_follow": {
|
||||
"more": "More",
|
||||
"who_to_follow": "Who to follow"
|
||||
|
|
106
src/i18n/es.json
106
src/i18n/es.json
|
@ -2,6 +2,10 @@
|
|||
"chat": {
|
||||
"title": "Chat"
|
||||
},
|
||||
"exporter": {
|
||||
"export": "Exportar",
|
||||
"processing": "Procesando. Pronto se te pedirá que descargues tu archivo"
|
||||
},
|
||||
"features_panel": {
|
||||
"chat": "Chat",
|
||||
"gopher": "Gopher",
|
||||
|
@ -19,7 +23,22 @@
|
|||
"apply": "Aplicar",
|
||||
"submit": "Enviar",
|
||||
"more": "Más",
|
||||
"generic_error": "Ha ocurrido un error"
|
||||
"generic_error": "Ha ocurrido un error",
|
||||
"optional": "opcional",
|
||||
"show_more": "Mostrar más",
|
||||
"show_less": "Mostrar menos",
|
||||
"cancel": "Cancelar"
|
||||
},
|
||||
"image_cropper": {
|
||||
"crop_picture": "Recortar la foto",
|
||||
"save": "Guardar",
|
||||
"save_without_cropping": "Guardar sin recortar",
|
||||
"cancel": "Cancelar"
|
||||
},
|
||||
"importer": {
|
||||
"submit": "Enviar",
|
||||
"success": "Importado con éxito",
|
||||
"error": "Se ha producido un error al importar el archivo."
|
||||
},
|
||||
"login": {
|
||||
"login": "Identificación",
|
||||
|
@ -30,6 +49,10 @@
|
|||
"register": "Registrar",
|
||||
"username": "Usuario",
|
||||
"hint": "Inicia sesión para unirte a la discusión"
|
||||
},
|
||||
"media_modal": {
|
||||
"previous": "Anterior",
|
||||
"next": "Siguiente"
|
||||
},
|
||||
"nav": {
|
||||
"about": "Sobre",
|
||||
|
@ -61,15 +84,19 @@
|
|||
"account_not_locked_warning_link": "bloqueada",
|
||||
"attachments_sensitive": "Contenido sensible",
|
||||
"content_type": {
|
||||
"text/plain": "Texto Plano"
|
||||
"text/plain": "Texto Plano",
|
||||
"text/html": "HTML",
|
||||
"text/markdown": "Markdown",
|
||||
"text/bbcode": "BBCode"
|
||||
},
|
||||
"content_warning": "Tema (opcional)",
|
||||
"default": "Acabo de aterrizar en L.A.",
|
||||
"direct_warning": "Esta entrada solo será visible para los usuarios mencionados.",
|
||||
"direct_warning": "Esta publicación solo será visible para los usuarios mencionados.",
|
||||
"direct_warning_to_first_only": "Esta publicación solo será visible para los usuarios mencionados al comienzo del mensaje.",
|
||||
"posting": "Publicando",
|
||||
"scope": {
|
||||
"direct": "Directo - Solo para los usuarios mencionados.",
|
||||
"private": "Solo-Seguidores - Solo tus seguidores leeran la entrada",
|
||||
"private": "Solo-Seguidores - Solo tus seguidores leeran la publicación",
|
||||
"public": "Público - Entradas visibles en las Líneas Temporales Públicas",
|
||||
"unlisted": "Sin Listar - Entradas no visibles en las Líneas Temporales Públicas"
|
||||
}
|
||||
|
@ -83,6 +110,9 @@
|
|||
"token": "Token de invitación",
|
||||
"captcha": "CAPTCHA",
|
||||
"new_captcha": "Click en la imagen para obtener un nuevo captca",
|
||||
"username_placeholder": "p.ej. lain",
|
||||
"fullname_placeholder": "p.ej. Lain Iwakura",
|
||||
"bio_placeholder": "e.g.\nHola, soy un ejemplo.\nAquí puedes poner algo representativo tuyo... o no.",
|
||||
"validations": {
|
||||
"username_required": "no puede estar vacío",
|
||||
"fullname_required": "no puede estar vacío",
|
||||
|
@ -91,8 +121,12 @@
|
|||
"password_confirmation_required": "no puede estar vacío",
|
||||
"password_confirmation_match": "la contraseña no coincide"
|
||||
}
|
||||
},
|
||||
"selectable_list": {
|
||||
"select_all": "Seleccionarlo todo"
|
||||
},
|
||||
"settings": {
|
||||
"app_name": "Nombre de la aplicación",
|
||||
"attachmentRadius": "Adjuntos",
|
||||
"attachments": "Adjuntos",
|
||||
"autoload": "Activar carga automática al llegar al final de la página",
|
||||
|
@ -101,6 +135,12 @@
|
|||
"avatarRadius": "Avatares",
|
||||
"background": "Fondo",
|
||||
"bio": "Biografía",
|
||||
"block_export": "Exportar usuarios bloqueados",
|
||||
"block_export_button": "Exporta la lista de tus usarios bloqueados a un archivo csv",
|
||||
"block_import": "Importar usuarios bloqueados",
|
||||
"block_import_error": "Error importando la lista de usuarios bloqueados",
|
||||
"blocks_imported": "¡Lista de usuarios bloqueados importada! El procesado puede tardar un poco.",
|
||||
"blocks_tab": "Bloqueados",
|
||||
"btnRadius": "Botones",
|
||||
"cBlue": "Azul (Responder, seguir)",
|
||||
"cGreen": "Verde (Retweet)",
|
||||
|
@ -127,7 +167,6 @@
|
|||
"filtering_explanation": "Todos los estados que contengan estas palabras serán silenciados, una por línea",
|
||||
"follow_export": "Exportar personas que tú sigues",
|
||||
"follow_export_button": "Exporta tus seguidores a un archivo csv",
|
||||
"follow_export_processing": "Procesando, en breve se te preguntará para guardar el archivo",
|
||||
"follow_import": "Importar personas que tú sigues",
|
||||
"follow_import_error": "Error al importal el archivo",
|
||||
"follows_imported": "¡Importado! Procesarlos llevará tiempo.",
|
||||
|
@ -135,12 +174,15 @@
|
|||
"general": "General",
|
||||
"hide_attachments_in_convo": "Ocultar adjuntos en las conversaciones",
|
||||
"hide_attachments_in_tl": "Ocultar adjuntos en la línea temporal",
|
||||
"hide_muted_posts": "Ocultar las publicaciones de los usuarios silenciados",
|
||||
"max_thumbnails": "Cantidad máxima de miniaturas por publicación",
|
||||
"hide_isp": "Ocultar el panel específico de la instancia",
|
||||
"preload_images": "Precargar las imágenes",
|
||||
"use_one_click_nsfw": "Abrir los adjuntos NSFW con un solo click.",
|
||||
"hide_post_stats": "Ocultar las estadísticas de las entradas (p.ej. el número de favoritos)",
|
||||
"hide_user_stats": "Ocultar las estadísticas del usuario (p.ej. el número de seguidores)",
|
||||
"hide_filtered_statuses": "Ocultar estados filtrados",
|
||||
"import_blocks_from_a_csv_file": "Importar lista de usuarios bloqueados dese un archivo csv",
|
||||
"import_followers_from_a_csv_file": "Importar personas que tú sigues a partir de un archivo csv",
|
||||
"import_theme": "Importar tema",
|
||||
"inputRadius": "Campos de entrada",
|
||||
|
@ -155,6 +197,7 @@
|
|||
"lock_account_description": "Restringir el acceso a tu cuenta solo a seguidores admitidos",
|
||||
"loop_video": "Vídeos en bucle",
|
||||
"loop_video_silent_only": "Bucle solo en vídeos sin sonido (p.ej. \"gifs\" de Mastodon)",
|
||||
"mutes_tab": "Silenciados",
|
||||
"play_videos_in_modal": "Reproducir los vídeos directamente en el visor de medios",
|
||||
"use_contain_fit": "No recortar los adjuntos en miniaturas",
|
||||
"name": "Nombre",
|
||||
|
@ -166,6 +209,8 @@
|
|||
"notification_visibility_mentions": "Menciones",
|
||||
"notification_visibility_repeats": "Repeticiones (Repeats)",
|
||||
"no_rich_text_description": "Eliminar el formato de texto enriquecido de todas las entradas",
|
||||
"no_blocks": "No hay usuarios bloqueados",
|
||||
"no_mutes": "No hay usuarios sinlenciados",
|
||||
"hide_follows_description": "No mostrar a quién sigo",
|
||||
"hide_followers_description": "No mostrar quién me sigue",
|
||||
"show_admin_badge": "Mostrar la placa de administrador en mi perfil",
|
||||
|
@ -190,8 +235,11 @@
|
|||
"reply_visibility_self": "Solo mostrar réplicas para mí",
|
||||
"saving_err": "Error al guardar los ajustes",
|
||||
"saving_ok": "Ajustes guardados",
|
||||
"search_user_to_block": "Buscar usuarios a bloquear",
|
||||
"search_user_to_mute": "Buscar usuarios a silenciar",
|
||||
"security_tab": "Seguridad",
|
||||
"scope_copy": "Copiar la visibilidad cuando contestamos (En los mensajes directos (MDs) siempre se copia)",
|
||||
"scope_copy": "Copiar la visibilidad de la publicación cuando contestamos (En los mensajes directos (MDs) siempre se copia)",
|
||||
"minimal_scopes_mode": "Minimizar las opciones de publicación",
|
||||
"set_new_avatar": "Cambiar avatar",
|
||||
"set_new_profile_background": "Cambiar fondo del perfil",
|
||||
"set_new_profile_banner": "Cambiar cabecera del perfil",
|
||||
|
@ -210,6 +258,7 @@
|
|||
"theme_help_v2_1": "También puede invalidar los colores y la opacidad de ciertos componentes si activa la casilla de verificación, use el botón \"Borrar todo\" para deshacer los cambios.",
|
||||
"theme_help_v2_2": "Los iconos debajo de algunas entradas son indicadores de contraste de fondo/texto, desplace el ratón para obtener información detallada. Tenga en cuenta que cuando se utilizan indicadores de contraste de transparencia se muestra el peor caso posible.",
|
||||
"tooltipRadius": "Información/alertas",
|
||||
"upload_a_photo": "Subir una foto",
|
||||
"user_settings": "Ajustes de Usuario",
|
||||
"values": {
|
||||
"false": "no",
|
||||
|
@ -325,6 +374,11 @@
|
|||
"checkbox": "He revisado los términos y condiciones",
|
||||
"link": "un bonito enlace"
|
||||
}
|
||||
},
|
||||
"version": {
|
||||
"title": "Versión",
|
||||
"backend_version": "Versión del Backend",
|
||||
"frontend_version": "Versión del Frontend"
|
||||
}
|
||||
},
|
||||
"timeline": {
|
||||
|
@ -336,7 +390,14 @@
|
|||
"repeated": "repetida",
|
||||
"show_new": "Mostrar lo nuevo",
|
||||
"up_to_date": "Actualizado",
|
||||
"no_more_statuses": "No hay más estados"
|
||||
"no_more_statuses": "No hay más estados",
|
||||
"no_statuses": "Sin estados"
|
||||
},
|
||||
"status": {
|
||||
"favorites": "Favoritos",
|
||||
"repeats": "Repetidos",
|
||||
"reply_to": "Responder a",
|
||||
"replies_list": "Respuestas:"
|
||||
},
|
||||
"user_card": {
|
||||
"approve": "Aprovar",
|
||||
|
@ -359,10 +420,37 @@
|
|||
"muted": "Silenciado",
|
||||
"per_day": "por día",
|
||||
"remote_follow": "Seguir",
|
||||
"statuses": "Estados"
|
||||
"statuses": "Estados",
|
||||
"unblock": "Desbloquear",
|
||||
"unblock_progress": "Desbloqueando...",
|
||||
"block_progress": "Bloqueando...",
|
||||
"unmute": "Desenmudecer",
|
||||
"unmute_progress": "Sesenmudeciendo...",
|
||||
"mute_progress": "Silenciando...",
|
||||
"admin_menu": {
|
||||
"moderation": "Moderación",
|
||||
"grant_admin": "Conceder permisos de Administrador",
|
||||
"revoke_admin": "Revocar permisos de Administrador",
|
||||
"grant_moderator": "Conceder permisos de Moderador",
|
||||
"revoke_moderator": "Revocar permisos de Moderador",
|
||||
"activate_account": "Activar cuenta",
|
||||
"deactivate_account": "Desactivar cuenta",
|
||||
"delete_account": "Borrar cuenta",
|
||||
"force_nsfw": "Marcar todas las publicaciones como NSFW (no es seguro/apropiado para el trabajo)",
|
||||
"strip_media": "Eliminar archivos multimedia de las publicaciones",
|
||||
"force_unlisted": "Forzar que se publique en el modo -Sin Listar-",
|
||||
"sandbox": "Forzar que se publique solo para tus seguidores",
|
||||
"disable_remote_subscription": "No permitir que usuarios de instancias remotas te siga.",
|
||||
"disable_any_subscription": "No permitir que ningún usuario te siga",
|
||||
"quarantine": "No permitir publicaciones de usuarios de instancias remotas",
|
||||
"delete_user": "Borrar usuario",
|
||||
"delete_user_confirmation": "¿Estás completamente seguro? Esta acción no se puede deshacer."
|
||||
}
|
||||
},
|
||||
"user_profile": {
|
||||
"timeline_title": "Linea temporal del usuario"
|
||||
"timeline_title": "Linea temporal del usuario",
|
||||
"profile_does_not_exist": "Lo sentimos, este perfil no existe.",
|
||||
"profile_loading_error": "Lo sentimos, hubo un error al cargar este perfil."
|
||||
},
|
||||
"who_to_follow": {
|
||||
"more": "Más",
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
"chat": {
|
||||
"title": "Messatjariá"
|
||||
},
|
||||
"exporter": {
|
||||
"export": "Exportar",
|
||||
"processing": "Tractament, vos demandarem lèu de telecargar lo fichièr"
|
||||
},
|
||||
"features_panel": {
|
||||
"chat": "Chat",
|
||||
"gopher": "Gopher",
|
||||
|
@ -30,6 +34,11 @@
|
|||
"save": "Salvar",
|
||||
"save_without_cropping": "Salvar sens talhada",
|
||||
"cancel": "Anullar"
|
||||
},
|
||||
"importer": {
|
||||
"submit": "Mandar",
|
||||
"success": "Corrèctament importat.",
|
||||
"error": "Una error s’es producha pendent l’importacion d’aqueste fichièr."
|
||||
},
|
||||
"login": {
|
||||
"login": "Connexion",
|
||||
|
@ -126,6 +135,11 @@
|
|||
"avatarRadius": "Avatars",
|
||||
"background": "Rèire plan",
|
||||
"bio": "Biografia",
|
||||
"block_export": "Exportar los blocatges",
|
||||
"block_export_button": "Exportar los blocatges dins un fichièr csv",
|
||||
"block_import": "Impòrt de blocatges",
|
||||
"block_import_error": "Error en importar los blocatges",
|
||||
"blocks_imported": "Blocatges importats ! Lo tractament tardarà un pauc.",
|
||||
"blocks_tab": "Blocatges",
|
||||
"btnRadius": "Botons",
|
||||
"cBlue": "Blau (Respondre, seguir)",
|
||||
|
@ -153,7 +167,6 @@
|
|||
"filtering_explanation": "Totes los estatuts amb aqueles mots seràn en silenci, un mot per linha",
|
||||
"follow_export": "Exportar los abonaments",
|
||||
"follow_export_button": "Exportar vòstres abonaments dins un fichièr csv",
|
||||
"follow_export_processing": "Tractament, vos demandarem lèu de telecargar lo fichièr",
|
||||
"follow_import": "Importar los abonaments",
|
||||
"follow_import_error": "Error en important los seguidors",
|
||||
"follows_imported": "Seguidors importats. Lo tractament pòt trigar una estona.",
|
||||
|
@ -188,6 +201,7 @@
|
|||
"use_contain_fit": "Talhar pas las pèças juntas per las vinhetas",
|
||||
"name": "Nom",
|
||||
"name_bio": "Nom & Bio",
|
||||
|
||||
"new_password": "Nòu senhal",
|
||||
"notification_visibility_follows": "Abonaments",
|
||||
"notification_visibility_likes": "Aimar",
|
||||
|
@ -380,6 +394,8 @@
|
|||
"no_statuses": "Cap d’estatuts"
|
||||
},
|
||||
"status": {
|
||||
"favorites": "Li a agradat",
|
||||
"repeats": "A repetit",
|
||||
"reply_to": "Respond a",
|
||||
"replies_list": "Responsas :"
|
||||
},
|
||||
|
@ -461,4 +477,4 @@
|
|||
"TiB": "Tio"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@ import chatModule from './modules/chat.js'
|
|||
import oauthModule from './modules/oauth.js'
|
||||
import mediaViewerModule from './modules/media_viewer.js'
|
||||
import oauthTokensModule from './modules/oauth_tokens.js'
|
||||
import reportsModule from './modules/reports.js'
|
||||
|
||||
import VueTimeago from 'vue-timeago'
|
||||
import VueI18n from 'vue-i18n'
|
||||
|
@ -75,7 +76,8 @@ const persistedStateOptions = {
|
|||
chat: chatModule,
|
||||
oauth: oauthModule,
|
||||
mediaViewer: mediaViewerModule,
|
||||
oauthTokens: oauthTokensModule
|
||||
oauthTokens: oauthTokensModule,
|
||||
reports: reportsModule
|
||||
},
|
||||
plugins: [persistedState, pushNotifications],
|
||||
strict: false // Socket modifies itself, let's ignore this for now.
|
||||
|
|
30
src/modules/reports.js
Normal file
30
src/modules/reports.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
import filter from 'lodash/filter'
|
||||
|
||||
const reports = {
|
||||
state: {
|
||||
userId: null,
|
||||
statuses: [],
|
||||
modalActivated: false
|
||||
},
|
||||
mutations: {
|
||||
openUserReportingModal (state, { userId, statuses }) {
|
||||
state.userId = userId
|
||||
state.statuses = statuses
|
||||
state.modalActivated = true
|
||||
},
|
||||
closeUserReportingModal (state) {
|
||||
state.modalActivated = false
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
openUserReportingModal ({ rootState, commit }, userId) {
|
||||
const statuses = filter(rootState.statuses.allStatuses, status => status.user.id === userId)
|
||||
commit('openUserReportingModal', { userId, statuses })
|
||||
},
|
||||
closeUserReportingModal ({ commit }) {
|
||||
commit('closeUserReportingModal')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default reports
|
|
@ -50,6 +50,7 @@ const MASTODON_MEDIA_UPLOAD_URL = '/api/v1/media'
|
|||
const MASTODON_STATUS_FAVORITEDBY_URL = id => `/api/v1/statuses/${id}/favourited_by`
|
||||
const MASTODON_STATUS_REBLOGGEDBY_URL = id => `/api/v1/statuses/${id}/reblogged_by`
|
||||
const MASTODON_PROFILE_UPDATE_URL = '/api/v1/accounts/update_credentials'
|
||||
const MASTODON_REPORT_USER_URL = '/api/v1/reports'
|
||||
|
||||
import { each, map, concat, last } from 'lodash'
|
||||
import { parseStatus, parseUser, parseNotification, parseAttachment } from '../entity_normalizer/entity_normalizer.service.js'
|
||||
|
@ -66,7 +67,24 @@ let fetch = (url, options) => {
|
|||
return oldfetch(fullUrl, options)
|
||||
}
|
||||
|
||||
const promisedRequest = (url, options) => {
|
||||
const promisedRequest = ({ method, url, payload, credentials, headers = {} }) => {
|
||||
const options = {
|
||||
method,
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
...headers
|
||||
}
|
||||
}
|
||||
if (payload) {
|
||||
options.body = JSON.stringify(payload)
|
||||
}
|
||||
if (credentials) {
|
||||
options.headers = {
|
||||
...options.headers,
|
||||
...authHeaders(credentials)
|
||||
}
|
||||
}
|
||||
return fetch(url, options)
|
||||
.then((response) => {
|
||||
return new Promise((resolve, reject) => response.json()
|
||||
|
@ -122,14 +140,11 @@ const updateBanner = ({credentials, banner}) => {
|
|||
}
|
||||
|
||||
const updateProfile = ({credentials, params}) => {
|
||||
return promisedRequest(MASTODON_PROFILE_UPDATE_URL, {
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
...authHeaders(credentials)
|
||||
},
|
||||
return promisedRequest({
|
||||
url: MASTODON_PROFILE_UPDATE_URL,
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(params)
|
||||
payload: params,
|
||||
credentials
|
||||
})
|
||||
.then((data) => parseUser(data))
|
||||
}
|
||||
|
@ -227,7 +242,7 @@ const denyUser = ({id, credentials}) => {
|
|||
|
||||
const fetchUser = ({id, credentials}) => {
|
||||
let url = `${MASTODON_USER_URL}/${id}`
|
||||
return promisedRequest(url, { headers: authHeaders(credentials) })
|
||||
return promisedRequest({ url, credentials })
|
||||
.then((data) => parseUser(data))
|
||||
}
|
||||
|
||||
|
@ -651,26 +666,20 @@ const changePassword = ({credentials, password, newPassword, newPasswordConfirma
|
|||
}
|
||||
|
||||
const fetchMutes = ({credentials}) => {
|
||||
return promisedRequest(MASTODON_USER_MUTES_URL, { headers: authHeaders(credentials) })
|
||||
return promisedRequest({ url: MASTODON_USER_MUTES_URL, credentials })
|
||||
.then((users) => users.map(parseUser))
|
||||
}
|
||||
|
||||
const muteUser = ({id, credentials}) => {
|
||||
return promisedRequest(MASTODON_MUTE_USER_URL(id), {
|
||||
headers: authHeaders(credentials),
|
||||
method: 'POST'
|
||||
})
|
||||
return promisedRequest({ url: MASTODON_MUTE_USER_URL(id), credentials, method: 'POST' })
|
||||
}
|
||||
|
||||
const unmuteUser = ({id, credentials}) => {
|
||||
return promisedRequest(MASTODON_UNMUTE_USER_URL(id), {
|
||||
headers: authHeaders(credentials),
|
||||
method: 'POST'
|
||||
})
|
||||
return promisedRequest({ url: MASTODON_UNMUTE_USER_URL(id), credentials, method: 'POST' })
|
||||
}
|
||||
|
||||
const fetchBlocks = ({credentials}) => {
|
||||
return promisedRequest(MASTODON_USER_BLOCKS_URL, { headers: authHeaders(credentials) })
|
||||
return promisedRequest({ url: MASTODON_USER_BLOCKS_URL, credentials })
|
||||
.then((users) => users.map(parseUser))
|
||||
}
|
||||
|
||||
|
@ -715,11 +724,25 @@ const markNotificationsAsSeen = ({id, credentials}) => {
|
|||
}
|
||||
|
||||
const fetchFavoritedByUsers = ({id}) => {
|
||||
return promisedRequest(MASTODON_STATUS_FAVORITEDBY_URL(id)).then((users) => users.map(parseUser))
|
||||
return promisedRequest({ url: MASTODON_STATUS_FAVORITEDBY_URL(id) }).then((users) => users.map(parseUser))
|
||||
}
|
||||
|
||||
const fetchRebloggedByUsers = ({id}) => {
|
||||
return promisedRequest(MASTODON_STATUS_REBLOGGEDBY_URL(id)).then((users) => users.map(parseUser))
|
||||
return promisedRequest({ url: MASTODON_STATUS_REBLOGGEDBY_URL(id) }).then((users) => users.map(parseUser))
|
||||
}
|
||||
|
||||
const reportUser = ({credentials, userId, statusIds, comment, forward}) => {
|
||||
return promisedRequest({
|
||||
url: MASTODON_REPORT_USER_URL,
|
||||
method: 'POST',
|
||||
payload: {
|
||||
'account_id': userId,
|
||||
'status_ids': statusIds,
|
||||
comment,
|
||||
forward
|
||||
},
|
||||
credentials
|
||||
})
|
||||
}
|
||||
|
||||
const apiService = {
|
||||
|
@ -773,7 +796,8 @@ const apiService = {
|
|||
suggestions,
|
||||
markNotificationsAsSeen,
|
||||
fetchFavoritedByUsers,
|
||||
fetchRebloggedByUsers
|
||||
fetchRebloggedByUsers,
|
||||
reportUser
|
||||
}
|
||||
|
||||
export default apiService
|
||||
|
|
|
@ -115,6 +115,7 @@ const backendInteractorService = (credentials) => {
|
|||
|
||||
const fetchFavoritedByUsers = (id) => apiService.fetchFavoritedByUsers({id})
|
||||
const fetchRebloggedByUsers = (id) => apiService.fetchRebloggedByUsers({id})
|
||||
const reportUser = (params) => apiService.reportUser({credentials, ...params})
|
||||
|
||||
const backendInteractorServiceInstance = {
|
||||
fetchStatus,
|
||||
|
@ -159,7 +160,8 @@ const backendInteractorService = (credentials) => {
|
|||
approveUser,
|
||||
denyUser,
|
||||
fetchFavoritedByUsers,
|
||||
fetchRebloggedByUsers
|
||||
fetchRebloggedByUsers,
|
||||
reportUser
|
||||
}
|
||||
|
||||
return backendInteractorServiceInstance
|
||||
|
|
|
@ -275,6 +275,9 @@ export const parseStatus = (data) => {
|
|||
output.retweeted_status = parseStatus(retweetedStatus)
|
||||
}
|
||||
|
||||
output.favoritedBy = []
|
||||
output.rebloggedBy = []
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue