PageSourceSearch

https://thorzt.com/assets/controllers/file_select_controller-quOwfNk.js

js thorzt.com collected 2026-10-05 17:52:26 UTC 3,756 bytes, 128 lines download raw bytes

1/* stimulusFetch: 'lazy' */
2import { Controller } from '@hotwired/stimulus';
3
4// noinspection JSUnusedGlobalSymbols loaded by stimulus
5/**
6 * @extends {Controller<HTMLElement>}
7 * @property {string} uploadUrlValue
8 * @property {string} currentPathValue
9 * @property {string} nameValue
10 * @property {Object} transValue
11 */
12export default class extends Controller {
13
14    static values = {
15        uploadUrl: String,
16        currentPath: String,
17        name: String,
18        trans: Object
19    }
20
21    /**
22     * @param {string} key
23     * @returns {string}
24     */
25    #trans (key) {
26        return this.transValue[key] || key;
27    }
28
29    async createFolder() {
30        /** @type {HTMLElement} */
31        const element = this.element;
32        const name = window.prompt(this.currentPathValue +  '\n\n' + this.#trans("Enter folder name"), '');
33        if (!name) return;
34        const formData = new FormData();
35        formData.append('folder', name);
36        formData.append('path', this.currentPathValue);
37        const response = await fetch(this.uploadUrlValue, {
38            method: 'POST',
39            body: formData
40        });
41        if (response.ok) {
42            element.closest('turbo-frame').reload();
43        } else {
44            console.error('Create folder failed');
45        }
46    }
47
48    setSelectedFile(evt) {
49        this.selectedFile = evt.target.value;
50    }
51
52    selectFile() {
53        if (this.selectedFile) {
54            /** @type {HTMLElement} */
55            const element = this.element;
56            element.dispatchEvent(new CustomEvent('frame-stack:close', {composed: true, bubbles: true}));
57            window.dispatchEvent(new CustomEvent('file-selected', {detail: {path: this.selectedFile, name: this.nameValue}}));
58        }
59    }
60
61    connect() {
62        /** @type {HTMLElement} */
63        const element = this.element;
64        this.bound = {
65            "new-folder": () => this.createFolder(),
66            "file-select:ok": () => this.selectFile()
67        };
68        for (let n in this.bound) {
69            window.addEventListener(n, this.bound[n]);
70        }
71        element.addEventListener('dragover', this.onDragOver.bind(this));
72        element.addEventListener('drop', this.onDrop.bind(this));
73    }
74
75    disconnect() {
76        for (let n in this.bound) {
77            window.removeEventListener(n, this.bound[n]);
78        }
79    }
80
81    onDragOver(event) {
82        event.preventDefault();
83        event.stopPropagation();
84        /** @type {HTMLElement} */
85        const element = this.element;
86        element.classList.add('drag-over');
87    }
88
89    onDrop(event) {
90        event.preventDefault();
91        event.stopPropagation();
92        /** @type {HTMLElement} */
93        const element = this.element;
94        element.classList.remove('drag-over');
95
96        const files = event.dataTransfer.files;
97        if (files.length > 0) {
98            this.uploadFiles(files).then(() => {});
99        }
100    }
101
102    async uploadFiles(files) {
103        /** @type {HTMLElement} */
104        const element = this.element;
105        const formData = new FormData();
106        formData.append('path', this.currentPathValue);
107
108        for (let i = 0; i < files.length; i++) {
109            formData.append(`file_${i}`, files[i]);
110        }
111
112        try {
113            const response = await fetch(this.uploadUrlValue, {
114                method: 'POST',
115                body: formData
116            });
117
118            if (response.ok) {
119                // Refresh the page or the Turbo Frame to show new files
120                element.closest('turbo-frame').reload();
121            } else {
122                console.error('Upload failed');
123            }
124        } catch (error) {
125            console.error('Error uploading files:', error);
126        }
127    }
128}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.