Repository navigation
Conversation
defts
force-pushed
the
feat/space-remove-from-timeline
branch
from
October 28, 2026 07:35
836d908 to
c97b545
Compare
A thumbnail whose photo is in one of your spaces gets a badge in its top-left corner: the Spaces icon in the space's colour, or white with a count when the photo is in several spaces. It counts every path into a space and stays off a space's own pages, the trash and the locked folder. Web asks a new POST /assets/spaces in batches and drops its spaces list when a space is edited, so a new colour shows without a reload. Mobile reads its local database and syncs once the server has taken an add, a removal or an edit, so the badge follows a change made in the app. Design: specs/2026-10-26-space-badge-design.md
Selected photos on the Photos timeline can now be removed from a space you own or edit, on web and mobile: "Remove from <space>" when they are in one such space, a picker with each space's colour and count when they are in several. The removal is the one a space already has, shared with the in-space action on both platforms; photos kept by a linked album or library are explained by name. The badges update at once, and another member's photo seen only through that space leaves the timeline, in place on web. On mobile, the in-space action's message is now translated and uses the server's count. Design: specs/2026-10-27-remove-from-space-timeline-design.md
defts
force-pushed
the
feat/space-remove-from-timeline
branch
from
October 31, 2026 21:31
c97b545 to
2232855
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
With the space badge (#1249), the Photos timeline shows which photos are in a space, but taking one out still means opening the space and finding the photo again. This adds removing from a space to the selection on the main Photos timeline, on web and mobile.
The removal is the one a space already has: the same server call and rules, the same confirmation on web and none on mobile, as inside a space. Photos that are in the space through a linked album or library can't be removed this way; the message names the album to edit, or says the photo comes from a linked library.
Afterwards the badges update at once. Another member's photo that you only saw through that space leaves your timeline, in place on web rather than through a reload that would scroll back to the top; your own photos stay, without the badge.
Builds on #1249: it reuses its
POST /assets/spacesroute and its local queries, so it can only merge after it. Until then this PR also lists #1249's commit; its own changes are here: defts/gallery@feat/space-badge...feat/space-remove-from-timelineDesign doc:
specs/2026-10-27-remove-from-space-timeline-design.md.Screenshots
How
web/src/lib/gallery/space-remove/.RemoveFromSpaceButton.svelteis a button of the Photos page's selection bar, shown whoever owns the selected photos, since an Editor may remove another member's photo. Once the selection settles (250 ms) it asksPOST /assets/spacesabout it, in batches of 1000 and cancelled if the selection changes, and keeps the spaces where the user is Owner or Editor.space-removal.tsholds the removal, which the in-spaceRemoveFromSpaceActionnow shares: confirmation,removeAssets, theSpaceRemoveAssetsevent and the messages; after a partial removal it unselects what left and keeps the rest.SpacePickerModaltakes an optional list of spaces with counts and a title, and then shows each space's colour.mobile/lib/gallery/.space_remove.provider.dartfinds the removable spaces of the selection with one Drift query over the badge's three paths (json_eachfor large selections), joined to the user's Owner and Editor memberships.remove_from_spaces.action.dartis the action of the main timeline's selection sheet, withspace_remove_picker.widget.dartwhen there are several spaces.space_removal.dartholds the removal and its messages, shared with the in-space action:SharedSpaceApiRepository.removeAssetsnow returns the IDs the server removed, and the photos left are explained through the linked-albums lookup, as on web. This moves the fork'sremoveFromSpaceout of the upstreamActionNotifierandActionServiceinto the fork namespace.remove_from_named_space,remove_from_a_spaceandremove_from_space_library_blocked, in en and the nine overlay locales.docs/docs/features/shared-spaces.md.No server change, no migration.
Known limits
Verification
space-removal.spec.ts(who may remove, grouping and order, batches and cancelling, a declined confirmation, a full and a partial removal, the linked-album, linked-library and fallback messages, a refusal),RemoveFromSpaceButton.spec.ts(hidden, one space, several, a dismissed picker, a late answer for an older selection, the timeline losing only another member's photo that was in that space alone),SpacePickerModal.spec.ts(the given spaces with counts and title).space_remove_provider_test: each path, a photo reaching a space twice, roles, order, a selection larger than SQLite's variable limit), the action (remove_from_spaces_action_test: where it shows, one space, several, a dismissed picker, only photos still selected, a refusal keeping the selection), the removal and its messages (space_removal_test), the in-space action and the repository.tsc,svelte-check,dart analyze --fatal-infosand the i18n check clean.Upstream files
Against the Immich v3.3.5 tag, on #1249 and with this PR:
web/src/routes/(user)/photos/[[assetId=id]]/+page.svelte<RemoveFromSpaceButton>mobile/lib/presentation/widgets/bottom_sheet/general_bottom_sheet.widget.dartmobile/lib/providers/infrastructure/action.provider.dartremoveFromSpacemoved to the fork'sSpaceRemovalServicemobile/lib/services/action.service.dartmobile/test/services/action.service_test.dartmobile/test/unit/mocks.dartEverything else is in the fork namespaces and fork-owned files (
SpacePickerModal,SchemaSpacePicker,RemoveFromSpaceActionon both platforms, the filtered timeline controller, the space repository), tests, docs and the strings.