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 14 commits 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
Contributor

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
Contributor

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

Sud-Puth and others added 3 commits June 23, 2025 14:11
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 <Sud-Puth@users.noreply.github.com>
Signed-off-by: Sudheer Puthana <Sud-Puth@users.noreply.github.com>
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 <Sud-Puth@users.noreply.github.com>
@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!

- 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 <Sud-Puth@users.noreply.github.com>
@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!

- 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 <Sud-Puth@users.noreply.github.com>
@Sud-Puth
Copy link
Author

@bwees - Check it out - made those updates

Signed-off-by: Sudheer Puthana <Sud-Puth@users.noreply.github.com>
@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!

- 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 <Sud-Puth@users.noreply.github.com>
@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

Signed-off-by: Sudheer Puthana <Sud-Puth@users.noreply.github.com>
@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 and others added 2 commits June 25, 2025 08:45
# Conflicts:
#	mobile/lib/widgets/common/immich_app_bar.dart
Signed-off-by: Sudheer Puthana <Sud-Puth@users.noreply.github.com>
@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

Signed-off-by: Sudheer Puthana <Sud-Puth@users.noreply.github.com>
@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 requested a review from alextran1502 June 25, 2025 14:14
@alextran1502
Copy link
Contributor

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 added 3 commits June 27, 2025 16:09
- 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 <Sud-Puth@users.noreply.github.com>
- 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 <Sud-Puth@users.noreply.github.com>
…_mobile

# Conflicts:
#	mobile/lib/widgets/asset_viewer/detail_panel/people_info.dart
#	mobile/lib/widgets/common/immich_app_bar.dart
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants