|
72 | 72 | </v-card-actions> |
73 | 73 | </v-card> |
74 | 74 | </v-dialog> |
| 75 | + |
| 76 | + <InternalCameraModal v-if="store.storeCameraMode === 'internal'" :selected-mode="mode" ref="internalCameraModal" @media-selected="setMediaFromInternal" /> |
75 | 77 | </template> |
76 | 78 |
|
77 | 79 | <script setup lang="ts"> |
|
108 | 110 | const imageInput = useTemplateRef('imageInput') |
109 | 111 | const videoInput = useTemplateRef('videoInput') |
110 | 112 | const video = useTemplateRef('video') |
| 113 | + const internalCameraModal = useTemplateRef('internalCameraModal') |
111 | 114 |
|
112 | 115 | const canContinue = computed(() => { |
113 | 116 | return mediaData.value !== undefined |
|
143 | 146 | return mapped.join('_') + extension |
144 | 147 | }) |
145 | 148 |
|
| 149 | + function setMediaFromInternal (newData: Blob) { |
| 150 | + // Convert to base64 for displaying |
| 151 | + inputFile.value = new File([newData], `internal.${mode.value === 'image' ? 'jpg' : '.mp4'}`, { |
| 152 | + type: newData.type, |
| 153 | + lastModified: Date.now(), |
| 154 | + }) |
| 155 | + } |
| 156 | +
|
146 | 157 | watch(inputFile, newValue => { |
147 | 158 | // If there is a new media file, reset data |
148 | 159 | inputFileDate.value = undefined |
|
190 | 201 | } |
191 | 202 | }) |
192 | 203 |
|
| 204 | + // async function save () { |
| 205 | + // if (inputFile.value && mediaData.value) { |
| 206 | + // const file = new File([inputFile.value], filename.value, { type: inputFile.value.type }) |
| 207 | +
|
| 208 | + // // 1. File System Access API — best UX on desktop, works on newer Samsung Internet too |
| 209 | + // if ('showSaveFilePicker' in window) { |
| 210 | + // try { |
| 211 | + // // @ts-expect-error |
| 212 | + // const handle = await window.showSaveFilePicker({ suggestedName: filename.value }) |
| 213 | + // const writable = await handle.createWritable() |
| 214 | + // await writable.write(inputFile.value) |
| 215 | + // await writable.close() |
| 216 | + // return |
| 217 | + // } catch (e: unknown) { |
| 218 | + // if (e instanceof DOMException && e.name === 'AbortError') { |
| 219 | + // return |
| 220 | + // } |
| 221 | + // console.warn('showSaveFilePicker failed:', e) |
| 222 | + // // Fall through |
| 223 | + // } |
| 224 | + // } |
| 225 | +
|
| 226 | + // // 2. Web Share API — best on mobile where showSaveFilePicker is absent |
| 227 | + // if (navigator.canShare?.({ files: [file] })) { |
| 228 | + // try { |
| 229 | + // await navigator.share({ files: [file], title: filename.value }) |
| 230 | + // return |
| 231 | + // } catch (e: unknown) { |
| 232 | + // if (e instanceof DOMException && e.name === 'AbortError') { |
| 233 | + // return |
| 234 | + // } |
| 235 | + // console.warn('Web Share failed:', e) |
| 236 | + // // Fall through |
| 237 | + // } |
| 238 | + // } |
| 239 | +
|
| 240 | + // // 3. FileSaver.js — desktop browsers without File System Access, and most other cases |
| 241 | + // saveAs(inputFile.value, filename.value) |
| 242 | + // } |
| 243 | + // } |
| 244 | +
|
193 | 245 | function save () { |
194 | 246 | if (mediaData.value) { |
195 | 247 | saveAs(mediaData.value, filename.value) |
|
219 | 271 | cell.value = c |
220 | 272 | }) |
221 | 273 | dialog.value = true |
222 | | - if (type === 'image') { |
223 | | - imageInput.value?.click() |
| 274 | +
|
| 275 | + if (store.storeCameraMode === 'internal') { |
| 276 | + internalCameraModal.value?.show() |
224 | 277 | } else { |
225 | | - videoInput.value?.click() |
| 278 | + if (type === 'image') { |
| 279 | + imageInput.value?.click() |
| 280 | + } else { |
| 281 | + videoInput.value?.click() |
| 282 | + } |
226 | 283 | } |
227 | 284 | } |
228 | 285 | function hide () { |
|
0 commit comments