mirror of
https://github.com/He4eT/elseifplayer.git
synced 2026-05-05 01:17:22 +00:00
Linting
This commit is contained in:
parent
3288234f36
commit
7a96d99055
21 changed files with 174 additions and 170 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
import { h } from 'preact'
|
import { h } from 'preact'
|
||||||
|
|
||||||
export default function ({ theme, setLocation, buildLink }) {
|
export default function LocalFileSelector ({ theme, setLocation, buildLink }) {
|
||||||
const fileInputHandler = ({ target }) => {
|
const fileInputHandler = ({ target }) => {
|
||||||
const file = target.files[0]
|
const file = target.files[0]
|
||||||
const url = `${URL.createObjectURL(file)}#${file.name}`
|
const url = `${URL.createObjectURL(file)}#${file.name}`
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { h } from 'preact'
|
import { h } from 'preact'
|
||||||
|
|
||||||
export default function ({ theme, setLocation, buildLink }) {
|
export default function TargetURLSelector ({ theme, setLocation, buildLink }) {
|
||||||
const urlRE = /^(http|https):\/\/[^ "]+$/
|
const urlRE = /^(http|https):\/\/[^ "]+$/
|
||||||
|
|
||||||
const onKeyPress = ({ keyCode, target }) => {
|
const onKeyPress = ({ keyCode, target }) => {
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,11 @@ import { h } from 'preact'
|
||||||
import { Link } from 'wouter-preact'
|
import { Link } from 'wouter-preact'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
buildPlayLinkHref
|
buildPlayLinkHref,
|
||||||
} from '~/src/utils/utils.routing'
|
} from '~/src/utils/utils.routing'
|
||||||
|
|
||||||
export default ({ name, ifdb, url }) => (
|
export default function GameEntry ({ name, ifdb, url }) {
|
||||||
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h4>{name}</h4>
|
<h4>{name}</h4>
|
||||||
<a
|
<a
|
||||||
|
|
@ -21,3 +22,4 @@ export default ({ name, ifdb, url }) => (
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { useEffect, useState } from 'preact/hooks'
|
||||||
|
|
||||||
import TextMessage from './TextMessage'
|
import TextMessage from './TextMessage'
|
||||||
|
|
||||||
export default function ({ inbox, currentWindow }) {
|
export default function GridBuffer ({ inbox, currentWindow }) {
|
||||||
const [prevMessages, setPrevMessages] = useState([])
|
const [prevMessages, setPrevMessages] = useState([])
|
||||||
const [messages, setMessages] = useState([])
|
const [messages, setMessages] = useState([])
|
||||||
|
|
||||||
|
|
@ -14,7 +14,7 @@ export default function ({ inbox, currentWindow }) {
|
||||||
|
|
||||||
const currentInbox = currentInboxObj?.lines ?? []
|
const currentInbox = currentInboxObj?.lines ?? []
|
||||||
|
|
||||||
const newOrPrev = (cur, prev) => i => {
|
const newOrPrev = (cur, prev) => (i) => {
|
||||||
const byId = (list, i) =>
|
const byId = (list, i) =>
|
||||||
list.find(({ line }) => line === i)
|
list.find(({ line }) => line === i)
|
||||||
|
|
||||||
|
|
@ -31,23 +31,23 @@ export default function ({ inbox, currentWindow }) {
|
||||||
|
|
||||||
const rawMessagesContent =
|
const rawMessagesContent =
|
||||||
rawMessages
|
rawMessages
|
||||||
.map(x => x.content)
|
.map((x) => x.content)
|
||||||
.map(([x]) => x)
|
.map(([x]) => x)
|
||||||
.map(({ text }) => text)
|
.map(({ text }) => text)
|
||||||
.map(text => text.trim())
|
.map((text) => text.trim())
|
||||||
|
|
||||||
const isEmpty =
|
const isEmpty =
|
||||||
rawMessagesContent
|
rawMessagesContent
|
||||||
.map(text => text.length)
|
.map((text) => text.length)
|
||||||
.every(l => l === 0)
|
.every((l) => l === 0)
|
||||||
|
|
||||||
const messages =
|
const messages =
|
||||||
rawMessagesContent
|
rawMessagesContent
|
||||||
.map(text =>
|
.map((text) =>
|
||||||
text.replace(' ', ' / '))
|
text.replace(' ', ' / '))
|
||||||
.map(text => ({
|
.map((text) => ({
|
||||||
style: 'grid',
|
style: 'grid',
|
||||||
text
|
text,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
setMessages(isEmpty ? [] : messages)
|
setMessages(isEmpty ? [] : messages)
|
||||||
|
|
|
||||||
|
|
@ -33,11 +33,11 @@ const keyNames = {
|
||||||
}
|
}
|
||||||
/* eslint-enable */
|
/* eslint-enable */
|
||||||
|
|
||||||
export default function ({
|
export default function InputBox ({
|
||||||
inputType,
|
inputType,
|
||||||
windows,
|
windows,
|
||||||
currentWindowId,
|
currentWindowId,
|
||||||
sendMessage
|
sendMessage,
|
||||||
}) {
|
}) {
|
||||||
const [targetWindow, setTargetWindow] = useState(null)
|
const [targetWindow, setTargetWindow] = useState(null)
|
||||||
const [inputText, setInputText] = useState('')
|
const [inputText, setInputText] = useState('')
|
||||||
|
|
@ -56,7 +56,7 @@ export default function ({
|
||||||
id === currentWindowId))
|
id === currentWindowId))
|
||||||
}, [currentWindowId, windows])
|
}, [currentWindowId, windows])
|
||||||
|
|
||||||
const send = message => {
|
const send = (message) => {
|
||||||
sendMessage(
|
sendMessage(
|
||||||
message,
|
message,
|
||||||
inputType,
|
inputType,
|
||||||
|
|
@ -65,12 +65,12 @@ export default function ({
|
||||||
setInputText('')
|
setInputText('')
|
||||||
}
|
}
|
||||||
|
|
||||||
const charHandler = event =>
|
const charHandler = (event) =>
|
||||||
(event.keyCode === 229
|
(event.keyCode === 229
|
||||||
? charHandlerMobile
|
? charHandlerMobile
|
||||||
: charHandlerDefault)(event)
|
: charHandlerDefault)(event)
|
||||||
|
|
||||||
const charHandlerDefault = event => {
|
const charHandlerDefault = (event) => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
|
||||||
const key =
|
const key =
|
||||||
|
|
@ -80,8 +80,8 @@ export default function ({
|
||||||
send(key)
|
send(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
const charHandlerMobile = event =>
|
const charHandlerMobile = (event) =>
|
||||||
setTimeout(_ => {
|
setTimeout(() => {
|
||||||
send(event.target.value.slice(-1).toUpperCase())
|
send(event.target.value.slice(-1).toUpperCase())
|
||||||
setInputText('')
|
setInputText('')
|
||||||
})
|
})
|
||||||
|
|
@ -96,7 +96,7 @@ export default function ({
|
||||||
if (keyCode === keyCodes.KEY_UP) {
|
if (keyCode === keyCodes.KEY_UP) {
|
||||||
setInputText(lastInput)
|
setInputText(lastInput)
|
||||||
|
|
||||||
setTimeout(_ => {
|
setTimeout(() => {
|
||||||
const end = lastInput.length
|
const end = lastInput.length
|
||||||
inputEl.current.setSelectionRange(end, end)
|
inputEl.current.setSelectionRange(end, end)
|
||||||
}, 0)
|
}, 0)
|
||||||
|
|
@ -113,16 +113,16 @@ export default function ({
|
||||||
autocorrect: 'off',
|
autocorrect: 'off',
|
||||||
spellcheck: 'false',
|
spellcheck: 'false',
|
||||||
placeholder: 'Press any key here',
|
placeholder: 'Press any key here',
|
||||||
onKeyDown: charHandler
|
onKeyDown: charHandler,
|
||||||
},
|
},
|
||||||
line: {
|
line: {
|
||||||
placeholder: ' > ',
|
placeholder: ' > ',
|
||||||
onKeyDown: lineArrowHandler,
|
onKeyDown: lineArrowHandler,
|
||||||
onKeyPress: lineHandler
|
onKeyPress: lineHandler,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const enterFullscreen = _ =>
|
const enterFullscreen = () =>
|
||||||
document.documentElement.requestFullscreen()
|
document.documentElement.requestFullscreen()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ import './player.css'
|
||||||
|
|
||||||
const INITIAL_STATUS = {
|
const INITIAL_STATUS = {
|
||||||
stage: 'loading',
|
stage: 'loading',
|
||||||
details: ['Preparing']
|
details: ['Preparing'],
|
||||||
}
|
}
|
||||||
|
|
||||||
const runMachine = ({ engine: Engine, file, handlers }) => {
|
const runMachine = ({ engine: Engine, file, handlers }) => {
|
||||||
|
|
@ -28,8 +28,8 @@ const runMachine = ({ engine: Engine, file, handlers }) => {
|
||||||
return { sendFn, instance: vm }
|
return { sendFn, instance: vm }
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ({
|
export default function Player ({
|
||||||
vmParts: { file, engine }, singleWindow
|
vmParts: { file, engine }, singleWindow,
|
||||||
}) {
|
}) {
|
||||||
const [status, setStatus] = useState(INITIAL_STATUS)
|
const [status, setStatus] = useState(INITIAL_STATUS)
|
||||||
|
|
||||||
|
|
@ -50,28 +50,28 @@ export default function ({
|
||||||
setWindows,
|
setWindows,
|
||||||
setCurrentWindowId,
|
setCurrentWindowId,
|
||||||
setInputType,
|
setInputType,
|
||||||
setInbox
|
setInbox,
|
||||||
})
|
}),
|
||||||
})
|
})
|
||||||
|
|
||||||
setVm(vm)
|
setVm(vm)
|
||||||
}, [file, engine])
|
}, [file, engine])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setSendMessage(_ => vm
|
setSendMessage(() => vm
|
||||||
? vm.sendFn
|
? vm.sendFn
|
||||||
: null)
|
: null)
|
||||||
}, [vm])
|
}, [vm])
|
||||||
|
|
||||||
const textWindow = inbox => currentWindow => {
|
const textWindow = (inbox) => (currentWindow) => {
|
||||||
const props = {
|
const props = {
|
||||||
inbox,
|
inbox,
|
||||||
currentWindow
|
currentWindow,
|
||||||
}
|
}
|
||||||
|
|
||||||
return ({
|
return ({
|
||||||
buffer: <TextBuffer {...props} />,
|
buffer: <TextBuffer {...props} />,
|
||||||
grid: <GridBuffer {...props} />
|
grid: <GridBuffer {...props} />,
|
||||||
})[currentWindow.type]
|
})[currentWindow.type]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -86,14 +86,14 @@ export default function ({
|
||||||
.sort(byTop)
|
.sort(byTop)
|
||||||
.filter(singleWindow
|
.filter(singleWindow
|
||||||
? ({ id }) => id === currentWindowId
|
? ({ id }) => id === currentWindowId
|
||||||
: _ => true)
|
: () => true)
|
||||||
.map(textWindow(inbox))}
|
.map(textWindow(inbox))}
|
||||||
</section>
|
</section>
|
||||||
<InputBox {...{
|
<InputBox {...{
|
||||||
inputType,
|
inputType,
|
||||||
windows,
|
windows,
|
||||||
currentWindowId,
|
currentWindowId,
|
||||||
sendMessage
|
sendMessage,
|
||||||
}} />
|
}} />
|
||||||
</section>)
|
</section>)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
import { h } from 'preact'
|
import { h } from 'preact'
|
||||||
import { Link } from 'wouter-preact'
|
import { Link } from 'wouter-preact'
|
||||||
|
|
||||||
const fail = details => (
|
const fail = (details) => (
|
||||||
<div className='status fail'>
|
<div className='status fail'>
|
||||||
<h1>
|
<h1>
|
||||||
Error
|
Error
|
||||||
</h1>
|
</h1>
|
||||||
{details.map(x => (<p key={x}>{x}</p>))}
|
{details.map((x) => (<p key={x}>{x}</p>))}
|
||||||
<hr />
|
<hr />
|
||||||
<Link href='/'>
|
<Link href='/'>
|
||||||
Home
|
Home
|
||||||
|
|
@ -21,9 +21,9 @@ const fail = details => (
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
const loading = details => (
|
const loading = (details) => (
|
||||||
<div className='status loading'>
|
<div className='status loading'>
|
||||||
{details.map(x => (<div key={x}>{x}</div>))}
|
{details.map((x) => (<div key={x}>{x}</div>))}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,10 @@ import { useEffect, useRef, useState } from 'preact/hooks'
|
||||||
|
|
||||||
import TextMessage from './TextMessage'
|
import TextMessage from './TextMessage'
|
||||||
|
|
||||||
const isFakeStatus = w =>
|
const isFakeStatus = (w) =>
|
||||||
w.height < 5
|
w.height < 5
|
||||||
|
|
||||||
const trimInputPrompt = messages =>
|
const trimInputPrompt = (messages) =>
|
||||||
messages.length < 1
|
messages.length < 1
|
||||||
? messages
|
? messages
|
||||||
: messages.slice(-1)[0].text === '>'
|
: messages.slice(-1)[0].text === '>'
|
||||||
|
|
@ -21,7 +21,7 @@ const parseInbox = (inbox, currentWindow) => {
|
||||||
if (!currentInbox) {
|
if (!currentInbox) {
|
||||||
return {
|
return {
|
||||||
clear: false,
|
clear: false,
|
||||||
incoming: []
|
incoming: [],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -45,11 +45,11 @@ const parseInbox = (inbox, currentWindow) => {
|
||||||
incoming,
|
incoming,
|
||||||
clear: isFakeStatus(currentWindow)
|
clear: isFakeStatus(currentWindow)
|
||||||
? true
|
? true
|
||||||
: currentInbox.clear
|
: currentInbox.clear,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ({ inbox, currentWindow }) {
|
export default function TextBuffer ({ inbox, currentWindow }) {
|
||||||
const [messages, setMessages] = useState([])
|
const [messages, setMessages] = useState([])
|
||||||
const textBufferEl = useRef(null)
|
const textBufferEl = useRef(null)
|
||||||
|
|
||||||
|
|
@ -57,7 +57,7 @@ export default function ({ inbox, currentWindow }) {
|
||||||
const { incoming, clear } =
|
const { incoming, clear } =
|
||||||
parseInbox(inbox, currentWindow)
|
parseInbox(inbox, currentWindow)
|
||||||
|
|
||||||
setMessages(messages => clear
|
setMessages((messages) => clear
|
||||||
? incoming
|
? incoming
|
||||||
: messages.concat(incoming))
|
: messages.concat(incoming))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { h } from 'preact'
|
import { h } from 'preact'
|
||||||
|
|
||||||
export default function ({ style, text }) {
|
export default function TextMessage ({ style, text }) {
|
||||||
const defaultContent = (
|
const defaultContent = (
|
||||||
<span className={['message', style].join(' ')}>
|
<span className={['message', style].join(' ')}>
|
||||||
{text}
|
{text}
|
||||||
|
|
@ -11,6 +11,6 @@ export default function ({ style, text }) {
|
||||||
input: (<span className='message input'>> {text}</span>),
|
input: (<span className='message input'>> {text}</span>),
|
||||||
subheader: (<strong className='message subheader'>{text}</strong>),
|
subheader: (<strong className='message subheader'>{text}</strong>),
|
||||||
emphasized: (<em className='message emphasized'>{text}</em>),
|
emphasized: (<em className='message emphasized'>{text}</em>),
|
||||||
endOfLine: (<br />)
|
endOfLine: (<br />),
|
||||||
})[style] || defaultContent
|
})[style] || defaultContent
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,16 +8,16 @@ import Status from './Status'
|
||||||
|
|
||||||
const INITIAL_STATUS = {
|
const INITIAL_STATUS = {
|
||||||
stage: 'loading',
|
stage: 'loading',
|
||||||
details: ['Loading']
|
details: ['Loading'],
|
||||||
}
|
}
|
||||||
|
|
||||||
const prepareVM = ({ url, setStatus, setParts }) => {
|
const prepareVM = ({ url, setStatus, setParts }) => {
|
||||||
const st = (stage, details) => args => {
|
const st = (stage, details) => (args) => {
|
||||||
setStatus({ stage, details: [details] })
|
setStatus({ stage, details: [details] })
|
||||||
return args
|
return args
|
||||||
}
|
}
|
||||||
|
|
||||||
const cleanUrl = url =>
|
const cleanUrl = (url) =>
|
||||||
url.startsWith('blob:')
|
url.startsWith('blob:')
|
||||||
? url.replace(/#(.*)$/g, '')
|
? url.replace(/#(.*)$/g, '')
|
||||||
: url
|
: url
|
||||||
|
|
@ -27,21 +27,21 @@ const prepareVM = ({ url, setStatus, setParts }) => {
|
||||||
.then(cleanUrl)
|
.then(cleanUrl)
|
||||||
.then(fetch)
|
.then(fetch)
|
||||||
.then(st('loading', 'Processing file'))
|
.then(st('loading', 'Processing file'))
|
||||||
.then(response => response.arrayBuffer())
|
.then((response) => response.arrayBuffer())
|
||||||
.then(arrayBuffer => new Uint8Array(arrayBuffer))
|
.then((arrayBuffer) => new Uint8Array(arrayBuffer))
|
||||||
.then(st('loading', 'Downloading engine'))
|
.then(st('loading', 'Downloading engine'))
|
||||||
.then(file => setParts({
|
.then((file) => setParts({
|
||||||
file,
|
file,
|
||||||
engine: engineByFilename(url)
|
engine: engineByFilename(url),
|
||||||
}))
|
}))
|
||||||
.then(st('loading', 'Running'))
|
.then(st('loading', 'Running'))
|
||||||
.catch(e => {
|
.catch((e) => {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
setStatus({ stage: 'fail', details: [e.message, url] })
|
setStatus({ stage: 'fail', details: [e.message, url] })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ({ url, singleWindow }) {
|
export default function UrlPlayer ({ url, singleWindow }) {
|
||||||
const [status, setStatus] = useState(INITIAL_STATUS)
|
const [status, setStatus] = useState(INITIAL_STATUS)
|
||||||
const [vmParts, setParts] = useState(null)
|
const [vmParts, setParts] = useState(null)
|
||||||
|
|
||||||
|
|
@ -55,7 +55,7 @@ export default function ({ url, singleWindow }) {
|
||||||
return vmParts
|
return vmParts
|
||||||
? (<Player {...{
|
? (<Player {...{
|
||||||
vmParts,
|
vmParts,
|
||||||
singleWindow
|
singleWindow,
|
||||||
}} />)
|
}} />)
|
||||||
: (<Status {...status} />)
|
: (<Status {...status} />)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,27 +7,27 @@ const formats = [
|
||||||
{
|
{
|
||||||
id: 'bocfel',
|
id: 'bocfel',
|
||||||
extensions: /z([3458]|blorb)$/,
|
extensions: /z([3458]|blorb)$/,
|
||||||
engine: bocfel
|
engine: bocfel,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'git',
|
id: 'git',
|
||||||
extensions: /(gblorb|ulx)$/,
|
extensions: /(gblorb|ulx)$/,
|
||||||
engine: git
|
engine: git,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'hugo',
|
id: 'hugo',
|
||||||
extensions: /hex$/,
|
extensions: /hex$/,
|
||||||
engine: hugo
|
engine: hugo,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'tads',
|
id: 'tads',
|
||||||
extensions: /(gam|t3)$/,
|
extensions: /(gam|t3)$/,
|
||||||
engine: tads
|
engine: tads,
|
||||||
}
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
export const engineByFilename = filename => {
|
export const engineByFilename = (filename) => {
|
||||||
const format = formats.find(x =>
|
const format = formats.find((x) =>
|
||||||
x.extensions.test(filename))
|
x.extensions.test(filename))
|
||||||
|
|
||||||
if (format) {
|
if (format) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import {
|
import {
|
||||||
compressToUTF16 as encode,
|
compressToUTF16 as encode,
|
||||||
decompressFromUTF16 as decode
|
decompressFromUTF16 as decode,
|
||||||
} from 'lz-string'
|
} from 'lz-string'
|
||||||
|
|
||||||
export const Handlers = ({
|
export const Handlers = ({
|
||||||
|
|
@ -8,33 +8,33 @@ export const Handlers = ({
|
||||||
setWindows,
|
setWindows,
|
||||||
setCurrentWindowId,
|
setCurrentWindowId,
|
||||||
setInputType,
|
setInputType,
|
||||||
setInbox
|
setInbox,
|
||||||
}) => ({
|
}) => ({
|
||||||
onInit: _ => {
|
onInit: () => {
|
||||||
setStatus({ stage: 'ready' })
|
setStatus({ stage: 'ready' })
|
||||||
},
|
},
|
||||||
/* */
|
/* */
|
||||||
onUpdateWindows: windows => {
|
onUpdateWindows: (windows) => {
|
||||||
setWindows(windows)
|
setWindows(windows)
|
||||||
},
|
},
|
||||||
onUpdateInputs: data => {
|
onUpdateInputs: (data) => {
|
||||||
if (data.length === 0) return null
|
if (data.length === 0) return null
|
||||||
|
|
||||||
const { type, id } = data[0]
|
const { type, id } = data[0]
|
||||||
setCurrentWindowId(id)
|
setCurrentWindowId(id)
|
||||||
setInputType(type)
|
setInputType(type)
|
||||||
},
|
},
|
||||||
onUpdateContent: inbox => {
|
onUpdateContent: (inbox) => {
|
||||||
setInbox(inbox)
|
setInbox(inbox)
|
||||||
},
|
},
|
||||||
onDisable: _ => {
|
onDisable: () => {
|
||||||
setInputType(null)
|
setInputType(null)
|
||||||
},
|
},
|
||||||
/* */
|
/* */
|
||||||
onFileNameRequest: (tosave, usage, _, setFileName) => {
|
onFileNameRequest: (tosave, usage, _, setFileName) => {
|
||||||
setFileName({
|
setFileName({
|
||||||
usage,
|
usage,
|
||||||
filename: prompt('Enter the filename')
|
filename: prompt('Enter the filename'),
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
onFileRead: ({ filename }) => {
|
onFileRead: ({ filename }) => {
|
||||||
|
|
@ -45,7 +45,7 @@ export const Handlers = ({
|
||||||
localStorage.setItem(`fake-fs/${filename}`, encode(content))
|
localStorage.setItem(`fake-fs/${filename}`, encode(content))
|
||||||
},
|
},
|
||||||
/* */
|
/* */
|
||||||
onExit: _ => {
|
onExit: () => {
|
||||||
setInputType(null)
|
setInputType(null)
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { h } from 'preact'
|
import { h } from 'preact'
|
||||||
|
|
||||||
export default function ({ themeEngine }) {
|
export default function ThemeSelector ({ themeEngine }) {
|
||||||
const options = themeEngine.themes.map(theme => (
|
const options = themeEngine.themes.map((theme) => (
|
||||||
<option
|
<option
|
||||||
key={theme}
|
key={theme}
|
||||||
value={theme}>
|
value={theme}>
|
||||||
|
|
|
||||||
14
src/index.js
14
src/index.js
|
|
@ -3,10 +3,10 @@ import { Route, Router, Switch } from 'wouter-preact'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
useHashLocation,
|
useHashLocation,
|
||||||
extractView
|
extractView,
|
||||||
} from '~/src/utils/utils.routing'
|
} from '~/src/utils/utils.routing'
|
||||||
import {
|
import {
|
||||||
useThemeEngine
|
useThemeEngine,
|
||||||
} from '~/src/themes/themes'
|
} from '~/src/themes/themes'
|
||||||
|
|
||||||
import HomeView from '~/src/views/HomeView/HomeView'
|
import HomeView from '~/src/views/HomeView/HomeView'
|
||||||
|
|
@ -21,12 +21,14 @@ function App () {
|
||||||
const themeEngine = useThemeEngine()
|
const themeEngine = useThemeEngine()
|
||||||
const [location] = useHashLocation()
|
const [location] = useHashLocation()
|
||||||
|
|
||||||
const playerView = (themeEngine, singleWindow) => params =>
|
const playerView = (themeEngine, singleWindow) =>
|
||||||
(<PlayerView {...{
|
function view (params) {
|
||||||
|
return (<PlayerView {...{
|
||||||
...themeEngine,
|
...themeEngine,
|
||||||
...params,
|
...params,
|
||||||
singleWindow
|
singleWindow,
|
||||||
}} />)
|
}} />)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Router hook={useHashLocation}>
|
<Router hook={useHashLocation}>
|
||||||
|
|
@ -38,7 +40,7 @@ function App () {
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path='/'>
|
<Route path='/'>
|
||||||
<HomeView {...{
|
<HomeView {...{
|
||||||
themeEngine
|
themeEngine,
|
||||||
}} />
|
}} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path='/games/'>
|
<Route path='/games/'>
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ const themes = [
|
||||||
'redrum',
|
'redrum',
|
||||||
'toxin',
|
'toxin',
|
||||||
'valve',
|
'valve',
|
||||||
'wasp'
|
'wasp',
|
||||||
]
|
]
|
||||||
|
|
||||||
const LS_THEME_KEY = 'elseifplayer/theme'
|
const LS_THEME_KEY = 'elseifplayer/theme'
|
||||||
|
|
@ -24,7 +24,7 @@ const getSavedTheme = () => {
|
||||||
return savedTheme || DEFAULT_THEME
|
return savedTheme || DEFAULT_THEME
|
||||||
}
|
}
|
||||||
|
|
||||||
const assertTheme = theme =>
|
const assertTheme = (theme) =>
|
||||||
themes.includes(theme)
|
themes.includes(theme)
|
||||||
? theme
|
? theme
|
||||||
: getSavedTheme()
|
: getSavedTheme()
|
||||||
|
|
@ -33,7 +33,7 @@ export const useThemeEngine = (initialTheme = getSavedTheme()) => {
|
||||||
const [currentTheme, setCurrentTheme] =
|
const [currentTheme, setCurrentTheme] =
|
||||||
useState(initialTheme)
|
useState(initialTheme)
|
||||||
|
|
||||||
const setTheme = theme => {
|
const setTheme = (theme) => {
|
||||||
const newTheme = assertTheme(theme)
|
const newTheme = assertTheme(theme)
|
||||||
|
|
||||||
setCurrentTheme(newTheme)
|
setCurrentTheme(newTheme)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import {
|
import {
|
||||||
useState, useEffect, useCallback
|
useState, useEffect, useCallback,
|
||||||
} from 'preact/hooks'
|
} from 'preact/hooks'
|
||||||
|
|
||||||
export const useHashLocation = () => {
|
export const useHashLocation = () => {
|
||||||
|
|
@ -16,7 +16,7 @@ export const useHashLocation = () => {
|
||||||
return () => window.removeEventListener('hashchange', handler)
|
return () => window.removeEventListener('hashchange', handler)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const navigate = useCallback(to =>
|
const navigate = useCallback((to) =>
|
||||||
(window.location.hash = to.replace('#/', '')), [])
|
(window.location.hash = to.replace('#/', '')), [])
|
||||||
return [loc, navigate]
|
return [loc, navigate]
|
||||||
}
|
}
|
||||||
|
|
@ -24,7 +24,7 @@ export const useHashLocation = () => {
|
||||||
export const buildPlayLinkHref = ({ url }) =>
|
export const buildPlayLinkHref = ({ url }) =>
|
||||||
`/#/play/${encodeURIComponent(url)}`
|
`/#/play/${encodeURIComponent(url)}`
|
||||||
|
|
||||||
export const extractView = location => {
|
export const extractView = (location) => {
|
||||||
const currentView = location.split('/').filter(Boolean)[0]
|
const currentView = location.split('/').filter(Boolean)[0]
|
||||||
return currentView || ''
|
return currentView || ''
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,10 @@ import './GamesView.css'
|
||||||
const tutorialGame = {
|
const tutorialGame = {
|
||||||
name: 'The Dreamhold',
|
name: 'The Dreamhold',
|
||||||
ifdb: 'https://ifdb.org/viewgame?id=3myqnrs64nbtwdaz',
|
ifdb: 'https://ifdb.org/viewgame?id=3myqnrs64nbtwdaz',
|
||||||
url: 'https://mirror.ifarchive.org/if-archive/games/zcode/dreamhold.z8'
|
url: 'https://mirror.ifarchive.org/if-archive/games/zcode/dreamhold.z8',
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function () {
|
export default function GamesView () {
|
||||||
return (
|
return (
|
||||||
<main className='view games'>
|
<main className='view games'>
|
||||||
|
|
||||||
|
|
@ -46,7 +46,7 @@ export default function () {
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<GameEntry {...{
|
<GameEntry {...{
|
||||||
...tutorialGame
|
...tutorialGame,
|
||||||
}} />
|
}} />
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
@ -73,10 +73,10 @@ export default function () {
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<ol>
|
<ol>
|
||||||
{top2019.map(game => (
|
{top2019.map((game) => (
|
||||||
<li key={game[0]}>
|
<li key={game[0]}>
|
||||||
<GameEntry {...{
|
<GameEntry {...{
|
||||||
...game
|
...game,
|
||||||
}} />
|
}} />
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
|
|
||||||
|
|
@ -3,18 +3,18 @@ export default [
|
||||||
/* Check with cheap-glk */
|
/* Check with cheap-glk */
|
||||||
'Counterfeit Monkey',
|
'Counterfeit Monkey',
|
||||||
'https://ifdb.org/viewgame?id=aearuuxv83plclpl',
|
'https://ifdb.org/viewgame?id=aearuuxv83plclpl',
|
||||||
'https://mirror.ifarchive.org/if-archive/games/glulx/CounterfeitMonkey.gblorb'
|
'https://mirror.ifarchive.org/if-archive/games/glulx/CounterfeitMonkey.gblorb',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Lost Pig',
|
'Lost Pig',
|
||||||
'https://ifdb.org/viewgame?id=mohwfk47yjzii14w',
|
'https://ifdb.org/viewgame?id=mohwfk47yjzii14w',
|
||||||
'https://mirror.ifarchive.org/if-archive/games/zcode/LostPig.z8'
|
'https://mirror.ifarchive.org/if-archive/games/zcode/LostPig.z8',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
/* Works. Check inputs */
|
/* Works. Check inputs */
|
||||||
'Anchorhead',
|
'Anchorhead',
|
||||||
'https://ifdb.org/viewgame?id=op0uw1gn1tjqmjt7',
|
'https://ifdb.org/viewgame?id=op0uw1gn1tjqmjt7',
|
||||||
'https://ifarchive.org/if-archive/games/zcode/anchor.z8'
|
'https://ifarchive.org/if-archive/games/zcode/anchor.z8',
|
||||||
],
|
],
|
||||||
/* [
|
/* [
|
||||||
'80 DAYS',
|
'80 DAYS',
|
||||||
|
|
@ -24,18 +24,18 @@ export default [
|
||||||
[
|
[
|
||||||
'Galatea',
|
'Galatea',
|
||||||
'https://ifdb.org/viewgame?id=urxrv27t7qtu52lb',
|
'https://ifdb.org/viewgame?id=urxrv27t7qtu52lb',
|
||||||
'https://mirror.ifarchive.org/if-archive/games/zcode/Galatea.zblorb'
|
'https://mirror.ifarchive.org/if-archive/games/zcode/Galatea.zblorb',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
/* Works. Check inputs */
|
/* Works. Check inputs */
|
||||||
'Photopia',
|
'Photopia',
|
||||||
'https://ifdb.org/viewgame?id=ju778uv5xaswnlpl',
|
'https://ifdb.org/viewgame?id=ju778uv5xaswnlpl',
|
||||||
'https://mirror.ifarchive.org/if-archive/games/zcode/photopia.z5'
|
'https://mirror.ifarchive.org/if-archive/games/zcode/photopia.z5',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Spider and Web',
|
'Spider and Web',
|
||||||
'https://ifdb.org/viewgame?id=2xyccw3pe0uovfad',
|
'https://ifdb.org/viewgame?id=2xyccw3pe0uovfad',
|
||||||
'https://mirror.ifarchive.org/if-archive/games/zcode/Tangle.z5'
|
'https://mirror.ifarchive.org/if-archive/games/zcode/Tangle.z5',
|
||||||
],
|
],
|
||||||
/* [
|
/* [
|
||||||
'Trinity',
|
'Trinity',
|
||||||
|
|
@ -60,12 +60,12 @@ export default [
|
||||||
[
|
[
|
||||||
'Slouching Towards Bedlam',
|
'Slouching Towards Bedlam',
|
||||||
'https://ifdb.org/viewgame?id=032krqe6bjn5au78',
|
'https://ifdb.org/viewgame?id=032krqe6bjn5au78',
|
||||||
'https://mirror.ifarchive.org/if-archive/games/competition2003/zcode/slouch/slouch.z5'
|
'https://mirror.ifarchive.org/if-archive/games/competition2003/zcode/slouch/slouch.z5',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Curses!',
|
'Curses!',
|
||||||
'https://ifdb.org/viewgame?id=plvzam05bmz3enh8',
|
'https://ifdb.org/viewgame?id=plvzam05bmz3enh8',
|
||||||
'https://mirror.ifarchive.org/if-archive/games/zcode/curses.z5'
|
'https://mirror.ifarchive.org/if-archive/games/zcode/curses.z5',
|
||||||
],
|
],
|
||||||
/* [
|
/* [
|
||||||
'howling dogs',
|
'howling dogs',
|
||||||
|
|
@ -75,12 +75,12 @@ export default [
|
||||||
[
|
[
|
||||||
'Violet',
|
'Violet',
|
||||||
'https://ifdb.org/viewgame?id=4glrrfh7wrp9zz7b',
|
'https://ifdb.org/viewgame?id=4glrrfh7wrp9zz7b',
|
||||||
'https://mirror.ifarchive.org/if-archive/games/zcode/Violet.zblorb'
|
'https://mirror.ifarchive.org/if-archive/games/zcode/Violet.zblorb',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'The Wizard Sniffer',
|
'The Wizard Sniffer',
|
||||||
'https://ifdb.org/viewgame?id=uq18rw9gt8j58da',
|
'https://ifdb.org/viewgame?id=uq18rw9gt8j58da',
|
||||||
'https://ifarchive.org/if-archive/games/competition2017/The%20Wizard%20Sniffer/The_Wizard_Sniffer.gblorb'
|
'https://ifarchive.org/if-archive/games/competition2017/The%20Wizard%20Sniffer/The_Wizard_Sniffer.gblorb',
|
||||||
],
|
],
|
||||||
/* [
|
/* [
|
||||||
'Eat Me',
|
'Eat Me',
|
||||||
|
|
@ -100,12 +100,12 @@ export default [
|
||||||
[
|
[
|
||||||
'Shade',
|
'Shade',
|
||||||
'https://ifdb.org/viewgame?id=hsfc7fnl40k4a30q',
|
'https://ifdb.org/viewgame?id=hsfc7fnl40k4a30q',
|
||||||
'https://mirror.ifarchive.org/if-archive/games/zcode/shade.z5'
|
'https://mirror.ifarchive.org/if-archive/games/zcode/shade.z5',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Vespers',
|
'Vespers',
|
||||||
'https://ifdb.org/viewgame?id=6dj2vguyiagrhvc2',
|
'https://ifdb.org/viewgame?id=6dj2vguyiagrhvc2',
|
||||||
'https://mirror.ifarchive.org/if-archive/games/zcode/vespers.z8'
|
'https://mirror.ifarchive.org/if-archive/games/zcode/vespers.z8',
|
||||||
],
|
],
|
||||||
/* [
|
/* [
|
||||||
'Will Not Let Me Go',
|
'Will Not Let Me Go',
|
||||||
|
|
@ -135,7 +135,7 @@ export default [
|
||||||
[
|
[
|
||||||
'Savoir-Faire',
|
'Savoir-Faire',
|
||||||
'https://ifdb.org/viewgame?id=p0cizeb3kiwzlm2p',
|
'https://ifdb.org/viewgame?id=p0cizeb3kiwzlm2p',
|
||||||
'https://mirror.ifarchive.org/if-archive/games/zcode/Savoir-Faire.zblorb'
|
'https://mirror.ifarchive.org/if-archive/games/zcode/Savoir-Faire.zblorb',
|
||||||
],
|
],
|
||||||
/* [
|
/* [
|
||||||
'With Those We Love Alive',
|
'With Those We Love Alive',
|
||||||
|
|
@ -145,7 +145,7 @@ export default [
|
||||||
[
|
[
|
||||||
'Aisle',
|
'Aisle',
|
||||||
'https://ifdb.org/viewgame?id=j49crlvd62mhwuzu',
|
'https://ifdb.org/viewgame?id=j49crlvd62mhwuzu',
|
||||||
'https://mirror.ifarchive.org/if-archive/games/zcode/Aisle.z5'
|
'https://mirror.ifarchive.org/if-archive/games/zcode/Aisle.z5',
|
||||||
],
|
],
|
||||||
/* [
|
/* [
|
||||||
'Blue Lacuna',
|
'Blue Lacuna',
|
||||||
|
|
@ -155,7 +155,7 @@ export default [
|
||||||
[
|
[
|
||||||
'Gun Mute',
|
'Gun Mute',
|
||||||
'https://ifdb.org/viewgame?id=xwedbibfksczn7eq',
|
'https://ifdb.org/viewgame?id=xwedbibfksczn7eq',
|
||||||
'https://mirror.ifarchive.org/if-archive/games/tads/GunMute.t3'
|
'https://mirror.ifarchive.org/if-archive/games/tads/GunMute.t3',
|
||||||
],
|
],
|
||||||
/* [
|
/* [
|
||||||
'The King of Shreds and Patches',
|
'The King of Shreds and Patches',
|
||||||
|
|
@ -180,7 +180,7 @@ export default [
|
||||||
[
|
[
|
||||||
'A Beauty Cold and Austere',
|
'A Beauty Cold and Austere',
|
||||||
'https://ifdb.org/viewgame?id=y9y7jozi0l76bb82',
|
'https://ifdb.org/viewgame?id=y9y7jozi0l76bb82',
|
||||||
'https://ifarchive.org/if-archive/games/competition2017/A%20Beauty%20Cold%20and%20Austere/A_Beauty_Cold_and_Austere.gblorb'
|
'https://ifarchive.org/if-archive/games/competition2017/A%20Beauty%20Cold%20and%20Austere/A_Beauty_Cold_and_Austere.gblorb',
|
||||||
],
|
],
|
||||||
/* [
|
/* [
|
||||||
'Cactus Blue Motel',
|
'Cactus Blue Motel',
|
||||||
|
|
@ -190,7 +190,7 @@ export default [
|
||||||
[
|
[
|
||||||
'Coloratura',
|
'Coloratura',
|
||||||
'https://ifdb.org/viewgame?id=g0fl99ovcrq2sqzk',
|
'https://ifdb.org/viewgame?id=g0fl99ovcrq2sqzk',
|
||||||
'https://mirror.ifarchive.org/if-archive/games/competition2013/glulx/coloratura/Coloratura.gblorb'
|
'https://mirror.ifarchive.org/if-archive/games/competition2013/glulx/coloratura/Coloratura.gblorb',
|
||||||
],
|
],
|
||||||
/* [
|
/* [
|
||||||
'Harmonia',
|
'Harmonia',
|
||||||
|
|
@ -200,12 +200,12 @@ export default [
|
||||||
[
|
[
|
||||||
'Lime Ergot',
|
'Lime Ergot',
|
||||||
'https://ifdb.org/viewgame?id=b8mb4fcwmf1hrxl',
|
'https://ifdb.org/viewgame?id=b8mb4fcwmf1hrxl',
|
||||||
'https://mirror.ifarchive.org/if-archive/games/glulx/Lime_Ergot.gblorb'
|
'https://mirror.ifarchive.org/if-archive/games/glulx/Lime_Ergot.gblorb',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Rameses',
|
'Rameses',
|
||||||
'https://ifdb.org/viewgame?id=0stz0hr7a98bp9mp',
|
'https://ifdb.org/viewgame?id=0stz0hr7a98bp9mp',
|
||||||
'https://mirror.ifarchive.org/if-archive/games/zcode/rameses.zblorb'
|
'https://mirror.ifarchive.org/if-archive/games/zcode/rameses.zblorb',
|
||||||
],
|
],
|
||||||
/* [
|
/* [
|
||||||
'Spellbreaker',
|
'Spellbreaker',
|
||||||
|
|
@ -220,7 +220,7 @@ export default [
|
||||||
[
|
[
|
||||||
'The Wand',
|
'The Wand',
|
||||||
'https://ifdb.org/viewgame?id=2jil5vbxmbv8riv1',
|
'https://ifdb.org/viewgame?id=2jil5vbxmbv8riv1',
|
||||||
'https://ifarchive.org/if-archive/games/glulx/Wand.ulx'
|
'https://ifarchive.org/if-archive/games/glulx/Wand.ulx',
|
||||||
],
|
],
|
||||||
/* [
|
/* [
|
||||||
'Zork I',
|
'Zork I',
|
||||||
|
|
@ -230,17 +230,17 @@ export default [
|
||||||
[
|
[
|
||||||
'1893: A World\'s Fair Mystery',
|
'1893: A World\'s Fair Mystery',
|
||||||
'https://ifdb.org/viewgame?id=00e0t7swrris5pg6',
|
'https://ifdb.org/viewgame?id=00e0t7swrris5pg6',
|
||||||
'https://mirror.ifarchive.org/if-archive/games/tads/1893.gam'
|
'https://mirror.ifarchive.org/if-archive/games/tads/1893.gam',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Adventure',
|
'Adventure',
|
||||||
'https://ifdb.org/viewgame?id=fft6pu91j85y4acv',
|
'https://ifdb.org/viewgame?id=fft6pu91j85y4acv',
|
||||||
'https://mirror.ifarchive.org/if-archive/games/zcode/Advent.z5'
|
'https://mirror.ifarchive.org/if-archive/games/zcode/Advent.z5',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Alias \'The Magpie\'',
|
'Alias \'The Magpie\'',
|
||||||
'https://ifdb.org/viewgame?id=yspn49v69hzc8rtb',
|
'https://ifdb.org/viewgame?id=yspn49v69hzc8rtb',
|
||||||
'https://ifarchive.org/if-archive/games/competition2018/Alias%20The%20Magpie/Alias%20%27The%20Magpie%27.gblorb'
|
'https://ifarchive.org/if-archive/games/competition2018/Alias%20The%20Magpie/Alias%20%27The%20Magpie%27.gblorb',
|
||||||
],
|
],
|
||||||
/* [
|
/* [
|
||||||
'De Baron',
|
'De Baron',
|
||||||
|
|
@ -255,22 +255,22 @@ export default [
|
||||||
[
|
[
|
||||||
'Cragne Manor',
|
'Cragne Manor',
|
||||||
'https://ifdb.org/viewgame?id=4x7nltu8p851tn4x',
|
'https://ifdb.org/viewgame?id=4x7nltu8p851tn4x',
|
||||||
'https://mirror.ifarchive.org/if-archive/games/glulx/cragne.gblorb'
|
'https://mirror.ifarchive.org/if-archive/games/glulx/cragne.gblorb',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'The Edifice',
|
'The Edifice',
|
||||||
'https://ifdb.org/viewgame?id=4tb9soabrb4apqzd',
|
'https://ifdb.org/viewgame?id=4tb9soabrb4apqzd',
|
||||||
'https://mirror.ifarchive.org/if-archive/games/zcode/edifice.z5'
|
'https://mirror.ifarchive.org/if-archive/games/zcode/edifice.z5',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Endless, Nameless',
|
'Endless, Nameless',
|
||||||
'https://ifdb.org/viewgame?id=7vtm1rq16hh3xch',
|
'https://ifdb.org/viewgame?id=7vtm1rq16hh3xch',
|
||||||
'https://ifarchive.org/if-archive/games/zcode/nameless.z8'
|
'https://ifarchive.org/if-archive/games/zcode/nameless.z8',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Everybody Dies',
|
'Everybody Dies',
|
||||||
'https://ifdb.org/viewgame?id=lyblvftb8xtlo0a1',
|
'https://ifdb.org/viewgame?id=lyblvftb8xtlo0a1',
|
||||||
'https://mirror.ifarchive.org/if-archive/games/competition2008/glulx/everybodydies/EverybodyDies.gblorb'
|
'https://mirror.ifarchive.org/if-archive/games/competition2008/glulx/everybodydies/EverybodyDies.gblorb',
|
||||||
],
|
],
|
||||||
/* [
|
/* [
|
||||||
'Fallen London',
|
'Fallen London',
|
||||||
|
|
@ -280,12 +280,12 @@ export default [
|
||||||
[
|
[
|
||||||
'Foo Foo',
|
'Foo Foo',
|
||||||
'https://ifdb.org/viewgame?id=ec6x9y8qcmsrxob9',
|
'https://ifdb.org/viewgame?id=ec6x9y8qcmsrxob9',
|
||||||
'https://ifarchive.org/if-archive/games/springthing/2016/FooFoo.gblorb'
|
'https://ifarchive.org/if-archive/games/springthing/2016/FooFoo.gblorb',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'The Gostak',
|
'The Gostak',
|
||||||
'https://ifdb.org/viewgame?id=w5s3sv43s3p98v45',
|
'https://ifdb.org/viewgame?id=w5s3sv43s3p98v45',
|
||||||
'https://mirror.ifarchive.org/if-archive/games/zcode/gostak.z5'
|
'https://mirror.ifarchive.org/if-archive/games/zcode/gostak.z5',
|
||||||
],
|
],
|
||||||
/* [
|
/* [
|
||||||
'The Hitchhiker\'s Guide to the Galaxy',
|
'The Hitchhiker\'s Guide to the Galaxy',
|
||||||
|
|
@ -305,27 +305,27 @@ export default [
|
||||||
[
|
[
|
||||||
'Inside the Facility',
|
'Inside the Facility',
|
||||||
'https://ifdb.org/viewgame?id=stsdri5zh7a4i5my',
|
'https://ifdb.org/viewgame?id=stsdri5zh7a4i5my',
|
||||||
'https://ifarchive.org/if-archive/games/competition2016/Inside%20the%20Facility/Facility.z8'
|
'https://ifarchive.org/if-archive/games/competition2016/Inside%20the%20Facility/Facility.z8',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Junior Arithmancer',
|
'Junior Arithmancer',
|
||||||
'https://ifdb.org/viewgame?id=pw1rbjt1t4n4n87s',
|
'https://ifdb.org/viewgame?id=pw1rbjt1t4n4n87s',
|
||||||
'https://ifarchive.org/if-archive/games/competition2018/Junior%20Arithmancer/Junior_Arithmancer.gblorb'
|
'https://ifarchive.org/if-archive/games/competition2018/Junior%20Arithmancer/Junior_Arithmancer.gblorb',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Make It Good',
|
'Make It Good',
|
||||||
'https://ifdb.org/viewgame?id=jdrbw1htq4ah8q57',
|
'https://ifdb.org/viewgame?id=jdrbw1htq4ah8q57',
|
||||||
'https://mirror.ifarchive.org/if-archive/games/zcode/MakeItGood.zblorb'
|
'https://mirror.ifarchive.org/if-archive/games/zcode/MakeItGood.zblorb',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Sub Rosa',
|
'Sub Rosa',
|
||||||
'https://ifdb.org/viewgame?id=73nvz9yui87ub3sd',
|
'https://ifdb.org/viewgame?id=73nvz9yui87ub3sd',
|
||||||
'https://mirror.ifarchive.org/if-archive/games/glulx/Sub_Rosa.gblorb'
|
'https://mirror.ifarchive.org/if-archive/games/glulx/Sub_Rosa.gblorb',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Suveh Nux',
|
'Suveh Nux',
|
||||||
'https://ifdb.org/viewgame?id=xkai23ry99qdxce3',
|
'https://ifdb.org/viewgame?id=xkai23ry99qdxce3',
|
||||||
'https://mirror.ifarchive.org/if-archive/games/zcode/suvehnux.z5'
|
'https://mirror.ifarchive.org/if-archive/games/zcode/suvehnux.z5',
|
||||||
],
|
],
|
||||||
/* [
|
/* [
|
||||||
'their angelical understanding',
|
'their angelical understanding',
|
||||||
|
|
@ -340,6 +340,6 @@ export default [
|
||||||
[
|
[
|
||||||
'Varicella',
|
'Varicella',
|
||||||
'https://ifdb.org/viewgame?id=ywwlr3tpxnktjasd',
|
'https://ifdb.org/viewgame?id=ywwlr3tpxnktjasd',
|
||||||
'https://mirror.ifarchive.org/if-archive/games/zcode/vgame.z8'
|
'https://mirror.ifarchive.org/if-archive/games/zcode/vgame.z8',
|
||||||
]
|
],
|
||||||
].map(([name, ifdb, url]) => ({ name, ifdb, url }))
|
].map(([name, ifdb, url]) => ({ name, ifdb, url }))
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { Link } from 'wouter-preact'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
useHashLocation,
|
useHashLocation,
|
||||||
buildPlayLinkHref
|
buildPlayLinkHref,
|
||||||
} from '~/src/utils/utils.routing'
|
} from '~/src/utils/utils.routing'
|
||||||
|
|
||||||
import LocalFileSelector from
|
import LocalFileSelector from
|
||||||
|
|
@ -15,7 +15,7 @@ import ThemeSelector from
|
||||||
|
|
||||||
import './HomeView.css'
|
import './HomeView.css'
|
||||||
|
|
||||||
export default function ({ themeEngine }) {
|
export default function HomeView ({ themeEngine }) {
|
||||||
const setLocation = useHashLocation()[1]
|
const setLocation = useHashLocation()[1]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -46,7 +46,7 @@ export default function ({ themeEngine }) {
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<ThemeSelector {...{
|
<ThemeSelector {...{
|
||||||
themeEngine
|
themeEngine,
|
||||||
}} />
|
}} />
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -97,7 +97,7 @@ export default function ({ themeEngine }) {
|
||||||
<LocalFileSelector {...{
|
<LocalFileSelector {...{
|
||||||
setLocation,
|
setLocation,
|
||||||
buildLink: buildPlayLinkHref,
|
buildLink: buildPlayLinkHref,
|
||||||
theme: themeEngine.currentTheme
|
theme: themeEngine.currentTheme,
|
||||||
}} />
|
}} />
|
||||||
</label>
|
</label>
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -108,7 +108,7 @@ export default function ({ themeEngine }) {
|
||||||
<TargetURLSelector {...{
|
<TargetURLSelector {...{
|
||||||
setLocation,
|
setLocation,
|
||||||
buildLink: buildPlayLinkHref,
|
buildLink: buildPlayLinkHref,
|
||||||
theme: themeEngine.currentTheme
|
theme: themeEngine.currentTheme,
|
||||||
}} />
|
}} />
|
||||||
</label>
|
</label>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { h } from 'preact'
|
import { h } from 'preact'
|
||||||
import { Link } from 'wouter-preact'
|
import { Link } from 'wouter-preact'
|
||||||
|
|
||||||
export default () => (
|
export default function NotFoundView () {
|
||||||
<main>
|
return <main>
|
||||||
<div className='status'>
|
<div className='status'>
|
||||||
<h1>
|
<h1>
|
||||||
404
|
404
|
||||||
|
|
@ -23,4 +23,4 @@ export default () => (
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
)
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,10 @@ import UrlPlayer from '~/src/components/Player/UrlPlayer'
|
||||||
|
|
||||||
import './PlayerView.css'
|
import './PlayerView.css'
|
||||||
|
|
||||||
const decode = encodedUrl => decodeURIComponent(encodedUrl)
|
const decode = (encodedUrl) => decodeURIComponent(encodedUrl)
|
||||||
|
|
||||||
export default function ({
|
export default function PlayerView ({
|
||||||
setTheme, theme, encodedUrl, singleWindow
|
setTheme, theme, encodedUrl, singleWindow,
|
||||||
}) {
|
}) {
|
||||||
useEffect(() => setTheme(theme), [setTheme, theme])
|
useEffect(() => setTheme(theme), [setTheme, theme])
|
||||||
|
|
||||||
|
|
@ -22,7 +22,7 @@ export default function ({
|
||||||
<main>
|
<main>
|
||||||
<UrlPlayer {...{
|
<UrlPlayer {...{
|
||||||
url: targetUrl,
|
url: targetUrl,
|
||||||
singleWindow
|
singleWindow,
|
||||||
}} />
|
}} />
|
||||||
</main>
|
</main>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue