about summary refs log tree commit diff
path: root/src/state/models/ui
diff options
context:
space:
mode:
Diffstat (limited to 'src/state/models/ui')
-rw-r--r--src/state/models/ui/my-feeds.ts157
-rw-r--r--src/state/models/ui/preferences.ts31
-rw-r--r--src/state/models/ui/profile.ts7
3 files changed, 187 insertions, 8 deletions
diff --git a/src/state/models/ui/my-feeds.ts b/src/state/models/ui/my-feeds.ts
new file mode 100644
index 000000000..f9ad06f77
--- /dev/null
+++ b/src/state/models/ui/my-feeds.ts
@@ -0,0 +1,157 @@
+import {makeAutoObservable} from 'mobx'
+import {FeedsDiscoveryModel} from '../discovery/feeds'
+import {CustomFeedModel} from '../feeds/custom-feed'
+import {RootStoreModel} from '../root-store'
+
+export type MyFeedsItem =
+  | {
+      _reactKey: string
+      type: 'spinner'
+    }
+  | {
+      _reactKey: string
+      type: 'discover-feeds-loading'
+    }
+  | {
+      _reactKey: string
+      type: 'error'
+      error: string
+    }
+  | {
+      _reactKey: string
+      type: 'saved-feeds-header'
+    }
+  | {
+      _reactKey: string
+      type: 'saved-feed'
+      feed: CustomFeedModel
+    }
+  | {
+      _reactKey: string
+      type: 'saved-feeds-load-more'
+    }
+  | {
+      _reactKey: string
+      type: 'discover-feeds-header'
+    }
+  | {
+      _reactKey: string
+      type: 'discover-feeds-no-results'
+    }
+  | {
+      _reactKey: string
+      type: 'discover-feed'
+      feed: CustomFeedModel
+    }
+
+export class MyFeedsUIModel {
+  discovery: FeedsDiscoveryModel
+
+  constructor(public rootStore: RootStoreModel) {
+    makeAutoObservable(this)
+    this.discovery = new FeedsDiscoveryModel(this.rootStore)
+  }
+
+  get saved() {
+    return this.rootStore.me.savedFeeds
+  }
+
+  get isRefreshing() {
+    return !this.saved.isLoading && this.saved.isRefreshing
+  }
+
+  get isLoading() {
+    return this.saved.isLoading || this.discovery.isLoading
+  }
+
+  async setup() {
+    if (!this.saved.hasLoaded) {
+      await this.saved.refresh()
+    }
+    if (!this.discovery.hasLoaded) {
+      await this.discovery.refresh()
+    }
+  }
+
+  async refresh() {
+    return Promise.all([this.saved.refresh(), this.discovery.refresh()])
+  }
+
+  async loadMore() {
+    return this.discovery.loadMore()
+  }
+
+  get items() {
+    let items: MyFeedsItem[] = []
+
+    items.push({
+      _reactKey: '__saved_feeds_header__',
+      type: 'saved-feeds-header',
+    })
+    if (this.saved.isLoading) {
+      items.push({
+        _reactKey: '__saved_feeds_loading__',
+        type: 'spinner',
+      })
+    } else if (this.saved.hasError) {
+      items.push({
+        _reactKey: '__saved_feeds_error__',
+        type: 'error',
+        error: this.saved.error,
+      })
+    } else {
+      const savedSorted = this.saved.all
+        .slice()
+        .sort((a, b) => a.displayName.localeCompare(b.displayName))
+      items = items.concat(
+        savedSorted.map(feed => ({
+          _reactKey: `saved-${feed.uri}`,
+          type: 'saved-feed',
+          feed,
+        })),
+      )
+      items.push({
+        _reactKey: '__saved_feeds_load_more__',
+        type: 'saved-feeds-load-more',
+      })
+    }
+
+    items.push({
+      _reactKey: '__discover_feeds_header__',
+      type: 'discover-feeds-header',
+    })
+    if (this.discovery.isLoading && !this.discovery.hasContent) {
+      items.push({
+        _reactKey: '__discover_feeds_loading__',
+        type: 'discover-feeds-loading',
+      })
+    } else if (this.discovery.hasError) {
+      items.push({
+        _reactKey: '__discover_feeds_error__',
+        type: 'error',
+        error: this.discovery.error,
+      })
+    } else if (this.discovery.isEmpty) {
+      items.push({
+        _reactKey: '__discover_feeds_no_results__',
+        type: 'discover-feeds-no-results',
+      })
+    } else {
+      items = items.concat(
+        this.discovery.feeds.map(feed => ({
+          _reactKey: `discover-${feed.uri}`,
+          type: 'discover-feed',
+          feed,
+        })),
+      )
+      if (this.discovery.isLoading) {
+        items.push({
+          _reactKey: '__discover_feeds_loading_more__',
+          type: 'spinner',
+        })
+      }
+    }
+
+    return items
+  }
+}
diff --git a/src/state/models/ui/preferences.ts b/src/state/models/ui/preferences.ts
index 64ab4ecba..7232a7b74 100644
--- a/src/state/models/ui/preferences.ts
+++ b/src/state/models/ui/preferences.ts
@@ -50,9 +50,11 @@ export class PreferencesModel {
   pinnedFeeds: string[] = []
   birthDate: Date | undefined = undefined
   homeFeedRepliesEnabled: boolean = true
-  homeFeedRepliesThreshold: number = 2
+  homeFeedRepliesByFollowedOnlyEnabled: boolean = true
+  homeFeedRepliesThreshold: number = 0
   homeFeedRepostsEnabled: boolean = true
   homeFeedQuotePostsEnabled: boolean = true
+  homeFeedMergeFeedEnabled: boolean = false
   requireAltTextEnabled: boolean = false
 
   // used to linearize async modifications to state
@@ -78,9 +80,12 @@ export class PreferencesModel {
       savedFeeds: this.savedFeeds,
       pinnedFeeds: this.pinnedFeeds,
       homeFeedRepliesEnabled: this.homeFeedRepliesEnabled,
+      homeFeedRepliesByFollowedOnlyEnabled:
+        this.homeFeedRepliesByFollowedOnlyEnabled,
       homeFeedRepliesThreshold: this.homeFeedRepliesThreshold,
       homeFeedRepostsEnabled: this.homeFeedRepostsEnabled,
       homeFeedQuotePostsEnabled: this.homeFeedQuotePostsEnabled,
+      homeFeedMergeFeedEnabled: this.homeFeedMergeFeedEnabled,
       requireAltTextEnabled: this.requireAltTextEnabled,
     }
   }
@@ -148,6 +153,14 @@ export class PreferencesModel {
       ) {
         this.homeFeedRepliesEnabled = v.homeFeedRepliesEnabled
       }
+      // check if home feed replies "followed only" are enabled in preferences, then hydrate
+      if (
+        hasProp(v, 'homeFeedRepliesByFollowedOnlyEnabled') &&
+        typeof v.homeFeedRepliesByFollowedOnlyEnabled === 'boolean'
+      ) {
+        this.homeFeedRepliesByFollowedOnlyEnabled =
+          v.homeFeedRepliesByFollowedOnlyEnabled
+      }
       // check if home feed replies threshold is enabled in preferences, then hydrate
       if (
         hasProp(v, 'homeFeedRepliesThreshold') &&
@@ -169,6 +182,13 @@ export class PreferencesModel {
       ) {
         this.homeFeedQuotePostsEnabled = v.homeFeedQuotePostsEnabled
       }
+      // check if home feed mergefeed is enabled in preferences, then hydrate
+      if (
+        hasProp(v, 'homeFeedMergeFeedEnabled') &&
+        typeof v.homeFeedMergeFeedEnabled === 'boolean'
+      ) {
+        this.homeFeedMergeFeedEnabled = v.homeFeedMergeFeedEnabled
+      }
       // check if requiring alt text is enabled in preferences, then hydrate
       if (
         hasProp(v, 'requireAltTextEnabled') &&
@@ -449,6 +469,11 @@ export class PreferencesModel {
     this.homeFeedRepliesEnabled = !this.homeFeedRepliesEnabled
   }
 
+  toggleHomeFeedRepliesByFollowedOnlyEnabled() {
+    this.homeFeedRepliesByFollowedOnlyEnabled =
+      !this.homeFeedRepliesByFollowedOnlyEnabled
+  }
+
   setHomeFeedRepliesThreshold(threshold: number) {
     this.homeFeedRepliesThreshold = threshold
   }
@@ -461,6 +486,10 @@ export class PreferencesModel {
     this.homeFeedQuotePostsEnabled = !this.homeFeedQuotePostsEnabled
   }
 
+  toggleHomeFeedMergeFeedEnabled() {
+    this.homeFeedMergeFeedEnabled = !this.homeFeedMergeFeedEnabled
+  }
+
   toggleRequireAltTextEnabled() {
     this.requireAltTextEnabled = !this.requireAltTextEnabled
   }
diff --git a/src/state/models/ui/profile.ts b/src/state/models/ui/profile.ts
index 11951b0ee..8525426bf 100644
--- a/src/state/models/ui/profile.ts
+++ b/src/state/models/ui/profile.ts
@@ -240,13 +240,6 @@ export class ProfileUiModel {
       .catch(err => this.rootStore.log.error('Failed to fetch lists', err))
   }
 
-  async update() {
-    const view = this.currentView
-    if (view instanceof PostsFeedModel) {
-      await view.update()
-    }
-  }
-
   async refresh() {
     await Promise.all([this.profile.refresh(), this.currentView.refresh()])
   }