Skip to content

Commit

Permalink
Add Switch.Profile.current and Switch.Profile.select() (replaces …
Browse files Browse the repository at this point in the history
…`Switch.currentProfile()` and `Switch.selectProfile()`)
  • Loading branch information
TooTallNate committed Apr 15, 2024
1 parent 2021109 commit 4018d04
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 43 deletions.
5 changes: 5 additions & 0 deletions .changeset/gold-planes-cheer.md
@@ -0,0 +1,5 @@
---
"nxjs-runtime": patch
---

Add `Switch.Profile.current` and `Switch.Profile.select()` (replaces `Switch.currentProfile()` and `Switch.selectProfile()`)
7 changes: 5 additions & 2 deletions packages/runtime/src/storage.ts
Expand Up @@ -6,9 +6,9 @@ import {
writeFileSync,
} from './fs';
import { URL } from './polyfills/url';
import { Profile } from './switch/profile';
import { Application } from './switch/ns';
import { INTERNAL_SYMBOL } from './internal';
import { currentProfile } from './switch/profile';
import {
assertInternalConstructor,
createInternal,
Expand Down Expand Up @@ -124,7 +124,10 @@ Object.defineProperty(globalThis, 'localStorage', {
configurable: true,
get() {
const { self } = Application;
const profile = currentProfile({ required: true });
let profile = Profile.current;
while (!profile) {
profile = Profile.current = Profile.select();
}

let saveData = self.findSaveData({
type: 1 /* FsSaveDataType_Account */,
Expand Down
68 changes: 27 additions & 41 deletions packages/runtime/src/switch/profile.ts
Expand Up @@ -12,6 +12,9 @@ function _init() {

export type ProfileUid = [bigint, bigint];

// The currently selected profile
let p: Profile | null | undefined;

/**
* Represents a user profile that exists on the system.
*/
Expand Down Expand Up @@ -49,6 +52,30 @@ export class Profile {
return proto($.accountProfileNew(uid), Profile);
}

static get current(): Profile | null {
if (typeof p !== 'undefined') return p;
_init();
p = $.accountCurrentProfile();
return p;
}

static set current(v: Profile | null) {
p = v;
}

/**
* Shows the user selection interface and returns a {@link Profile}
* instance representing the user that was selected.
*
* @note This function blocks the event loop until the user has made their selection.
*/
static select() {
_init();
const p = $.accountSelectProfile();
if (p) proto(p, Profile);
return p;
}

/**
* Can be used as an iterator to retrieve the list of user profiles.
*
Expand All @@ -74,44 +101,3 @@ Object.defineProperty(Profile.prototype, inspect.keys, {
enumerable: false,
value: () => ['uid', 'nickname', 'image'],
});

let p: Profile | null = null;

export interface CurrentProfileOptions {
required?: boolean;
}

/**
* Return a {@link Profile} instance if there was a preselected user
* when launching the application, or `null` if there was none.
*
* If `required: true` is set and there was no preselected user, then
* the user selection interface will be shown to allow the user to
* select a profile. Subsequent calls to `currentProfile()` will
* return the selected profile without user interaction.
*/
export function currentProfile(
opts: CurrentProfileOptions & { required: true },
): Profile;
export function currentProfile(opts?: CurrentProfileOptions): Profile | null;
export function currentProfile({ required }: CurrentProfileOptions = {}) {
_init();
if (p) return p;
p = $.accountCurrentProfile();
if (p) proto(p, Profile);
while (!p && required) p = selectProfile();
return p;
}

/**
* Shows the user selection interface and returns a {@link Profile}
* instance representing the user that was selected.
*
* @note This function blocks the event loop until the user has made their selection.
*/
export function selectProfile() {
_init();
const p = $.accountSelectProfile();
if (p) proto(p, Profile);
return p;
}

0 comments on commit 4018d04

Please sign in to comment.