Welcome band only for newcomers, with Don't show again
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e0db5cc655
commit
75065f90cd
4 files changed
+40
-4
No files matched your search
@@ -641,6 +641,13 @@ class AppShellState extends State<AppShell> with SingleTickerProviderStateMixin
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// No Jellyfin account, no server joined or hosted yet, band not
|
||||||
|
/// dismissed: the welcome band explains the three ways in.
|
||||||
|
bool get _newcomer =>
|
||||||
|
!AppSettings.instance.welcomeDismissed.value &&
|
||||||
|
_jellyfin.isEmpty &&
|
||||||
|
SessionState.instance.recents.value.isEmpty;
|
||||||
|
|
||||||
Widget _body(bool online, bool alone) {
|
Widget _body(bool online, bool alone) {
|
||||||
final coord = SessionState.instance.coordinator;
|
final coord = SessionState.instance.coordinator;
|
||||||
final tabBody = switch (_tab) {
|
final tabBody = switch (_tab) {
|
||||||
@@ -651,12 +658,14 @@ class AppShellState extends State<AppShell> with SingleTickerProviderStateMixin
|
|||||||
solo: alone,
|
solo: alone,
|
||||||
// Offline, a put-up starts a solo session, which hosts.
|
// Offline, a put-up starts a solo session, which hosts.
|
||||||
isHost: !online || coord.hostFile != null,
|
isHost: !online || coord.hostFile != null,
|
||||||
banner: online
|
// Only for newcomers: the strip has Join and Host for everyone else.
|
||||||
|
banner: online || !_newcomer
|
||||||
? null
|
? null
|
||||||
: WelcomeBand(
|
: WelcomeBand(
|
||||||
onJoin: () => _connect(ConnectMode.join),
|
onJoin: () => _connect(ConnectMode.join),
|
||||||
onHost: () => _connect(ConnectMode.host),
|
onHost: () => _connect(ConnectMode.host),
|
||||||
onSolo: _watchSolo,
|
onSolo: _watchSolo,
|
||||||
|
onDismiss: () => setState(AppSettings.instance.dismissWelcome),
|
||||||
),
|
),
|
||||||
jellyfinStart: _libraryStart,
|
jellyfinStart: _libraryStart,
|
||||||
onPutUp: _putUp,
|
onPutUp: _putUp,
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ class WelcomeBand extends StatelessWidget {
|
|||||||
final VoidCallback onJoin;
|
final VoidCallback onJoin;
|
||||||
final VoidCallback onHost;
|
final VoidCallback onHost;
|
||||||
final VoidCallback onSolo;
|
final VoidCallback onSolo;
|
||||||
const WelcomeBand({super.key, required this.onJoin, required this.onHost, required this.onSolo});
|
final VoidCallback? onDismiss;
|
||||||
|
const WelcomeBand({super.key, required this.onJoin, required this.onHost, required this.onSolo, this.onDismiss});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -40,6 +41,19 @@ class WelcomeBand extends StatelessWidget {
|
|||||||
Text(appName, style: t.titleLarge?.copyWith(fontWeight: FontWeight.w700, height: 1.1)),
|
Text(appName, style: t.titleLarge?.copyWith(fontWeight: FontWeight.w700, height: 1.1)),
|
||||||
const SizedBox(height: 2),
|
const SizedBox(height: 2),
|
||||||
Text(appTagline, style: TextStyle(color: scheme.onSurfaceVariant)),
|
Text(appTagline, style: TextStyle(color: scheme.onSurfaceVariant)),
|
||||||
|
if (onDismiss != null)
|
||||||
|
TextButton(
|
||||||
|
key: const ValueKey('welcome-dismiss'),
|
||||||
|
onPressed: onDismiss,
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
minimumSize: const Size(0, 24),
|
||||||
|
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||||
|
foregroundColor: scheme.onSurfaceVariant,
|
||||||
|
textStyle: const TextStyle(fontSize: 12),
|
||||||
|
),
|
||||||
|
child: const Text("Don't show again"),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -76,7 +90,7 @@ class WelcomeBand extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
return Container(
|
final band = Container(
|
||||||
key: const ValueKey('welcome-band'),
|
key: const ValueKey('welcome-band'),
|
||||||
margin: const EdgeInsets.fromLTRB(20, 16, 20, 0),
|
margin: const EdgeInsets.fromLTRB(20, 16, 20, 0),
|
||||||
padding: const EdgeInsets.all(14),
|
padding: const EdgeInsets.all(14),
|
||||||
@@ -110,6 +124,7 @@ class WelcomeBand extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
return band;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ const _keyProgressLine = 'progressLine';
|
|||||||
const _keySoundVolume = 'soundVolume';
|
const _keySoundVolume = 'soundVolume';
|
||||||
const _keySoundsOff = 'soundsOff';
|
const _keySoundsOff = 'soundsOff';
|
||||||
const _keySoundPreset = 'soundPreset';
|
const _keySoundPreset = 'soundPreset';
|
||||||
|
const _keyWelcomeDismissed = 'welcomeDismissed';
|
||||||
const _keySoundPresetFor = 'soundPresetFor';
|
const _keySoundPresetFor = 'soundPresetFor';
|
||||||
const _keyUnreadyOnSwap = 'unreadyOnSwap';
|
const _keyUnreadyOnSwap = 'unreadyOnSwap';
|
||||||
const _keyIdleSitsOut = 'idleSitsOut';
|
const _keyIdleSitsOut = 'idleSitsOut';
|
||||||
@@ -58,6 +59,8 @@ class AppSettings {
|
|||||||
/// The sound set (`SoundPreset` name) every sound uses unless
|
/// The sound set (`SoundPreset` name) every sound uses unless
|
||||||
/// [soundPresetFor] picks another one for it.
|
/// [soundPresetFor] picks another one for it.
|
||||||
final soundPreset = signal('cosmic');
|
final soundPreset = signal('cosmic');
|
||||||
|
/// The offline welcome band's × was pressed: never show it again.
|
||||||
|
final welcomeDismissed = signal(false);
|
||||||
/// `SfxKind` name -> `SoundPreset` name, per-sound overrides.
|
/// `SfxKind` name -> `SoundPreset` name, per-sound overrides.
|
||||||
final soundPresetFor = signal<Map<String, String>>(const {});
|
final soundPresetFor = signal<Map<String, String>>(const {});
|
||||||
|
|
||||||
@@ -110,6 +113,8 @@ class AppSettings {
|
|||||||
if (vol is num) soundVolume.value = vol.toDouble().clamp(0, 1);
|
if (vol is num) soundVolume.value = vol.toDouble().clamp(0, 1);
|
||||||
final off = box.get(_keySoundsOff);
|
final off = box.get(_keySoundsOff);
|
||||||
if (off is List) soundsOff.value = Set.unmodifiable(off.whereType<String>());
|
if (off is List) soundsOff.value = Set.unmodifiable(off.whereType<String>());
|
||||||
|
final welcomeOff = box.get(_keyWelcomeDismissed);
|
||||||
|
if (welcomeOff is bool) welcomeDismissed.value = welcomeOff;
|
||||||
final soundSet = box.get(_keySoundPreset);
|
final soundSet = box.get(_keySoundPreset);
|
||||||
if (soundSet is String) soundPreset.value = soundSet;
|
if (soundSet is String) soundPreset.value = soundSet;
|
||||||
final per = box.get(_keySoundPresetFor);
|
final per = box.get(_keySoundPresetFor);
|
||||||
@@ -186,6 +191,11 @@ class AppSettings {
|
|||||||
_put(_keySoundsOff, soundsOff.value.toList());
|
_put(_keySoundsOff, soundsOff.value.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dismissWelcome() {
|
||||||
|
welcomeDismissed.value = true;
|
||||||
|
_put(_keyWelcomeDismissed, true);
|
||||||
|
}
|
||||||
|
|
||||||
void setSoundPreset(String preset) {
|
void setSoundPreset(String preset) {
|
||||||
soundPreset.value = preset;
|
soundPreset.value = preset;
|
||||||
_put(_keySoundPreset, preset);
|
_put(_keySoundPreset, preset);
|
||||||
|
|||||||
@@ -733,7 +733,9 @@ always scrolls the page). Space never presses a focused button
|
|||||||
bytes). Online, a name change (once typing settles) or picture change
|
bytes). Online, a name change (once typing settles) or picture change
|
||||||
goes out through `Profile.push` (`coordinator.updateProfile`).
|
goes out through `Profile.push` (`coordinator.updateProfile`).
|
||||||
- **Welcome** (`welcome.dart`): offline the Library opens with
|
- **Welcome** (`welcome.dart`): offline the Library opens with
|
||||||
`WelcomeBand` over the source switch (sizes away when online): the app
|
`WelcomeBand` over the source switch, only for newcomers (no Jellyfin
|
||||||
|
account, no recent server, not dismissed with "Don't show again";
|
||||||
|
sizes away when online): the app
|
||||||
icon, Starsync and "Watch together, in sync", then three `WayCard`s,
|
icon, Starsync and "Watch together, in sync", then three `WayCard`s,
|
||||||
Join a friend first (filled), Host, Watch solo (opens Files, or
|
Join a friend first (filled), Host, Watch solo (opens Files, or
|
||||||
Jellyfin when linked); beside the name from 940 px, under it below,
|
Jellyfin when linked); beside the name from 940 px, under it below,
|
||||||
|
|||||||
Reference in new issue
Block a user