Compare commits

..

5 commits

Author SHA1 Message Date
3ef278fa5f TextBuffer: add scroll targets 2024-01-27 03:28:05 +01:00
6cba8066c1 package.json: update eslint 2023-07-03 10:31:37 +03:00
c3074d66f8 package-lock.json: npm audit fix 2023-06-29 22:20:47 +03:00
483c8ec806 package.json: update packages 2023-06-29 22:20:47 +03:00
312a959202
Update README.md 2023-06-29 22:12:38 +03:00
6 changed files with 922 additions and 695 deletions

View file

@ -27,6 +27,8 @@ npm run build <public-url>
npm run build /some-directory npm run build /some-directory
``` ```
The finalized production bundle will be generated and stored in the `/docs` directory.
## Direct links ## Direct links
You can provide a direct link to a specific game using the following URL format: You can provide a direct link to a specific game using the following URL format:

1663
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -17,20 +17,20 @@
"preact/jsx-dev-runtime": "preact/jsx-runtime" "preact/jsx-dev-runtime": "preact/jsx-runtime"
}, },
"devDependencies": { "devDependencies": {
"@parcel/transformer-sass": "^2.9.1", "@parcel/transformer-sass": "^2.9.3",
"buffer": "^6.0.3", "buffer": "^6.0.3",
"crypto-browserify": "^3.12.0", "crypto-browserify": "^3.12.0",
"eslint": "^8.41.0", "eslint": "^8.44.0",
"eslint-config-preact": "^1.3.0", "eslint-config-preact": "^1.3.0",
"events": "^3.3.0", "events": "^3.3.0",
"parcel": "^2.9.1", "parcel": "^2.9.3",
"parcel-reporter-static-files-copy": "^1.5.0", "parcel-reporter-static-files-copy": "^1.5.0",
"path-browserify": "^1.0.1", "path-browserify": "^1.0.1",
"process": "^0.11.10", "process": "^0.11.10",
"stream-browserify": "^3.0.0" "stream-browserify": "^3.0.0"
}, },
"dependencies": { "dependencies": {
"@fontsource/open-sans": "^5.0.1", "@fontsource/open-sans": "^5.0.3",
"base32768": "^3.0.1", "base32768": "^3.0.1",
"cheap-glkote": "^0.5.1", "cheap-glkote": "^0.5.1",
"emglken": "^0.5.2", "emglken": "^0.5.2",

View file

@ -4,6 +4,9 @@ import TextMessage from '../TextMessage/TextMessage'
import * as s from '../../Player.module.scss' import * as s from '../../Player.module.scss'
const eol = { style: 'endOfLine' }
const scrollTarget = { style: 'scrollTarget' }
const isFakeStatus = (w) => const isFakeStatus = (w) =>
w.height < 5 w.height < 5
@ -22,15 +25,13 @@ const parseInbox = (inbox, currentWindow) => {
if (!currentInbox) { if (!currentInbox) {
return { return {
clear: false, clear: false,
incoming: [], incoming: [scrollTarget],
} }
} }
const { text: inboxMessagesRaw } = const { text: inboxMessagesRaw } =
currentInbox currentInbox
const eol = { style: 'endOfLine' }
const incoming = const incoming =
inboxMessagesRaw inboxMessagesRaw
/* Normalize. */ /* Normalize. */
@ -40,7 +41,7 @@ const parseInbox = (inbox, currentWindow) => {
: [eol]) : [eol])
/* Flatten. */ /* Flatten. */
.reduce((acc, x) => .reduce((acc, x) =>
acc.concat(x), []) acc.concat(x), [scrollTarget])
return { return {
incoming, incoming,
@ -63,13 +64,13 @@ export default function TextBuffer ({ inbox, currentWindow }) {
: messages.concat(incoming)) : messages.concat(incoming))
setTimeout(() => { setTimeout(() => {
const inputs = const scrollTargets =
textBufferEl.current.querySelectorAll('.message.input') textBufferEl.current.querySelectorAll(`.${scrollTarget.style}`)
const lastInput = const freshScrollTarget =
inputs[inputs.length - 1] scrollTargets[scrollTargets.length - 1]
lastInput freshScrollTarget
? lastInput.scrollIntoView() ? freshScrollTarget.scrollIntoView()
: textBufferEl.current.scrollTo({ : textBufferEl.current.scrollTo({
top: textBufferEl.current.scrollHeight, top: textBufferEl.current.scrollHeight,
behavior: 'smooth', behavior: 'smooth',

View file

@ -15,6 +15,8 @@ export default function TextMessage ({ style, text }) {
(<strong className={[s.message, s.subheader].join(' ')}>{text}</strong>), (<strong className={[s.message, s.subheader].join(' ')}>{text}</strong>),
emphasized: emphasized:
(<em className={[s.message, s.emphasized].join(' ')}>{text}</em>), (<em className={[s.message, s.emphasized].join(' ')}>{text}</em>),
scrollTarget:
(<div className={[s.scrollTarget, style].join(' ')}></div>),
endOfLine: endOfLine:
(<br />), (<br />),
})[style] || defaultContent })[style] || defaultContent

View file

@ -1,6 +1,5 @@
.message { .message {
&.input { &.input {
scroll-margin-top: var(--inner-padding);
color: var(--input-color); color: var(--input-color);
} }
@ -9,3 +8,7 @@
color: var(--accent-color); color: var(--accent-color);
} }
} }
.scrollTarget {
scroll-margin-block-start: var(--inner-padding);
}