import generator , { Entity } from 'megalodon' ; import Timeline , { TimelineState } from './AccountProfile/Timeline' ; import Follows , { FollowsState } from './AccountProfile/Follows' ; import Followers , { FollowersState } from './AccountProfile/Followers' ; import { Module , MutationTree , ActionTree , GetterTree } from 'vuex' ; import { RootState } from '@/store' ; type ParsedAccount = { username : string ; acct : string ; url : string ; } ; type SearchAccount = { parsedAccount : ParsedAccount ; status : Entity . Status ; } ; export type AccountProfileState = { account : Entity . Account | null ; relationship : Entity . Relationship | null ; loading : boolean ; identityProofs : Array < Entity . IdentityProof > ; } ; type AccountProfileModule = { Followers : FollowersState ; Follows : FollowsState ; Timeline : TimelineState ; } ; export type AccountProfileModuleState = AccountProfileModule & AccountProfileState ; const state = ( ) : AccountProfileState => ( { account : null , relationship : null , loading : false , identityProofs : [ ] } ) ; export const MUTATION_TYPES = { CHANGE_ACCOUNT : 'changeAccount' , CHANGE_RELATIONSHIP : 'changeRelationship' , CHANGE_LOADING : 'changeLoading' , CHANGE_IDENTITY_PROOFS : 'changeIdentityProofs' } ; const mutations = { [ MUTATION_TYPES . CHANGE_ACCOUNT ] : ( state , account ) => { state . account = account ; } , [ MUTATION_TYPES . CHANGE_RELATIONSHIP ] : ( state , relationship ) => { state . relationship = relationship ; } , [ MUTATION_TYPES . CHANGE_LOADING ] : ( state , value ) => { state . loading = value ; } , [ MUTATION_TYPES . CHANGE_IDENTITY_PROOFS ] : ( state , values ) => { state . identityProofs = values ; } } ; const actions = { fetchAccount : async ( { rootState , dispatch } , accountID ) : Promise < Entity . Account > => { const client = generator ( rootState . TimelineSpace . sns , rootState . TimelineSpace . account . baseURL , rootState . TimelineSpace . account . accessToken , rootState . App . userAgent ) ; const res = await client . getAccount ( accountID ) ; dispatch ( 'identityProofs' , res . data ) ; return res . data ; } , searchAccount : async ( { rootState } , searchAccount ) : Promise < Entity . Account > => { const client = generator ( rootState . TimelineSpace . sns , rootState . TimelineSpace . account . baseURL , rootState . TimelineSpace . account . accessToken , rootState . App . userAgent ) ; if ( searchAccount . status . in_reply_to_account_id ) { const res = await client . getAccount ( searchAccount . status . in_reply_to_account_id ) ; if ( res . status === 200 ) { const user = accountMatch ( [ res . data ] , searchAccount . parsedAccount , rootState . TimelineSpace . account . domain ) ; if ( user ) return user ; } } if ( searchAccount . status . in_reply_to_id ) { const res = await client . getStatusContext ( searchAccount . status . id ) ; if ( res . status === 200 ) { const accounts = res . data . ancestors . map ( s => s . account ) . concat ( res . data . descendants . map ( s => s . account ) ) ; const user = accountMatch ( accounts , searchAccount . parsedAccount , rootState . TimelineSpace . account . domain ) ; if ( user ) return user ; } } const res = await client . searchAccount ( searchAccount . parsedAccount . url , { resolve : true } ) ; if ( res . data . length <= 0 ) throw new AccountNotFound ( 'empty result' ) ; const user = accountMatch ( res . data , searchAccount . parsedAccount , rootState . TimelineSpace . account . domain ) ; if ( ! user ) throw new AccountNotFound ( 'not found' ) ; return user ; } , changeAccount : ( { commit , dispatch } , account ) => { dispatch ( 'fetchRelationship' , account ) ; dispatch ( 'identityProofs' , account ) ; commit ( MUTATION_TYPES . CHANGE_ACCOUNT , account ) ; } , fetchRelationship : async ( { commit , rootState } , account ) : Promise < Entity . Relationship > => { commit ( MUTATION_TYPES . CHANGE_RELATIONSHIP , null ) ; const client = generator ( rootState . TimelineSpace . sns , rootState . TimelineSpace . account . baseURL , rootState . TimelineSpace . account . accessToken , rootState . App . userAgent ) ; const res = await client . getRelationship ( account . id ) ; commit ( MUTATION_TYPES . CHANGE_RELATIONSHIP , res . data ) ; return res . data ; } , reload : async ( { dispatch , state , commit } ) => { commit ( MUTATION_TYPES . CHANGE_LOADING , true ) ; Promise . all ( [ dispatch ( 'fetchRelationship' , state . account ) , dispatch ( 'TimelineSpace/Contents/SideBar/AccountProfile/Timeline/Posts/fetchTimeline' , state . account , { root : true } ) , dispatch ( 'TimelineSpace/Contents/SideBar/AccountProfile/Timeline/PostsAndReplies/fetchTimeline' , state . account , { root : true } ) , dispatch ( 'TimelineSpace/Contents/SideBar/AccountProfile/Timeline/Media/fetchTimeline' , state . account , { root : true } ) , dispatch ( 'TimelineSpace/Contents/SideBar/AccountProfile/Followers/fetchFollowers' , state . account , { root : true } ) , dispatch ( 'TimelineSpace/Contents/SideBar/AccountProfile/Follows/fetchFollows' , state . account , { root : true } ) ] ) . finally ( ( ) => { commit ( MUTATION_TYPES . CHANGE_LOADING , false ) ; } ) ; } , follow : async ( { commit , rootState , dispatch } , account ) => { const client = generator ( rootState . TimelineSpace . sns , rootState . TimelineSpace . account . baseURL , rootState . TimelineSpace . account . accessToken , rootState . App . userAgent ) ; const res = await client . followAccount ( account . id ) ; commit ( MUTATION_TYPES . CHANGE_RELATIONSHIP , res . data ) ; dispatch ( 'fetchRelationship' , account ) ; return res . data ; } , unfollow : async ( { commit , rootState , dispatch } , account ) => { const client = generator ( rootState . TimelineSpace . sns , rootState . TimelineSpace . account . baseURL , rootState . TimelineSpace . account . accessToken , rootState . App . userAgent ) ; const res = await client . unfollowAccount ( account . id ) ; commit ( MUTATION_TYPES . CHANGE_RELATIONSHIP , res . data ) ; dispatch ( 'fetchRelationship' , account ) ; return res . data ; } , close : ( { commit } ) => { commit ( MUTATION_TYPES . CHANGE_ACCOUNT , null ) ; } , unmute : async ( { rootState , commit , dispatch } , account ) => { const client = generator ( rootState . TimelineSpace . sns , rootState . TimelineSpace . account . baseURL , rootState . TimelineSpace . account . accessToken , rootState . App . userAgent ) ; const res = await client . unmuteAccount ( account . id ) ; commit ( MUTATION_TYPES . CHANGE_RELATIONSHIP , res . data ) ; dispatch ( 'fetchRelationship' , account ) ; return res . data ; } , block : async ( { rootState , commit , dispatch } , account ) => { const client = generator ( rootState . TimelineSpace . sns , rootState . TimelineSpace . account . baseURL , rootState . TimelineSpace . account . accessToken , rootState . App . userAgent ) ; const res = await client . blockAccount ( account . id ) ; commit ( MUTATION_TYPES . CHANGE_RELATIONSHIP , res . data ) ; dispatch ( 'fetchRelationship' , account ) ; return res . data ; } , unblock : async ( { rootState , commit , dispatch } , account ) => { const client = generator ( rootState . TimelineSpace . sns , rootState . TimelineSpace . account . baseURL , rootState . TimelineSpace . account . accessToken , rootState . App . userAgent ) ; const res = await client . unblockAccount ( account . id ) ; commit ( MUTATION_TYPES . CHANGE_RELATIONSHIP , res . data ) ; dispatch ( 'fetchRelationship' , account ) ; return res . data ; } , identityProofs : async ( { rootState , commit } , account ) => { const client = generator ( rootState . TimelineSpace . sns , rootState . TimelineSpace . account . baseURL , rootState . TimelineSpace . account . accessToken , rootState . App . userAgent ) ; const res = await client . getIdentityProof ( account . id ) ; commit ( MUTATION_TYPES . CHANGE_IDENTITY_PROOFS , res . data ) ; } , subscribe : async ( { rootState , commit } , account ) => { const client = generator ( rootState . TimelineSpace . sns , rootState . TimelineSpace . account . baseURL , rootState . TimelineSpace . account . accessToken , rootState . App . userAgent ) ; const res = await client . subscribeAccount ( account . id ) ; commit ( MUTATION_TYPES . CHANGE_RELATIONSHIP , res . data ) ; } , unsubscribe : async ( { rootState , commit } , account ) => { const client = generator ( rootState . TimelineSpace . sns , rootState . TimelineSpace . account . baseURL , rootState . TimelineSpace . account . accessToken , rootState . App . userAgent ) ; const res = await client . unsubscribeAccount ( account . id ) ; commit ( MUTATION_TYPES . CHANGE_RELATIONSHIP , res . data ) ; } } ; const getters = { isOwnProfile : ( state , _getters , rootState ) => { if ( ! state . account ) { return false ; } const own = rootState . TimelineSpace . account ; if ( `${ own . baseURL }/@${ own . username }` === state . account . url ) { return true ; } return `${ own . baseURL }/users/${ own . username }` === state . account . url ; } } ; const AccountProfile = { namespaced : true , modules : { Follows , Followers , Timeline } , state : state , mutations : mutations , actions : actions , getters : getters } ; class AccountNotFound extends Error { } export default AccountProfile ; const accountMatch = ( findAccounts , parsedAccount , domain ) : Entity . Account | false => { const account = findAccounts . find ( a => `@${ a . acct }` === parsedAccount . acct ) ; if ( account ) return account ; const pleromaUser = findAccounts . find ( a => a . acct === parsedAccount . acct ) ; if ( pleromaUser ) return pleromaUser ; const localUser = findAccounts . find ( a => `@${ a . username }@${ domain }` === parsedAccount . acct ) ; if ( localUser ) return localUser ; const user = findAccounts . find ( a => a . url === parsedAccount . url ) ; if ( ! user ) return false ; return user ; } ;