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