Skip to content
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

feat: folder view #11880

Merged
merged 45 commits into from
Aug 21, 2024
Merged

feat: folder view #11880

merged 45 commits into from
Aug 21, 2024

Conversation

davidakerr
Copy link
Contributor

@davidakerr davidakerr commented Aug 18, 2024

A quick exploration into the possibilities of folder view, full thread here #5409 (comment)

Todo's

  • Design

    • Designs mockups
    • Designs Implemented in tailwind/svelte
  • Core Functionality

    • Inline Folder Thumbnail Icons (and back to previous folder icon)
    • Reuse Thumbnail Display Components
    • On-Click Image Display (like photos and photos/:id)
    • Image/Folder Multi Select Actions (Create Album, Delete, etc)
    • getAssetsByOriginalPath function should return only images directly in that path, not all images from that path down
    • Gather External Library root folders, remove unnecessary absolute pathing from begining [1] [2]
    • Move server logic to folder.*.ts rather than asset.*.ts ?
    • Redis caching ? (currently mocked out as svelte store with caching)
      • Folder Structure
      • Path Asset Searches
      • Cache invalidation on relevant library modifications

Any more todo items I can add them in here, if you add them to the comments.

Screenshots

Light mode Dark mode
light dark

@alextran1502
Copy link
Contributor

FYI, we use tailwindcss, so you don't have to create custom CSS classes

Endpoint now only returns direct children of the path instead of all images in all subfolders.  Functions renamed and scoped to "folder", endpoints renamed
@xttlegendapi
Copy link

xttlegendapi commented Aug 18, 2024

It looks very promising!
External libraries where not showing up at all first. but now after our latest commits external libraries are showing in the sidebar but not in the main view
(edit:you probably know about it already sorry, but the pr looks great and the path to full implementation very clear now)
screenshot

@davidakerr
Copy link
Contributor Author

It looks very promising! External libraries where not showing up at all first. but now after our latest commits external libraries are showing in the sidebar but not in the main view...

Good catch, I should have tested this. Try it now. Thanks @xttlegendapi ❤️

@etnoy
Copy link
Contributor

etnoy commented Aug 18, 2024

Haven't had the opportunity to review this very much but YES I want this feature

@benmccann
Copy link
Contributor

In terms of UI, I think one thing that could make it a bit cleaner is not having so many folder icons. Maybe we could look at Synology Photos for inspiration which uses arrow characters - those also helps differentiate which folders are expanded vs not. They also use a non-bold font for the folder names, which I think would be worth testing as well

https://www.synology.com/img/beta/dsm70/photos/[email protected]

@davidakerr davidakerr changed the title feat: folder view poc feat: folder view Aug 19, 2024
@alextran1502 alextran1502 marked this pull request as ready for review August 20, 2024 22:43
Copy link
Member

Choose a reason for hiding this comment

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

Those changes are unrelated - can we revert them?

Copy link
Contributor

Choose a reason for hiding this comment

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

I purposely do this so we can mount external for dev environment easily without the need of tracking the docker-compose.dev.yml changes

Copy link
Member

Choose a reason for hiding this comment

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

Hm ok, I wouldn't mount them at /home/user then though, that feels weird to me

Copy link
Contributor

Choose a reason for hiding this comment

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

just an arbitrary path, we can have anything there 😄

constructor(private service: ViewService) {}

@Get('folder/unique-paths')
@Authenticated()
Copy link
Member

Choose a reason for hiding this comment

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

Those should probably have specific permissions. FOLDER_READ?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think asset.read is fine. The data is just asset.originalPath which is covered by asset.read

});

const results = await builder
.select("DISTINCT substring(asset.originalPath FROM '^(.*/)[^/]*$')", 'directoryPath')
Copy link
Member

Choose a reason for hiding this comment

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

This is supposed to capture everything until the last slash? I don't have experience with databases and I haven't seen a plan but this looks very slow to me.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I presumed it would be quicker to do it in the DB query rather than fetching all assets and producing a Set with JS

Copy link
Contributor

Choose a reason for hiding this comment

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

I think we just need to make sure this is using an index and not doing a full table scan.

.select("DISTINCT substring(asset.originalPath FROM '^(.*/)[^/]*$')", 'directoryPath')
.getRawMany();

return results.map((row: { directoryPath: string }) => row.directoryPath.replace(/^\/|\/$/g, ''));
Copy link
Member

Choose a reason for hiding this comment

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

This regex looks wrong. We're replacing / or /? Why not just /? Also, you probably don't want start (^) and end (^) there without any wildcards

);
}),
)
.orderBy("regexp_replace(asset.originalPath, '.*/(.+)', '\\1')", 'ASC')
Copy link
Member

Choose a reason for hiding this comment

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

Same question/comment here

server/src/services/view.service.spec.ts Outdated Show resolved Hide resolved
const parts = path.split('/');
let current = root;
for (const part of parts) {
if (!current[part]) {
Copy link
Member

Choose a reason for hiding this comment

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

!{} is also true, which makes this a bit weird imo. I think we should be more explicit here by writing current[part] === undefined

Copy link
Contributor Author

@davidakerr davidakerr Aug 20, 2024

Choose a reason for hiding this comment

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

> !{}
false

Being explicit is nice though. The code doesn't set the value to undefined, so that would need to be augmented also.

Copy link
Member

Choose a reason for hiding this comment

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

Oh huh, that's weird.

server/src/services/view.service.ts Outdated Show resolved Hide resolved
server/src/services/view.service.ts Outdated Show resolved Hide resolved
@alextran1502 alextran1502 merged commit 0753829 into immich-app:main Aug 21, 2024
23 checks passed
aviv926 added a commit to aviv926/immich that referenced this pull request Aug 22, 2024
jrasm91 added a commit that referenced this pull request Aug 28, 2024
* Documentation updates

* PR feedback

* PR feedback

* Originally implemented using #11880

* add to FAQ

* Remove mTLS

---------

Co-authored-by: Jason Rasmussen <[email protected]>
calvinbui added a commit to calvinbui/ansible-monorepo that referenced this pull request Sep 1, 2024
…0 (#2857)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [ghcr.io/immich-app/immich-machine-learning](https://github.com/immich-app/immich) | minor | `v1.112.1-cuda` -> `v1.113.0-cuda` |
| [ghcr.io/immich-app/immich-server](https://github.com/immich-app/immich) | minor | `v1.112.1` -> `v1.113.0` |

---

### Release Notes

<details>
<summary>immich-app/immich (ghcr.io/immich-app/immich-machine-learning)</summary>

### [`v1.113.0`](https://github.com/immich-app/immich/releases/tag/v1.113.0)

[Compare Source](immich-app/immich@v1.112.1...v1.113.0)

##### v1.113.0

> \[!WARNING]
>
> ## Breaking changes
>
> For **OAuth users**, please replace `app.immich:/` with `app.immich:///oauth-callback` for the Redirect URI in your OAuth provider settings

##### Highlights

Welcome to release `v1.113.0` of Immich! This is one of the biggest releases yet, introducing some of the most requested features since the early days of Immich. Let's dive right into what we have in place for this release:

-   Folder view
-   Tags
-   Timeline improvements
-   Library refresh stability
-   Mobile album sync

##### Folder view

You can now browse your photos and videos by folder like in a file explorer. You can use the storage template migration feature for the best experience with uploaded assets in this view.

This feature is especially useful for scanned photos, which are difficult to put in a timeline. It has been a long-requested feature.

You can enable this feature from the `Users Settings > Features > Folders`.

![folder-enabled](https://github.com/user-attachments/assets/aab4a16a-0888-49de-b51a-785ef557261a)

The UI is currently only available for the web; mobile will come in a subsequent release.

![folder](https://github.com/user-attachments/assets/2786da30-83b3-4168-bb98-180dad53a6a4)

![folder-2](https://github.com/user-attachments/assets/163a3ee8-3c3d-4c98-abb6-9c94eb4b362c)

##### Tags

Immich now supports hierarchical tags, with the ability to read existing tags from the `TagList` and `Keywords` exif properties. Any changes to tags made through Immich are also written back to a sidecar file. You can re-run the metadata extraction jobs for all assets to import your existing tags.

You can enable this feature from the `Users Settings > Features > Tags`.

![tag-enabled](https://github.com/user-attachments/assets/20a7a99e-13f6-46f2-8744-20dd95d8456b)

The UI is currently only available for the web; mobile will come in a subsequent release.

https://github.com/user-attachments/assets/d543f531-4b0e-4dcf-8918-e76c7f1b288b

##### Timeline improvements

This release introduces a rewrite of the web timeline component. It can now handle a large number of assets in a single day or month and has been successfully tested with a very large data set (over a million assets). Photographers frequently request this since they can easily take thousands of photos in a given day.

With these performance improvements, you'll see fewer placeholders while loading, which will make for a more fluid scrolling and scrubbing experience.

##### Library refresh stability

In relation to the previous point, the stability of library scanning has improved. Previously, you could run out of memory when starting a refresh with libraries containing millions of assets. Now, we queue the refresh jobs in batches. These enhancements won't make scanning go any faster, but they greatly reduce the likelihood of out-of-memory errors that would cause Immich to crash.

##### Mobile album sync

You can now sync or mirror an album from your phone to the Immich server on your account. For example, if you select `Recents`, `Camera` and `Videos` album for backup, the corresponding album with the same name will be created on the server. Once the assets from those albums are uploaded, they will be put into the target albums automatically.

You can enable this feature from the album selection in the backup screen.

<img src="https://github.com/user-attachments/assets/67b329f5-15ff-4128-af52-4a50df852a07" width="300" alt="sync-album"/>

For existing installations, you can sync the already uploaded assets by going to the backup screen and pressing the `Sync` button.

<img src="https://github.com/user-attachments/assets/ca0847fd-edab-4ebe-b8e1-093ce7e3cc37" width="300" alt="sync-button"/>

Have a wonderful weekend,

Cheers!

***

##### Support Immich

<p align="center">
<img src="https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExbjY2eWc5Y2F0ZW56MmR4aWE0dDhzZXlidXRmYWZyajl1bWZidXZpcyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/87CKDqErVfMqY/giphy.gif" width="450" title="SUPPORT THE PROJECT!">
</p>

If you find the project helpful, you can support Immich by purchasing a product key at <https://buy.immich.app>.

Cheers! 🍻

<!-- Release notes generated using configuration in .github/release.yml at main -->

##### What's Changed

##### 🚨 Breaking Changes

-   feat(server): granular permissions for api keys by [@&#8203;jrasm91](https://github.com/jrasm91) in immich-app/immich#11824
-   refactor(server): stacks by [@&#8203;jrasm91](https://github.com/jrasm91) in immich-app/immich#11453
-   fix(server): album statistics endpoint by [@&#8203;jrasm91](https://github.com/jrasm91) in immich-app/immich#11924
-   fix: remove `asset.resized` by [@&#8203;jrasm91](https://github.com/jrasm91) in immich-app/immich#11983
-   fix(mobile): use a valid OAuth callback URL by [@&#8203;qrkourier](https://github.com/qrkourier) in immich-app/immich#10832

##### 🚀 Features

-   feat: folder view by [@&#8203;davidakerr](https://github.com/davidakerr) in immich-app/immich#11880
-   feat(web): Scroll to asset in gridview; increase gridview perf; reduce memory; scrollbar ticks in fixed position by [@&#8203;midzelis](https://github.com/midzelis) in immich-app/immich#10646
-   feat: loading screen, initSDK on bootstrap, fix FOUC for theme by [@&#8203;midzelis](https://github.com/midzelis) in immich-app/immich#10350
-   feat(mobile): preserve mobile album info on upload by [@&#8203;alextran1502](https://github.com/alextran1502) in immich-app/immich#11965
-   feat: tags by [@&#8203;jrasm91](https://github.com/jrasm91) in immich-app/immich#11980
-   feat(web): jump to timeline by [@&#8203;alextran1502](https://github.com/alextran1502) in immich-app/immich#12117

##### 🌟 Enhancements

-   feat(server): do not automatically download android motion videos by [@&#8203;jrasm91](https://github.com/jrasm91) in immich-app/immich#11774
-   feat(web): pasting coordinates by [@&#8203;michelheusschen](https://github.com/michelheusschen) in immich-app/immich#11866
-   feat(web): drag and drop or paste directories for upload by [@&#8203;simkli](https://github.com/simkli) in immich-app/immich#11879
-   feat(web): Left hand navigation for memories by [@&#8203;carlesalbasboix](https://github.com/carlesalbasboix) in immich-app/immich#11913
-   feat(web): my immich shortcut by [@&#8203;danieldietzler](https://github.com/danieldietzler) in immich-app/immich#12007
-   fix(web): show a clearer confirmation message when deleting an unnamed album by [@&#8203;Snowknight26](https://github.com/Snowknight26) in immich-app/immich#11988
-   feat(format): nrw format by [@&#8203;avsm](https://github.com/avsm) in immich-app/immich#12048
-   feat(web): restore scroll position on navigating back to search page by [@&#8203;alextran1502](https://github.com/alextran1502) in immich-app/immich#12042
-   feat(server): Storage template support album condition by [@&#8203;feyst](https://github.com/feyst) in immich-app/immich#12000
-   fix(mobile): Changes in the UI for the image editor pages by [@&#8203;Yuvi-raj-P](https://github.com/Yuvi-raj-P) in immich-app/immich#12018
-   feat(web): announce notifications to screen readers by [@&#8203;ben-basten](https://github.com/ben-basten) in immich-app/immich#12071
-   fix(server): don't crash when refreshing large libraries by [@&#8203;etnoy](https://github.com/etnoy) in immich-app/immich#7934
-   feat(server): sort images in duplicate groups by date by [@&#8203;GeoffreyFrogeye](https://github.com/GeoffreyFrogeye) in immich-app/immich#12094
-   feat(ml): support dynamic scaling by [@&#8203;rkojedzinszky](https://github.com/rkojedzinszky) in immich-app/immich#12065
-   feat(web): navigate assets with gestures (next/prev) by [@&#8203;kaziu687](https://github.com/kaziu687) in immich-app/immich#11888
-   fix(mobile): allow create empty non-shared albums, add proper button colors by [@&#8203;src52](https://github.com/src52) in immich-app/immich#12103
-   feat: user's features preferences by [@&#8203;alextran1502](https://github.com/alextran1502) in immich-app/immich#12099
-   chore(server): log path when generating external thumbnail by [@&#8203;etnoy](https://github.com/etnoy) in immich-app/immich#12107

##### 🐛 Bug fixes

-   fix(web): focus trap inside portal by [@&#8203;michelheusschen](https://github.com/michelheusschen) in immich-app/immich#11797
-   fix(mobile): show correct notification icon for android by [@&#8203;karthikraja001](https://github.com/karthikraja001) in immich-app/immich#11863
-   fix(web): show camera make in search options after searching by [@&#8203;michelheusschen](https://github.com/michelheusschen) in immich-app/immich#11884
-   fix(web): correctly populate the camera model search dropdown by [@&#8203;Snowknight26](https://github.com/Snowknight26) in immich-app/immich#11883
-   fix(server): create shared album from the mobile app does not trigger send email invite by [@&#8203;alextran1502](https://github.com/alextran1502) in immich-app/immich#11911
-   fix(server): do not match live photos across libraries by [@&#8203;jrasm91](https://github.com/jrasm91) in immich-app/immich#11952
-   fix(web): rating stars accessibility by [@&#8203;ben-basten](https://github.com/ben-basten) in immich-app/immich#11966
-   fix(mobile): Fix for incorrectly naming edited files and structure change by [@&#8203;Yuvi-raj-P](https://github.com/Yuvi-raj-P) in immich-app/immich#11741
-   fix: align camera model drop down behavior with other drop downs on web and mobile by [@&#8203;x24git](https://github.com/x24git) in immich-app/immich#11951
-   fix(web): announce current theme to screen reader users by [@&#8203;ben-basten](https://github.com/ben-basten) in immich-app/immich#12039
-   fix(web): show supporter badge for account less than 14 days by [@&#8203;alextran1502](https://github.com/alextran1502) in immich-app/immich#12058
-   fix(web): shared link expiration date accessibility by [@&#8203;ben-basten](https://github.com/ben-basten) in immich-app/immich#12060
-   chore(web): ignore shortcut toggle when entering email and password by [@&#8203;alextran1502](https://github.com/alextran1502) in immich-app/immich#12082
-   chore(web): ensure goto is awaited for login page by [@&#8203;alextran1502](https://github.com/alextran1502) in immich-app/immich#12087
-   fix(server): ensure new exclusion patterns work by [@&#8203;etnoy](https://github.com/etnoy) in immich-app/immich#12102
-   fix(server): skip smtp validation if unchanged by [@&#8203;michelheusschen](https://github.com/michelheusschen) in immich-app/immich#12111
-   fix(mobile): long waiting time for login request when server is unreachable by [@&#8203;alextran1502](https://github.com/alextran1502) in immich-app/immich#12100
-   fix: user specific fields in asset search by [@&#8203;jrasm91](https://github.com/jrasm91) in immich-app/immich#12125
-   fix(web): Device list shows Ubuntu as unknown OS by [@&#8203;spfncer](https://github.com/spfncer) in immich-app/immich#12127
-   fix(web): reset asset grid after changing album order by [@&#8203;michelheusschen](https://github.com/michelheusschen) in immich-app/immich#12139

##### 📚 Documentation

-   fix(docs): read-only affects XMP writing by [@&#8203;C-Otto](https://github.com/C-Otto) in immich-app/immich#11823
-   docs: clarify external domain setting by [@&#8203;pikapower9080](https://github.com/pikapower9080) in immich-app/immich#11958
-   docs: add Immich Kiosk and Immich Power Tools to Community Projects by [@&#8203;Tyree](https://github.com/Tyree) in immich-app/immich#12055
-   docs: mTLS/self signed FAQ entry by [@&#8203;mmomjian](https://github.com/mmomjian) in immich-app/immich#12074
-   docs: external library deletion/edits by [@&#8203;mmomjian](https://github.com/mmomjian) in immich-app/immich#12079
-   docs: sql query for duplicate files by [@&#8203;mmomjian](https://github.com/mmomjian) in immich-app/immich#12086
-   docs: Documentation updates by [@&#8203;aviv926](https://github.com/aviv926) in immich-app/immich#11516
-   docs: update roadmap by [@&#8203;jrasm91](https://github.com/jrasm91) in immich-app/immich#12126
-   fix: README_zh_CN.md link by [@&#8203;ttzytt](https://github.com/ttzytt) in immich-app/immich#12124
-   docs(guide): nginx caching proxy by [@&#8203;pcouy](https://github.com/pcouy) in immich-app/immich#12140

##### New Contributors

-   [@&#8203;aaronjrodrigues](https://github.com/aaronjrodrigues) made their first contribution in immich-app/immich#11851
-   [@&#8203;karthikraja001](https://github.com/karthikraja001) made their first contribution in immich-app/immich#11863
-   [@&#8203;simkli](https://github.com/simkli) made their first contribution in immich-app/immich#11879
-   [@&#8203;carlesalbasboix](https://github.com/carlesalbasboix) made their first contribution in immich-app/immich#11907
-   [@&#8203;pikapower9080](https://github.com/pikapower9080) made their first contribution in immich-app/immich#11958
-   [@&#8203;davidakerr](https://github.com/davidakerr) made their first contribution in immich-app/immich#11880
-   [@&#8203;x24git](https://github.com/x24git) made their first contribution in immich-app/immich#11951
-   [@&#8203;Tonux599](https://github.com/Tonux599) made their first contribution in immich-app/immich#12027
-   [@&#8203;avsm](https://github.com/avsm) made their first contribution in immich-app/immich#12048
-   [@&#8203;Tyree](https://github.com/Tyree) made their first contribution in immich-app/immich#12055
-   [@&#8203;feyst](https://github.com/feyst) made their first contribution in immich-app/immich#12000
-   [@&#8203;Tiefseetauchner](https://github.com/Tiefseetauchner) made their first contribution in immich-app/immich#11874
-   [@&#8203;qrkourier](https://github.com/qrkourier) made their first contribution in immich-app/immich#10832
-   [@&#8203;GeoffreyFrogeye](https://github.com/GeoffreyFrogeye) made their first contribution in immich-app/immich#12094
-   [@&#8203;rkojedzinszky](https://github.com/rkojedzinszky) made their first contribution in immich-app/immich#12065
-   [@&#8203;kaziu687](https://github.com/kaziu687) made their first contribution in immich-app/immich#11888
-   [@&#8203;src52](https://github.com/src52) made their first contribution in immich-app/immich#12103
-   [@&#8203;spfncer](https://github.com/spfncer) made their first contribution in immich-app/immich#12127
-   [@&#8203;ttzytt](https://github.com/ttzytt) made their first contribution in immich-app/immich#12124

**Full Changelog**: https://github.com/immich-app/immich/compare/v1.112.1...

</details>

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC41OC4wIiwidXBkYXRlZEluVmVyIjoiMzguNTguMCIsInRhcmdldEJyYW5jaCI6Im1hc3RlciIsImxhYmVscyI6W119-->

Co-authored-by: Renovate Bot <[email protected]>
Co-authored-by: Calvin Bui <[email protected]>
Reviewed-on: https://gitea.bui.ng/calvinbui/ansible-monorepo/pulls/2857
Co-authored-by: renovate <[email protected]>
Co-committed-by: renovate <[email protected]>
@cole21771
Copy link

This is such a great feature and helps so much with being able to view photos in external libraries! Is there any plans to add this to the mobile version?

@bo0tzz
Copy link
Member

bo0tzz commented Sep 9, 2024

Yes, mobile UI for this and the tags view is being worked on this week.

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.

9 participants