@@ -13,6 +13,8 @@ import {
13
13
fa_xmark
14
14
} from './icons.js' ;
15
15
import { showMessage , i18n } from './message.js' ;
16
+ import type { Config , ModelManager } from './model.js' ;
17
+ import type { Tips } from './widget.js' ;
16
18
17
19
interface Tools {
18
20
/**
@@ -34,86 +36,122 @@ interface Tools {
34
36
}
35
37
36
38
/**
37
- * Waifu tools configuration.
38
- * @type {Tools }
39
+ * Waifu tools manager.
39
40
*/
40
- const tools : Tools = {
41
- hitokoto : {
42
- icon : fa_comment ,
43
- callback : async ( template : string ) => {
44
- // Add hitokoto.cn API
45
- const response = await fetch ( 'https://v1.hitokoto.cn' ) ;
46
- const result = await response . json ( ) ;
47
- const text = i18n ( template , result . from , result . creator ) ;
48
- showMessage ( result . hitokoto , 6000 , 9 ) ;
49
- setTimeout ( ( ) => {
50
- showMessage ( text , 4000 , 9 ) ;
51
- } , 6000 ) ;
52
- } ,
53
- } ,
54
- asteroids : {
55
- icon : fa_paper_plane ,
56
- callback : ( ) => {
57
- if ( window . Asteroids ) {
58
- if ( ! window . ASTEROIDSPLAYERS ) window . ASTEROIDSPLAYERS = [ ] ;
59
- window . ASTEROIDSPLAYERS . push ( new window . Asteroids ( ) ) ;
60
- } else {
61
- const script = document . createElement ( 'script' ) ;
62
- script . src =
63
- 'https://fastly.jsdelivr.net/gh/stevenjoezhang/asteroids/asteroids.js' ;
64
- document . head . appendChild ( script ) ;
65
- }
66
- } ,
67
- } ,
68
- 'switch-model' : {
69
- icon : fa_user_circle ,
70
- callback : ( ) => { } ,
71
- } ,
72
- 'switch-texture' : {
73
- icon : fa_street_view ,
74
- callback : ( ) => { } ,
75
- } ,
76
- photo : {
77
- icon : fa_camera_retro ,
78
- callback : ( message : string | string [ ] ) => {
79
- showMessage ( message , 6000 , 9 ) ;
80
- const canvas = document . getElementById ( 'live2d' ) as HTMLCanvasElement ;
81
- if ( ! canvas ) return ;
82
- const imageUrl = canvas . toDataURL ( ) ;
41
+ class ToolsManager {
42
+ tools : Tools ;
43
+ config : Config ;
44
+
45
+ constructor ( model : ModelManager , config : Config , tips : Tips ) {
46
+ this . config = config ;
47
+ this . tools = {
48
+ hitokoto : {
49
+ icon : fa_comment ,
50
+ callback : async ( ) => {
51
+ // Add hitokoto.cn API
52
+ const response = await fetch ( 'https://v1.hitokoto.cn' ) ;
53
+ const result = await response . json ( ) ;
54
+ const template = tips . message . hitokoto ;
55
+ const text = i18n ( template , result . from , result . creator ) ;
56
+ showMessage ( result . hitokoto , 6000 , 9 ) ;
57
+ setTimeout ( ( ) => {
58
+ showMessage ( text , 4000 , 9 ) ;
59
+ } , 6000 ) ;
60
+ }
61
+ } ,
62
+ asteroids : {
63
+ icon : fa_paper_plane ,
64
+ callback : ( ) => {
65
+ if ( window . Asteroids ) {
66
+ if ( ! window . ASTEROIDSPLAYERS ) window . ASTEROIDSPLAYERS = [ ] ;
67
+ window . ASTEROIDSPLAYERS . push ( new window . Asteroids ( ) ) ;
68
+ } else {
69
+ const script = document . createElement ( 'script' ) ;
70
+ script . src =
71
+ 'https://fastly.jsdelivr.net/gh/stevenjoezhang/asteroids/asteroids.js' ;
72
+ document . head . appendChild ( script ) ;
73
+ }
74
+ }
75
+ } ,
76
+ 'switch-model' : {
77
+ icon : fa_user_circle ,
78
+ callback : ( ) => model . loadNextModel ( )
79
+ } ,
80
+ 'switch-texture' : {
81
+ icon : fa_street_view ,
82
+ callback : ( ) => {
83
+ let successMessage = '' , failMessage = '' ;
84
+ if ( tips ) {
85
+ successMessage = tips . message . changeSuccess ;
86
+ failMessage = tips . message . changeFail ;
87
+ }
88
+ model . loadRandTexture ( successMessage , failMessage ) ;
89
+ }
90
+ } ,
91
+ photo : {
92
+ icon : fa_camera_retro ,
93
+ callback : ( ) => {
94
+ const message = tips . message . photo ;
95
+ showMessage ( message , 6000 , 9 ) ;
96
+ const canvas = document . getElementById ( 'live2d' ) as HTMLCanvasElement ;
97
+ if ( ! canvas ) return ;
98
+ const imageUrl = canvas . toDataURL ( ) ;
99
+
100
+ const link = document . createElement ( 'a' ) ;
101
+ link . style . display = 'none' ;
102
+ link . href = imageUrl ;
103
+ link . download = 'live2d-photo.png' ;
83
104
84
- const link = document . createElement ( 'a' ) ;
85
- link . style . display = 'none' ;
86
- link . href = imageUrl ;
87
- link . download = 'live2d-photo.png' ;
105
+ document . body . appendChild ( link ) ;
106
+ link . click ( ) ;
107
+ document . body . removeChild ( link ) ;
108
+ }
109
+ } ,
110
+ info : {
111
+ icon : fa_info_circle ,
112
+ callback : ( ) => {
113
+ open ( 'https://github.com/stevenjoezhang/live2d-widget' ) ;
114
+ }
115
+ } ,
116
+ quit : {
117
+ icon : fa_xmark ,
118
+ callback : ( ) => {
119
+ localStorage . setItem ( 'waifu-display' , Date . now ( ) . toString ( ) ) ;
120
+ const message = tips . message . goodbye ;
121
+ showMessage ( message , 2000 , 11 ) ;
122
+ const waifu = document . getElementById ( 'waifu' ) ;
123
+ if ( ! waifu ) return ;
124
+ waifu . style . bottom = '-500px' ;
125
+ setTimeout ( ( ) => {
126
+ waifu . style . display = 'none' ;
127
+ const waifuToggle = document . getElementById ( 'waifu-toggle' ) ;
128
+ if ( ! waifuToggle ) return ;
129
+ waifuToggle . classList . add ( 'waifu-toggle-active' ) ;
130
+ } , 3000 ) ;
131
+ }
132
+ }
133
+ } ;
134
+ }
88
135
89
- document . body . appendChild ( link ) ;
90
- link . click ( ) ;
91
- document . body . removeChild ( link ) ;
92
- } ,
93
- } ,
94
- info : {
95
- icon : fa_info_circle ,
96
- callback : ( ) => {
97
- open ( 'https://github.com/stevenjoezhang/live2d-widget' ) ;
98
- } ,
99
- } ,
100
- quit : {
101
- icon : fa_xmark ,
102
- callback : ( message : string | string [ ] ) => {
103
- localStorage . setItem ( 'waifu-display' , Date . now ( ) . toString ( ) ) ;
104
- showMessage ( message , 2000 , 11 ) ;
105
- const waifu = document . getElementById ( 'waifu' ) ;
106
- if ( ! waifu ) return ;
107
- waifu . style . bottom = '-500px' ;
108
- setTimeout ( ( ) => {
109
- waifu . style . display = 'none' ;
110
- const waifuToggle = document . getElementById ( 'waifu-toggle' ) ;
111
- if ( ! waifuToggle ) return ;
112
- waifuToggle . classList . add ( 'waifu-toggle-active' ) ;
113
- } , 3000 ) ;
114
- } ,
115
- } ,
116
- } ;
136
+ registerTools ( ) {
137
+ if ( ! Array . isArray ( this . config . tools ) ) {
138
+ this . config . tools = Object . keys ( this . tools ) ;
139
+ }
140
+ for ( const toolName of this . config . tools ! ) {
141
+ if ( this . tools [ toolName ] ) {
142
+ const { icon, callback } = this . tools [ toolName ] ;
143
+ document
144
+ . getElementById ( 'waifu-tool' ) !
145
+ . insertAdjacentHTML (
146
+ 'beforeend' ,
147
+ `<span id="waifu-tool-${ toolName } ">${ icon } </span>` ,
148
+ ) ;
149
+ document
150
+ . getElementById ( `waifu-tool-${ toolName } ` ) !
151
+ . addEventListener ( 'click' , callback ) ;
152
+ }
153
+ }
154
+ }
155
+ }
117
156
118
- export default tools ;
119
- export { Tools } ;
157
+ export { ToolsManager , Tools } ;
0 commit comments