Merge remote-tracking branch 'upstream/develop' into shigusegubu

* upstream/develop: (24 commits)
  link interaction avatars to the user profile
  Use more clear explanation in the scope notice, make sure the hide button doesn't overlap with text in notice.
  use backendInteractor
  refactor api service functions using new helper
  clean up
  update favorite number earlier
  update status interaction upon retweet action response
  sync up favoritedBy with favorite/unfavorite action
  do not regenerate status object
  reduce needless calculation
  Move scope visibility notice to the status form, make it dismissible
  Revert "eliminate expandable prop in favor of inConversation"
  status attention doesn’t have relationship entities
  make it short
  fix wrong inlineExpanded
  expanded is always false, eliminate it
  eliminate expandable prop in favor of inConversation
  fix conversationId comparision bug using integer format
  Display additional scope description above the status form for mobile users.
  Update es.json
  ...
This commit is contained in:
Henry Jameson 2019-05-09 22:04:17 +03:00
commit 0084a63e41
22 changed files with 193 additions and 113 deletions

View file

@ -1,4 +1,5 @@
import UserAvatar from '../user_avatar/user_avatar.vue'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
const AvatarList = {
props: ['users'],
@ -9,6 +10,11 @@ const AvatarList = {
},
components: {
UserAvatar
},
methods: {
userProfileLink (user) {
return generateProfileLink(user.id, user.screen_name, this.$store.state.instance.restrictedNicknames)
}
}
}

View file

@ -1,8 +1,8 @@
<template>
<div class="avatars">
<div class="avatars-item" v-for="user in slicedUsers">
<UserAvatar :user="user" class="avatar-small" />
</div>
<router-link :to="userProfileLink(user)" class="avatars-item" v-for="user in slicedUsers">
<UserAvatar :user="user" class="avatar-small" />
</router-link>
</div>
</template>

View file

@ -11,7 +11,7 @@
@goto="setHighlight"
@toggleExpanded="toggleExpanded"
:key="status.id"
:inlineExpanded="collapsable"
:inlineExpanded="collapsable && isExpanded"
:statusoid="status"
:expandable='!isExpanded'
:focused="focused(status.id)"

View file

@ -33,6 +33,8 @@
@import '../../_variables.scss';
.media-modal-view {
z-index: 1001;
&:hover {
.modal-view-button-arrow {
opacity: 0.75;

View file

@ -1,5 +1,5 @@
import PostStatusForm from '../post_status_form/post_status_form.vue'
import { throttle } from 'lodash'
import { debounce } from 'lodash'
const MobilePostStatusModal = {
components: {
@ -16,11 +16,15 @@ const MobilePostStatusModal = {
}
},
created () {
window.addEventListener('scroll', this.handleScroll)
if (this.autohideFloatingPostButton) {
this.activateFloatingPostButtonAutohide()
}
window.addEventListener('resize', this.handleOSK)
},
destroyed () {
window.removeEventListener('scroll', this.handleScroll)
if (this.autohideFloatingPostButton) {
this.deactivateFloatingPostButtonAutohide()
}
window.removeEventListener('resize', this.handleOSK)
},
computed: {
@ -28,10 +32,30 @@ const MobilePostStatusModal = {
return this.$store.state.users.currentUser
},
isHidden () {
return this.hidden || this.inputActive
return this.autohideFloatingPostButton && (this.hidden || this.inputActive)
},
autohideFloatingPostButton () {
return !!this.$store.state.config.autohideFloatingPostButton
}
},
watch: {
autohideFloatingPostButton: function (isEnabled) {
if (isEnabled) {
this.activateFloatingPostButtonAutohide()
} else {
this.deactivateFloatingPostButtonAutohide()
}
}
},
methods: {
activateFloatingPostButtonAutohide () {
window.addEventListener('scroll', this.handleScrollStart)
window.addEventListener('scroll', this.handleScrollEnd)
},
deactivateFloatingPostButtonAutohide () {
window.removeEventListener('scroll', this.handleScrollStart)
window.removeEventListener('scroll', this.handleScrollEnd)
},
openPostForm () {
this.postFormOpen = true
this.hidden = true
@ -65,26 +89,19 @@ const MobilePostStatusModal = {
this.inputActive = false
}
},
handleScroll: throttle(function () {
const scrollAmount = window.scrollY - this.oldScrollPos
const scrollingDown = scrollAmount > 0
if (scrollingDown !== this.scrollingDown) {
this.amountScrolled = 0
this.scrollingDown = scrollingDown
if (!scrollingDown) {
this.hidden = false
}
} else if (scrollingDown) {
this.amountScrolled += scrollAmount
if (this.amountScrolled > 100 && !this.hidden) {
this.hidden = true
}
handleScrollStart: debounce(function () {
if (window.scrollY > this.oldScrollPos) {
this.hidden = true
} else {
this.hidden = false
}
this.oldScrollPos = window.scrollY
this.scrollingDown = scrollingDown
}, 100)
}, 100, {leading: true, trailing: false}),
handleScrollEnd: debounce(function () {
this.hidden = false
this.oldScrollPos = window.scrollY
}, 100, {leading: false, trailing: true})
}
}

View file

@ -7,7 +7,7 @@
>
<div class="post-form-modal-panel panel" @click.stop="">
<div class="panel-heading">{{$t('post_status.new_status')}}</div>
<PostStatusForm class="panel-body" @posted="closePostForm"/>
<PostStatusForm class="panel-body" @posted="closePostForm" />
</div>
</div>
<button

View file

@ -182,6 +182,9 @@ const PostStatusForm = {
},
safeDMEnabled () {
return this.$store.state.instance.safeDM
},
hideScopeNotice () {
return this.$store.state.config.hideScopeNotice
}
},
methods: {
@ -336,6 +339,9 @@ const PostStatusForm = {
},
changeVis (visibility) {
this.newStatus.visibility = visibility
},
dismissScopeNotice () {
this.$store.dispatch('setOption', { name: 'hideScopeNotice', value: true })
}
}
}

View file

@ -9,7 +9,25 @@
class="visibility-notice">
<router-link :to="{ name: 'user-settings' }">{{ $t('post_status.account_not_locked_warning_link') }}</router-link>
</i18n>
<p v-if="newStatus.visibility === 'direct'" class="visibility-notice">
<p v-if="!hideScopeNotice && newStatus.visibility === 'public'" class="visibility-notice notice-dismissible">
<span>{{ $t('post_status.scope_notice.public') }}</span>
<a v-on:click.prevent="dismissScopeNotice()" class="button-icon dismiss">
<i class='icon-cancel'></i>
</a>
</p>
<p v-else-if="!hideScopeNotice && newStatus.visibility === 'unlisted'" class="visibility-notice notice-dismissible">
<span>{{ $t('post_status.scope_notice.unlisted') }}</span>
<a v-on:click.prevent="dismissScopeNotice()" class="button-icon dismiss">
<i class='icon-cancel'></i>
</a>
</p>
<p v-else-if="!hideScopeNotice && newStatus.visibility === 'private' && $store.state.users.currentUser.locked" class="visibility-notice notice-dismissible">
<span>{{ $t('post_status.scope_notice.private') }}</span>
<a v-on:click.prevent="dismissScopeNotice()" class="button-icon dismiss">
<i class='icon-cancel'></i>
</a>
</p>
<p v-else-if="newStatus.visibility === 'direct'" class="visibility-notice">
<span v-if="safeDMEnabled">{{ $t('post_status.direct_warning_to_first_only') }}</span>
<span v-else>{{ $t('post_status.direct_warning_to_all') }}</span>
</p>

View file

@ -46,6 +46,7 @@ const settings = {
streamingLocal: user.streaming,
pauseOnUnfocusedLocal: user.pauseOnUnfocused,
hoverPreviewLocal: user.hoverPreview,
autohideFloatingPostButtonLocal: user.autohideFloatingPostButton,
hideMutedPostsLocal: typeof user.hideMutedPosts === 'undefined'
? instance.hideMutedPosts
@ -183,6 +184,9 @@ const settings = {
hoverPreviewLocal (value) {
this.$store.dispatch('setOption', { name: 'hoverPreview', value })
},
autohideFloatingPostButtonLocal (value) {
this.$store.dispatch('setOption', { name: 'autohideFloatingPostButton', value })
},
muteWordsString (value) {
value = filter(value.split('\n'), (word) => trim(word).length > 0)
this.$store.dispatch('setOption', { name: 'muteWords', value })

View file

@ -122,6 +122,10 @@
{{$t('settings.minimal_scopes_mode')}} {{$t('settings.instance_default', { value: minimalScopesModeDefault })}}
</label>
</li>
<li>
<input type="checkbox" id="autohideFloatingPostButton" v-model="autohideFloatingPostButtonLocal">
<label for="autohideFloatingPostButton">{{$t('settings.autohide_floating_post_button')}}</label>
</li>
</ul>
</div>

View file

@ -31,7 +31,6 @@ const Status = {
data () {
return {
replying: false,
expanded: false,
unmuted: false,
userExpanded: false,
preview: null,
@ -161,7 +160,7 @@ const Status = {
if (this.$store.state.config.replyVisibility === 'all') {
return false
}
if (this.inlineExpanded || this.expanded || this.inConversation || !this.isReply) {
if (this.inConversation || !this.isReply) {
return false
}
if (this.status.user.id === this.$store.state.users.currentUser.id) {
@ -175,7 +174,7 @@ const Status = {
if (this.status.user.id === this.status.attentions[i].id) {
continue
}
if (checkFollowing && this.status.attentions[i].following) {
if (checkFollowing && this.$store.getters.findUser(this.status.attentions[i].id).following) {
return false
}
if (this.status.attentions[i].id === this.$store.state.users.currentUser.id) {

View file

@ -139,7 +139,7 @@
</div>
<transition name="fade">
<div class="favs-repeated-users" v-if="combinedFavsAndRepeatsUsers.length > 0 && isFocused">
<div class="favs-repeated-users" v-if="isFocused && combinedFavsAndRepeatsUsers.length > 0">
<div class="stats">
<div class="stat-count" v-if="statusFromGlobalRepository.rebloggedBy && statusFromGlobalRepository.rebloggedBy.length > 0">
<a class="stat-title">{{ $t('status.repeats') }}</a>