1 | <script setup lang="ts">
|
---|
2 |
|
---|
3 | import { ref, getCurrentInstance } from 'vue'
|
---|
4 |
|
---|
5 | import UploadZone from './UploadZone.vue'
|
---|
6 |
|
---|
7 | const inst = getCurrentInstance()
|
---|
8 |
|
---|
9 | const auto_start = ref(false)
|
---|
10 | const auto_reset = ref(false)
|
---|
11 | const keep_going = ref(false)
|
---|
12 | const max_jobs = ref(3)
|
---|
13 |
|
---|
14 | const can_reset = ref(false)
|
---|
15 | const can_start = ref(false)
|
---|
16 | const can_pick = ref(false)
|
---|
17 | const can_abort = ref(false)
|
---|
18 |
|
---|
19 | const reset = (): void => {
|
---|
20 | (inst as any).refs.uploader.reset()
|
---|
21 | }
|
---|
22 |
|
---|
23 | const start = (): void => {
|
---|
24 | (inst as any).refs.uploader.start()
|
---|
25 | }
|
---|
26 |
|
---|
27 | const pick = (): void => {
|
---|
28 | (inst as any).refs.uploader.pick()
|
---|
29 | }
|
---|
30 |
|
---|
31 | const abort = (): void => {
|
---|
32 | (inst as any).refs.uploader.abort()
|
---|
33 | }
|
---|
34 |
|
---|
35 | const log = (code: string, args: any[]) => {
|
---|
36 | console.log.apply(null, ['>', code].concat(args))
|
---|
37 | }
|
---|
38 |
|
---|
39 | </script>
|
---|
40 |
|
---|
41 | <template>
|
---|
42 | <div class='over'>
|
---|
43 | <button @click='pick' :disabled='!can_pick'>pick</button>
|
---|
44 | <span> </span>
|
---|
45 | <button @click='start' :disabled='!can_start'>start</button>
|
---|
46 | <span> </span>
|
---|
47 | <button @click='abort' :disabled='!can_abort'>abort</button>
|
---|
48 | <span> </span>
|
---|
49 | <button @click='reset' :disabled='!can_reset'>reset</button>
|
---|
50 | <p />
|
---|
51 | <input type='checkbox' v-model='auto_start' id='auto-start' />
|
---|
52 | <label for='auto-start'> auto-start</label><br />
|
---|
53 | <input type='checkbox' v-model='auto_reset' id='auto-reset' />
|
---|
54 | <label for='auto-reset'> auto-reset</label><br />
|
---|
55 | <input type='checkbox' v-model='keep_going' id='keep-going' />
|
---|
56 | <label for='keep-going'> keep-going</label><br />
|
---|
57 | <p />
|
---|
58 |
|
---|
59 | <component class='uploader' :is='UploadZone' target='https://vite.js29a.usermd.net/upload.php'
|
---|
60 | :max-jobs='max_jobs' :auto-start='auto_start' :auto-reset='auto_reset'
|
---|
61 | :keep-going='keep_going' ref='uploader'
|
---|
62 | @update:canPick='(flag: boolean) => can_pick = flag'
|
---|
63 | @update:canStart='(flag: boolean) => can_start = flag'
|
---|
64 | @update:canAbort='(flag: boolean) => can_abort = flag'
|
---|
65 | @update:canReset='(flag: boolean) => can_reset = flag'
|
---|
66 | @debug='(code: string, args: any[]) => log(code, args)'>
|
---|
67 | <template #idle='{ pick }'>
|
---|
68 | <div class='idle'>
|
---|
69 | idle
|
---|
70 | <br />
|
---|
71 | <button @click='pick()'>pick</button>
|
---|
72 | </div>
|
---|
73 | </template>
|
---|
74 |
|
---|
75 | <template #hover>
|
---|
76 | <div class='hover'>
|
---|
77 | hover
|
---|
78 | </div>
|
---|
79 | </template>
|
---|
80 |
|
---|
81 | <template #wait='{ start, queue }'>
|
---|
82 | <div class='wait'>
|
---|
83 | wait
|
---|
84 | <br />
|
---|
85 | <button @click='pick()'>pick</button>
|
---|
86 | <br />
|
---|
87 | <button @click='start()'>start</button>
|
---|
88 | <br/>
|
---|
89 | <div v-for='file in queue'>{{ file.name }}</div>
|
---|
90 | </div>
|
---|
91 | </template>
|
---|
92 |
|
---|
93 | <template #uploading='{ progress, current, queue, abort, errors }'>
|
---|
94 | <div class='uploading'>
|
---|
95 | uploading
|
---|
96 | <br />
|
---|
97 | <button @click='abort()'>abort</button>
|
---|
98 | <br />
|
---|
99 | {{ progress.length }} / {{ current.length }} / {{ queue.length }}
|
---|
100 | <br />
|
---|
101 | <button @click='abort()'>abort</button>
|
---|
102 | <b>errors:</b> <span v-for='error in errors'>{{ error.file.name }}</span>
|
---|
103 | <b>progress:</b> <div v-for='item in progress'>{{ item }}</div>
|
---|
104 | <b>current:</b>
|
---|
105 | <div v-for='item in current'>
|
---|
106 | {{ item.file.name }}: {{ item.current }} of {{ item.total }}
|
---|
107 | </div>
|
---|
108 | <b>remaining:</b>
|
---|
109 | <div v-for='file in queue'>{{ file.name }}</div>
|
---|
110 | </div>
|
---|
111 | </template>
|
---|
112 |
|
---|
113 | <template #done='{ result, reset }'>
|
---|
114 | <div class='done'>
|
---|
115 | done
|
---|
116 | <br />
|
---|
117 | <button @click='reset()'>reset</button>
|
---|
118 | <br />
|
---|
119 | <div v-for='item in result'>{{ item }}</div>
|
---|
120 | </div>
|
---|
121 | </template>
|
---|
122 |
|
---|
123 | <template #error='{ error, reset }'>
|
---|
124 | <div class='error'>
|
---|
125 | error
|
---|
126 | <br />
|
---|
127 | <button @click='reset()'>reset</button>
|
---|
128 | <div>{{ error }}</div>
|
---|
129 | </div>
|
---|
130 | </template>
|
---|
131 |
|
---|
132 | <template #aborted='{ result, reset }'>
|
---|
133 | <div class='aborted'>
|
---|
134 | aborted
|
---|
135 | <br />
|
---|
136 | <button @click='reset()'>reset</button>
|
---|
137 | <div v-for='item in result'>{{ item }}</div>
|
---|
138 | </div>
|
---|
139 | </template>
|
---|
140 |
|
---|
141 | <template #with-errors='{ result, errors }'>
|
---|
142 | <div class='with-errors'>
|
---|
143 | with errors
|
---|
144 | <br />
|
---|
145 | <b>errors(s):</b>
|
---|
146 | <div v-for='item in errors'>{{ item.file.name }} / {{ item.error }}</div>
|
---|
147 | <b>ok:</b>
|
---|
148 | <div v-for='item in result'>{{ item }}</div>
|
---|
149 | </div>
|
---|
150 | </template>
|
---|
151 | </component>
|
---|
152 | </div>
|
---|
153 | </template>
|
---|
154 |
|
---|
155 | <style scoped>
|
---|
156 |
|
---|
157 | .over {
|
---|
158 | position: absolute;
|
---|
159 | border-radius: 20px;
|
---|
160 | top: 50%;
|
---|
161 | left: 50%;
|
---|
162 | transform: translate(-50%, -50%);
|
---|
163 | }
|
---|
164 |
|
---|
165 | .uploader {
|
---|
166 | border: 3px dashed #fff;
|
---|
167 | width: 512px;
|
---|
168 | height: 384px;
|
---|
169 | display: inline-block;
|
---|
170 | }
|
---|
171 |
|
---|
172 | .idle,
|
---|
173 | .hover,
|
---|
174 | .wait,
|
---|
175 | .uploading,
|
---|
176 | .done,
|
---|
177 | .error,
|
---|
178 | .aborted,
|
---|
179 | .with-errors {
|
---|
180 | width: 100%;
|
---|
181 | height: 100%;
|
---|
182 | border: 1px solid #0ff;
|
---|
183 | padding: 5px;
|
---|
184 | overflow: auto;
|
---|
185 | }
|
---|
186 |
|
---|
187 | .status {
|
---|
188 | width: 25%;
|
---|
189 | height: auto;
|
---|
190 | background-color: #555;
|
---|
191 | color: #fff;
|
---|
192 | position: absolute;
|
---|
193 | right: 0px;
|
---|
194 | bottom: 0px;
|
---|
195 | padding: 2px 2px 2px 2px;
|
---|
196 | text-align: center;
|
---|
197 | font-weight: bold;
|
---|
198 | border-radius: 10px 0px 0px 0px;
|
---|
199 | border: 1px solid #0ff;
|
---|
200 | opacity: 0.75;
|
---|
201 | }
|
---|
202 |
|
---|
203 | .idle {
|
---|
204 | background-color: #088;
|
---|
205 | color: black;
|
---|
206 | }
|
---|
207 |
|
---|
208 | .hover {
|
---|
209 | background-color: #088;
|
---|
210 | color: white;
|
---|
211 | cursor: copy;
|
---|
212 | }
|
---|
213 |
|
---|
214 | .wait {
|
---|
215 | background-color: #880;
|
---|
216 | color: black;
|
---|
217 | }
|
---|
218 |
|
---|
219 | .uploading {
|
---|
220 | background-color: #050;
|
---|
221 | color: white;
|
---|
222 | }
|
---|
223 |
|
---|
224 | .done {
|
---|
225 | background-color: #00f;
|
---|
226 | color: white;
|
---|
227 | }
|
---|
228 |
|
---|
229 | .error {
|
---|
230 | background-color: #800;
|
---|
231 | color: white;
|
---|
232 | }
|
---|
233 |
|
---|
234 | .aborted {
|
---|
235 | background-color: #300;
|
---|
236 | color: white;
|
---|
237 | }
|
---|
238 |
|
---|
239 | .with-errors {
|
---|
240 | background-color: #800;
|
---|
241 | color: white;
|
---|
242 | }
|
---|
243 |
|
---|
244 | </style>
|
---|
245 |
|
---|