Skip to content

Commit

Permalink
Add light mode colour map (much better!)
Browse files Browse the repository at this point in the history
  • Loading branch information
retrixe committed Jan 27, 2022
1 parent a665866 commit ca1239b
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 33 deletions.
33 changes: 29 additions & 4 deletions src/minecraft/chatToJsx.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ import React from 'react'
import { StyleProp, TextProps, TextStyle } from 'react-native'
import translations from './translations'

// TODO: Add a better color map for light mode, as Mojang color map is terrible.
export const lightModeColorMap: {} = {}

export const mojangColorMap: ColorMap = {
black: '#000000',
dark_blue: '#0000AA',
Expand All @@ -24,6 +21,15 @@ export const mojangColorMap: ColorMap = {
white: '#FFFFFF'
}

export const lightColorMap: ColorMap = {
...mojangColorMap,
white: '#000000', // LOW-TODO: Should white be pure black?
green: '#55c855',
gray: '#999999',
yellow: '#b9b955',
aqua: '#55cdcd'
}

export interface ColorMap {
[color: string]: string
black: string
Expand Down Expand Up @@ -66,6 +72,8 @@ export interface TranslatedChat {
with: PlainTextChat[]
}

export type MinecraftChat = PlainTextChat | TranslatedChat | string

export interface ClickEvent {
// TODO: Build actual support for this.
action:
Expand Down Expand Up @@ -155,7 +163,7 @@ const flattenExtraComponents = (chat: PlainTextChat): PlainTextChat[] => {
}

const parseChatToJsx = (
chat: PlainTextChat | TranslatedChat | string,
chat: MinecraftChat,
Component: React.ComponentType<TextProps>,
colorMap: ColorMap,
componentProps?: {},
Expand Down Expand Up @@ -199,4 +207,21 @@ const parseChatToJsx = (
)
}

// React Component-ised.
const ChatToJsxNonMemo = ({
chat,
component,
colorMap,
componentProps,
trim
}: {
chat: MinecraftChat
component: React.ComponentType<TextProps>
colorMap: ColorMap
componentProps?: {}
trim?: boolean
}) => parseChatToJsx(chat, component, colorMap, componentProps, trim)
// Memoisation means this is only re-rendered if the props changed.
export const ChatToJsx = React.memo(ChatToJsxNonMemo)

export default parseChatToJsx
37 changes: 23 additions & 14 deletions src/screens/ChatScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@ import globalStyle from '../globalStyle'
import useDarkMode from '../context/useDarkMode'
import SettingsContext from '../context/settingsContext'
import ConnectionContext from '../context/connectionContext'
import parseChatToJsx, { mojangColorMap } from '../minecraft/chatToJsx'
import {
ChatToJsx,
mojangColorMap,
lightColorMap,
MinecraftChat,
ColorMap
} from '../minecraft/chatToJsx'
import { concatPacketData } from '../minecraft/packet'
import { readVarInt } from '../minecraft/packetUtils'
import TextField from '../components/TextField'
Expand All @@ -27,20 +33,25 @@ type ChatNavigationProp = NativeStackNavigationProp<
>
interface Message {
key: number
text: JSX.Element
text: MinecraftChat
}

const renderItem = ({ item }: { item: Message }) => (
<View style={styles.androidScaleInvert}>{item.text}</View>
) // https://reactnative.dev/docs/optimizing-flatlist-configuration
const ChatMessageList = (props: { messages: Message[] }) => {
const renderItem = (colorMap: ColorMap) => {
const ItemRenderer = ({ item }: { item: Message }) => (
<View style={styles.androidScaleInvert}>
<ChatToJsx chat={item.text} component={Text} colorMap={colorMap} />
</View>
)
return ItemRenderer // LOW-TODO: Performance implications?
} // https://reactnative.dev/docs/optimizing-flatlist-configuration
const ChatMessageList = (props: { messages: Message[]; darkMode: boolean }) => {
return (
<FlatList
inverted={Platform.OS !== 'android'}
data={props.messages}
style={[styles.androidScaleInvert, styles.chatArea]}
contentContainerStyle={styles.chatAreaScrollView}
renderItem={renderItem}
renderItem={renderItem(props.darkMode ? mojangColorMap : lightColorMap)}
/>
)
}
Expand All @@ -51,11 +62,11 @@ const ChatMessageListMemo = React.memo(

const createErrorHandler = (
color: string,
addMessage: (text: JSX.Element) => void,
addMessage: (text: MinecraftChat) => void,
translated: string
) => (error: unknown) => {
console.error(error)
addMessage(<Text style={{ color }}>[EnderChat] {translated}</Text>)
addMessage('[EnderChat] ' + translated)
}
const sendMessageErr = 'Failed to send message to server!'
const parseMessageErr = 'An error occurred when parsing chat.'
Expand All @@ -73,7 +84,7 @@ const ChatScreen = ({ navigation }: { navigation: ChatNavigationProp }) => {
const loggedInRef = useRef(false)

const colorMap = mojangColorMap
const addMessage = (text: JSX.Element) =>
const addMessage = (text: MinecraftChat) =>
setMessages(m => {
const trunc = m.length > 500 ? m.slice(0, 499) : m
return [{ key: id++, text }].concat(trunc)
Expand Down Expand Up @@ -109,9 +120,7 @@ const ChatScreen = ({ navigation }: { navigation: ChatNavigationProp }) => {
.toString('utf8')
const position = packet.data.readInt8(chatVarIntLength + chatLength)
// LOW-TODO: Support position 2 and sender.
if (position === 0 || position === 1) {
addMessage(parseChatToJsx(JSON.parse(chatJson), Text, colorMap))
}
if (position === 0 || position === 1) addMessage(JSON.parse(chatJson))
} catch (e) {
createErrorHandler(colorMap.dark_red, addMessage, parseMessageErr)(e)
}
Expand Down Expand Up @@ -195,7 +204,7 @@ const ChatScreen = ({ navigation }: { navigation: ChatNavigationProp }) => {
)}
{loggedIn && (
<>
<ChatMessageListMemo messages={messages} />
<ChatMessageListMemo messages={messages} darkMode={darkMode} />
<View style={darkMode ? styles.textAreaDark : styles.textArea}>
<TextField
value={message}
Expand Down
37 changes: 22 additions & 15 deletions src/screens/ServerScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@ import AccountsContext from '../context/accountsContext'
import ConnectionContext from '../context/connectionContext'
import { resolveHostname, protocolMap } from '../minecraft/utils'
import initiateConnection from '../minecraft/connection'
import parseChatToJsx, {
mojangColorMap,
PlainTextChat
import {
ChatToJsx,
MinecraftChat,
lightColorMap,
mojangColorMap
} from '../minecraft/chatToJsx'
import useDarkMode from '../context/useDarkMode'

Expand Down Expand Up @@ -68,7 +70,7 @@ const ServerScreen = () => {
}>({})
const [disconnectDialog, setDisconnectDialog] = useState<{
server: string
reason: PlainTextChat | string
reason: MinecraftChat
} | null>(null)

useEffect(() => {
Expand Down Expand Up @@ -216,9 +218,12 @@ const ServerScreen = () => {
<Text style={dialogStyles.modalTitle}>
Disconnected from {disconnectDialog.server}
</Text>
{parseChatToJsx(disconnectDialog.reason, Text, mojangColorMap, {
style: styles.serverDescription
})}
<ChatToJsx
chat={disconnectDialog.reason}
component={Text}
colorMap={darkMode ? mojangColorMap : lightColorMap}
componentProps={{ style: styles.serverDescription }}
/>
<View style={dialogStyles.modalButtons}>
<View style={globalStyle.flexSpacer} />
<Pressable
Expand Down Expand Up @@ -349,14 +354,16 @@ const ServerScreen = () => {
(ping as LegacyPing).maxPlayers}{' '}
players online | Ping: {ping.ping}ms
</Text>
{parseChatToJsx(
(ping as Ping).description ??
(ping as LegacyPing).motd,
Text,
mojangColorMap,
{ style: styles.serverDescription },
true
)}
<ChatToJsx
chat={
(ping as Ping).description ??
(ping as LegacyPing).motd
}
component={Text}
colorMap={darkMode ? mojangColorMap : lightColorMap}
componentProps={{ styles: styles.serverDescription }}
trim
/>
</>
) : (
<Text style={styles.serverDescription}>
Expand Down

0 comments on commit ca1239b

Please sign in to comment.