Skip to content

Commit

Permalink
functional twitch chat integration
Browse files Browse the repository at this point in the history
  • Loading branch information
goldbuick committed Jan 4, 2025
1 parent 74d2cfb commit a742593
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 66 deletions.
8 changes: 5 additions & 3 deletions cafe/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ window.addEventListener('paste', (event) => {

// read files from clipboardData
const files = [...event.clipboardData.files]
files.forEach((file) => vm_loader('app', 'file', file, registerreadplayer()))
files.forEach((file) =>
vm_loader('app', 'file', file.name, file, registerreadplayer()),
)
})

window.addEventListener('drop', (event) => {
Expand All @@ -72,15 +74,15 @@ window.addEventListener('drop', (event) => {
if (item.kind === 'file') {
const file = item.getAsFile()
if (ispresent(file)) {
vm_loader('app', 'file', file, registerreadplayer())
vm_loader('app', 'file', file.name, file, registerreadplayer())
}
}
})
} else {
// Use DataTransfer interface to access the file(s)
const files = [...(event.dataTransfer?.files ?? [])]
files.forEach((file) =>
vm_loader('app', 'file', file, registerreadplayer()),
vm_loader('app', 'file', file.name, file, registerreadplayer()),
)
}
})
Expand Down
33 changes: 32 additions & 1 deletion zss/device/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,39 @@ export function vm_flush(sender: string, tag: string, player: string) {
export function vm_loader(
sender: string,
event: string,
filename: string,
content: any,
player: string,
) {
hub.emit('vm:loader', sender, [event, content], player)
function createtextreader() {
return {
filename,
cursor: 0,
lines: content.split('\n'),
}
}
function createbinaryreader() {
return {
filename,
cursor: 0,
bytes: content,
dataview: new DataView(content.buffer),
}
}
let withcontent: any
switch (event) {
case 'file':
withcontent = content
break
case 'chat':
withcontent = createtextreader()
break
case 'text':
withcontent = createtextreader()
break
case 'binary':
withcontent = createbinaryreader()
break
}
hub.emit('vm:loader', sender, [event, withcontent], player)
}
3 changes: 2 additions & 1 deletion zss/device/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ const chat = createdevice('chat', [], (message) => {
vm_loader(
chat.name(),
'chat',
`${user}: ${text}`,
message.data,
`${user}:${text}`,
registerreadplayer(),
)
})
Expand Down
45 changes: 29 additions & 16 deletions zss/firmware/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,43 @@ import { maptostring } from 'zss/chip'
import { tape_info } from 'zss/device/api'
import { createfirmware } from 'zss/firmware'
import { createsid } from 'zss/mapping/guid'
import { ispresent } from 'zss/mapping/types'
import { MEMORY_LABEL, memoryensuresoftwarebook } from 'zss/memory'
import { memoryloadercontent, memoryloaderevent } from 'zss/memory/loader'
import { BINARY_READER, TEXT_READER } from 'zss/memory/types'
import { ARG_TYPE, readargs } from 'zss/words/reader'
import { NAME } from 'zss/words/types'

import { binaryloader } from './loader/binaryloader'
import { textloader } from './loader/textloader'

export const LOADER_FIRMWARE = createfirmware({
get(chip, name) {
// check loader flags

// const binaryfile = memoryreadbinaryfile(chip.id())
// if (ispresent(binaryfile)) {
// switch (NAME(name)) {
// case 'filename':
// // name of binary file
// return [ispresent(binaryfile.filename), binaryfile.filename]
// case 'cursor':
// // return where we are in the binary file ?
// return [ispresent(binaryfile.cursor), binaryfile.cursor]
// }
// }

const type = memoryloaderevent(chip.id())
switch (type) {
case 'chat': {
const textreader: TEXT_READER = memoryloadercontent(chip.id())
switch (name) {
case 'filename':
return [true, textreader.filename]
case 'cursor':
return [true, textreader.cursor]
case 'lines':
return [true, textreader.lines.length]
}
break
}
case 'binary': {
const binaryreader: BINARY_READER = memoryloadercontent(chip.id())
switch (name) {
case 'filename':
return [true, binaryreader.filename]
case 'cursor':
return [true, binaryreader.cursor]
case 'bytes':
return [true, binaryreader.bytes.length]
}
break
}
}
return [false, undefined]
},
})
Expand Down
90 changes: 50 additions & 40 deletions zss/firmware/loader/parsefile.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
import JSZip from 'jszip'
import mime from 'mime/lite'
import { api_error, tape_info } from 'zss/device/api'
import { api_error, tape_info, vm_loader } from 'zss/device/api'
import { ispresent } from 'zss/mapping/types'
import { MEMORY_LABEL, memoryensuresoftwarebook } from 'zss/memory'
import { bookreadcodepagewithtype, bookwritecodepage } from 'zss/memory/book'
import {
codepagereadname,
codepagereadtype,
codepagereadtypetostring,
createcodepage,
} from 'zss/memory/codepage'
import { NAME } from 'zss/words/types'

export function mimetypeofbytesread(filename: string, filebytes: Uint8Array) {
Expand All @@ -35,38 +27,7 @@ export function mimetypeofbytesread(filename: string, filebytes: Uint8Array) {
return mime.getType(filename) ?? 'application/octet-stream'
}

// create codepage from source text
function createcodepagefromtext(text: string) {
const codepage = createcodepage(text, {})
const pagename = codepagereadname(codepage)
const pagetype = codepagereadtypetostring(codepage)

const mainbook = memoryensuresoftwarebook(MEMORY_LABEL.MAIN)
if (!ispresent(mainbook)) {
return
}

// only create if target doesn't already exist
const codepagetype = codepagereadtype(codepage)
const maybepage = bookreadcodepagewithtype(mainbook, codepagetype, pagename)

if (ispresent(maybepage)) {
tape_info(
'memory',
`${mainbook.name} already has a [${pagetype}] named ${pagename}`,
)
} else {
bookwritecodepage(mainbook, codepage)
tape_info('memory', `created [${pagetype}] ${pagename} in ${mainbook.name}`)
}
}

// various handlers
export async function parsetextfile(file: File) {
const text = await file.text()
createcodepagefromtext(text)
}

export async function parsezipfile(
file: File,
onreadfile: (zipfile: File) => void,
Expand Down Expand Up @@ -108,3 +69,52 @@ export async function parsebinaryfile(
api_error('memory', 'crash', err.message)
}
}

export function parsewebfile(player: string, file: File | undefined) {
function handlefiletype(type: string) {
if (!ispresent(file)) {
return
}
switch (type) {
case 'text/plain':
file
.text()
.then((content) =>
vm_loader('parsefile', 'text', file.name, content, player),
)
.catch((err) => api_error('fileloader', 'crash', err.message))
break
case 'application/zip':
parsezipfile(file, (ifile) => parsewebfile(player, ifile)).catch(
(err) => api_error('fileloader', 'crash', err.message),
)
break
case 'application/octet-stream':
parsebinaryfile(file, (fileext, binaryfile) =>
vm_loader('parsefile', 'binary', fileext, binaryfile, player),
).catch((err) => api_error('memory', 'crash', err.message))
break
default:
file
.arrayBuffer()
.then((arraybuffer) => {
const type = mimetypeofbytesread(
file.name,
new Uint8Array(arraybuffer),
)
if (type) {
handlefiletype(type)
} else {
return api_error(
'memory',
'loadfile',
`unsupported file ${file.name}`,
)
}
})
.catch((err) => api_error('memory', 'crash', err.message))
return
}
}
handlefiletype(file?.type ?? '')
}
5 changes: 2 additions & 3 deletions zss/firmware/loader/textloader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,13 @@ export const textloader: FIRMWARE_COMMAND = (chip, words) => {
)
break
default: {
const [pattern, iii] = readargs(words, ii, [ARG_TYPE.STRING])
// we have pattern + names for captures
const line = textreader.lines[textreader.cursor] ?? ''
const regex = new RegExp(pattern, 'i')
const regex = new RegExp(kind, 'i')
const result = regex.exec(line)
if (ispresent(result)) {
let m = 1
for (let i = iii; i < words.length; ) {
for (let i = ii; i < words.length; ) {
// read next name to set
const [name, next] = readargs(words, i, [ARG_TYPE.STRING])
// set entry
Expand Down
2 changes: 0 additions & 2 deletions zss/memory/loader.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { tape_info } from 'zss/device/api'
import { createsid } from 'zss/mapping/guid'
import { ispresent } from 'zss/mapping/types'

Expand Down Expand Up @@ -45,6 +44,5 @@ export function memoryloader(event: string, content: any) {
EVENT_BY_ID[id] = event
CONTENT_BY_ID[id] = content
memoryloaderstart(id, loaders[i].code)
tape_info('memory', 'starting loader', mainbook.timestamp, id)
}
}

0 comments on commit a742593

Please sign in to comment.