Skip to content

Commit

Permalink
Release soon (#84)
Browse files Browse the repository at this point in the history
  • Loading branch information
zardoy authored Mar 11, 2024
2 parents 0c09e30 + af43339 commit 016f6a5
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 10 deletions.
8 changes: 4 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion src/react/ChatContainer.css
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ div.chat-wrapper {
.input-mobile .chat-completions {
transform: none;
top: 100%;
padding-left: 0;
padding-left: calc(env(safe-area-inset-left) / 2);
margin-top: 20px;
/* input height */
}

Expand Down
5 changes: 3 additions & 2 deletions src/react/ChatContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { miscUiState } from '../globalState'
import { MessagePart } from './MessageFormatted'
import './ChatContainer.css'
import { isIos } from './utils'
import { reactKeyForMessage } from './Scoreboard'

export type Message = {
parts: MessageFormatPart[],
Expand Down Expand Up @@ -145,7 +146,7 @@ export default ({ messages, opacity = 1, fetchCompletionItems, opened, sendMessa

const auxInputFocus = (fireKey: string) => {
chatInput.current.focus()
document.dispatchEvent(new KeyboardEvent('keydown', { code: fireKey }))
chatInput.current.dispatchEvent(new KeyboardEvent('keydown', { code: fireKey, bubbles: true }))
}

const getDefaultCompleteValue = () => {
Expand Down Expand Up @@ -206,7 +207,7 @@ export default ({ messages, opacity = 1, fetchCompletionItems, opened, sendMessa
}}>
{opacity && <div ref={chatMessages} className={`chat ${opened ? 'opened' : ''}`} id="chat-messages" style={{ opacity }}>
{messages.map((m) => (
<MessageLine key={m.id} message={m} />
<MessageLine key={reactKeyForMessage(m)} message={m} />
))}
</div> || undefined}
</div>
Expand Down
12 changes: 9 additions & 3 deletions src/react/MessageFormattedString.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,16 @@ import { formatMessage } from '../botUtils'
import MessageFormatted from './MessageFormatted'

/** like MessageFormatted, but receives raw string or json instead, uses window.loadedData */
export default ({ message }: { message: string | Record<string, any> }) => {
export default ({ message }: { message: string | Record<string, any> | null }) => {
const messageJson = useMemo(() => {
return formatMessage(typeof message === 'string' ? fromFormattedString(message) : message)
if (!message) return null
try {
return formatMessage(typeof message === 'string' ? fromFormattedString(message) : message)
} catch (err) {
console.error(err) // todo ensure its being logged
return null
}
}, [message])

return <MessageFormatted parts={messageJson} />
return messageJson ? <MessageFormatted parts={messageJson} /> : null
}
37 changes: 37 additions & 0 deletions src/react/Scoreboard.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
.scoreboard-container {
z-index: -2;
pointer-events: none;
white-space: nowrap;
position: fixed;
right: 0px;
top: 50%;
transform: translateY(-50%);
background-color: rgba(0, 0, 0, 0.4);
min-width: 100px;
max-width: 400px;
display: flex;
flex-direction: column;
padding-inline: 5px;
font-size: 0.5rem;
max-height: 70%;
overflow: hidden;
}

@media (max-width: 800px) {
.scoreboard-container {
font-size: 0.4rem;
}
}

.scoreboard-title {
text-align: center;
}

.item-container {
display: flex;
}

.item-value {
margin-left: auto;
color: lightcoral;
}
27 changes: 27 additions & 0 deletions src/react/Scoreboard.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { Meta, StoryObj } from '@storybook/react'

import Scoreboard from './Scoreboard'

const meta: Meta<typeof Scoreboard> = {
component: Scoreboard
}

export default meta
type Story = StoryObj<typeof Scoreboard>;

export const Primary: Story = {
args: {
title: 'Scoreboard',
items: [
{
name: 'item 1',
value: 9
},
{
name: 'item 2',
value: 8
}
],
open: true
}
}
40 changes: 40 additions & 0 deletions src/react/Scoreboard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import './Scoreboard.css'
import MessageFormattedString from './MessageFormattedString'


export type ScoreboardItems = Array<{name: string, value: number, displayName?: any}>

type ScoreboardProps = {
title: string,
items: ScoreboardItems,
open: boolean
}

export const reactKeyForMessage = (message) => {
return typeof message === 'string' ? message : JSON.stringify(message)
}

export default function Scoreboard ({ title, items, open }: ScoreboardProps) {

if (!open) return null
return (
<div className='scoreboard-container'>
<div className='scoreboard-title'>
<MessageFormattedString message={title} />
</div>
{
items.map((item) => {
const message = item.displayName ?? item.name
return <div key={reactKeyForMessage(message) + '_' + item.value} className='item-container'>
<div className='item-name'>
<MessageFormattedString message={message} />
</div>
<div className='item-value'>
{item.value}
</div>
</div>
})
}
</div>
)
}
41 changes: 41 additions & 0 deletions src/react/ScoreboardProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { useMemo, useState } from 'react'
import Scoreboard from './Scoreboard'
import type { ScoreboardItems } from './Scoreboard'


export default function ScoreboardProvider () {
const [title, setTitle] = useState('Scoreboard')
const [items, setItems] = useState<ScoreboardItems>([])
const [open, setOpen] = useState(false)

useMemo(() => { // useMemo instead of useEffect to register them asap and not after the initial dom render
const updateSidebarScoreboard = () => {
if (bot.scoreboard.sidebar) {
setTitle(bot.scoreboard.sidebar.title)
setItems([...bot.scoreboard.sidebar.items])
setOpen(true)
} else {
setOpen(false)
}
}

bot.on('scoreboardCreated', updateSidebarScoreboard) // not used atm but still good to have
bot.on('scoreboardTitleChanged', updateSidebarScoreboard)
bot.on('scoreUpdated', updateSidebarScoreboard)
bot.on('scoreRemoved', updateSidebarScoreboard)
bot.on('scoreboardDeleted', updateSidebarScoreboard)
bot.on('scoreboardPosition', () => {
void Promise.resolve().then(() => {
updateSidebarScoreboard()
}) // mineflayer bug: wait for the next tick to get the correct scoreboard position
})
}, [])

return(
<Scoreboard
title={title}
items={items}
open={open}
/>
)
}
2 changes: 2 additions & 0 deletions src/reactUi.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import SelectOption from './react/SelectOption'
import EnterFullscreenButton from './react/EnterFullscreenButton'
import ChatProvider from './react/ChatProvider'
import TitleProvider from './react/TitleProvider'
import ScoreboardProvider from './react/ScoreboardProvider'
import SoundMuffler from './react/SoundMuffler'
import TouchControls from './react/TouchControls'
import widgets from './react/widgets'
Expand Down Expand Up @@ -62,6 +63,7 @@ const InGameUi = () => {
<ChatProvider />
<SoundMuffler />
<TitleProvider />
<ScoreboardProvider />
<TouchAreasControlsProvider />
</Portal>
<DisplayQr />
Expand Down

0 comments on commit 016f6a5

Please sign in to comment.