25
25
<IconButton icon =" fa-trash" @click =" beginCharDeletion(character)" />
26
26
<IconButton icon =" fa-copy" @click =" cloneCharacter(character)" />
27
27
<IconButton icon =" fa-file-arrow-down" @click =" exportCharacter(character)" />
28
+
29
+ <IconButton v-if =" !VicarSync.isCharacterSyncedOut(character) && !VicarSync.isCharacterSyncedIn(character)" icon =" fas fa-link" @click =" linkCharacterWithSync(character)" />
30
+ <IconButton v-else icon =" fas fa-cloud-upload-alt" @click =" infoSyncModalVisible = true" />
31
+
28
32
<IconButton v-if =" isShareAvailable()" icon =" fa-share-nodes" @click =" shareCharacter(character)" />
29
33
<IconButton icon =" fa-eye" @click =" viewCharacter(character)" />
30
34
</div >
35
+
36
+ <Modal :shown =" enableSyncModalVisible" @close =" enableSyncModalVisible = false" >
37
+ <div class =" p-10 w-400 d-flex flex-column" style =" gap : 1rem ; font-size : 1rem " >
38
+ <b style =" font-size : 1.2rem " >{{$t('character.sync.enable.text')}}</b >
39
+ <select class =" form-control" v-model =" enableSyncModalType" >
40
+ <option value =" out" >{{$t('character.sync.enable.type.out')}}</option >
41
+ <option value =" in" >{{$t('character.sync.enable.type.in')}}</option >
42
+ </select >
43
+
44
+ <div class =" form-group mb-0" v-if =" enableSyncModalType === 'in'" >
45
+ <label >{{$t('character.sync.hash')}}:</label >
46
+ <input class =" form-control" v-model =" enableSyncModalInHash" />
47
+ </div >
48
+
49
+ <div style =" width : 100% ; display : flex ; justify-content : center ; align-items : center " >
50
+ <button class =" btn btn-primary" :disabled =" enableSyncModalType === 'in' && enableSyncModalInHash.length <= 0" @click =" finishLinkCharacterWithSync" >{{$t('character.sync.enable')}}</button >
51
+ </div >
52
+ </div >
53
+ </Modal >
54
+
55
+ <Modal :shown =" infoSyncModalVisible" @close =" infoSyncModalVisible = false" >
56
+ <div class =" p-10 w-400 d-flex flex-column" style =" gap : 1rem ; font-size : 1rem " >
57
+ <b style =" font-size : 1.2rem " >{{$t('character.sync.info.text')}}</b >
58
+
59
+ <div class =" form-group mb-0" v-if =" VicarSync.isCharacterSyncedOut(character)" >
60
+ <label >{{$t('character.sync.hash')}}:</label >
61
+ <div style =" display : flex ; justify-content : center ; align-items : center " >
62
+ <input class =" form-control" :value =" VicarSync.getCharacterSyncOutId(character)" />
63
+ <button class =" btn btn-primary" @click =" copySyncOutId" >{{$t('character.sync.info.hashcopy')}}</button >
64
+ </div >
65
+ </div >
66
+
67
+ <div style =" width : 100% ; display : flex ; justify-content : center ; align-items : center " >
68
+ <button class =" btn btn-primary" @click =" beginUnlinkCharacterWithSync" >{{$t(infoSyncModalDisableConfirm ? 'character.sync.info.disable.confirm' : 'character.sync.info.disable')}}</button >
69
+ </div >
70
+ </div >
71
+ </Modal >
31
72
</div >
32
73
</template >
33
74
@@ -40,9 +81,11 @@ import {ICharacter} from "@/types/models";
40
81
import CharacterStorage from " @/libs/io/character-storage" ;
41
82
import FileCreator from " @/libs/io/file-creator" ;
42
83
import {Mutation } from " vuex-class" ;
84
+ import {VicarSync } from " @/libs/io/vicar-sync" ;
85
+ import Modal from " @/components/modal/Modal.vue" ;
43
86
44
87
@Component ({
45
- components: {IconButton , Avatar , Bullet }
88
+ components: {Modal , IconButton , Avatar , Bullet }
46
89
})
47
90
export default class Character extends Vue {
48
91
@@ -55,6 +98,15 @@ export default class Character extends Vue {
55
98
@Mutation (" setLevelMode" )
56
99
private setLevelMode! : (mode : boolean ) => void ;
57
100
101
+ private VicarSync = VicarSync ;
102
+
103
+ private enableSyncModalVisible = false ;
104
+ private enableSyncModalType: " in" | " out" = " out" ;
105
+ private enableSyncModalInHash = " " ;
106
+
107
+ private infoSyncModalVisible = false ;
108
+ private infoSyncModalDisableConfirm: number | null = null ;
109
+
58
110
private cloneCharacter(character : ICharacter ) {
59
111
const newChar = {... character };
60
112
newChar .name += " - " + this .$t (' character.copy' ).toString ();
@@ -72,6 +124,54 @@ export default class Character extends Vue {
72
124
this .$router .push ({name: ' viewer' });
73
125
}
74
126
127
+ private linkCharacterWithSync() {
128
+ this .enableSyncModalVisible = true ;
129
+ }
130
+
131
+ private async finishLinkCharacterWithSync() {
132
+ if (this .enableSyncModalType === " out" ) {
133
+ const hash = await VicarSync .enableCharacterOutSync (this .character );
134
+ if (hash ) {
135
+ await navigator .clipboard .writeText (hash );
136
+ }
137
+ } else {
138
+ await VicarSync .syncCharacterIn (this .character , this .enableSyncModalInHash );
139
+ }
140
+ this .$forceUpdate ();
141
+ this .enableSyncModalVisible = false ;
142
+ this .enableSyncModalInHash = " " ;
143
+ this .enableSyncModalType = " out" ;
144
+ }
145
+
146
+ private async beginUnlinkCharacterWithSync() {
147
+ if (this .infoSyncModalDisableConfirm === null ) {
148
+ this .infoSyncModalDisableConfirm = setTimeout (() => {
149
+ this .infoSyncModalDisableConfirm = null ;
150
+ }, 3000 );
151
+ } else {
152
+ await this .unlinkCharacterWithSync ();
153
+
154
+ this .infoSyncModalVisible = false ;
155
+
156
+ clearTimeout (this .infoSyncModalDisableConfirm );
157
+ this .infoSyncModalDisableConfirm = null ;
158
+ }
159
+ }
160
+
161
+ private async unlinkCharacterWithSync() {
162
+ if (VicarSync .isCharacterSyncedOut (this .character )) {
163
+ await VicarSync .disableCharacterOutSync (this .character );
164
+ } else if (VicarSync .isCharacterSyncedIn (this .character )) {
165
+ await VicarSync .unsyncCharacterIn (this .character );
166
+ }
167
+
168
+ this .$forceUpdate ();
169
+ }
170
+
171
+ private async copySyncOutId() {
172
+ await navigator .clipboard .writeText (VicarSync .getCharacterSyncOutId (this .character ));
173
+ }
174
+
75
175
@Inject (" begin-char-deletion" )
76
176
private beginCharDeletion! : (character : ICharacter ) => void ;
77
177
0 commit comments