Add guided Discord setup

This commit is contained in:
Samuel Elliott
2022-06-16 16:21:01 +01:00
parent 961f5cc150
commit 3d8612b7b9
5 changed files with 52 additions and 21 deletions

View File

@@ -7,7 +7,8 @@ import ipc, { events } from '../ipc.js';
import { getAccounts, RequestState, Root, useAsync, useDiscordPresenceSource, useEventListener } from '../util.js';
export interface DiscordSetupProps {
//
users?: string[];
friend_nsa_id?: string;
}
enum DiscordSourceType {
@@ -28,14 +29,16 @@ export default function DiscordSetup(props: DiscordSetupProps) {
const [discord_presence_source, discord_presence_source_state] = useDiscordPresenceSource();
const [selectedMode, setSelectedMode] = useState(DiscordSourceType.NONE);
const [selectedMode, setSelectedMode] = useState(props.users?.length && props.friend_nsa_id ?
DiscordSourceType.ZNC : DiscordSourceType.NONE);
const [selectedUserId, setSelectedUserId] = useState<string | null>(null);
const [selectedFriendNsaId, setSelectedFriendNsaId] = useState<string | null>(null);
const [selectedFriendNsaId, setSelectedFriendNsaId] = useState<string | null>(props.friend_nsa_id ?? null);
const [presenceUrl, setPresenceUrl] = useState('');
useEffect(() => {
if (!discord_presence_source) {
setSelectedMode(DiscordSourceType.NONE);
setSelectedMode(props.users?.length && props.friend_nsa_id ?
DiscordSourceType.ZNC : DiscordSourceType.NONE);
} else if ('na_id' in discord_presence_source) {
setSelectedMode(DiscordSourceType.ZNC);
setSelectedUserId(discord_presence_source.na_id);
@@ -55,11 +58,14 @@ export default function DiscordSetup(props: DiscordSetupProps) {
const friend = useMemo(() => selectedFriendNsaId ? friends?.find(f => f.nsaId === selectedFriendNsaId) : undefined,
[selectedFriendNsaId, friends]);
const filtered_users = useMemo(() => users?.filter(u => selectedUserId === u.user.id ||
(u.nso && (!props.users || props.users.includes(u.user.id)))), [users, props.users, selectedUserId]);
useEventListener(events, 'window:refresh', () => (forceRefreshAccounts(), forceRefreshFriends()), []);
useEffect(() => {
if (users?.length && !user) setSelectedUserId(users[0].user.id);
}, [users, user]);
if (filtered_users?.length && !user) setSelectedUserId(filtered_users[0].user.id);
}, [filtered_users, user]);
useEffect(() => {
if (friends?.length && !friend) setSelectedFriendNsaId(friends[0].nsaId);
@@ -113,7 +119,7 @@ export default function DiscordSetup(props: DiscordSetupProps) {
<Picker<string> selectedValue={selectedUserId ?? ''} onValueChange={setSelectedUserId}
style={[styles.picker, theme.picker]}
>
{users.filter(u => u.nso).map(u => <Picker.Item
{filtered_users?.map(u => <Picker.Item
key={u.user.id}
label={u.user.nickname +
(u.user.nickname !== u.nso!.nsoAccount.user.name ? '/' + u.nso!.nsoAccount.user.name : '')}
@@ -121,7 +127,18 @@ export default function DiscordSetup(props: DiscordSetupProps) {
/>)}
</Picker>
{user && friends_with_presence ? <>
{props.friend_nsa_id && (!selectedFriendNsaId || selectedFriendNsaId === props.friend_nsa_id) ? <>
<Text style={[styles.header, theme.text]}>3. Select friend</Text>
<Text style={[styles.help, theme.text]}>This is the user you want to share.</Text>
<Picker<string> selectedValue={selectedFriendNsaId ?? ''} onValueChange={setSelectedFriendNsaId}
style={[styles.picker, theme.picker]}
enabled={false}
>
<Picker.Item key={props.friend_nsa_id} label={friend?.name ?? props.friend_nsa_id}
value={props.friend_nsa_id} />
</Picker>
</> : user && friends_with_presence ? <>
<Text style={[styles.header, theme.text]}>3. Select friend</Text>
<Text style={[styles.help, theme.text]}>This is the user you want to share.</Text>

View File

@@ -43,6 +43,13 @@ export default function SetupDiscordPresence(props: {
{u.nso!.nsoAccount.user.name !== u.user.nickname ? ' (' + u.user.nickname + ')' : ''}
</React.Fragment>)}.
</Text>
<View style={styles.button}>
<Button title="Setup" onPress={() => ipc.showDiscordModal({
users: added_friends.map(u => u.user.id),
friend_nsa_id: props.user.nso!.nsoAccount.user.nsaId,
})} color={'#' + accent_colour} />
</View>
</> :!source && users ? <>
<Text style={[styles.text, theme.text]}>Add a Nintendo Switch Online account with this user as a friend to set up Discord Rich Presence.</Text>
</> : source && 'na_id' in source && source.na_id === props.user.user.id && !source.friend_nsa_id ? <>

View File

@@ -45,6 +45,12 @@ function Friend(props: {
}) {
const theme = useColourScheme() === 'light' ? light : dark;
const onPress = useCallback(() => {
ipc.showFriendModal({
user: props.user!.user.id,
friend: props.friend.nsaId,
});
}, [ipc, props.user?.user.id, props.friend.nsaId]);
const onContextMenu = useCallback(() => {
ipc.showFriendMenu(props.user!.user, props.user!.nso!.nsoAccount.user, props.friend);
}, [ipc, props.user?.user, props.user?.nso?.nsoAccount.user]);
@@ -59,7 +65,7 @@ function Friend(props: {
{props.friend.presence.updatedAt ? <FriendPresence presence={props.friend.presence} /> : null}
</View>;
const touchable = props.user ? <TouchableOpacity onPress={() => ipc.showFriendModal(props.user!.user.id, props.friend.nsaId)}>
const touchable = props.user ? <TouchableOpacity onPress={onPress}>
{content}
</TouchableOpacity> : content;

View File

@@ -13,6 +13,8 @@ import { hrduration } from '../../util/misc.js';
import { DiscordPresence } from '../../discord/util.js';
import { getDiscordRpcClients } from '../../discord/rpc.js';
import { defaultTitle } from '../../discord/titles.js';
import type { FriendProps } from '../browser/friend/index.js';
import type { DiscordSetupProps } from '../browser/discord/index.js';
const debug = createDebug('app:main:ipc');
@@ -71,10 +73,7 @@ export function setupIpc(appinstance: App, ipcMain: IpcMain) {
}))));
ipcMain.handle('nxapi:nso:activeevent', (e, token: string) => store.users.get(token).then(u => u.getActiveEvent()));
ipcMain.handle('nxapi:window:showfriend', (e, na_id: string, nsa_id: string) => createWindow(WindowType.FRIEND, {
user: na_id,
friend: nsa_id,
}, {
ipcMain.handle('nxapi:window:showfriend', (e, props: FriendProps) => createWindow(WindowType.FRIEND, props, {
parent: BrowserWindow.fromWebContents(e.sender) ?? undefined,
modal: true,
show: false,
@@ -87,7 +86,7 @@ export function setupIpc(appinstance: App, ipcMain: IpcMain) {
minHeight: 300,
maxHeight: 300,
}).id);
ipcMain.handle('nxapi:window:discord', e => createWindow(WindowType.DISCORD_PRESENCE, {}, {
ipcMain.handle('nxapi:window:discord', (e, props: DiscordSetupProps) => createWindow(WindowType.DISCORD_PRESENCE, props, {
parent: BrowserWindow.fromWebContents(e.sender) ?? undefined,
modal: true,
show: false,

View File

@@ -2,15 +2,17 @@ import { contextBridge, ipcRenderer } from 'electron';
import * as process from 'node:process';
import { EventEmitter } from 'node:events';
import createDebug from 'debug';
import type { User } from 'discord-rpc';
import type { SharingItem } from '../main/electron.js';
import type { DiscordPresenceConfiguration, DiscordPresenceSource, WindowConfiguration } from '../common/types.js';
import type { SavedToken } from '../../common/auth/nso.js';
import type { SavedMoonToken } from '../../common/auth/moon.js';
import type { UpdateCacheData } from '../../common/update.js';
import { Announcements, CurrentUser, Friend, GetActiveEventResult, WebService, WebServices } from '../../api/znc-types.js';
import { DiscordPresence } from '../../discord/util.js';
import { User } from 'discord-rpc';
import { SharingItem } from '../main/electron.js';
import { NintendoAccountUser } from '../../api/na.js';
import type { Announcements, CurrentUser, Friend, GetActiveEventResult, WebService, WebServices } from '../../api/znc-types.js';
import type { DiscordPresence } from '../../discord/util.js';
import type { NintendoAccountUser } from '../../api/na.js';
import type { DiscordSetupProps } from '../browser/discord/index.js';
import type { FriendProps } from '../browser/friend/index.js';
const debug = createDebug('app:preload');
@@ -51,8 +53,8 @@ const ipc = {
getNintendoAccountMoonToken: (id: string) => inv<string | undefined>('moon:gettoken', id),
getSavedMoonToken: (token: string) => inv<SavedMoonToken | undefined>('moon:getcachedtoken', token),
showFriendModal: (na_id: string, nsa_id: string) => inv<number>('window:showfriend', na_id, nsa_id),
showDiscordModal: () => inv<number>('window:discord'),
showFriendModal: (props: FriendProps) => inv<number>('window:showfriend', props),
showDiscordModal: (props: DiscordSetupProps = {}) => inv<number>('window:discord', props),
setWindowHeight: (height: number) => inv('window:setheight', height),
openExternalUrl: (url: string) => inv('misc:open-url', url),