2019-06-17 15:15:27 +00:00
< template >
2020-06-25 09:36:35 +00:00
< div >
2022-01-10 14:19:16 +00:00
< breadcrumbs -nav :links ="breadcrumbsLinks" / >
2023-05-03 07:25:48 +00:00
< div v-if ="identity" >
2023-09-07 09:57:09 +00:00
< h1 class = "flex justify-center" >
2023-05-03 07:25:48 +00:00
< span v-if ="isUpdate" class="line-clamp-2" > {{
displayName ( identity )
} } < / span >
2023-09-07 09:57:09 +00:00
< span v-else > {{ t ( " I create an identity " ) }} < / span >
2020-06-25 09:36:35 +00:00
< / h1 >
2023-08-13 17:26:18 +00:00
< o -field horizontal :label ="t('Avatar')" >
2023-08-13 16:05:36 +00:00
< picture -upload
v - model = "avatarFile"
: defaultImage = "identity.avatar"
: maxSize = "avatarMaxSize"
/ >
< / o - f i e l d >
2020-06-25 09:36:35 +00:00
2022-07-12 08:55:28 +00:00
< o -field
2021-09-07 15:52:34 +00:00
horizontal
2023-09-07 09:57:09 +00:00
: label = "t('Display name')"
2021-09-07 15:52:34 +00:00
label - for = "identity-display-name"
>
2022-07-12 08:55:28 +00:00
< o -input
2020-02-18 07:57:00 +00:00
aria - required = "true"
required
2020-06-25 09:36:35 +00:00
v - model = "identity.name"
2023-08-02 13:15:07 +00:00
@ input = "(event: any) => updateUsername(event.target.value)"
2021-09-07 15:52:34 +00:00
id = "identity-display-name"
2021-11-07 13:59:20 +00:00
dir = "auto"
2023-12-14 09:50:38 +00:00
expanded
2020-02-18 07:57:00 +00:00
/ >
2022-07-12 08:55:28 +00:00
< / o - f i e l d >
2019-06-17 15:15:27 +00:00
2022-07-12 08:55:28 +00:00
< o -field
2020-06-25 09:36:35 +00:00
horizontal
2023-09-07 09:57:09 +00:00
class = "username-field"
: label = "t('Username')"
2021-09-07 15:52:34 +00:00
label - for = "identity-username"
2020-06-25 09:36:35 +00:00
: message = "message"
>
2023-09-07 09:57:09 +00:00
< o -field class = "!mt-0" >
2022-07-12 08:55:28 +00:00
< o -input
2023-09-07 09:57:09 +00:00
expanded
class = "!mt-0"
2020-06-25 09:36:35 +00:00
aria - required = "true"
required
v - model = "identity.preferredUsername"
: disabled = "isUpdate"
2021-11-07 13:59:20 +00:00
dir = "auto"
2020-06-25 09:36:35 +00:00
: use - html5 - validation = "!isUpdate"
pattern = "[a-z0-9_]+"
2021-09-07 15:52:34 +00:00
id = "identity-username"
2020-06-25 09:36:35 +00:00
/ >
< p class = "control" >
2023-08-13 21:02:41 +00:00
< span class = "button is-static !h-auto" > @ { { getInstanceHost } } < / span >
2020-06-25 09:36:35 +00:00
< / p >
2022-07-12 08:55:28 +00:00
< / o - f i e l d >
< / o - f i e l d >
2020-06-25 09:36:35 +00:00
2022-07-12 08:55:28 +00:00
< o -field
2021-09-07 15:52:34 +00:00
horizontal
2023-09-07 09:57:09 +00:00
: label = "t('Description')"
2021-09-07 15:52:34 +00:00
label - for = "identity-summary"
>
2022-07-12 08:55:28 +00:00
< o -input
2020-11-30 09:24:11 +00:00
type = "textarea"
2021-11-07 13:59:20 +00:00
dir = "auto"
2020-11-30 09:24:11 +00:00
aria - required = "false"
v - model = "identity.summary"
2021-09-07 15:52:34 +00:00
id = "identity-summary"
2023-12-14 09:50:38 +00:00
expanded
2020-11-30 09:24:11 +00:00
/ >
2022-07-12 08:55:28 +00:00
< / o - f i e l d >
2019-06-17 15:15:27 +00:00
2022-07-12 08:55:28 +00:00
< o -notification
variant = "danger"
2020-06-25 09:36:35 +00:00
has - icon
aria - close - label = "Close notification"
role = "alert"
: key = "error"
v - for = "error in errors"
2022-07-12 08:55:28 +00:00
> { { error } } < / o - n o t i f i c a t i o n
2020-06-25 09:36:35 +00:00
>
2023-09-07 09:57:09 +00:00
< o -field class = "flex justify-center !my-6" >
2020-06-25 09:36:35 +00:00
< div class = "control" >
2022-07-12 08:55:28 +00:00
< o -button type = "button" variant = "primary" @click ="submit()" >
2023-09-07 09:57:09 +00:00
{ { t ( "Save" ) } }
2022-07-12 08:55:28 +00:00
< / o - b u t t o n >
2020-06-25 09:36:35 +00:00
< / div >
2022-07-12 08:55:28 +00:00
< / o - f i e l d >
2020-06-25 09:36:35 +00:00
2023-09-07 09:57:09 +00:00
< o -field class = "flex justify-center" >
2022-07-12 08:55:28 +00:00
< o -button
2021-09-07 15:52:34 +00:00
v - if = "isUpdate"
@ click = "openDeleteIdentityConfirmation()"
2022-08-26 14:08:58 +00:00
variant = "text"
2021-09-07 15:52:34 +00:00
>
2023-09-07 09:57:09 +00:00
{ { t ( "Delete this identity" ) } }
2022-07-12 08:55:28 +00:00
< / o - b u t t o n >
< / o - f i e l d >
2021-03-26 18:01:55 +00:00
< section v-if ="isUpdate" >
2023-09-07 09:57:09 +00:00
< h2 > { { t ( "Profile feeds" ) } } < / h2 >
2021-03-26 18:01:55 +00:00
< p >
{ {
2023-09-07 09:57:09 +00:00
t (
2021-03-26 18:01:55 +00:00
"These feeds contain event data for the events for which this specific profile is a participant or creator. You should keep these private. You can find feeds for all of your profiles into your notification settings."
)
} }
< / p >
< div v-if ="identity.feedTokens && identity.feedTokens.length > 0" >
< div
2022-07-12 08:55:28 +00:00
class = "flex flex-wrap gap-2"
2021-03-26 18:01:55 +00:00
v - for = "feedToken in identity.feedTokens"
: key = "feedToken.token"
>
2022-07-12 08:55:28 +00:00
< o -tooltip
2023-09-07 09:57:09 +00:00
: label = "t('URL copied to clipboard')"
2021-03-26 18:01:55 +00:00
: active = "showCopiedTooltip.atom"
2022-07-12 08:55:28 +00:00
variant = "success"
position = "left"
2023-12-14 09:50:38 +00:00
/ >
< o -button
tag = "a"
icon - left = "rss"
@ click = "
( e : Event ) =>
copyURL ( e , tokenToURL ( feedToken . token , 'atom' ) , 'atom' )
"
: href = "tokenToURL(feedToken.token, 'atom')"
target = "_blank"
> { { t ( "RSS/Atom Feed" ) } } < / o - b u t t o n
2021-03-26 18:01:55 +00:00
>
2022-07-12 08:55:28 +00:00
< o -tooltip
2023-09-07 09:57:09 +00:00
: label = "t('URL copied to clipboard')"
2021-03-26 18:01:55 +00:00
: active = "showCopiedTooltip.ics"
2022-07-12 08:55:28 +00:00
variant = "success"
position = "left"
2023-12-14 09:50:38 +00:00
/ >
< o -button
tag = "a"
@ click = "
( e : Event ) =>
copyURL ( e , tokenToURL ( feedToken . token , 'ics' ) , 'ics' )
"
icon - left = "calendar-sync"
: href = "tokenToURL(feedToken.token, 'ics')"
target = "_blank"
> { { t ( "ICS/WebCal Feed" ) } } < / o - b u t t o n
2021-03-26 18:01:55 +00:00
>
2022-07-12 08:55:28 +00:00
< o -button
2021-03-26 18:01:55 +00:00
icon - left = "refresh"
2022-07-12 08:55:28 +00:00
variant = "text"
2021-03-26 18:01:55 +00:00
@ click = "openRegenerateFeedTokensConfirmation"
2023-09-07 09:57:09 +00:00
> { { t ( "Regenerate new links" ) } } < / o - b u t t o n
2021-03-26 18:01:55 +00:00
>
< / div >
< / div >
< div v-else >
2022-07-12 08:55:28 +00:00
< o -button
2021-03-26 18:01:55 +00:00
icon - left = "refresh"
2022-07-12 08:55:28 +00:00
variant = "text"
2021-03-26 18:01:55 +00:00
@ click = "generateFeedTokens"
2023-09-07 09:57:09 +00:00
> { { t ( "Create new links" ) } } < / o - b u t t o n
2021-03-26 18:01:55 +00:00
>
< / div >
< / section >
2019-06-17 15:15:27 +00:00
< / div >
< / div >
< / template >
2021-11-07 13:59:20 +00:00
< style scoped lang = "scss" >
@ use "@/styles/_mixins" as * ;
2023-09-07 09:57:09 +00:00
// h1 {
// display: flex;
// justify-content: center;
// }
2019-06-17 15:15:27 +00:00
2023-09-07 09:57:09 +00:00
// .username-field + .field {
// margin-bottom: 0;
// }
2021-03-26 18:01:55 +00:00
2022-07-12 08:55:28 +00:00
: deep ( . buttons > * : not ( : last - child ) . button ) {
2021-11-04 17:14:36 +00:00
@ include margin - right ( 0.5 rem ) ;
2021-03-26 18:01:55 +00:00
}
2019-06-17 15:15:27 +00:00
< / style >
2022-07-12 08:55:28 +00:00
< script lang = "ts" setup >
2019-09-11 07:59:01 +00:00
import {
CREATE _PERSON ,
DELETE _PERSON ,
FETCH _PERSON ,
IDENTITIES ,
2021-08-05 13:49:54 +00:00
PERSON _FRAGMENT ,
2022-07-12 08:55:28 +00:00
PERSON _FRAGMENT _FEED _TOKENS ,
2019-09-11 07:59:01 +00:00
UPDATE _PERSON ,
2022-07-12 08:55:28 +00:00
} from "@/graphql/actor" ;
import { IPerson , displayName } from "@/types/actor" ;
import PictureUpload from "@/components/PictureUpload.vue" ;
import { MOBILIZON _INSTANCE _HOST } from "@/api/_entrypoint" ;
import RouteName from "@/router/name" ;
2023-05-30 07:03:51 +00:00
import { buildFileFromIMedia , buildFileVariable } from "@/utils/image" ;
2022-07-12 08:55:28 +00:00
import { changeIdentity } from "@/utils/identity" ;
2021-03-26 18:01:55 +00:00
import {
CREATE _FEED _TOKEN _ACTOR ,
DELETE _FEED _TOKEN ,
} from "@/graphql/feed_tokens" ;
import { IFeedToken } from "@/types/feedtoken.model" ;
2021-05-12 16:10:07 +00:00
import { ServerParseError } from "@apollo/client/link/http" ;
import { ApolloCache , FetchResult , InMemoryCache } from "@apollo/client/core" ;
2021-08-05 13:49:54 +00:00
import pick from "lodash/pick" ;
import { ActorType } from "@/types/enums" ;
2022-07-12 08:55:28 +00:00
import { useRouter } from "vue-router" ;
import { useCurrentActorClient } from "@/composition/apollo/actor" ;
import { useMutation , useQuery , useApolloClient } from "@vue/apollo-composable" ;
import { useAvatarMaxSize } from "@/composition/config" ;
import { computed , inject , reactive , ref , watch } from "vue" ;
import { useI18n } from "vue-i18n" ;
import { convertToUsername } from "@/utils/username" ;
import { Dialog } from "@/plugins/dialog" ;
import { Notifier } from "@/plugins/notifier" ;
import { AbsintheGraphQLErrors } from "@/types/errors.model" ;
2023-03-17 17:10:59 +00:00
import { ICurrentUser } from "@/types/current-user.model" ;
2023-11-21 15:04:09 +00:00
import { useHead } from "@unhead/vue" ;
2022-07-12 08:55:28 +00:00
const { t } = useI18n ( { useScope : "global" } ) ;
const router = useRouter ( ) ;
const props = defineProps < { isUpdate : boolean ; identityName ? : string } > ( ) ;
const { currentActor } = useCurrentActorClient ( ) ;
2023-05-30 07:03:51 +00:00
const {
result : personResult ,
onError : onPersonError ,
onResult : onPersonResult ,
} = useQuery < {
2022-07-12 08:55:28 +00:00
fetchPerson : IPerson ;
} > (
FETCH _PERSON ,
( ) => ( {
username : props . identityName ,
} ) ,
( ) => ( {
enabled : props . identityName !== undefined ,
} )
) ;
2023-05-30 07:03:51 +00:00
onPersonResult ( async ( { data } ) => {
avatarFile . value = await buildFileFromIMedia ( data ? . fetchPerson ? . avatar ) ;
} ) ;
2022-07-12 08:55:28 +00:00
onPersonError ( ( err ) => handleErrors ( err as unknown as AbsintheGraphQLErrors ) ) ;
const person = computed ( ( ) => personResult . value ? . fetchPerson ) ;
const baseIdentity : IPerson = {
id : undefined ,
avatar : null ,
name : "" ,
preferredUsername : "" ,
summary : "" ,
feedTokens : [ ] ,
url : "" ,
domain : null ,
type : ActorType . PERSON ,
suspended : false ,
} ;
2023-09-07 09:57:09 +00:00
const identity = ref < IPerson > ( baseIdentity ) ;
2022-07-12 08:55:28 +00:00
watch ( person , ( ) => {
console . debug ( "person changed" , person . value ) ;
if ( person . value ) {
2023-09-07 09:57:09 +00:00
identity . value = { ... person . value } ;
2019-11-18 16:37:38 +00:00
}
2022-07-12 08:55:28 +00:00
} ) ;
const avatarMaxSize = useAvatarMaxSize ( ) ;
const errors = ref < string [ ] > ( [ ] ) ;
const avatarFile = ref < File | null > ( null ) ;
const showCopiedTooltip = reactive ( { ics : false , atom : false } ) ;
const isUpdate = computed ( ( ) => props . isUpdate ) ;
const identityName = computed ( ( ) => props . identityName ) ;
const message = computed ( ( ) : string | null => {
if ( props . isUpdate ) return null ;
return t (
"Only alphanumeric lowercased characters and underscores are supported."
) ;
} ) ;
watch ( isUpdate , ( ) => {
resetFields ( ) ;
} ) ;
watch ( identityName , async ( ) => {
// Only used when we update the identity
if ( ! isUpdate . value ) {
identity . value = baseIdentity ;
return ;
2019-06-17 15:15:27 +00:00
}
2022-07-12 08:55:28 +00:00
await redirectIfNoIdentitySelected ( identityName . value ) ;
2019-06-17 15:15:27 +00:00
2022-07-12 08:55:28 +00:00
if ( ! identityName . value ) {
router . push ( { name : "CreateIdentity" } ) ;
}
2019-06-17 15:15:27 +00:00
2022-07-12 08:55:28 +00:00
if ( identityName . value && identity . value ) {
avatarFile . value = null ;
}
} ) ;
const submit = ( ) : Promise < void > => {
if ( props . isUpdate ) return updateIdentity ( ) ;
return createIdentity ( ) ;
} ;
const {
mutate : deletePersonMutation ,
onDone : deletePersonDone ,
onError : deletePersonError ,
} = useMutation ( DELETE _PERSON , ( ) => ( {
update : ( store : ApolloCache < InMemoryCache > ) => {
2023-03-17 18:06:46 +00:00
const data = store . readQuery < { loggedUser : Pick < ICurrentUser , " actors " > } > ( {
2022-07-12 08:55:28 +00:00
query : IDENTITIES ,
} ) ;
2019-11-05 14:03:35 +00:00
2022-07-12 08:55:28 +00:00
if ( data ) {
store . writeQuery ( {
query : IDENTITIES ,
data : {
2023-03-17 17:10:59 +00:00
loggedUser : {
... data . loggedUser ,
2023-03-17 18:06:46 +00:00
actors : data . loggedUser . actors . filter (
( i ) => i . id !== identity . value . id
) ,
} ,
2022-07-12 08:55:28 +00:00
} ,
} ) ;
2019-06-17 15:15:27 +00:00
}
2022-07-12 08:55:28 +00:00
} ,
} ) ) ;
2019-06-17 15:15:27 +00:00
2022-07-12 08:55:28 +00:00
const notifier = inject < Notifier > ( "notifier" ) ;
2019-06-17 15:15:27 +00:00
2022-07-12 08:55:28 +00:00
const { resolveClient } = useApolloClient ( ) ;
2019-06-17 15:15:27 +00:00
2022-07-12 08:55:28 +00:00
deletePersonDone ( async ( ) => {
notifier ? . success (
t ( "Identity {displayName} deleted" , {
displayName : displayName ( identity . value ) ,
} )
) ;
2019-09-11 07:59:01 +00:00
/ * *
2022-07-12 08:55:28 +00:00
* If we just deleted the current identity ,
* we need to change it to the next one
2019-09-11 07:59:01 +00:00
* /
2022-07-12 08:55:28 +00:00
const client = resolveClient ( ) ;
const data = client . readQuery < {
2023-03-17 18:06:46 +00:00
loggedUser : Pick < ICurrentUser , " actors " > ;
2022-07-12 08:55:28 +00:00
} > ( { query : IDENTITIES } ) ;
if ( data ) {
2023-03-17 17:10:59 +00:00
await maybeUpdateCurrentActorCache ( data . loggedUser . actors [ 0 ] ) ;
2022-07-12 08:55:28 +00:00
}
2019-06-17 15:15:27 +00:00
2022-07-12 08:55:28 +00:00
await redirectIfNoIdentitySelected ( ) ;
} ) ;
deletePersonError ( ( err ) => handleError ( err ) ) ;
/ * *
* Delete an identity
* /
const deleteIdentity = async ( ) : Promise < void > => {
deletePersonMutation ( {
id : identity . value ? . id ,
} ) ;
} ;
const {
mutate : updateIdentityMutation ,
onDone : updateIdentityDone ,
onError : updateIdentityError ,
} = useMutation ( UPDATE _PERSON , ( ) => ( {
update : (
store : ApolloCache < InMemoryCache > ,
{ data : updateData } : FetchResult
) => {
2023-03-17 18:06:46 +00:00
const data = store . readQuery < { loggedUser : Pick < ICurrentUser , " actors " > } > ( {
2022-07-12 08:55:28 +00:00
query : IDENTITIES ,
} ) ;
2019-06-17 15:15:27 +00:00
2022-07-12 08:55:28 +00:00
if ( data && updateData ? . updatePerson ) {
maybeUpdateCurrentActorCache ( updateData ? . updatePerson ) ;
2019-06-17 15:15:27 +00:00
2022-07-12 08:55:28 +00:00
store . writeFragment ( {
fragment : PERSON _FRAGMENT ,
id : ` Person: ${ updateData ? . updatePerson . id } ` ,
data : {
... updateData ? . updatePerson ,
type : ActorType . PERSON ,
2019-06-17 15:15:27 +00:00
} ,
} ) ;
}
2022-07-12 08:55:28 +00:00
} ,
} ) ) ;
updateIdentityDone ( ( ) => {
notifier ? . success (
t ( "Identity {displayName} updated" , {
displayName : displayName ( identity . value ) ,
} ) as string
) ;
} ) ;
updateIdentityError ( ( err ) => handleError ( err ) ) ;
const updateIdentity = async ( ) : Promise < void > => {
const variables = await buildVariables ( ) ;
updateIdentityMutation ( variables ) ;
} ;
const {
mutate : createIdentityMutation ,
onDone : createIdentityDone ,
onError : createIdentityError ,
} = useMutation ( CREATE _PERSON , ( ) => ( {
update : (
store : ApolloCache < InMemoryCache > ,
{ data : updateData } : FetchResult
) => {
2023-03-17 18:06:46 +00:00
const data = store . readQuery < { loggedUser : Pick < ICurrentUser , " actors " > } > ( {
2022-07-12 08:55:28 +00:00
query : IDENTITIES ,
} ) ;
2019-06-17 15:15:27 +00:00
2022-07-12 08:55:28 +00:00
if ( data && updateData ? . createPerson ) {
store . writeQuery ( {
query : IDENTITIES ,
data : {
2023-03-17 17:10:59 +00:00
loggedUser : {
... data . loggedUser ,
actors : [
2023-03-17 18:06:46 +00:00
... data . loggedUser . actors ,
{ ... updateData ? . createPerson , type : ActorType . PERSON } ,
] ,
} ,
2019-06-17 15:15:27 +00:00
} ,
} ) ;
2020-10-02 07:52:47 +00:00
}
2022-07-12 08:55:28 +00:00
} ,
} ) ) ;
2020-10-02 07:52:47 +00:00
2022-07-12 08:55:28 +00:00
createIdentityDone ( ( ) => {
notifier ? . success (
t ( "Identity {displayName} created" , {
displayName : displayName ( identity . value ) ,
} )
) ;
2019-06-17 15:15:27 +00:00
2022-07-12 08:55:28 +00:00
router . push ( {
name : RouteName . UPDATE _IDENTITY ,
params : { identityName : identity . value . preferredUsername } ,
} ) ;
} ) ;
2021-03-26 18:01:55 +00:00
2022-07-12 08:55:28 +00:00
createIdentityError ( ( err ) => handleError ( err ) ) ;
2021-03-26 18:01:55 +00:00
2022-07-12 08:55:28 +00:00
const createIdentity = async ( ) : Promise < void > => {
const variables = await buildVariables ( ) ;
2021-04-12 08:43:04 +00:00
2022-07-12 08:55:28 +00:00
createIdentityMutation ( variables ) ;
} ;
2021-03-26 18:01:55 +00:00
2022-07-12 08:55:28 +00:00
const handleErrors = ( absintheErrors : AbsintheGraphQLErrors ) : void => {
if ( absintheErrors . some ( ( error ) => error . status _code === 401 ) ) {
router . push ( { name : RouteName . LOGIN } ) ;
2021-03-26 18:01:55 +00:00
}
2022-07-12 08:55:28 +00:00
} ;
// eslint-disable-next-line class-methods-use-this
const getInstanceHost = computed ( ( ) : string => {
return MOBILIZON _INSTANCE _HOST ;
} ) ;
const tokenToURL = ( token : string , format : string ) : string => {
return ` ${ window . location . origin } /events/going/ ${ token } / ${ format } ` ;
} ;
const copyURL = ( e : Event , url : string , format : "ics" | "atom" ) : void => {
if ( navigator . clipboard ) {
e . preventDefault ( ) ;
navigator . clipboard . writeText ( url ) ;
showCopiedTooltip [ format ] = true ;
setTimeout ( ( ) => {
showCopiedTooltip [ format ] = false ;
} , 2000 ) ;
2021-03-26 18:01:55 +00:00
}
2022-07-12 08:55:28 +00:00
} ;
const generateFeedTokens = async ( ) : Promise < void > => {
await createNewFeedToken ( { actorId : identity . value ? . id } ) ;
} ;
const regenerateFeedTokens = async ( ) : Promise < void > => {
if ( identity . value ? . feedTokens . length < 1 ) return ;
await deleteFeedToken ( { token : identity . value . feedTokens [ 0 ] . token } ) ;
await createNewFeedToken (
{ actorId : identity . value ? . id } ,
{
update ( cache , { data } ) {
const actorId = data ? . createFeedToken . actor ? . id ;
const newFeedToken = data ? . createFeedToken . token ;
if ( ! newFeedToken ) return ;
let cachedData = cache . readFragment < {
id : string | undefined ;
feedTokens : { token : string } [ ] ;
} > ( {
id : ` Person: ${ actorId } ` ,
fragment : PERSON _FRAGMENT _FEED _TOKENS ,
} ) ;
// Remove the old token
cachedData = {
id : cachedData ? . id ,
feedTokens : [
... ( cachedData ? . feedTokens ? ? [ ] ) . slice ( 0 , - 1 ) ,
{ token : newFeedToken } ,
] ,
} ;
cache . writeFragment ( {
id : ` Person: ${ actorId } ` ,
fragment : PERSON _FRAGMENT _FEED _TOKENS ,
data : cachedData ,
} ) ;
} ,
}
) ;
} ;
const { mutate : deleteFeedToken } = useMutation ( DELETE _FEED _TOKEN ) ;
const { mutate : createNewFeedToken } = useMutation < {
createFeedToken : IFeedToken ;
} > ( CREATE _FEED _TOKEN _ACTOR , ( ) => ( {
update ( cache , { data } ) {
const actorId = data ? . createFeedToken . actor ? . id ;
const newFeedToken = data ? . createFeedToken . token ;
if ( ! newFeedToken ) return ;
let cachedData = cache . readFragment < {
id : string | undefined ;
feedTokens : { token : string } [ ] ;
} > ( {
id : ` Person: ${ actorId } ` ,
fragment : PERSON _FRAGMENT _FEED _TOKENS ,
2021-03-26 18:01:55 +00:00
} ) ;
2022-07-12 08:55:28 +00:00
// Add the new token to the list
cachedData = {
id : cachedData ? . id ,
feedTokens : [ ... ( cachedData ? . feedTokens ? ? [ ] ) , { token : newFeedToken } ] ,
} ;
cache . writeFragment ( {
id : ` Person: ${ actorId } ` ,
fragment : PERSON _FRAGMENT _FEED _TOKENS ,
data : cachedData ,
2021-03-26 18:01:55 +00:00
} ) ;
2022-07-12 08:55:28 +00:00
} ,
} ) ) ;
const dialog = inject < Dialog > ( "dialog" ) ;
const openRegenerateFeedTokensConfirmation = ( ) : void => {
dialog ? . confirm ( {
2022-08-26 14:08:58 +00:00
variant : "warning" ,
2022-07-12 08:55:28 +00:00
title : t ( "Regenerate new links" ) as string ,
message : t (
"You'll need to change the URLs where there were previously entered."
) as string ,
confirmText : t ( "Regenerate new links" ) as string ,
cancelText : t ( "Cancel" ) as string ,
onConfirm : ( ) => regenerateFeedTokens ( ) ,
} ) ;
} ;
const openDeleteIdentityConfirmation = ( ) : void => {
dialog ? . prompt ( {
2022-08-26 14:08:58 +00:00
variant : "danger" ,
2022-07-12 08:55:28 +00:00
title : t ( "Delete your identity" ) as string ,
message : ` ${ t (
"This will delete / anonymize all content (events, comments, messages, participations…) created from this identity."
) }
2019-09-12 09:34:01 +00:00
< br / > < br / >
2022-07-12 08:55:28 +00:00
$ { t (
2020-02-18 07:57:00 +00:00
"If this identity is the only administrator of some groups, you need to delete them before being able to delete this identity."
) }
2022-07-12 08:55:28 +00:00
$ { t (
2020-02-18 07:57:00 +00:00
"Otherwise this identity will just be removed from the group administrators."
) }
2019-09-12 09:34:01 +00:00
< br / > < br / >
2022-07-12 08:55:28 +00:00
$ { t (
2020-11-30 09:24:11 +00:00
'To confirm, type your identity username "{preferredUsername}"' ,
{
2022-07-12 08:55:28 +00:00
preferredUsername : identity . value . preferredUsername ,
2020-11-30 09:24:11 +00:00
}
) } ` ,
2022-07-12 08:55:28 +00:00
confirmText : t ( "Delete {preferredUsername}" , {
preferredUsername : identity . value . preferredUsername ,
} ) ,
inputAttrs : {
placeholder : identity . value . preferredUsername ,
pattern : identity . value . preferredUsername ,
} ,
onConfirm : ( ) => deleteIdentity ( ) ,
} ) ;
} ;
const handleError = ( err : any ) => {
console . error ( err ) ;
if ( err ? . networkError ? . name === "ServerParseError" ) {
const error = err ? . networkError as ServerParseError ;
if ( error ? . response ? . status === 413 ) {
const errorMessage = props . isUpdate
? t (
"Unable to update the profile. The avatar picture may be too heavy."
)
: t (
"Unable to create the profile. The avatar picture may be too heavy."
) ;
errors . value . push ( errorMessage as string ) ;
}
2019-06-17 15:15:27 +00:00
}
2022-07-12 08:55:28 +00:00
if ( err . graphQLErrors !== undefined ) {
err . graphQLErrors . forEach (
( { message : errorMessage } : { message : string } ) => {
notifier ? . error ( errorMessage ) ;
2021-04-12 08:43:04 +00:00
}
2022-07-12 08:55:28 +00:00
) ;
2019-06-17 15:15:27 +00:00
}
2022-07-12 08:55:28 +00:00
} ;
2019-06-17 15:15:27 +00:00
2022-07-12 08:55:28 +00:00
const buildVariables = async ( ) : Promise < Record < string , unknown > > => {
/ * *
* We set the avatar only if user has selected one
* /
let avatarObj : Record < string , unknown > = { avatar : null } ;
if ( avatarFile . value ) {
avatarObj = buildFileVariable (
avatarFile . value ,
2021-08-05 13:49:54 +00:00
"avatar" ,
2022-07-12 08:55:28 +00:00
` ${ identity . value . preferredUsername } 's avatar `
) ;
2019-06-17 15:15:27 +00:00
}
2022-07-12 08:55:28 +00:00
return pick ( { ... identity . value , ... avatarObj } , [
"id" ,
"preferredUsername" ,
"name" ,
"summary" ,
"avatar" ,
] ) ;
} ;
const redirectIfNoIdentitySelected = async ( identityParam ? : string ) => {
if ( identityParam ) return ;
// await loadLoggedPersonIfNeeded();
if ( currentActor . value ) {
await router . push ( {
params : { identityName : currentActor . value ? . preferredUsername } ,
} ) ;
2019-09-11 07:59:01 +00:00
}
2022-07-12 08:55:28 +00:00
} ;
const maybeUpdateCurrentActorCache = async ( newIdentity : IPerson ) => {
if ( currentActor . value ) {
if (
currentActor . value . preferredUsername === identity . value . preferredUsername
) {
await changeIdentity ( newIdentity ) ;
2019-06-17 15:15:27 +00:00
}
2022-07-12 08:55:28 +00:00
// currentActor.value = newIdentity;
2019-06-17 15:15:27 +00:00
}
2022-07-12 08:55:28 +00:00
} ;
2019-06-17 15:15:27 +00:00
2022-07-12 08:55:28 +00:00
// const loadLoggedPersonIfNeeded = async (bypassCache = false) => {
// if (currentActor.value) return;
2019-06-17 15:15:27 +00:00
2022-07-12 08:55:28 +00:00
// const result = await this.$apollo.query({
// query: CURRENT_ACTOR_CLIENT,
// fetchPolicy: bypassCache ? "network-only" : undefined,
// });
2019-06-17 15:15:27 +00:00
2022-07-12 08:55:28 +00:00
// currentActor.value = result.data.currentActor;
// };
2019-06-17 15:15:27 +00:00
2022-07-12 08:55:28 +00:00
const resetFields = ( ) => {
// identity.value = new Person();
// oldDisplayName.value = null;
avatarFile . value = null ;
} ;
2022-01-10 14:19:16 +00:00
2022-07-12 08:55:28 +00:00
const breadcrumbsLinks = computed (
( ) : { name : string ; params : Record < string , any > ; text : string } [ ] => {
2022-01-10 14:19:16 +00:00
const links = [
{
name : RouteName . IDENTITIES ,
params : { } ,
2022-07-12 08:55:28 +00:00
text : t ( "Profiles" ) as string ,
2022-01-10 14:19:16 +00:00
} ,
] ;
2022-07-12 08:55:28 +00:00
if ( props . isUpdate && identity . value ) {
2022-01-10 14:19:16 +00:00
links . push ( {
name : RouteName . UPDATE _IDENTITY ,
2022-07-12 08:55:28 +00:00
params : { identityName : identity . value . preferredUsername } ,
text : identity . value . name ,
2022-01-10 14:19:16 +00:00
} ) ;
} else {
links . push ( {
name : RouteName . CREATE _IDENTITY ,
params : { } ,
2022-07-12 08:55:28 +00:00
text : t ( "New profile" ) as string ,
2022-01-10 14:19:16 +00:00
} ) ;
}
return links ;
}
2022-07-12 08:55:28 +00:00
) ;
2023-04-07 13:58:38 +00:00
const updateUsername = ( value : string ) => {
identity . value . preferredUsername = convertToUsername ( value ) ;
2022-07-12 08:55:28 +00:00
} ;
2023-05-30 07:03:51 +00:00
useHead ( {
title : computed ( ( ) => {
let title = t ( "Create a new profile" ) as string ;
if ( isUpdate . value ) {
title = t ( "Edit profile {profile}" , {
profile : identityName . value ,
} ) as string ;
}
return title ;
} ) ,
} ) ;
2019-06-17 15:15:27 +00:00
< / script >