Merge pull request #911 from h3poteto/iss-772
closes #772 Add a menu to read follow requests, and accept/reject it
This commit is contained in:
commit
5bfd369646
|
@ -26,6 +26,7 @@ const state = (): SideMenuState => {
|
||||||
unreadLocalTimeline: false,
|
unreadLocalTimeline: false,
|
||||||
unreadDirectMessagesTimeline: false,
|
unreadDirectMessagesTimeline: false,
|
||||||
unreadPublicTimeline: false,
|
unreadPublicTimeline: false,
|
||||||
|
unreadFollowRequests: false,
|
||||||
lists: [],
|
lists: [],
|
||||||
tags: [],
|
tags: [],
|
||||||
collapse: false
|
collapse: false
|
||||||
|
@ -62,10 +63,7 @@ describe('SideMenu', () => {
|
||||||
get: (_path: string, _params: object) => {
|
get: (_path: string, _params: object) => {
|
||||||
return new Promise<Response<List[]>>(resolve => {
|
return new Promise<Response<List[]>>(resolve => {
|
||||||
const res: Response<List[]> = {
|
const res: Response<List[]> = {
|
||||||
data: [
|
data: [list1, list2],
|
||||||
list1,
|
|
||||||
list2
|
|
||||||
],
|
|
||||||
status: 200,
|
status: 200,
|
||||||
statusText: 'OK',
|
statusText: 'OK',
|
||||||
headers: {}
|
headers: {}
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
{
|
{
|
||||||
"side_menu": {
|
"side_menu": {
|
||||||
"direct": "Direct messages"
|
"direct": "Direct messages",
|
||||||
|
"follow_requests": "Follow Requests"
|
||||||
},
|
},
|
||||||
"header_menu": {
|
"header_menu": {
|
||||||
"settings": "Settings",
|
"settings": "Settings",
|
||||||
"switch_streaming": "Use websocket for streaming. If the timeline does not update with streaming, please try it."
|
"switch_streaming": "Use websocket for streaming. If the timeline does not update with streaming, please try it.",
|
||||||
|
"follow_requests": "Follow Requests",
|
||||||
|
"direct_messages": "Direct Messages"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"timeline": {
|
"timeline": {
|
||||||
|
@ -38,5 +41,13 @@
|
||||||
"hideAllAttachments": "Hide all medias"
|
"hideAllAttachments": "Hide all medias"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"follow_requests": {
|
||||||
|
"accept": "Accept",
|
||||||
|
"reject": "Reject"
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"follow_request_accept_error": "Failed to accept the request",
|
||||||
|
"follow_reuqest_reject_error": "failed to reject the request"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
"notification": "Notification",
|
"notification": "Notification",
|
||||||
"mention": "Mention",
|
"mention": "Mention",
|
||||||
"direct": "Direct messages",
|
"direct": "Direct messages",
|
||||||
|
"follow_requests": "Follow Requests",
|
||||||
"favourite": "Favourite",
|
"favourite": "Favourite",
|
||||||
"local": "Local timeline",
|
"local": "Local timeline",
|
||||||
"public": "Public timeline",
|
"public": "Public timeline",
|
||||||
|
@ -61,6 +62,8 @@
|
||||||
"notification": "Notification",
|
"notification": "Notification",
|
||||||
"mention": "Mention",
|
"mention": "Mention",
|
||||||
"favourite": "Favourite",
|
"favourite": "Favourite",
|
||||||
|
"follow_requests": "Follow Requests",
|
||||||
|
"direct_messages": "Direct Messages",
|
||||||
"local": "Local timeline",
|
"local": "Local timeline",
|
||||||
"public": "Public timeline",
|
"public": "Public timeline",
|
||||||
"hashtag": "Hashtag",
|
"hashtag": "Hashtag",
|
||||||
|
@ -298,6 +301,10 @@
|
||||||
"followers": "Followers"
|
"followers": "Followers"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"follow_requests": {
|
||||||
|
"accept": "Accept",
|
||||||
|
"reject": "Reject"
|
||||||
|
},
|
||||||
"hashtag": {
|
"hashtag": {
|
||||||
"tag_name": "Tag name",
|
"tag_name": "Tag name",
|
||||||
"delete_tag": "Delete tag",
|
"delete_tag": "Delete tag",
|
||||||
|
@ -337,6 +344,8 @@
|
||||||
"timeline_fetch_error": "Failed to fetch timeline",
|
"timeline_fetch_error": "Failed to fetch timeline",
|
||||||
"notification_fetch_error": "Failed to fetch notification",
|
"notification_fetch_error": "Failed to fetch notification",
|
||||||
"favourite_fetch_error": "Failed to fetch favorite",
|
"favourite_fetch_error": "Failed to fetch favorite",
|
||||||
|
"follow_request_accept_error": "Failed to accept the request",
|
||||||
|
"follow_reuqest_reject_error": "failed to reject the request",
|
||||||
"start_streaming_error": "Failed to start streaming",
|
"start_streaming_error": "Failed to start streaming",
|
||||||
"attach_error": "Could not attach the file",
|
"attach_error": "Could not attach the file",
|
||||||
"authorize_duplicate_error": "Can not login the same account of the same domain",
|
"authorize_duplicate_error": "Can not login the same account of the same domain",
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"side_menu": {
|
||||||
|
"follow_requests": "Follow Requests"
|
||||||
|
},
|
||||||
|
"header_menu": {
|
||||||
|
"follow_requests": "Follow Requests",
|
||||||
|
"direct_messages": "Direct Messages"
|
||||||
|
},
|
||||||
|
"follow_requests": {
|
||||||
|
"accept": "Accept",
|
||||||
|
"reject": "Reject"
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"follow_request_accept_error": "Failed to accept the request",
|
||||||
|
"follow_reuqest_reject_error": "failed to reject the request"
|
||||||
|
}
|
||||||
|
}
|
|
@ -1 +1,17 @@
|
||||||
|
{
|
||||||
|
"side_menu": {
|
||||||
|
"follow_requests": "Follow Requests"
|
||||||
|
},
|
||||||
|
"header_menu": {
|
||||||
|
"follow_requests": "Follow Requests",
|
||||||
|
"direct_messages": "Direct Messages"
|
||||||
|
},
|
||||||
|
"follow_requests": {
|
||||||
|
"accept": "Accept",
|
||||||
|
"reject": "Reject"
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"follow_request_accept_error": "Failed to accept the request",
|
||||||
|
"follow_reuqest_reject_error": "failed to reject the request"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
"home": "ホーム",
|
"home": "ホーム",
|
||||||
"notification": "通知",
|
"notification": "通知",
|
||||||
"direct": "ダイレクトメッセージ",
|
"direct": "ダイレクトメッセージ",
|
||||||
|
"follow_requests": "フォローリクエスト",
|
||||||
"favourite": "お気に入り",
|
"favourite": "お気に入り",
|
||||||
"local": "ローカル",
|
"local": "ローカル",
|
||||||
"public": "連合",
|
"public": "連合",
|
||||||
|
@ -59,6 +60,8 @@
|
||||||
"home": "ホーム",
|
"home": "ホーム",
|
||||||
"notification": "通知",
|
"notification": "通知",
|
||||||
"favourite": "お気に入り",
|
"favourite": "お気に入り",
|
||||||
|
"follow_requests": "フォローリクエスト",
|
||||||
|
"direct_messages": "ダイレクトメッセージ",
|
||||||
"local": "ローカルタイムライン",
|
"local": "ローカルタイムライン",
|
||||||
"public": "連合タイムライン",
|
"public": "連合タイムライン",
|
||||||
"hashtag": "ハッシュタグ",
|
"hashtag": "ハッシュタグ",
|
||||||
|
@ -289,6 +292,10 @@
|
||||||
"followers": "フォロワー"
|
"followers": "フォロワー"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"follow_requests": {
|
||||||
|
"accept": "承認",
|
||||||
|
"reject": "却下"
|
||||||
|
},
|
||||||
"hashtag": {
|
"hashtag": {
|
||||||
"tag_name": "タグ名",
|
"tag_name": "タグ名",
|
||||||
"delete_tag": "タグを削除",
|
"delete_tag": "タグを削除",
|
||||||
|
@ -328,6 +335,8 @@
|
||||||
"timeline_fetch_error": "タイムラインの読み込みに失敗しました",
|
"timeline_fetch_error": "タイムラインの読み込みに失敗しました",
|
||||||
"notification_fetch_error": "通知の読み込みに失敗しました",
|
"notification_fetch_error": "通知の読み込みに失敗しました",
|
||||||
"favourite_fetch_error": "お気に入りの読み込みに失敗しました",
|
"favourite_fetch_error": "お気に入りの読み込みに失敗しました",
|
||||||
|
"follow_request_accept_error": "フォローリクエストの承認に失敗しました",
|
||||||
|
"follow_reuqest_reject_error": "フォローリクエストの却下に失敗しました",
|
||||||
"start_streaming_error": "ストリーミングを開始できませんでした",
|
"start_streaming_error": "ストリーミングを開始できませんでした",
|
||||||
"attach_error": "ファイルを添付できませんでした",
|
"attach_error": "ファイルを添付できませんでした",
|
||||||
"authorize_duplicate_error": "同一ドメイン同一アカウントではログインできません",
|
"authorize_duplicate_error": "同一ドメイン同一アカウントではログインできません",
|
||||||
|
|
|
@ -9,5 +9,20 @@
|
||||||
"hideAllAttachments": "Hide all medias"
|
"hideAllAttachments": "Hide all medias"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"side_menu": {
|
||||||
|
"follow_requests": "Follow Requests"
|
||||||
|
},
|
||||||
|
"header_menu": {
|
||||||
|
"follow_requests": "Follow Requests",
|
||||||
|
"direct_messages": "Direct Messages"
|
||||||
|
},
|
||||||
|
"follow_requests": {
|
||||||
|
"accept": "Accept",
|
||||||
|
"reject": "Reject"
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"follow_request_accept_error": "Failed to accept the request",
|
||||||
|
"follow_reuqest_reject_error": "failed to reject the request"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
{
|
{
|
||||||
"side_menu": {
|
"side_menu": {
|
||||||
"direct": "Direct messages"
|
"direct": "Direct messages",
|
||||||
|
"follow_requests": "Follow Requests"
|
||||||
},
|
},
|
||||||
"header_menu": {
|
"header_menu": {
|
||||||
"settings": "Settings",
|
"settings": "Settings",
|
||||||
"switch_streaming": "Use websocket for streaming. If the timeline does not update with streaming, please try it."
|
"switch_streaming": "Use websocket for streaming. If the timeline does not update with streaming, please try it.",
|
||||||
|
"follow_requests": "Follow Requests",
|
||||||
|
"direct_messages": "Direct Messages"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"timeline": {
|
"timeline": {
|
||||||
|
@ -38,5 +41,13 @@
|
||||||
"hideAllAttachments": "Hide all medias"
|
"hideAllAttachments": "Hide all medias"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"follow_requests": {
|
||||||
|
"accept": "Accept",
|
||||||
|
"reject": "Reject"
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"follow_request_accept_error": "Failed to accept the request",
|
||||||
|
"follow_reuqest_reject_error": "failed to reject the request"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
id="timeline_space"
|
id="timeline_space"
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
:element-loading-text="$t('message.loading')"
|
:element-loading-text="$t('message.loading')"
|
||||||
element-loading-spinner="el-icon-loading"
|
element-loading-spinner="el-icon-loading"
|
||||||
element-loading-background="rgba(0, 0, 0, 0.8)"
|
element-loading-background="rgba(0, 0, 0, 0.8)"
|
||||||
v-shortkey="shortcutEnabled ? {help: ['shift', '?']} : {}"
|
v-shortkey="shortcutEnabled ? { help: ['shift', '?'] } : {}"
|
||||||
@shortkey="handleKey"
|
@shortkey="handleKey"
|
||||||
>
|
>
|
||||||
<side-menu></side-menu>
|
<side-menu></side-menu>
|
||||||
<div :class="collapse ? 'page-narrow':'page'">
|
<div :class="collapse ? 'page-narrow' : 'page'">
|
||||||
<header class="header" style="-webkit-app-region: drag;">
|
<header class="header" style="-webkit-app-region: drag;">
|
||||||
<header-menu></header-menu>
|
<header-menu></header-menu>
|
||||||
</header>
|
</header>
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
</div>
|
</div>
|
||||||
<modals></modals>
|
<modals></modals>
|
||||||
<receive-drop v-show="droppableVisible"></receive-drop>
|
<receive-drop v-show="droppableVisible"></receive-drop>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -32,7 +32,7 @@ import ReceiveDrop from './TimelineSpace/ReceiveDrop'
|
||||||
export default {
|
export default {
|
||||||
name: 'timeline-space',
|
name: 'timeline-space',
|
||||||
components: { SideMenu, HeaderMenu, Modals, Contents, ReceiveDrop },
|
components: { SideMenu, HeaderMenu, Modals, Contents, ReceiveDrop },
|
||||||
data () {
|
data() {
|
||||||
return {
|
return {
|
||||||
dropTarget: null,
|
dropTarget: null,
|
||||||
droppableVisible: false
|
droppableVisible: false
|
||||||
|
@ -43,23 +43,20 @@ export default {
|
||||||
loading: state => state.TimelineSpace.loading,
|
loading: state => state.TimelineSpace.loading,
|
||||||
collapse: state => state.TimelineSpace.SideMenu.collapse
|
collapse: state => state.TimelineSpace.SideMenu.collapse
|
||||||
}),
|
}),
|
||||||
...mapGetters('TimelineSpace/Modals', [
|
...mapGetters('TimelineSpace/Modals', ['modalOpened']),
|
||||||
'modalOpened'
|
shortcutEnabled: function() {
|
||||||
]),
|
|
||||||
shortcutEnabled: function () {
|
|
||||||
return !this.modalOpened
|
return !this.modalOpened
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async created () {
|
async created() {
|
||||||
this.$store.dispatch('TimelineSpace/Contents/SideBar/close')
|
this.$store.dispatch('TimelineSpace/Contents/SideBar/close')
|
||||||
this.$store.commit('TimelineSpace/changeLoading', true)
|
this.$store.commit('TimelineSpace/changeLoading', true)
|
||||||
await this.initialize()
|
await this.initialize().finally(() => {
|
||||||
.finally(() => {
|
|
||||||
this.$store.commit('TimelineSpace/changeLoading', false)
|
this.$store.commit('TimelineSpace/changeLoading', false)
|
||||||
this.$store.commit('GlobalHeader/updateChanging', false)
|
this.$store.commit('GlobalHeader/updateChanging', false)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted() {
|
||||||
window.addEventListener('dragenter', this.onDragEnter)
|
window.addEventListener('dragenter', this.onDragEnter)
|
||||||
window.addEventListener('dragleave', this.onDragLeave)
|
window.addEventListener('dragleave', this.onDragLeave)
|
||||||
window.addEventListener('dragover', this.onDragOver)
|
window.addEventListener('dragover', this.onDragOver)
|
||||||
|
@ -68,7 +65,7 @@ export default {
|
||||||
this.$store.commit('TimelineSpace/Modals/Jump/changeModal', true)
|
this.$store.commit('TimelineSpace/Modals/Jump/changeModal', true)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
beforeDestroy () {
|
beforeDestroy() {
|
||||||
window.removeEventListener('dragenter', this.onDragEnter)
|
window.removeEventListener('dragenter', this.onDragEnter)
|
||||||
window.removeEventListener('dragleave', this.onDragLeave)
|
window.removeEventListener('dragleave', this.onDragLeave)
|
||||||
window.removeEventListener('dragover', this.onDragOver)
|
window.removeEventListener('dragover', this.onDragOver)
|
||||||
|
@ -77,14 +74,14 @@ export default {
|
||||||
this.$store.dispatch('TimelineSpace/unbindStreamings')
|
this.$store.dispatch('TimelineSpace/unbindStreamings')
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async clear () {
|
async clear() {
|
||||||
await this.$store.dispatch('TimelineSpace/clearAccount')
|
await this.$store.dispatch('TimelineSpace/clearAccount')
|
||||||
this.$store.dispatch('TimelineSpace/clearContentsTimelines')
|
this.$store.dispatch('TimelineSpace/clearContentsTimelines')
|
||||||
await this.$store.dispatch('TimelineSpace/removeShortcutEvents')
|
await this.$store.dispatch('TimelineSpace/removeShortcutEvents')
|
||||||
await this.$store.dispatch('TimelineSpace/clearUnread')
|
await this.$store.dispatch('TimelineSpace/clearUnread')
|
||||||
return 'clear'
|
return 'clear'
|
||||||
},
|
},
|
||||||
async initialize () {
|
async initialize() {
|
||||||
await this.clear()
|
await this.clear()
|
||||||
|
|
||||||
this.$store.dispatch('TimelineSpace/watchShortcutEvents')
|
this.$store.dispatch('TimelineSpace/watchShortcutEvents')
|
||||||
|
@ -95,11 +92,11 @@ export default {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
this.$store.dispatch('TimelineSpace/SideMenu/fetchLists', account)
|
this.$store.dispatch('TimelineSpace/SideMenu/fetchLists', account)
|
||||||
|
this.$store.dispatch('TimelineSpace/SideMenu/fetchFollowRequests', account)
|
||||||
await this.$store.dispatch('TimelineSpace/loadUnreadNotification', this.$route.params.id)
|
await this.$store.dispatch('TimelineSpace/loadUnreadNotification', this.$route.params.id)
|
||||||
|
|
||||||
// Load timelines
|
// Load timelines
|
||||||
await this.$store.dispatch('TimelineSpace/fetchContentsTimelines', account)
|
await this.$store.dispatch('TimelineSpace/fetchContentsTimelines', account).catch(_ => {
|
||||||
.catch(_ => {
|
|
||||||
this.$message({
|
this.$message({
|
||||||
message: this.$t('message.timeline_fetch_error'),
|
message: this.$t('message.timeline_fetch_error'),
|
||||||
type: 'error'
|
type: 'error'
|
||||||
|
@ -115,7 +112,7 @@ export default {
|
||||||
this.$store.dispatch('TimelineSpace/fetchEmojis', account)
|
this.$store.dispatch('TimelineSpace/fetchEmojis', account)
|
||||||
this.$store.dispatch('TimelineSpace/fetchInstance', account)
|
this.$store.dispatch('TimelineSpace/fetchInstance', account)
|
||||||
},
|
},
|
||||||
handleDrop (e) {
|
handleDrop(e) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
this.droppableVisible = false
|
this.droppableVisible = false
|
||||||
|
@ -132,8 +129,7 @@ export default {
|
||||||
}
|
}
|
||||||
this.$store.dispatch('TimelineSpace/Modals/NewToot/openModal')
|
this.$store.dispatch('TimelineSpace/Modals/NewToot/openModal')
|
||||||
this.$store.dispatch('TimelineSpace/Modals/NewToot/incrementMediaId')
|
this.$store.dispatch('TimelineSpace/Modals/NewToot/incrementMediaId')
|
||||||
this.$store.dispatch('TimelineSpace/Modals/NewToot/uploadImage', file)
|
this.$store.dispatch('TimelineSpace/Modals/NewToot/uploadImage', file).catch(() => {
|
||||||
.catch(() => {
|
|
||||||
this.$message({
|
this.$message({
|
||||||
message: this.$t('message.attach_error'),
|
message: this.$t('message.attach_error'),
|
||||||
type: 'error'
|
type: 'error'
|
||||||
|
@ -141,19 +137,19 @@ export default {
|
||||||
})
|
})
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
onDragEnter (e) {
|
onDragEnter(e) {
|
||||||
this.dropTarget = e.target
|
this.dropTarget = e.target
|
||||||
this.droppableVisible = true
|
this.droppableVisible = true
|
||||||
},
|
},
|
||||||
onDragLeave (e) {
|
onDragLeave(e) {
|
||||||
if (e.target === this.dropTarget) {
|
if (e.target === this.dropTarget) {
|
||||||
this.droppableVisible = false
|
this.droppableVisible = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onDragOver (e) {
|
onDragOver(e) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
},
|
},
|
||||||
handleKey (event) {
|
handleKey(event) {
|
||||||
switch (event.srcKey) {
|
switch (event.srcKey) {
|
||||||
case 'help':
|
case 'help':
|
||||||
this.$store.commit('TimelineSpace/Modals/Shortcut/changeModal', true)
|
this.$store.commit('TimelineSpace/Modals/Shortcut/changeModal', true)
|
||||||
|
@ -205,5 +201,4 @@ export default {
|
||||||
width: calc(100% - 65px - 64px);
|
width: calc(100% - 65px - 64px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
<template>
|
||||||
|
<div id="follow-requests">
|
||||||
|
<template v-for="account in requests">
|
||||||
|
<user :user="account" :request="true" @acceptRequest="accept" @rejectRequest="reject"></user>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapState } from 'vuex'
|
||||||
|
import User from '@/components/molecules/User'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'folllow-requests',
|
||||||
|
components: { User },
|
||||||
|
computed: {
|
||||||
|
...mapState('TimelineSpace/Contents/FollowRequests', {
|
||||||
|
requests: state => state.requests
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async mounted() {
|
||||||
|
await this.initialize()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async initialize() {
|
||||||
|
await this.$store.dispatch('TimelineSpace/Contents/FollowRequests/fetchRequests').catch(_ => {
|
||||||
|
this.$message({
|
||||||
|
message: this.$t('message.timeline_fetch_error'),
|
||||||
|
type: 'error'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
accept(account) {
|
||||||
|
this.$store.dispatch('TimelineSpace/Contents/FollowRequests/acceptRequest', account).catch(_ => {
|
||||||
|
this.$message({
|
||||||
|
message: this.$t('message.follow_request_accept_error'),
|
||||||
|
type: 'error'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
reject(account) {
|
||||||
|
this.$store.dispatch('TimelineSpace/Contents/FollowRequests/rejectRequest', account).catch(_ => {
|
||||||
|
this.$message({
|
||||||
|
message: this.$t('message.follow_request_reject_error'),
|
||||||
|
type: 'error'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scorped></style>
|
|
@ -115,6 +115,9 @@ export default {
|
||||||
case 'mentions':
|
case 'mentions':
|
||||||
this.$store.commit('TimelineSpace/HeaderMenu/updateTitle', this.$t('header_menu.mention'))
|
this.$store.commit('TimelineSpace/HeaderMenu/updateTitle', this.$t('header_menu.mention'))
|
||||||
break
|
break
|
||||||
|
case 'follow-requests':
|
||||||
|
this.$store.commit('TimelineSpace/HeaderMenu/updateTitle', this.$t('header_menu.follow_requests'))
|
||||||
|
break
|
||||||
case 'local':
|
case 'local':
|
||||||
this.$store.commit('TimelineSpace/HeaderMenu/updateTitle', this.$t('header_menu.local'))
|
this.$store.commit('TimelineSpace/HeaderMenu/updateTitle', this.$t('header_menu.local'))
|
||||||
break
|
break
|
||||||
|
@ -134,7 +137,7 @@ export default {
|
||||||
this.$store.commit('TimelineSpace/HeaderMenu/updateTitle', this.$t('header_menu.lists'))
|
this.$store.commit('TimelineSpace/HeaderMenu/updateTitle', this.$t('header_menu.lists'))
|
||||||
break
|
break
|
||||||
case 'direct-messages':
|
case 'direct-messages':
|
||||||
this.$store.commit('TimelineSpace/HeaderMenu/updateTitle', 'Direct Messages')
|
this.$store.commit('TimelineSpace/HeaderMenu/updateTitle', this.$t('header_menu.direct_messages'))
|
||||||
break
|
break
|
||||||
case 'edit-list':
|
case 'edit-list':
|
||||||
this.$store.commit('TimelineSpace/HeaderMenu/updateTitle', this.$t('header_menu.members'))
|
this.$store.commit('TimelineSpace/HeaderMenu/updateTitle', this.$t('header_menu.members'))
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div id="side_menu">
|
<div id="side_menu">
|
||||||
<div :class="collapse ? 'profile-wrapper narrow-menu':'profile-wrapper'" style="-webkit-app-region: drag;">
|
<div :class="collapse ? 'profile-wrapper narrow-menu' : 'profile-wrapper'" style="-webkit-app-region: drag;">
|
||||||
<div :class="collapse ? 'profile-narrow' : 'profile-wide'">
|
<div :class="collapse ? 'profile-narrow' : 'profile-wide'">
|
||||||
<div class="account">
|
<div class="account">
|
||||||
<div class="avatar" v-if="collapse">
|
<div class="avatar" v-if="collapse">
|
||||||
|
@ -15,9 +15,9 @@
|
||||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||||
</span>
|
</span>
|
||||||
<el-dropdown-menu slot="dropdown">
|
<el-dropdown-menu slot="dropdown">
|
||||||
<el-dropdown-item command="show">{{ $t("side_menu.show_profile") }}</el-dropdown-item>
|
<el-dropdown-item command="show">{{ $t('side_menu.show_profile') }}</el-dropdown-item>
|
||||||
<el-dropdown-item command="edit">{{ $t("side_menu.edit_profile") }}</el-dropdown-item>
|
<el-dropdown-item command="edit">{{ $t('side_menu.edit_profile') }}</el-dropdown-item>
|
||||||
<el-dropdown-item command="settings">{{ $t("side_menu.settings") }}</el-dropdown-item>
|
<el-dropdown-item command="settings">{{ $t('side_menu.settings') }}</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
</div>
|
</div>
|
||||||
|
@ -38,68 +38,85 @@
|
||||||
:collapse="collapse"
|
:collapse="collapse"
|
||||||
active-text-color="#ffffff"
|
active-text-color="#ffffff"
|
||||||
:router="true"
|
:router="true"
|
||||||
:class="collapse ? 'el-menu-vertical timeline-menu narrow-menu':'el-menu-vertical timeline-menu'"
|
:class="collapse ? 'el-menu-vertical timeline-menu narrow-menu' : 'el-menu-vertical timeline-menu'"
|
||||||
role="menu">
|
role="menu"
|
||||||
|
>
|
||||||
<el-menu-item :index="`/${id()}/home`" role="menuitem" :title="$t('side_menu.home')">
|
<el-menu-item :index="`/${id()}/home`" role="menuitem" :title="$t('side_menu.home')">
|
||||||
<icon name="home"></icon>
|
<icon name="home"></icon>
|
||||||
<span>{{ $t("side_menu.home") }}</span>
|
<span>{{ $t('side_menu.home') }}</span>
|
||||||
<el-badge is-dot :hidden="!unreadHomeTimeline">
|
<el-badge is-dot :hidden="!unreadHomeTimeline"> </el-badge>
|
||||||
</el-badge>
|
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
<el-menu-item :index="`/${id()}/notifications`" role="menuitem" :title="$t('side_menu.notification')">
|
<el-menu-item :index="`/${id()}/notifications`" role="menuitem" :title="$t('side_menu.notification')">
|
||||||
<icon name="bell"></icon>
|
<icon name="bell"></icon>
|
||||||
<span>{{ $t("side_menu.notification") }}</span>
|
<span>{{ $t('side_menu.notification') }}</span>
|
||||||
<el-badge is-dot :hidden="!unreadNotifications">
|
<el-badge is-dot :hidden="!unreadNotifications"> </el-badge>
|
||||||
</el-badge>
|
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
<el-menu-item :index="`/${id()}/mentions`" role="menuitem" :title="$t('side_menu.mention')">
|
<el-menu-item :index="`/${id()}/mentions`" role="menuitem" :title="$t('side_menu.mention')">
|
||||||
<icon name="at"></icon>
|
<icon name="at"></icon>
|
||||||
<span>{{ $t("side_menu.mention") }}</span>
|
<span>{{ $t('side_menu.mention') }}</span>
|
||||||
<el-badge is-dot :hidden="!unreadMentions">
|
<el-badge is-dot :hidden="!unreadMentions"> </el-badge>
|
||||||
</el-badge>
|
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
<el-menu-item :index="`/${id()}/direct-messages`" role="menuitem">
|
<el-menu-item :index="`/${id()}/direct-messages`" role="menuitem" :title="$t('side_menu.direct')">
|
||||||
<icon name="envelope"></icon>
|
<icon name="envelope"></icon>
|
||||||
<span>{{ $t("side_menu.direct") }}</span>
|
<span>{{ $t('side_menu.direct') }}</span>
|
||||||
<el-badge is-dot :hidden="!unreadDirectMessagesTimeline">
|
<el-badge is-dot :hidden="!unreadDirectMessagesTimeline"> </el-badge>
|
||||||
</el-badge>
|
</el-menu-item>
|
||||||
|
<el-menu-item
|
||||||
|
v-if="unreadFollowRequests"
|
||||||
|
:index="`/${id()}/follow-requests`"
|
||||||
|
role="menuitem"
|
||||||
|
:title="$t('side_menu.follow_requests')"
|
||||||
|
>
|
||||||
|
<icon name="users"></icon>
|
||||||
|
<span>{{ $t('side_menu.follow_requests') }}</span>
|
||||||
|
<el-badge is-dot></el-badge>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
<el-menu-item :index="`/${id()}/favourites`" role="menuitem" :title="$t('side_menu.favourite')">
|
<el-menu-item :index="`/${id()}/favourites`" role="menuitem" :title="$t('side_menu.favourite')">
|
||||||
<icon name="star"></icon>
|
<icon name="star"></icon>
|
||||||
<span>{{ $t("side_menu.favourite") }}</span>
|
<span>{{ $t('side_menu.favourite') }}</span>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
<el-menu-item :index="`/${id()}/local`" role="menuitem" :title="$t('side_menu.local')">
|
<el-menu-item :index="`/${id()}/local`" role="menuitem" :title="$t('side_menu.local')">
|
||||||
<icon name="users"></icon>
|
<icon name="users"></icon>
|
||||||
<span>{{ $t("side_menu.local") }}</span>
|
<span>{{ $t('side_menu.local') }}</span>
|
||||||
<el-badge is-dot :hidden="!unreadLocalTimeline">
|
<el-badge is-dot :hidden="!unreadLocalTimeline"> </el-badge>
|
||||||
</el-badge>
|
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
<el-menu-item :index="`/${id()}/public`" role="menuitem" :title="$t('side_menu.public')">
|
<el-menu-item :index="`/${id()}/public`" role="menuitem" :title="$t('side_menu.public')">
|
||||||
<icon name="globe"></icon>
|
<icon name="globe"></icon>
|
||||||
<span>{{ $t("side_menu.public") }}</span>
|
<span>{{ $t('side_menu.public') }}</span>
|
||||||
<el-badge is-dot :hidden="!unreadPublicTimeline">
|
<el-badge is-dot :hidden="!unreadPublicTimeline"> </el-badge>
|
||||||
</el-badge>
|
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
<el-menu-item :index="`/${id()}/search`" role="menuitem" :title="$t('side_menu.search')">
|
<el-menu-item :index="`/${id()}/search`" role="menuitem" :title="$t('side_menu.search')">
|
||||||
<icon name="search"></icon>
|
<icon name="search"></icon>
|
||||||
<span>{{ $t("side_menu.search") }}</span>
|
<span>{{ $t('side_menu.search') }}</span>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
<el-menu-item :index="`/${id()}/hashtag`" role="menuitem" :title="$t('side_menu.hashtag')">
|
<el-menu-item :index="`/${id()}/hashtag`" role="menuitem" :title="$t('side_menu.hashtag')">
|
||||||
<icon name="hashtag"></icon>
|
<icon name="hashtag"></icon>
|
||||||
<span>{{ $t("side_menu.hashtag") }}</span>
|
<span>{{ $t('side_menu.hashtag') }}</span>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
<template v-for="tag in tags">
|
<template v-for="tag in tags">
|
||||||
<el-menu-item :index="`/${id()}/hashtag/${tag.tagName}`" :class="collapse ? '' : 'sub-menu'" :key="tag.tagName" role="menuitem" :title="tag.tagName">
|
<el-menu-item
|
||||||
|
:index="`/${id()}/hashtag/${tag.tagName}`"
|
||||||
|
:class="collapse ? '' : 'sub-menu'"
|
||||||
|
:key="tag.tagName"
|
||||||
|
role="menuitem"
|
||||||
|
:title="tag.tagName"
|
||||||
|
>
|
||||||
<icon name="hashtag" scale="0.8"></icon>
|
<icon name="hashtag" scale="0.8"></icon>
|
||||||
<span>{{ tag.tagName }}</span>
|
<span>{{ tag.tagName }}</span>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
</template>
|
</template>
|
||||||
<el-menu-item :index="`/${id()}/lists`" role="menuitem" :title="$t('side_menu.lists')">
|
<el-menu-item :index="`/${id()}/lists`" role="menuitem" :title="$t('side_menu.lists')">
|
||||||
<icon name="list-ul"></icon>
|
<icon name="list-ul"></icon>
|
||||||
<span>{{ $t("side_menu.lists") }}</span>
|
<span>{{ $t('side_menu.lists') }}</span>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
<template v-for="list in lists">
|
<template v-for="list in lists">
|
||||||
<el-menu-item :index="`/${id()}/lists/${list.id}`" :class="collapse ? '' : 'sub-menu'" :key="list.id" role="menuitem" :title="list.title">
|
<el-menu-item
|
||||||
|
:index="`/${id()}/lists/${list.id}`"
|
||||||
|
:class="collapse ? '' : 'sub-menu'"
|
||||||
|
:key="list.id"
|
||||||
|
role="menuitem"
|
||||||
|
:title="list.title"
|
||||||
|
>
|
||||||
<icon name="list-ul" scale="0.8"></icon>
|
<icon name="list-ul" scale="0.8"></icon>
|
||||||
<span>{{ list.title }}</span>
|
<span>{{ list.title }}</span>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
|
@ -128,6 +145,7 @@ export default {
|
||||||
unreadLocalTimeline: state => state.unreadLocalTimeline,
|
unreadLocalTimeline: state => state.unreadLocalTimeline,
|
||||||
unreadDirectMessagesTimeline: state => state.unreadDirectMessagesTimeline,
|
unreadDirectMessagesTimeline: state => state.unreadDirectMessagesTimeline,
|
||||||
unreadPublicTimeline: state => state.unreadPublicTimeline,
|
unreadPublicTimeline: state => state.unreadPublicTimeline,
|
||||||
|
unreadFollowRequests: state => state.unreadFollowRequests,
|
||||||
lists: state => state.lists,
|
lists: state => state.lists,
|
||||||
tags: state => state.tags,
|
tags: state => state.tags,
|
||||||
collapse: state => state.collapse
|
collapse: state => state.collapse
|
||||||
|
@ -138,22 +156,21 @@ export default {
|
||||||
hideGlobalHeader: state => state.GlobalHeader.hide
|
hideGlobalHeader: state => state.GlobalHeader.hide
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
created () {
|
created() {
|
||||||
this.$store.dispatch('TimelineSpace/SideMenu/readCollapse')
|
this.$store.dispatch('TimelineSpace/SideMenu/readCollapse')
|
||||||
this.$store.dispatch('TimelineSpace/SideMenu/listTags')
|
this.$store.dispatch('TimelineSpace/SideMenu/listTags')
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
activeRoute () {
|
activeRoute() {
|
||||||
return this.$route.path
|
return this.$route.path
|
||||||
},
|
},
|
||||||
id () {
|
id() {
|
||||||
return this.$route.params.id
|
return this.$route.params.id
|
||||||
},
|
},
|
||||||
handleProfile (command) {
|
handleProfile(command) {
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case 'show':
|
case 'show':
|
||||||
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/fetchAccount', this.account.accountId)
|
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/fetchAccount', this.account.accountId).then(account => {
|
||||||
.then((account) => {
|
|
||||||
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/changeAccount', account)
|
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/changeAccount', account)
|
||||||
this.$store.commit('TimelineSpace/Contents/SideBar/changeOpenSideBar', true)
|
this.$store.commit('TimelineSpace/Contents/SideBar/changeOpenSideBar', true)
|
||||||
})
|
})
|
||||||
|
@ -169,13 +186,13 @@ export default {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
doCollapse () {
|
doCollapse() {
|
||||||
this.$store.dispatch('TimelineSpace/SideMenu/changeCollapse', true)
|
this.$store.dispatch('TimelineSpace/SideMenu/changeCollapse', true)
|
||||||
},
|
},
|
||||||
releaseCollapse () {
|
releaseCollapse() {
|
||||||
this.$store.dispatch('TimelineSpace/SideMenu/changeCollapse', false)
|
this.$store.dispatch('TimelineSpace/SideMenu/changeCollapse', false)
|
||||||
},
|
},
|
||||||
async changeGlobalHeader (value) {
|
async changeGlobalHeader(value) {
|
||||||
await this.$store.dispatch('GlobalHeader/switchHide', value)
|
await this.$store.dispatch('GlobalHeader/switchHide', value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="user" @click="openUser(user)" aria-label="user">
|
<div class="user" @click="openUser(user)" aria-label="user">
|
||||||
<div class="icon" role="presentation">
|
<div class="icon" role="presentation">
|
||||||
<FailoverImg :src="user.avatar" :alt="`Avatar of ${user.username}`" />
|
<FailoverImg :src="user.avatar" :alt="`Avatar of ${user.username}`" />
|
||||||
</div>
|
</div>
|
||||||
|
@ -7,9 +7,7 @@
|
||||||
<div class="username">
|
<div class="username">
|
||||||
<bdi v-html="username(user)"></bdi>
|
<bdi v-html="username(user)"></bdi>
|
||||||
</div>
|
</div>
|
||||||
<div class="acct">
|
<div class="acct">@{{ user.acct }}</div>
|
||||||
@{{ user.acct }}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="tool" v-if="remove">
|
<div class="tool" v-if="remove">
|
||||||
<el-button type="text" @click.stop.prevent="removeAccount(user)">
|
<el-button type="text" @click.stop.prevent="removeAccount(user)">
|
||||||
|
@ -17,18 +15,37 @@
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="tool" v-if="relationship">
|
<div class="tool" v-if="relationship">
|
||||||
<el-button v-if="relationship.following" class="unfollow" type="text" @click.stop.prevent="unfollowAccount(user)" :title="$t('side_bar.account_profile.unfollow')">
|
<el-button
|
||||||
|
v-if="relationship.following"
|
||||||
|
class="unfollow"
|
||||||
|
type="text"
|
||||||
|
@click.stop.prevent="unfollowAccount(user)"
|
||||||
|
:title="$t('side_bar.account_profile.unfollow')"
|
||||||
|
>
|
||||||
<icon name="user-times"></icon>
|
<icon name="user-times"></icon>
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button v-else-if="relationship.requested" class="requested" type="text" :title="$t('side_bar.account_profile.follow_requested')">
|
<el-button v-else-if="relationship.requested" class="requested" type="text" :title="$t('side_bar.account_profile.follow_requested')">
|
||||||
<icon name="hourglass"></icon>
|
<icon name="hourglass"></icon>
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button v-else-if="!relationship.following" class="follow" type="text" @click.stop.prevent="followAccount(user)" :title="$t('side_bar.account_profile.follow')">
|
<el-button
|
||||||
|
v-else-if="!relationship.following"
|
||||||
|
class="follow"
|
||||||
|
type="text"
|
||||||
|
@click.stop.prevent="followAccount(user)"
|
||||||
|
:title="$t('side_bar.account_profile.follow')"
|
||||||
|
>
|
||||||
<icon name="user-plus"></icon>
|
<icon name="user-plus"></icon>
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="tool" v-else-if="request">
|
||||||
|
<el-button class="accept" type="text" @click.stop.prevent="acceptRequest(user)" :title="$t('follow_requests.accept')">
|
||||||
|
<icon name="check"></icon>
|
||||||
|
</el-button>
|
||||||
|
<el-button class="reject" type="text" @click.stop.prevent="rejectRequest(user)" :tilte="$t('follow_requests.reject')">
|
||||||
|
<icon name="times"></icon>
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -52,29 +69,39 @@ export default {
|
||||||
relationship: {
|
relationship: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: null
|
default: null
|
||||||
|
},
|
||||||
|
request: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
username (account) {
|
username(account) {
|
||||||
if (account.display_name !== '') {
|
if (account.display_name !== '') {
|
||||||
return emojify(account.display_name, account.emojis)
|
return emojify(account.display_name, account.emojis)
|
||||||
} else {
|
} else {
|
||||||
return account.username
|
return account.username
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
openUser (account) {
|
openUser(account) {
|
||||||
this.$store.dispatch('TimelineSpace/Contents/SideBar/openAccountComponent')
|
this.$store.dispatch('TimelineSpace/Contents/SideBar/openAccountComponent')
|
||||||
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/changeAccount', account)
|
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/changeAccount', account)
|
||||||
this.$store.commit('TimelineSpace/Contents/SideBar/changeOpenSideBar', true)
|
this.$store.commit('TimelineSpace/Contents/SideBar/changeOpenSideBar', true)
|
||||||
},
|
},
|
||||||
removeAccount (account) {
|
removeAccount(account) {
|
||||||
this.$emit('removeAccount', account)
|
this.$emit('removeAccount', account)
|
||||||
},
|
},
|
||||||
unfollowAccount (account) {
|
unfollowAccount(account) {
|
||||||
this.$emit('unfollowAccount', account)
|
this.$emit('unfollowAccount', account)
|
||||||
},
|
},
|
||||||
followAccount (account) {
|
followAccount(account) {
|
||||||
this.$emit('followAccount', account)
|
this.$emit('followAccount', account)
|
||||||
|
},
|
||||||
|
acceptRequest(account) {
|
||||||
|
this.$emit('acceptRequest', account)
|
||||||
|
},
|
||||||
|
rejectRequest(account) {
|
||||||
|
this.$emit('rejectRequest', account)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,6 +178,11 @@ export default {
|
||||||
padding-top: 8px;
|
padding-top: 8px;
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.accept,
|
||||||
|
.reject {
|
||||||
|
margin-right: 24px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -14,7 +14,7 @@ const router = new Router({
|
||||||
path: '/authorize',
|
path: '/authorize',
|
||||||
name: 'authorize',
|
name: 'authorize',
|
||||||
component: require('@/components/Authorize').default,
|
component: require('@/components/Authorize').default,
|
||||||
props: (route) => ({ url: route.query.url })
|
props: route => ({ url: route.query.url })
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/preferences/',
|
path: '/preferences/',
|
||||||
|
@ -87,6 +87,11 @@ const router = new Router({
|
||||||
name: 'mentions',
|
name: 'mentions',
|
||||||
component: require('@/components/TimelineSpace/Contents/Mentions').default
|
component: require('@/components/TimelineSpace/Contents/Mentions').default
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'follow-requests',
|
||||||
|
name: 'follow-requests',
|
||||||
|
component: require('@/components/TimelineSpace/Contents/FollowRequests').default
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'favourites',
|
path: 'favourites',
|
||||||
name: 'favourites',
|
name: 'favourites',
|
||||||
|
|
|
@ -8,6 +8,7 @@ import Search, { SearchModuleState } from './Contents/Search'
|
||||||
import Lists from './Contents/Lists'
|
import Lists from './Contents/Lists'
|
||||||
import Hashtag, { HashtagModuleState } from './Contents/Hashtag'
|
import Hashtag, { HashtagModuleState } from './Contents/Hashtag'
|
||||||
import DirectMessages, { DirectMessagesState } from './Contents/DirectMessages'
|
import DirectMessages, { DirectMessagesState } from './Contents/DirectMessages'
|
||||||
|
import FollowRequests, { FollowRequestsState } from './Contents/FollowRequests'
|
||||||
import Mentions, { MentionsState } from './Contents/Mentions'
|
import Mentions, { MentionsState } from './Contents/Mentions'
|
||||||
import { Module } from 'vuex'
|
import { Module } from 'vuex'
|
||||||
import { RootState } from '@/store'
|
import { RootState } from '@/store'
|
||||||
|
@ -15,16 +16,17 @@ import { RootState } from '@/store'
|
||||||
export interface ContentsState {}
|
export interface ContentsState {}
|
||||||
|
|
||||||
export interface ContentsModuleState extends ContentsState {
|
export interface ContentsModuleState extends ContentsState {
|
||||||
SideBar: SideBarModuleState,
|
SideBar: SideBarModuleState
|
||||||
Home: HomeState,
|
Home: HomeState
|
||||||
Notifications: NotificationsState,
|
Notifications: NotificationsState
|
||||||
Mentions: MentionsState,
|
Mentions: MentionsState
|
||||||
DirectMessages: DirectMessagesState,
|
DirectMessages: DirectMessagesState
|
||||||
Favourites: FavouritesState,
|
Favourites: FavouritesState
|
||||||
Local: LocalState,
|
Local: LocalState
|
||||||
Public: PublicState,
|
Public: PublicState
|
||||||
Search: SearchModuleState,
|
Search: SearchModuleState
|
||||||
Hashtag: HashtagModuleState
|
Hashtag: HashtagModuleState
|
||||||
|
FollowRequests: FollowRequestsState
|
||||||
}
|
}
|
||||||
|
|
||||||
const state = (): ContentsState => ({})
|
const state = (): ContentsState => ({})
|
||||||
|
@ -43,7 +45,8 @@ const Contents: Module<ContentsState, RootState> = {
|
||||||
Public,
|
Public,
|
||||||
Search,
|
Search,
|
||||||
Lists,
|
Lists,
|
||||||
Hashtag
|
Hashtag,
|
||||||
|
FollowRequests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
import Mastodon, { Account, Response } from 'megalodon'
|
||||||
|
import { Module, MutationTree, ActionTree } from 'vuex'
|
||||||
|
import { RootState } from '@/store'
|
||||||
|
|
||||||
|
export interface FollowRequestsState {
|
||||||
|
requests: Array<Account>
|
||||||
|
}
|
||||||
|
|
||||||
|
const state = (): FollowRequestsState => ({
|
||||||
|
requests: []
|
||||||
|
})
|
||||||
|
|
||||||
|
export const MUTATION_TYPES = {
|
||||||
|
UPDATE_REQUESTS: 'updateRequests'
|
||||||
|
}
|
||||||
|
|
||||||
|
const mutations: MutationTree<FollowRequestsState> = {
|
||||||
|
[MUTATION_TYPES.UPDATE_REQUESTS]: (state, accounts: Array<Account>) => {
|
||||||
|
state.requests = accounts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const actions: ActionTree<FollowRequestsState, RootState> = {
|
||||||
|
fetchRequests: async ({ commit, rootState }): Promise<Array<Account>> => {
|
||||||
|
const client = new Mastodon(rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.account.baseURL + '/api/v1')
|
||||||
|
const res: Response<Array<Account>> = await client.get<Array<Account>>('/follow_requests')
|
||||||
|
commit(MUTATION_TYPES.UPDATE_REQUESTS, res.data)
|
||||||
|
return res.data
|
||||||
|
},
|
||||||
|
acceptRequest: async ({ dispatch, rootState }, user: Account) => {
|
||||||
|
const client = new Mastodon(rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.account.baseURL + '/api/v1')
|
||||||
|
const res: Response<{}> = await client.post<{}>(`/follow_requests/${user.id}/authorize`)
|
||||||
|
dispatch('fetchRequests')
|
||||||
|
dispatch('TimelineSpace/SideMenu/fetchFollowRequests', rootState.TimelineSpace.account, { root: true })
|
||||||
|
return res.data
|
||||||
|
},
|
||||||
|
rejectRequest: async ({ dispatch, rootState }, user: Account) => {
|
||||||
|
const client = new Mastodon(rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.account.baseURL + '/api/v1')
|
||||||
|
const res: Response<{}> = await client.post<{}>(`/follow_requests/${user.id}/reject`)
|
||||||
|
dispatch('fetchRequests')
|
||||||
|
dispatch('TimelineSpace/SideMenu/fetchFollowRequests', rootState.TimelineSpace.account, { root: true })
|
||||||
|
return res.data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const FollowRequests: Module<FollowRequestsState, RootState> = {
|
||||||
|
namespaced: true,
|
||||||
|
state: state,
|
||||||
|
mutations: mutations,
|
||||||
|
actions: actions
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FollowRequests
|
|
@ -1,4 +1,4 @@
|
||||||
import Mastodon, { List, Response } from 'megalodon'
|
import Mastodon, { List, Response, Account } from 'megalodon'
|
||||||
import { ipcRenderer } from 'electron'
|
import { ipcRenderer } from 'electron'
|
||||||
import { Module, MutationTree, ActionTree } from 'vuex'
|
import { Module, MutationTree, ActionTree } from 'vuex'
|
||||||
import LocalTag from '~/src/types/localTag'
|
import LocalTag from '~/src/types/localTag'
|
||||||
|
@ -6,14 +6,15 @@ import LocalAccount from '~/src/types/localAccount'
|
||||||
import { RootState } from '@/store'
|
import { RootState } from '@/store'
|
||||||
|
|
||||||
export interface SideMenuState {
|
export interface SideMenuState {
|
||||||
unreadHomeTimeline: boolean,
|
unreadHomeTimeline: boolean
|
||||||
unreadNotifications: boolean,
|
unreadNotifications: boolean
|
||||||
unreadMentions: boolean,
|
unreadMentions: boolean
|
||||||
unreadLocalTimeline: boolean,
|
unreadLocalTimeline: boolean
|
||||||
unreadDirectMessagesTimeline: boolean,
|
unreadDirectMessagesTimeline: boolean
|
||||||
unreadPublicTimeline: boolean,
|
unreadPublicTimeline: boolean
|
||||||
lists: Array<List>,
|
unreadFollowRequests: boolean
|
||||||
tags: Array<LocalTag>,
|
lists: Array<List>
|
||||||
|
tags: Array<LocalTag>
|
||||||
collapse: boolean
|
collapse: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +25,7 @@ const state = (): SideMenuState => ({
|
||||||
unreadLocalTimeline: false,
|
unreadLocalTimeline: false,
|
||||||
unreadDirectMessagesTimeline: false,
|
unreadDirectMessagesTimeline: false,
|
||||||
unreadPublicTimeline: false,
|
unreadPublicTimeline: false,
|
||||||
|
unreadFollowRequests: false,
|
||||||
lists: [],
|
lists: [],
|
||||||
tags: [],
|
tags: [],
|
||||||
collapse: false
|
collapse: false
|
||||||
|
@ -36,6 +38,7 @@ export const MUTATION_TYPES = {
|
||||||
CHANGE_UNREAD_LOCAL_TIMELINE: 'changeUnreadLocalTimeline',
|
CHANGE_UNREAD_LOCAL_TIMELINE: 'changeUnreadLocalTimeline',
|
||||||
CHANGE_UNREAD_DIRECT_MESSAGES_TIMELINE: 'changeUnreadDirectMessagesTimeline',
|
CHANGE_UNREAD_DIRECT_MESSAGES_TIMELINE: 'changeUnreadDirectMessagesTimeline',
|
||||||
CHANGE_UNREAD_PUBLIC_TIMELINE: 'changeUnreadPublicTimeline',
|
CHANGE_UNREAD_PUBLIC_TIMELINE: 'changeUnreadPublicTimeline',
|
||||||
|
CHANGE_UNREAD_FOLLOW_REQUESTS: 'changeUnreadFollowRequests',
|
||||||
UPDATE_LISTS: 'updateLists',
|
UPDATE_LISTS: 'updateLists',
|
||||||
CHANGE_COLLAPSE: 'changeCollapse',
|
CHANGE_COLLAPSE: 'changeCollapse',
|
||||||
UPDATE_TAGS: 'updateTags'
|
UPDATE_TAGS: 'updateTags'
|
||||||
|
@ -60,6 +63,9 @@ const mutations: MutationTree<SideMenuState> = {
|
||||||
[MUTATION_TYPES.CHANGE_UNREAD_PUBLIC_TIMELINE]: (state, value: boolean) => {
|
[MUTATION_TYPES.CHANGE_UNREAD_PUBLIC_TIMELINE]: (state, value: boolean) => {
|
||||||
state.unreadPublicTimeline = value
|
state.unreadPublicTimeline = value
|
||||||
},
|
},
|
||||||
|
[MUTATION_TYPES.CHANGE_UNREAD_FOLLOW_REQUESTS]: (state, value: boolean) => {
|
||||||
|
state.unreadFollowRequests = value
|
||||||
|
},
|
||||||
[MUTATION_TYPES.UPDATE_LISTS]: (state, lists: Array<List>) => {
|
[MUTATION_TYPES.UPDATE_LISTS]: (state, lists: Array<List>) => {
|
||||||
state.lists = lists
|
state.lists = lists
|
||||||
},
|
},
|
||||||
|
@ -74,14 +80,18 @@ const mutations: MutationTree<SideMenuState> = {
|
||||||
const actions: ActionTree<SideMenuState, RootState> = {
|
const actions: ActionTree<SideMenuState, RootState> = {
|
||||||
fetchLists: async ({ commit, rootState }, account: LocalAccount | null = null): Promise<Array<List>> => {
|
fetchLists: async ({ commit, rootState }, account: LocalAccount | null = null): Promise<Array<List>> => {
|
||||||
if (account === null) account = rootState.TimelineSpace.account
|
if (account === null) account = rootState.TimelineSpace.account
|
||||||
const client = new Mastodon(
|
const client = new Mastodon(account!.accessToken!, account!.baseURL + '/api/v1')
|
||||||
account!.accessToken!,
|
|
||||||
account!.baseURL + '/api/v1'
|
|
||||||
)
|
|
||||||
const res: Response<Array<List>> = await client.get<Array<List>>('/lists')
|
const res: Response<Array<List>> = await client.get<Array<List>>('/lists')
|
||||||
commit(MUTATION_TYPES.UPDATE_LISTS, res.data)
|
commit(MUTATION_TYPES.UPDATE_LISTS, res.data)
|
||||||
return res.data
|
return res.data
|
||||||
},
|
},
|
||||||
|
fetchFollowRequests: async ({ commit, rootState }, account: LocalAccount | null = null): Promise<Array<Account>> => {
|
||||||
|
if (account === null) account = rootState.TimelineSpace.account
|
||||||
|
const client = new Mastodon(account!.accessToken!, account!.baseURL + '/api/v1')
|
||||||
|
const res: Response<Array<Account>> = await client.get<Array<Account>>('/follow_requests')
|
||||||
|
commit(MUTATION_TYPES.CHANGE_UNREAD_FOLLOW_REQUESTS, res.data.length > 0)
|
||||||
|
return res.data
|
||||||
|
},
|
||||||
clearUnread: ({ commit }) => {
|
clearUnread: ({ commit }) => {
|
||||||
commit(MUTATION_TYPES.CHANGE_UNREAD_HOME_TIMELINE, false)
|
commit(MUTATION_TYPES.CHANGE_UNREAD_HOME_TIMELINE, false)
|
||||||
commit(MUTATION_TYPES.CHANGE_UNREAD_NOTIFICATIONS, false)
|
commit(MUTATION_TYPES.CHANGE_UNREAD_NOTIFICATIONS, false)
|
||||||
|
|
Loading…
Reference in New Issue