Skip to content

feat(mobile): add read only mode #19368

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Sud-Puth
Copy link

@Sud-Puth Sud-Puth commented Jun 20, 2025

Description

Introduces a "Read-only Mode" feature.

  • Read-only Mode state is persisted in app settings.
  • Added a new app setting allowUserAvatarOverride to toggle read-only mode via the user avatar icon.
  • Updated translations.
  • Added a message in the app bar dialog indicating when read-only mode is active.
  • When Kid Mode is enabled,
    • Disables selecting the multigrid & the bottom bar
    • Removes the top bar from view

In total just enables the users to give the Immich app on their mobile to their little loved ones without them deleting nor pressing something that they shouldn't have.

How Has This Been Tested?

  • Tested using installing the debug app on an Android 16 phone & the SDK emulator

{E6CB6329-94E9-4918-8716-21C2B549A412}
{7CC87286-A98A-4695-B65D-CCBACEA28B6B}
{9EB4010A-B8CB-4BD7-801C-EFF9F420336A}

flutter_03

Checklist:

  • I have performed a self-review of my own code
  • I have made corresponding changes to the documentation if applicable
  • I have no unrelated changes in the PR.
  • I have confirmed that any new dependencies are strictly necessary.
  • I have written tests for new code (if applicable)
  • I have followed naming conventions/patterns in the surrounding code
  • All code in src/services/ uses repositories implementations for database calls, filesystem operations, etc.
  • All code in src/repositories/ is pretty basic/simple and does not have any immich specific logic (that belongs in src/services/)

@alextran1502
Copy link
Member

Thank you for the PR, however, we are likely not going to accept this as it is quite a niche use case

@Sud-Puth
Copy link
Author

Sud-Puth commented Jun 20, 2025 via email

@alextran1502
Copy link
Member

Let's call this a read-only mode, and brainstorm on where to put a quick toggle that is still having a good UI

@bwees
Copy link
Member

bwees commented Jun 20, 2025

@Sud-Puth This is great! I had a few ideas on ways we can compromise on feature visibility and quick access to the setting for parents. I am thinking that it would be best to put a toggle in the advanced settings pane that controls the setting. Beneath the title, we can put a little description that explains an easier method to quickly enable/disable it.

That "easier" method would then be something akin to double-tapping the user icon would toggle the read-only mode. We would put a small banner in the user dialog saying "Read-only mode enabled" with a description "Double-tap the user icon to exit". This allows us to keep the user dialog simple while still having a quick way to enable and disable it when a parent gives their phone to their kid.

@bwees bwees changed the title feat(mobile): Add Kid (Readonly) Mode toggle feat(mobile): add read only mode Jun 20, 2025
@Sud-Puth
Copy link
Author

@bwees -- love that idea ! will push those changes up soon

@bwees
Copy link
Member

bwees commented Jun 20, 2025

Thank you! I will work with you on this to get it polished then we can get Alex for the final review.

@Sud-Puth
Copy link
Author

OK so latest update - 2 settings in Advanced & Text notification based in the dialog based on which mode is selected.
{E6CB6329-94E9-4918-8716-21C2B549A412}
{7CC87286-A98A-4695-B65D-CCBACEA28B6B}
{9EB4010A-B8CB-4BD7-801C-EFF9F420336A}

@Sud-Puth
Copy link
Author

@bwees - give it a whirl now

@bwees
Copy link
Member

bwees commented Jun 23, 2025

Thanks for making these changes!

A few notes:

  1. Let's make it so the double tap to exit is always enabled. There really isn't a need to have a whole setting just to enable/disable this functionality. We can adjust the explainer text to include information about the hidden double-tap.

  2. I think it would be best if the "read only mode enabled" in the user dialog was a little more prominent. Maybe a light red background or red text would be best here.

  3. In addition to the text, I think it would be good to show some form of icon to know that you are in readonly mode. Right now when you look at the interface when in readonly mode, there is no clear indication readonly mode is active. Maybe an icon in the top bar or a persistent "Read only mode activated" SnackBar. We should make it clear to the user that readonly mode is active if they accidentally get into the state.

  4. There are still icons visible in the bottom of the screen when in readonly mode. We should not show a button if it does not do anything (or show a disabled state) so it does not confuse the user.

image

This is coming along great. Thanks for working with us to get this ready!

@Sud-Puth
Copy link
Author

So I don't like the Red color for background nor text -

  • It just deters the look and styling of the application, I just went with the theme colors and I think this is better-
    let me know what you think -
    {E33623F8-1FBE-4ED4-93ED-303A3A6A2FB2}
    vs
    {4F0D51CA-BD19-4462-B578-24E1ABF98CC4}
  1. having the snackbar - cause we call to clear the snackbar on some activities like casting and there maybe other uses for the snackbar that the snackbar is not supposed to be used for, I tried to use materialbanner but it was going to be again too much of a theme digression.
    I opted for a simple - edit_off icon and when the user taps on that - we display the snackbar with the same text as on the dialog page
    {26315FEF-D75C-4470-809E-3E5329179F07}

Check the latest commit - 0ae277a

@bwees
Copy link
Member

bwees commented Jun 24, 2025

I agree, it doesn't look great with the red. I made some changes to the user dialog message styling to make it fit in with the dialog better. If you could replace the buildReadonlyMessage() with the following:

buildReadonlyMessage() {
      if (isReadonlyModeEnabled) {
        return Padding(
          padding: const EdgeInsets.only(
            left: 10.0,
            right: 10.0,
          ),
          child: ListTile(
            dense: true,
            visualDensity: VisualDensity.standard,
            contentPadding: const EdgeInsets.only(left: 20, right: 20),
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(10),
            ),
            minLeadingWidth: 20,
            tileColor: theme.primaryColor.withAlpha(80),
            title: Text(
              "profile_drawer_readonly_mode",
              style: theme.textTheme.labelLarge?.copyWith(
                color: theme.textTheme.labelLarge?.color?.withAlpha(250),
              ),
              textAlign: TextAlign.center,
            ).tr(),
          ),
        );
      } else {
        return const SizedBox.shrink();
      }

    }

It should looks like this after moving the build to above the action buttons:

Screenshot 2025-06-24 at 10 31 14 AM

Lets also add one more snack bar to the UI so when you double tap the user icon or toggle the switch in advanced settings, it says either the "Read only mode enabled. Double-tap...." or "Read only mode disabled". That way there is a clear indication outside of the icon showing/hiding.

We should also hide the cloud button next to the user avatar when in readonly mode.

image

This is super close, we are just down to the polishing and user interaction stuff now. Thanks for working through these changes with us!

@Sud-Puth
Copy link
Author

@bwees - Check it out - made those updates

@bwees
Copy link
Member

bwees commented Jun 24, 2025

Thank you!

I think we are good to hide the select icon for the rows when in readonly. You should be able to add a conditional in group_divider_tile.dart:

I also posted a few code review changes to match our code style a bit better. Once these are complete I think its good for Alex to review!

@Sud-Puth
Copy link
Author

@bwees -- Thanks for the review - that makes the code much cleaner & easy to read. I made all those changes in 1 go rather than committing in each time.
Also modified & tested the select on the group_divider_tile - all good now - please check bf175fc

@bwees
Copy link
Member

bwees commented Jun 25, 2025

Awesome thanks! I will take a look at this first thing tomorrow and let you know if there are any last changes before final review

@bwees
Copy link
Member

bwees commented Jun 25, 2025

Looks like the translation file needs alphabetized, can you run npm run format:i18n from the web directory to make the tests pass?

@Sud-Puth
Copy link
Author

@bwees - all done - will monitor for sometime for the checks & will come back later. Thanks for all the things !

@Sud-Puth
Copy link
Author

@bwees - one last change for the dart analysis -
The code that I have is https://github.com/immich-app/immich/pull/19368/files#diff-53a59687e96c23aed66051a271aa747b36be4586b84627b1766d0f60df17b23aR276

          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(10),
          ),
  • I am changing it to
          shape: const RoundedRectangleBorder(
            borderRadius: BorderRadius.all(
              Radius.circular(10),
            ),
          )

not sure why the local dart analysis wouldn't fail fwiw

@bwees
Copy link
Member

bwees commented Jun 25, 2025

@bwees - one last change for the dart analysis - The code that I have is https://github.com/immich-app/immich/pull/19368/files#diff-53a59687e96c23aed66051a271aa747b36be4586b84627b1766d0f60df17b23aR276

          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(10),
          ),
  • I am changing it to
          shape: const RoundedRectangleBorder(
            borderRadius: BorderRadius.all(
              Radius.circular(10),
            ),
          )

not sure why the local dart analysis wouldn't fail fwiw

Awesome thanks, we just added DCM rules to out CI actions yesterday so your local machine might not be setup to run them. This should fix it.

bwees
bwees previously approved these changes Jun 25, 2025
@bwees bwees requested a review from alextran1502 June 25, 2025 14:14
@alextran1502
Copy link
Member

Just testing the PR, and I have a few comments

  1. The info sheet in gallery view still displays the edit options for date, description, and location.
  2. Instead of having a cross-out pencil icon button to indicate read-only mode, perhaps changing the color of the app bar would be nicer

@Sud-Puth
Copy link
Author

  1. Thanks for pointing that out - Made changes to the info sheet on detail panel.
  2. What color do we prefer ? I just feel like that it would take the theme of the app into a different state/look. We tried to put the message rather than the icon on the app bar but that also did not look nice. Please let me know.
    {D068881B-ADBD-47B6-A7F3-BB8BC9453D49}

For now I pushed up the update with the cross-out pencil button removed but the app bar having a color change with read-only mode.

@Sud-Puth
Copy link
Author

Sud-Puth commented Jul 2, 2025

@alextran1502 - just a reminder for a review whenever - did not want this to fall out of your view

@alextran1502
Copy link
Member

@Sud-Puth Thanks for the reminder! can you allow maintainers to push to this PR? I might modify a few things regarding the styling before merging it

@Sud-Puth
Copy link
Author

Sud-Puth commented Jul 2, 2025

@alextran1502 - done

@@ -203,26 +205,38 @@ class TopControlAppBar extends HookConsumerWidget {
actionsIconTheme: const IconThemeData(size: iconSize),
shape: const Border(),
actions: [
if (asset.isRemote && isOwner) buildFavoriteButton(a),
if (asset.isRemote && isOwner && !isReadonlyModeEnabled)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of hiding the individual component action, maybe just hiding the entire top/bottom control bar would be cleaner.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense but I was considering on a what-if scenario if we wanted to implement and show something on read-only mode but I can def. remove it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh also the back button is gone if we remove the top control app bar, the back button still works though.

@alextran1502 alextran1502 self-assigned this Jul 6, 2025
@alextran1502 alextran1502 moved this to To Review in Alex's list Jul 6, 2025
@Sud-Puth
Copy link
Author

Sud-Puth commented Jul 7, 2025

@alextran1502 - Updated/Addressed

@bwees
Copy link
Member

bwees commented Jul 10, 2025

@Sud-Puth this is on our list to review. Thanks for working through these changes with us!

@alextran1502
Copy link
Member

Not forgetting you, been busy with other works, will take a look shortly

@bwees
Copy link
Member

bwees commented Jul 22, 2025

@Sud-Puth thanks for your patience on this feature, we have been hard at work on a lot of performance improvements in the mobile app. As part of this, we are preparing to release an improved timeline view and asset viewer (both places which this feature touches). I am going to migrate these changes to the new interface components and this feature will release alongside them as a new feature.

All of the backend you implemented is very good and will be used, I am just going to migrate the control visibility conditionals to the new interface. All changes will be attached to this PR so it stays contained and credit for work is retained.

Thanks again for your hard work and patience on this feature, I'm excited to get this merged!

@bwees bwees force-pushed the kid_mode_mobile branch from 424e1e0 to 1a4e0bd Compare July 22, 2025 19:00
@bwees bwees requested a review from alextran1502 July 22, 2025 20:52
@Sud-Puth
Copy link
Author

@bwees - Appreciate the constant updates and thank you for getting all things updated . Hopefully this is going to be used as much as I am using the debug app. 🤞 Def. find it much useful on a daily usage

@bwees
Copy link
Member

bwees commented Jul 23, 2025

Glad to hear it, we are finishing up this massive mobile rewrite then hopefully we can get it into the review pipeline. I will do my best to keep you/this thread updated with the status.

@Sud-Puth
Copy link
Author

Yup - I keep seeing the PRs - let me know if I can help with my time in any way

@bwees
Copy link
Member

bwees commented Jul 23, 2025

Yup - I keep seeing the PRs - let me know if I can help with my time in any way

if you want, you can join our discord and check out the #contributing channel. Discussions happen there where people pick up bugfixes or features.

@bwees bwees force-pushed the kid_mode_mobile branch from af50850 to 4c3317c Compare July 23, 2025 20:23
@bwees bwees dismissed their stale review July 23, 2025 20:24

out of date

@bwees bwees force-pushed the kid_mode_mobile branch 2 times, most recently from 0f33486 to c357146 Compare July 28, 2025 22:00
This commit introduces a "Kid (Readonly) Mode" feature.

- Adds a `KidModeProvider` to manage the state of Kid Mode.
- Implements a `KidModeCheckbox` widget in the app bar dialog to toggle Kid Mode.
- When Kid Mode is enabled,
  - Disables selecting the multigrid & the bottom bar
  - Removes the top bar from view

Signed-off-by: Sudheer Puthana <[email protected]>

Reverts the changes to devtools_options.yaml file

Signed-off-by: Sudheer Puthana <[email protected]>

refactor: replace Kid Mode with Readonly Mode

This commit replaces the "Kid Mode" feature with a more generic "Readonly Mode".

- Renamed `KidModeProvider` to `ReadonlyModeProvider`.
- Readonly Mode state is now persisted in app settings.
- Added a new app setting `allowUserAvatarOverride` to toggle read-only mode.
- Updated translations.
- Added a message in the app bar dialog indicating when read-only mode is active.

Signed-off-by: Sudheer Puthana <[email protected]>

Address comments -

- Removes the `allowUserAvatarOverride` setting.
- Hides the bottom gallery bar when read-only mode is enabled.
- Adds an icon on the main app bar when read-only mode is enabled with a snackbar.

Signed-off-by: Sudheer Puthana <[email protected]>

Update to snackbar

- When toggling readonly mode from either the settings or the app bar, a snackbar notification will now appear.
- The readonly mode message in the profile drawer has been restyled.
- The upload button in the app bar is now hidden when readonly mode is enabled.

Signed-off-by: Sudheer Puthana <[email protected]>

Removes clearing of snackbar

Signed-off-by: Sudheer Puthana <[email protected]>

Address Comments

- Consolidated snackbar messages for enabling/disabling readonly mode.
- Ensured the "Select All" icon in asset group titles is hidden in readonly mode.

Signed-off-by: Sudheer Puthana <[email protected]>

Adds in the missing translation keys for readonly_mode

Signed-off-by: Sudheer Puthana <[email protected]>

Fix translation

Signed-off-by: Sudheer Puthana <[email protected]>

Fix check failure for BorderRadius

Signed-off-by: Sudheer Puthana <[email protected]>

Changes:
- Adjusted AppBar background color in readonly mode.
- Removes cross-out pencil icon button in favor of above.
- Hides the "Edit" icon next to date/time, disable description and onTap for people and location when readonly mode is enabled.

Signed-off-by: Sudheer Puthana <[email protected]>

Address comments from Alex

- Moved readonly mode check to `GalleryAppBar` to hide the entire `TopControlAppBar` when readonly mode is enabled.
- Changed `toggleReadonlyMode` in `ImmichAppBar` to directly toggle the state.

Signed-off-by: Sudheer Puthana <[email protected]>

migrate readonly mode to new beta timeline

remove readonly mode from legacy UI

only show readonly functionality when on beta timeline

simplify selection icon

update generated provider

chore: more formatting
@bwees bwees force-pushed the kid_mode_mobile branch from c357146 to 2fa0bd4 Compare July 30, 2025 19:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: To Review
Development

Successfully merging this pull request may close these issues.

3 participants