import { Assets , GameVersion , LatestGameVersion , } from "~/composables/Utilities" ; import { Class , getClassTree } from "~/composables/Characters" ; import { Ref , ref } from "vue" ; import { builds } from "~/data/builds" ; import { useAuth , useDB } from "~/State" ; import { useToast } from "vue-toastification" ; import dayjs from "dayjs" ; import md5Hex from "md5-hex" ; export type BuildTab = { skills : Record < number , string > ; comment ? : string ; } ; export type Build = { title : string ; version : GameVersion ; level ? : number ; class : Class ; tabs : BuildTab [ ] ; notes ? : string ; } ; type BuildMeta = { author : string ; id : string ; likes : number ; likedByCurrentUser : boolean ; } ; const classAlias = { [ Class . Beginner ] : "all" , [ Class . Journeyman ] : "jma" , [ Class . Maestro ] : "mae" , [ Class . Warrior ] : "war" , [ Class . Barbarian ] : "bar" , [ Class . Squire ] : "sqr" , [ Class . Archer ] : "arc" , [ Class . Bowman ] : "bow" , [ Class . Hunter ] : "hun" , [ Class . Mage ] : "mag" , [ Class . Shaman ] : "sha" , [ Class . Wizard ] : "wiz" , } ; const currentBuild = ref ( null ) ; const currentBuildMeta = ref ( { author : "" , id : "" , likes : 0 , likedByCurrentUser : false , } ) ; const { db , DbRef } = useDB ( ) ; export function useBuilds ( ) { const { user } = useAuth ( ) ; const toast = useToast ( ) ; const createNewBuild = ( class_ ) => { const numTabs = getClassTree ( class_ ) . length ; const tabs = [ ] ; for ( const _ of Array ( numTabs ) ) { tabs . push ( { skills : { } , } ) ; } currentBuild . value = { title : "" , level : 1 , version : LatestGameVersion , class : class_ , tabs : tabs , } ; currentBuildMeta . value = { author : "" , id : "" , likes : 0 , likedByCurrentUser : false , } ; } ; const getTalentAsset = ( build , tab , slot ) => { let role = "" ; const classTree = getClassTree ( build . class ) ; if ( tab === 1 && slot <= 10 ) { role = classAlias [ classTree . slice ( - 1 ) [ 0 ] ] ; } else if ( ( tab === 1 && slot > 10 ) || tab === 2 ) { if ( build . class !== Class . Beginner ) { role = classAlias [ classTree . slice ( - 2 ) [ 0 ] ] ; } } else if ( tab === 3 ) { role = classAlias [ classTree . slice ( - 3 ) [ 0 ] ] ; } return Assets . TalentImage ( role , tab , slot ) ; } ; const loadBuildFromDatabase = async ( id ) => { if ( ! id ) { toast . warning ( "Invalid build ID." ) ; return ; } const buildSnapshot = await db . ref ( `${ DbRef . Builds }/${ id }` ) . once ( "value" ) ; if ( buildSnapshot . exists ( ) && buildSnapshot . val ( ) ) { const buildData = buildSnapshot . val ( ) ; currentBuild . value = JSON . parse ( buildData . build ) as Build ; currentBuildMeta . value = { author : buildData . author , id , likes : buildData . likes , likedByCurrentUser : false , } ; if ( user . value ) { const likedByCurrentUser = await db . ref ( `${ DbRef . Builds }/${ id }/likedBy/${ user . value . uid }` ) . once ( "value" ) ; currentBuildMeta . value . likedByCurrentUser = likedByCurrentUser . val ( ) ; } toast . info ( `Loaded build "${ currentBuild . value . title }"` ) ; } else { toast . error ( "Failed to load build. It may have been deleted." ) ; } } ; const likeBuild = async ( buildId ) => { if ( ! user . value ) { toast . error ( "You must be logged in to do that!" ) ; return ; } console . log ( user . value . uid , buildId ) ; db . ref ( `${ DbRef . Builds }/${ buildId }/likedBy/${ user . value . uid }` ) . set ( true ) . then ( ( ) => { db . ref ( `${ DbRef . Builds }/${ buildId }/likes` ) . transaction ( ( data ) => { if ( data !== null ) { data += 1 ; } return data ; } ) . then ( ( ) => { toast . success ( "Thanks for liking this build!" ) ; } ) ; } ) ; } ; const unlikeBuild = async ( buildId ) => { if ( ! user . value ) { toast . error ( "You must be logged in to do that!" ) ; return ; } db . ref ( `${ DbRef . Builds }/${ buildId }/likedBy/${ user . value . uid }` ) . remove ( ) . then ( ( ) => { db . ref ( `${ DbRef . Builds }/${ buildId }/likes` ) . transaction ( ( data ) => { if ( data !== null ) { data -= 1 ; } return data ; } ) ; } ) ; } ; const uploadBuild = ( ) => { if ( ! user . value ) { toast . error ( "You must be logged in to do that!" ) ; return ; } if ( ! currentBuild . value || ! currentBuild . value . title || ! currentBuild . value . notes ) { toast . warning ( "Your build is missing a title/notes." ) ; return ; } const buildEncoded = JSON . stringify ( currentBuild . value ) ; const buildHash = md5Hex ( dayjs ( ) . toString ( ) + buildEncoded ) . slice ( 0 , 12 ) ; const buildData = { author : user . value . uid , build : buildEncoded , likes : 0 , likedBy : { } , } ; db . ref ( `${ DbRef . Builds }/${ buildHash }` ) . set ( buildData ) . then ( ( _ ) => { toast . success ( "Your build was uploaded successfully!" ) ; currentBuildMeta . value = { author : buildData . author , id : buildHash , likes : 0 , likedByCurrentUser : false , } ; } ) ; } ; return { builds , createNewBuild , currentBuild , currentBuildMeta , getTalentAsset , likeBuild , loadBuildFromDatabase , unlikeBuild , uploadBuild , } ; }