44 */
55import type { IFileListFilterChip , INode } from '@nextcloud/files'
66
7+ import { subscribe } from '@nextcloud/event-bus'
78import { FileListFilter , registerFileListFilter } from '@nextcloud/files'
9+ import { ShareType } from '@nextcloud/sharing'
810import Vue from 'vue'
11+
912import FileListFilterAccount from '../components/FileListFilterAccount.vue'
1013
1114export interface IAccountData {
1215 uid : string
1316 displayName : string
1417}
1518
16- type CurrentInstance = Vue & { resetFilter : ( ) => void , toggleAccount : ( account : string ) => void }
19+ type CurrentInstance = Vue & {
20+ resetFilter : ( ) => void
21+ setAvailableAccounts : ( accounts : IAccountData [ ] ) => void
22+ toggleAccount : ( account : string ) => void
23+ }
1724
1825/**
1926 * File list filter to filter by owner / sharee
2027 */
2128class AccountFilter extends FileListFilter {
2229
30+ private availableAccounts : IAccountData [ ]
2331 private currentInstance ?: CurrentInstance
2432 private filterAccounts ?: IAccountData [ ]
2533
2634 constructor ( ) {
2735 super ( 'files_sharing:account' , 100 )
36+ this . availableAccounts = [ ]
37+
38+ subscribe ( 'files:list:updated' , ( { contents } ) => {
39+ this . updateAvailableAccounts ( contents )
40+ } )
2841 }
2942
3043 public mount ( el : HTMLElement ) {
@@ -33,11 +46,11 @@ class AccountFilter extends FileListFilter {
3346 }
3447
3548 const View = Vue . extend ( FileListFilterAccount as never )
36- this . currentInstance = new View ( {
37- el,
38- } )
39- . $on ( 'update:accounts' , this . setAccounts . bind ( this ) )
49+ this . currentInstance = new View ( { el } )
50+ . $on ( 'update:accounts' , ( accounts ?: IAccountData [ ] ) => this . setAccounts ( accounts ) )
4051 . $mount ( ) as CurrentInstance
52+ this . currentInstance
53+ . setAvailableAccounts ( this . availableAccounts )
4154 }
4255
4356 public filter ( nodes : INode [ ] ) : INode [ ] {
@@ -70,6 +83,11 @@ class AccountFilter extends FileListFilter {
7083 this . currentInstance ?. resetFilter ( )
7184 }
7285
86+ /**
87+ * Set accounts that should be filtered.
88+ *
89+ * @param accounts - Account to filter or undefined if inactive.
90+ */
7391 public setAccounts ( accounts ?: IAccountData [ ] ) {
7492 this . filterAccounts = accounts
7593 let chips : IFileListFilterChip [ ] = [ ]
@@ -85,6 +103,49 @@ class AccountFilter extends FileListFilter {
85103 this . filterUpdated ( )
86104 }
87105
106+ /**
107+ * Update the accounts owning nodes or have nodes shared to them.
108+ *
109+ * @param nodes - The current content of the file list.
110+ */
111+ protected updateAvailableAccounts ( nodes : INode [ ] ) : void {
112+ const available = new Map < string , IAccountData > ( )
113+
114+ for ( const node of nodes ) {
115+ const owner = node . owner
116+ if ( owner && ! available . has ( owner ) ) {
117+ available . set ( owner , {
118+ uid : owner ,
119+ displayName : node . attributes [ 'owner-display-name' ] ?? node . owner ,
120+ } )
121+ }
122+
123+ // ensure sharees is an array (if only one share then it is just an object)
124+ const sharees : { id : string , 'display-name' : string , type : ShareType } [ ] = [ node . attributes . sharees ?. sharee ] . flat ( ) . filter ( Boolean )
125+ for ( const sharee of [ sharees ] . flat ( ) ) {
126+ // Skip link shares and other without user
127+ if ( sharee . id === '' ) {
128+ continue
129+ }
130+ if ( sharee . type !== ShareType . User && sharee . type !== ShareType . Remote ) {
131+ continue
132+ }
133+ // Add if not already added
134+ if ( ! available . has ( sharee . id ) ) {
135+ available . set ( sharee . id , {
136+ uid : sharee . id ,
137+ displayName : sharee [ 'display-name' ] ,
138+ } )
139+ }
140+ }
141+ }
142+
143+ this . availableAccounts = [ ...available . values ( ) ]
144+ if ( this . currentInstance ) {
145+ this . currentInstance . setAvailableAccounts ( this . availableAccounts )
146+ }
147+ }
148+
88149}
89150
90151/**
0 commit comments