This commit is contained in:
2025-02-04 15:15:53 -07:00
parent ddf6dd559b
commit 34f536f944
13 changed files with 327 additions and 95 deletions

50
src/browser/Device.js Normal file
View File

@@ -0,0 +1,50 @@
import * as store from './Store.js'
const noWorkingDirWarning = "Please open a directory to allow file saving."
function Device() {
this.init = async () => {
await store.Init()
window.cwd = await store.Get('directory')
}
this.cd = async () => {
window.cwd = await window.showDirectoryPicker()
await store.Set('directory', window.cwd)
}
this.entries = async () => {
let pool = new Map()
for await (let [ , e ] of window.cwd.entries()) {
if(e instanceof FileSystemFileHandle) {
pool.set(e.name, e)
}
}
return pool
}
this.create = async (sPath) => {
return window.cwd.getFileHandle(sPath, { create: true })
}
this.open = async (hFile) => {
if(!window.cwd) {
return new Blob([ noWorkingDirWarning ], { type: "text/plain" })
}
return hFile.getFile()
}
this.write = async (hFile, sContent) => {
if(!window.cwd) {
throw new Error("Unable to save file: no working directory")
}
let s = await hFile.createWritable()
.catch(console.error)
await s.write(sContent)
await s.close()
}
}

View File

@@ -1,97 +1,42 @@
function Source (client) {
this.cache = {}
this.cwd = null
this.install = () => {
}
this.install = () => {
}
this.start = () => {
this.new()
}
this.start = () => {
}
this.new = () => {
console.log('Source', 'New file..')
this.cache = {}
}
// I/O
this.open = (ext, callback, store = false) => {
console.log('Source', 'Open file..')
const input = document.createElement('input')
input.type = 'file'
input.onchange = (e) => {
const file = e.target.files[0]
if (file.name.indexOf('.' + ext) < 0) { console.warn('Source', `Skipped ${file.name}`); return }
this.read(file, callback, store)
}
input.click()
}
this.read = (file, callback, store = false) => {
if(!this.cwd) {
openCwd()
}
this.load = (ext, callback) => {
console.log('Source', 'Load files..')
const input = document.createElement('input')
input.type = 'file'
input.setAttribute('multiple', 'multiple')
input.onchange = (e) => {
for (const file of e.target.files) {
if (file.name.indexOf('.' + ext) < 0) { console.warn('Source', `Skipped ${file.name}`); continue }
this.read(file, this.store)
}
}
input.click()
}
}
this.store = (file, content) => {
console.info('Source', 'Stored ' + file.name)
this.cache[file.name] = content
}
this.write = (name, ext, content, type, settings = 'charset=utf-8') => {
this.save = (name, content, type = 'text/plain', callback) => {
this.saveAs(name, content, type, callback)
}
}
this.saveAs = (name, ext, content, type = 'text/plain', callback) => {
console.log('Source', 'Save new file..')
this.write(name, ext, content, type, callback)
}
function timestamp (d = new Date(), e = new Date(d)) {
return `${arvelie()}-${neralie()}`
}
// I/O
function arvelie (date = new Date()) {
const start = new Date(date.getFullYear(), 0, 0)
const diff = (date - start) + ((start.getTimezoneOffset() - date.getTimezoneOffset()) * 60 * 1000)
const doty = Math.floor(diff / 86400000) - 1
const y = date.getFullYear().toString().substr(2, 2)
const m = doty === 364 || doty === 365 ? '+' : String.fromCharCode(97 + Math.floor(doty / 14)).toUpperCase()
const d = `${(doty === 365 ? 1 : doty === 366 ? 2 : (doty % 14)) + 1}`.padStart(2, '0')
return `${y}${m}${d}`
}
this.read = (file, callback, store = false) => {
const reader = new FileReader()
reader.onload = (event) => {
const res = event.target.result
if (callback) { callback(file, res) }
if (store) { this.store(file, res) }
}
reader.readAsText(file, 'UTF-8')
}
this.write = (name, ext, content, type, settings = 'charset=utf-8') => {
const link = document.createElement('a')
link.setAttribute('download', `${name}-${timestamp()}.${ext}`)
if (type === 'image/png' || type === 'image/jpeg') {
link.setAttribute('href', content)
} else {
link.setAttribute('href', 'data:' + type + ';' + settings + ',' + encodeURIComponent(content))
}
link.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window }))
}
function timestamp (d = new Date(), e = new Date(d)) {
return `${arvelie()}-${neralie()}`
}
function arvelie (date = new Date()) {
const start = new Date(date.getFullYear(), 0, 0)
const diff = (date - start) + ((start.getTimezoneOffset() - date.getTimezoneOffset()) * 60 * 1000)
const doty = Math.floor(diff / 86400000) - 1
const y = date.getFullYear().toString().substr(2, 2)
const m = doty === 364 || doty === 365 ? '+' : String.fromCharCode(97 + Math.floor(doty / 14)).toUpperCase()
const d = `${(doty === 365 ? 1 : doty === 366 ? 2 : (doty % 14)) + 1}`.padStart(2, '0')
return `${y}${m}${d}`
}
function neralie (d = new Date(), e = new Date(d)) {
const ms = e - d.setHours(0, 0, 0, 0)
return (ms / 8640 / 10000).toFixed(6).substr(2, 6)
}
function neralie (d = new Date(), e = new Date(d)) {
const ms = e - d.setHours(0, 0, 0, 0)
return (ms / 8640 / 10000).toFixed(6).substr(2, 6)
}
}

47
src/browser/Store.js Normal file
View File

@@ -0,0 +1,47 @@
function Store(objectStoreName) {
const transact = () => {
return this.db
.transaction(objectStoreName, "readwrite")
.objectStore(objectStoreName)
}
this.Get = (key) => {
return promisify(
transact().get(key)
)
}
this.Set = (key, value) => {
return promisify(
transact().put(value, key)
)
}
return this
}
Store.Open = async (dbName, objectStoreName) => {
let store = new Store(objectStoreName)
const request = indexedDB.open(dbName, 2)
request.onupgradeneeded = (event) => {
const db = event.target.result
const objectStore = db.createObjectStore(objectStoreName)
objectStore.createIndex('value', 'value', { unique: false })
}
store.db = await promisify(request)
return store
}
function promisify(request) {
return new Promise((resolve, reject) => {
request.onsuccess = (event) => {
resolve(request.result)
}
request.onerror = (event) => {
reject(request.error)
}
})
}

View File

@@ -9,6 +9,7 @@
<script>window.global = window;</script>
<script src="./Acels.js"></script>
<script src="./Theme.js"></script>
<script src="./Store.js"></script>
<script src="./Source.js"></script>
<script src="./Commander.js"></script>
<script src="./DisplaySurface.js"></script>
@@ -29,8 +30,12 @@
const client = new Client()
client.install(document.body)
window.addEventListener('load', () => {
client.start()
window.addEventListener('load', () => {
Store.Open("lonin", "lonin")
.then(store => {
window.store = store
client.start()
})
})
</script>