Repository navigation
Conversation
defts
force-pushed
the
feat/library-view
branch
3 times, most recently
from
October 29, 2026 07:42
242c482 to
2fd77e6
Compare
Photos can now show only your personal photos (yours, in no space) or only what reaches you through your spaces, yours included, like the library view of Apple Photos. Both stays the default, and the choice only shows once one of your spaces is on your timeline. The server takes an optional libraryView on the timeline, the flat search fields and POST /search/options, so search counts match the results. Web and mobile remember the choice, and mobile filters its local timeline the same way. On mobile, the Photos grouping chip becomes a display menu holding the view and the grouping, and browsing in search mode stays within the view; a text search spans every photo. Design: specs/2026-10-26-library-view-design.md See open-noodle#1038.
defts
force-pushed
the
feat/library-view
branch
from
October 31, 2026 21:31
2fd77e6 to
312a3f5
Compare
Collaborator
|
@defts I really like the idea. The only thing that I would like to change is the location of the filter. I find that it adds a bit too much noise to the main timeline. How about we move these buttons into the filter panel? On mobile it looks fine to me. I'm referring to this part
|
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
#1038 asks how to see only the photos that are in no space (Q2). This adds a three-way view to Photos, like the library view of Apple Photos:
The control only shows once one of your spaces is on your timeline; until then the view is Both. The choice is remembered (per browser on web, per device on mobile), filters narrow within it (on mobile, browsing in search mode), and a text or similar-photo search spans every photo.
Design:
specs/2026-10-26-library-view-design.md.Web
Mobile
On mobile the Photos app bar's grouping chip becomes a display menu, in the same slot: the photos shown (Both / Personal / Spaces) and the timeline grouping (Years / Months / All). The menu stays open while each choice applies and closes on a tap outside; the button stays neutral and shows the view that narrows the timeline. Browsing in search mode stays within the view, and its counts follow it.
How
libraryView(personal|spaces) on the timeline and the flat search fields; without it nothing changes, so stock clients are unaffected.withLibraryView(src/gallery/utils/library-view.ts) only narrows the query, reusingspaceAssetPathBranchesandsharedWithViewer.checkLibraryViewruns inresolveViewerScopeand refuses shared links, a timeline that is not the caller's (album and space pages), andspaceswithoutwithSharedSpaces.PillGroup(web/src/lib/gallery/pill-group/) is the pill the grouping control already drew, and both controls use it now (arrow keys included). The toolbar wraps its chips instead of squeezing them. An empty view shows "no results", and "View in timeline" goes back to Both so the photo is there.POST /search/optionstakeslibraryViewtoo, as/timeline/bucketsdoes, so the counts match the results; the cache of unfiltered options keys on it.PhotosViewMenuButton(mobile/lib/gallery/photos_view_menu.widget.dart) replaces the compact grouping chip, which goes away with its short labels; it is no wider, so the logo keeps its size (Logo shrinks inconsistently in top bar on mobile depending on active icons (loading spinner / sort icon) #1030). Every choice reloads the timeline and rebuilds the app bar, so the menu is a route of its own that reads app-wide providers, not an overlay anchored to the button; it slides over the neighbouring actions on a 360-dp screen and follows the text direction. The view section only shows with a space on the timeline. The merged timeline SQL (drift and the scoped SQL) takes the view as a nullable:library_view. The Photos search scope (searchScopeProvider's default) carries the view, and browsing sends it (/timeline/buckets, the metadata search,/search/options); a query (/search/smart) does not. The view is stored under 90007, in the fork's block of store ids.Known limits
Verification
timeline-library-viewandsearch-library-viewmedium specs (12: each view, bucket counts, statistics, the Photos album filter, a stack split across views, the refusals);/search/optionsunder each view against/timeline/buckets, each view cached on its own; the controller passing the view on and refusing an unknown one; the unit suite (6940) and the utils, search options and library view medium suites (287).check:svelteandtscclean.server/src/queries/*.sqlunchanged; the OpenAPI spec and the SDK regenerated.Seen while testing, not changed here
On mobile, switching the view in the "All" grid swaps the timeline service while the previous rows are still on screen (the segments keep their last value while the new buckets load). Those rows ask the new service for assets before it knows its count, so
TimelineService.getAssetsthrows and the error is logged until the grid redraws. I left it for a separate fix: the row should notrequireDataa failed load, andAsyncMutexshould not hand a failed operation's error to the next one.Upstream files: grew
server/src/dtos/time-bucket.dto.ts.extendserver/src/repositories/asset.repository.tsserver/src/repositories/search.repository.tsweb/src/lib/services/asset.service.tsweb/src/routes/(user)/photos/[[assetId=id]]/+page.sveltemobile/lib/presentation/pages/dev/main_timeline.page.dartmobile/lib/presentation/widgets/timeline/timeline.widget.dartmobile/lib/domain/models/store.model.dartmobile/lib/infrastructure/repositories/timeline.repository.dartmobile/lib/domain/services/timeline.service.dartserver/src/services/timeline.service.tsis untouched.