[UI] Overall cleanup and fixes

This commit is contained in:
Beef 2023-01-14 02:41:28 +00:00
parent a8b5beff6e
commit dee5ed0172
10 changed files with 91 additions and 67 deletions

View file

@ -1,30 +1,26 @@
// Loosely based on https://github.com/Aliucord/AliucordRN/blob/main/src/ui/patchTheme.ts // Based on https://github.com/Aliucord/AliucordRN/blob/main/src/ui/patchTheme.ts
// Literally could not figure this out, many thanks // Literally could not figure this out, many thanks
import { findByProps, findByStoreName } from "@metro/filters"; import { findByProps, findByStoreName } from "@metro/filters";
import { FluxDispatcher } from "@metro/common"; import { FluxDispatcher } from "@metro/common";
import logger from "@/lib/logger"; import logger from "@lib/logger";
const ThemeManager = findByProps("updateTheme", "overrideTheme"); const ThemeManager = findByProps("updateTheme", "overrideTheme");
const AMOLEDThemeManager = findByProps("setAMOLEDThemeEnabled"); const AMOLEDThemeManager = findByProps("setAMOLEDThemeEnabled");
const ThemeStore = findByStoreName("ThemeStore"); const ThemeStore = findByStoreName("ThemeStore");
const UnsyncedUserSettingsStore = findByStoreName("UnsyncedUserSettingsStore"); const UnsyncedUserSettingsStore = findByStoreName("UnsyncedUserSettingsStore");
export function fixTheme() {
try {
if (ThemeStore) {
function override() { function override() {
const theme = ThemeStore.theme || "dark"; const theme = ThemeStore.theme || "dark";
ThemeManager.overrideTheme(theme); ThemeManager.overrideTheme(theme);
if (AMOLEDThemeManager && UnsyncedUserSettingsStore.useAMOLEDTheme === 2) { if (AMOLEDThemeManager && UnsyncedUserSettingsStore.useAMOLEDTheme === 2) AMOLEDThemeManager.setAMOLEDThemeEnabled(true);
AMOLEDThemeManager.setAMOLEDThemeEnabled(true);
}
FluxDispatcher.unsubscribe("I18N_LOAD_START", override); FluxDispatcher.unsubscribe("I18N_LOAD_START", override);
} }
FluxDispatcher.subscribe("I18N_LOAD_START", override); export function fixTheme() {
} try {
if (ThemeStore) FluxDispatcher.subscribe("I18N_LOAD_START", override);
} catch(e) { } catch(e) {
logger.error("Failed to fix theme...", e) logger.error("Failed to fix theme...", e)
} }

View file

@ -22,7 +22,7 @@ export default function AssetDisplay({ asset }: AssetDisplayProps) {
return ( return (
<FormRow <FormRow
label={`${asset.name} - ${asset.id}`} label={`${asset.name} - ${asset.id}`}
trailing={() => <RN.Image source={asset.id} style={styles.asset} />} trailing={<RN.Image source={asset.id} style={styles.asset} />}
onPress={() => { onPress={() => {
copyText(asset.name); copyText(asset.name);
showToast("Copied asset name to clipboard.", getAssetIDByName("toast_copy_link")); showToast("Copied asset name to clipboard.", getAssetIDByName("toast_copy_link"));

View file

@ -4,6 +4,7 @@ import { Plugin } from "@types";
import { getAssetIDByName } from "@ui/assets"; import { getAssetIDByName } from "@ui/assets";
import { removePlugin, startPlugin, stopPlugin, showSettings, getSettings } from "@lib/plugins"; import { removePlugin, startPlugin, stopPlugin, showSettings, getSettings } from "@lib/plugins";
import { showToast } from "@ui/toasts"; import { showToast } from "@ui/toasts";
import copyText from "@lib/utils/copyText";
const { FormRow, FormSwitch } = Forms; const { FormRow, FormSwitch } = Forms;
const { TouchableOpacity, Image } = General; const { TouchableOpacity, Image } = General;
@ -13,6 +14,7 @@ const styles = stylesheet.createThemedStyleSheet({
backgroundColor: stylesheet.ThemeColorMap.BACKGROUND_SECONDARY, backgroundColor: stylesheet.ThemeColorMap.BACKGROUND_SECONDARY,
borderRadius: 5, borderRadius: 5,
margin: 10, margin: 10,
marginTop: 0,
}, },
header: { header: {
backgroundColor: stylesheet.ThemeColorMap.BACKGROUND_TERTIARY, backgroundColor: stylesheet.ThemeColorMap.BACKGROUND_TERTIARY,
@ -21,7 +23,7 @@ const styles = stylesheet.createThemedStyleSheet({
}, },
actions: { actions: {
justifyContent: "flex-end", justifyContent: "flex-end",
flexDirection: "row", flexDirection: "row-reverse",
alignItems: "center", alignItems: "center",
}, },
icon: { icon: {
@ -73,6 +75,14 @@ export default function PluginCard({ plugin }: PluginCardProps) {
> >
<Image style={styles.icon} source={getAssetIDByName("ic_message_delete")} /> <Image style={styles.icon} source={getAssetIDByName("ic_message_delete")} />
</TouchableOpacity> </TouchableOpacity>
<TouchableOpacity
onPress={() => {
copyText(plugin.id);
showToast("Copied plugin URL to clipboard.", getAssetIDByName("toast_copy_link"));
}}
>
<Image style={styles.icon} source={getAssetIDByName("copy")} />
</TouchableOpacity>
<TouchableOpacity <TouchableOpacity
onPress={() => { onPress={() => {
plugin.update = !plugin.update; plugin.update = !plugin.update;

View file

@ -13,14 +13,14 @@ export default function SettingsSection({ navigation }: SettingsSectionProps) {
<FormSection key="Vendetta" title="Vendetta"> <FormSection key="Vendetta" title="Vendetta">
<FormRow <FormRow
label="General" label="General"
leading={() => <FormRow.Icon source={getAssetIDByName("settings")} />} leading={<FormRow.Icon source={getAssetIDByName("settings")} />}
trailing={FormRow.Arrow} trailing={FormRow.Arrow}
onPress={() => navigation.push("VendettaSettings")} onPress={() => navigation.push("VendettaSettings")}
/> />
<FormDivider /> <FormDivider />
<FormRow <FormRow
label="Plugins" label="Plugins"
leading={() => <FormRow.Icon source={getAssetIDByName("debug")} />} leading={<FormRow.Icon source={getAssetIDByName("debug")} />}
trailing={FormRow.Arrow} trailing={FormRow.Arrow}
onPress={() => navigation.push("VendettaPlugins")} onPress={() => navigation.push("VendettaPlugins")}
/> />
@ -29,7 +29,7 @@ export default function SettingsSection({ navigation }: SettingsSectionProps) {
<FormDivider /> <FormDivider />
<FormRow <FormRow
label="Developer" label="Developer"
leading={() => <FormRow.Icon source={getAssetIDByName("ic_progress_wrench_24px")} />} leading={<FormRow.Icon source={getAssetIDByName("ic_progress_wrench_24px")} />}
trailing={FormRow.Arrow} trailing={FormRow.Arrow}
onPress={() => navigation.push("VendettaDeveloper")} onPress={() => navigation.push("VendettaDeveloper")}
/> />

View file

@ -1,10 +1,9 @@
import { Plugin } from "@types";
import { navigation, navigationStack, NavigationNative, stylesheet, constants } from "@metro/common"; import { navigation, navigationStack, NavigationNative, stylesheet, constants } from "@metro/common";
import { General } from "@ui/components"; import { General } from "@ui/components";
import { getAssetIDByName } from "@ui/assets"; import { getAssetIDByName } from "@ui/assets";
interface PluginSettingsProps { interface SubpageProps {
plugin: Plugin; name: string;
children: JSX.Element; children: JSX.Element;
} }
@ -39,11 +38,11 @@ const styles = stylesheet.createThemedStyleSheet({
export const Settings = navigationStack.createStackNavigator(); export const Settings = navigationStack.createStackNavigator();
const { TouchableOpacity, Image } = General; const { TouchableOpacity, Image } = General;
export default function PluginSettings({ plugin, children }: PluginSettingsProps) { export default function Subpage({ name, children }: SubpageProps) {
return ( return (
<NavigationNative.NavigationContainer> <NavigationNative.NavigationContainer>
<Settings.Navigator <Settings.Navigator
initialRouteName={plugin.manifest.name} initialRouteName={name}
style={styles.container} style={styles.container}
screenOptions={{ screenOptions={{
cardOverlayEnabled: false, cardOverlayEnabled: false,
@ -54,7 +53,7 @@ export default function PluginSettings({ plugin, children }: PluginSettingsProps
}} }}
> >
<Settings.Screen <Settings.Screen
name={plugin.manifest.name} name={name}
component={children} component={children}
options={{ options={{
headerTitleStyle: styles.headerTitle, headerTitleStyle: styles.headerTitle,

View file

@ -15,8 +15,8 @@ export default function Version({ label, version, icon }: VersionProps) {
return ( return (
<FormRow <FormRow
label={label} label={label}
leading={() => <FormRow.Icon source={getAssetIDByName(icon)} />} leading={<FormRow.Icon source={getAssetIDByName(icon)} />}
trailing={() => <FormText>{version}</FormText>} trailing={<FormText>{version}</FormText>}
onPress={() => { onPress={() => {
copyText(`${label} - ${version}`); copyText(`${label} - ${version}`);
showToast("Copied version to clipboard.", getAssetIDByName("toast_copy_link")); showToast("Copied version to clipboard.", getAssetIDByName("toast_copy_link"));

View file

@ -0,0 +1,40 @@
import { ReactNative as RN, stylesheet } from "@metro/common";
import { Forms, Search } from "@ui/components";
import { all } from "@ui/assets";
import AssetDisplay from "@ui/settings/components/AssetDisplay";
const { FormDivider } = Forms;
const styles = stylesheet.createThemedStyleSheet({
search: {
margin: 0,
padding: 15,
borderBottomWidth: 0,
background: "none",
backgroundColor: "none",
}
});
export default function AssetBrowser() {
const [searchName, setSearchName] = React.useState("");
return (
<RN.View style={{ flex: 1 }}>
<Search
style={styles.search}
onChangeText={(v: string) => setSearchName(v)}
placeholder="Search..."
/>
<RN.FlatList
data={Object.values(all).filter(a => a.name.includes(searchName))}
renderItem={({ item }) => (
<>
<AssetDisplay asset={item} />
<FormDivider />
</>
)}
keyExtractor={item => item.name}
/>
</RN.View>
)
}

View file

@ -1,32 +1,20 @@
import { ReactNative as RN, stylesheet } from "@metro/common"; import { ReactNative as RN, navigation } from "@metro/common";
import { Forms, Search } from "@ui/components"; import { Forms } from "@ui/components";
import { getAssetIDByName } from "@ui/assets"; import { getAssetIDByName } from "@ui/assets";
import { showToast } from "@/ui/toasts"; import { showToast } from "@/ui/toasts";
import { connectToDebugger } from "@lib/debug"; import { connectToDebugger } from "@lib/debug";
import { all } from "@ui/assets";
import settings from "@lib/settings"; import settings from "@lib/settings";
import logger from "@lib/logger"; import logger from "@lib/logger";
import AssetDisplay from "@ui/settings/components/AssetDisplay"; import Subpage from "@ui/settings/components/Subpage";
import AssetBrowser from "@ui/settings/pages/AssetBrowser";
const { FormSection, FormRow, FormInput, FormDivider } = Forms; const { FormSection, FormRow, FormInput, FormDivider } = Forms;
const styles = stylesheet.createThemedStyleSheet({
search: {
margin: 0,
padding: 0,
paddingRight: 15,
paddingLeft: 15,
borderBottomWidth: 0,
backgroundColor: "none"
}
})
export default function Developer() { export default function Developer() {
const [debuggerUrl, setDebuggerUrl] = React.useState(settings.debuggerUrl || ""); const [debuggerUrl, setDebuggerUrl] = React.useState(settings.debuggerUrl || "");
const [searchName, setSearchName] = React.useState("");
return ( return (
<RN.View> <RN.View style={{ flex: 1 }}>
<FormSection title="Debug"> <FormSection title="Debug">
<FormInput <FormInput
value={debuggerUrl} value={debuggerUrl}
@ -40,14 +28,12 @@ export default function Developer() {
<FormRow <FormRow
label="Connect to debug websocket" label="Connect to debug websocket"
leading={() => <FormRow.Icon source={getAssetIDByName("copy")} />} leading={() => <FormRow.Icon source={getAssetIDByName("copy")} />}
trailing={FormRow.Arrow}
onPress={() => connectToDebugger(debuggerUrl)} onPress={() => connectToDebugger(debuggerUrl)}
/> />
<FormDivider /> <FormDivider />
{window.__vendetta_rdc && <FormRow {window.__vendetta_rdc && <FormRow
label="Connect to React DevTools" label="Connect to React DevTools"
leading={() => <FormRow.Icon source={getAssetIDByName("ic_badge_staff")} />} leading={() => <FormRow.Icon source={getAssetIDByName("ic_badge_staff")} />}
trailing={FormRow.Arrow}
onPress={() => { onPress={() => {
try { try {
window.__vendetta_rdc?.connectToDevTools({ window.__vendetta_rdc?.connectToDevTools({
@ -61,21 +47,15 @@ export default function Developer() {
}} }}
/>} />}
</FormSection> </FormSection>
<FormSection title="Assets"> <FormSection title="Other">
<Search <FormRow
style={styles.search} label="Asset Browser"
onChangeText={(v: string) => setSearchName(v)} leading={() => <FormRow.Icon source={getAssetIDByName("ic_media_upload")} />}
placeholder="Search..." trailing={FormRow.Arrow}
/> onPress={() => navigation.push(Subpage, {
<RN.FlatList name: "Asset Browser",
data={Object.values(all).filter(a => a.name.includes(searchName))} children: AssetBrowser,
renderItem={({ item }) => ( })}
<>
<AssetDisplay asset={item} />
<FormDivider />
</>
)}
keyExtractor={item => item.name}
/> />
</FormSection> </FormSection>
</RN.View> </RN.View>

View file

@ -110,7 +110,6 @@ export default function General() {
<FormRow <FormRow
label="Reload Discord" label="Reload Discord"
leading={<FormRow.Icon source={getAssetIDByName("ic_message_retry")} />} leading={<FormRow.Icon source={getAssetIDByName("ic_message_retry")} />}
trailing={FormRow.Arrow}
onPress={() => RN.NativeModules.BundleUpdaterManager.reload()} onPress={() => RN.NativeModules.BundleUpdaterManager.reload()}
/> />
<FormDivider /> <FormDivider />

View file

@ -1,4 +1,4 @@
import { ReactNative as RN, stylesheet } from "@metro/common"; import { ReactNative as RN } from "@metro/common";
import { Forms } from "@ui/components"; import { Forms } from "@ui/components";
import { showToast } from "@ui/toasts"; import { showToast } from "@ui/toasts";
import { getAssetIDByName } from "@ui/assets"; import { getAssetIDByName } from "@ui/assets";
@ -12,7 +12,7 @@ export default function Plugins() {
const [pluginList, setPluginList] = React.useState(plugins); const [pluginList, setPluginList] = React.useState(plugins);
return ( return (
<RN.View> <RN.View style={{ flex: 1 }}>
<FormInput <FormInput
value={pluginUrl} value={pluginUrl}
onChange={(v: string) => setPluginUrl(v)} onChange={(v: string) => setPluginUrl(v)}
@ -20,8 +20,7 @@ export default function Plugins() {
/> />
<FormRow <FormRow
label="Install plugin" label="Install plugin"
leading={<FormRow.Icon source={getAssetIDByName("add_white")} />} leading={<FormRow.Icon source={getAssetIDByName("ic_add_perk_24px")} />}
trailing={FormRow.Arrow}
onPress={() => { onPress={() => {
fetchPlugin(pluginUrl).then(() => { fetchPlugin(pluginUrl).then(() => {
setPluginUrl(""); setPluginUrl("");
@ -33,6 +32,7 @@ export default function Plugins() {
} }
/> />
<RN.FlatList <RN.FlatList
style={{ marginTop: 10 }}
data={Object.values(pluginList)} data={Object.values(pluginList)}
renderItem={({ item }) => <PluginCard plugin={item} />} renderItem={({ item }) => <PluginCard plugin={item} />}
keyExtractor={item => item.id} keyExtractor={item => item.id}