coomdev
2 years ago
8 changed files with 225 additions and 70 deletions
@ -0,0 +1,128 @@ |
|||
<script lang="ts"> |
|||
import { appState } from './stores' |
|||
import type { ImageProcessor } from './main' |
|||
|
|||
import { fireNotification, getSelectedFile } from './utils' |
|||
|
|||
export let processors: ImageProcessor[] = [] |
|||
export let textinput: HTMLTextAreaElement |
|||
|
|||
let files: File[] = [] |
|||
|
|||
const addContent = (...newfiles: File[]) => { |
|||
files = [...files, ...newfiles] |
|||
if (files.length > 5) { |
|||
fireNotification( |
|||
'warning', |
|||
'Can only add up to 5 attachments, further attachments will be dropped', |
|||
) |
|||
files = files.slice(0, 5) |
|||
} |
|||
} |
|||
|
|||
const embedText = async (e: Event) => { |
|||
if (textinput.value == '') return |
|||
if (textinput.value.length > 2000) { |
|||
fireNotification("error", "Message attachments are limited to 2000 characters") |
|||
return; |
|||
} |
|||
addContent( |
|||
new File( |
|||
[new Blob([textinput.value], { type: 'text/plain' })], |
|||
`message${files.length}.txt`, |
|||
), |
|||
) |
|||
textinput.value = '' |
|||
} |
|||
|
|||
const embedContent = async (e: Event) => { |
|||
const file = await getSelectedFile() |
|||
if (!file) return |
|||
const type = file.type |
|||
try { |
|||
const proc = processors |
|||
.filter((e) => e.inject) |
|||
.find((e) => e.match(file.name)) |
|||
if (!proc) throw new Error('Container filetype not supported') |
|||
const buff = await proc.inject!(file, [...files].slice(0, 5)) |
|||
document.dispatchEvent( |
|||
new CustomEvent('QRSetFile', { |
|||
//detail: { file: new Blob([buff]), name: file.name, type: file.type } |
|||
detail: { file: new Blob([buff], { type }), name: file.name }, |
|||
}), |
|||
) |
|||
fireNotification( |
|||
'success', |
|||
`File${files.length > 1 ? 's' : ''} successfully embedded!`, |
|||
) |
|||
} catch (err) { |
|||
const e = err as Error |
|||
fireNotification('error', "Couldn't embed file: " + e.message) |
|||
} |
|||
} |
|||
|
|||
const embedFile = async (e: Event) => { |
|||
const input = document.createElement('input') as HTMLInputElement |
|||
input.setAttribute('type', 'file') |
|||
input.multiple = true |
|||
input.onchange = async (ev) => { |
|||
if (input.files) { |
|||
addContent(...input.files) |
|||
} |
|||
} |
|||
input.click() |
|||
} |
|||
</script> |
|||
|
|||
<div class="root"> |
|||
<!-- svelte-ignore a11y-missing-attribute --> |
|||
<a on:click={embedFile} title="Add a file"> |
|||
<i class="fa fa-magnet"> {$appState.is4chanX ? '' : '🧲'} </i> |
|||
</a> |
|||
<div class="additionnal"> |
|||
<!-- svelte-ignore a11y-missing-attribute --> |
|||
<a |
|||
on:click={embedText} |
|||
title="Add a message (this uses the content of the comment text box)" |
|||
> |
|||
<i class="fa fa-pencil"> {$appState.is4chanX ? '' : '🖉'} </i> |
|||
</a> |
|||
<!-- svelte-ignore a11y-missing-attribute --> |
|||
<a on:click={embedContent} title="Ready to Embed (Select a file before)"> |
|||
<i class="fa fa-check"> {$appState.is4chanX ? '' : '✅'} </i> |
|||
</a> |
|||
{#if files.length} |
|||
<!-- svelte-ignore a11y-missing-attribute --> |
|||
<a on:click={() => (files = [])} title="Discard ALL selected content"> |
|||
<i class="fa fa-times"> {$appState.is4chanX ? '' : '❌'} </i> |
|||
</a> |
|||
{/if} |
|||
</div> |
|||
</div> |
|||
|
|||
<style scoped> |
|||
a { |
|||
cursor: pointer; |
|||
} |
|||
|
|||
.root { |
|||
position: relative; |
|||
} |
|||
|
|||
.additionnal { |
|||
display: none; |
|||
position: absolute; |
|||
flex-direction: column; |
|||
gap: 5px; |
|||
outline: 1px solid #ce3d08; |
|||
padding: 5px; |
|||
background-color: #fffdee; |
|||
border-radius: 5px; |
|||
left: 50%; |
|||
transform: translateX(-50%); |
|||
} |
|||
|
|||
.root:hover > .additionnal { |
|||
display: flex; |
|||
} |
|||
</style> |
@ -0,0 +1,9 @@ |
|||
export type QueryProcessor = { |
|||
thumbnailSelector: string; |
|||
md5Selector: string; |
|||
filenameSelector: string; |
|||
linkSelector: string; |
|||
postWithFileSelector: string; |
|||
postContainerSelector: string; |
|||
controlHostSelector: string; |
|||
}; |
Loading…
Reference in new issue