Update saved feeds to use preferences
parent
acea0e074d
commit
5537d19e55
|
@ -38,7 +38,7 @@ export class CustomFeedModel {
|
|||
}
|
||||
|
||||
get isSaved() {
|
||||
return this.data.viewer?.saved
|
||||
return this.rootStore.preferences.savedFeeds.includes(this.uri)
|
||||
}
|
||||
|
||||
get isLiked() {
|
||||
|
@ -49,23 +49,11 @@ export class CustomFeedModel {
|
|||
// =
|
||||
|
||||
async save() {
|
||||
await this.rootStore.agent.app.bsky.feed.saveFeed({
|
||||
feed: this.uri,
|
||||
})
|
||||
runInAction(() => {
|
||||
this.data.viewer = this.data.viewer || {}
|
||||
this.data.viewer.saved = true
|
||||
})
|
||||
await this.rootStore.preferences.addSavedFeed(this.uri)
|
||||
}
|
||||
|
||||
async unsave() {
|
||||
await this.rootStore.agent.app.bsky.feed.unsaveFeed({
|
||||
feed: this.uri,
|
||||
})
|
||||
runInAction(() => {
|
||||
this.data.viewer = this.data.viewer || {}
|
||||
this.data.viewer.saved = false
|
||||
})
|
||||
await this.rootStore.preferences.removeSavedFeed(this.uri)
|
||||
}
|
||||
|
||||
async like() {
|
||||
|
@ -82,7 +70,7 @@ export class CustomFeedModel {
|
|||
}
|
||||
|
||||
async unlike() {
|
||||
if (!this.data.viewer.like) {
|
||||
if (!this.data.viewer?.like) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
|
|
|
@ -135,7 +135,7 @@ export class ImageModel implements RNImage {
|
|||
// Only for mobile
|
||||
async crop() {
|
||||
try {
|
||||
const cropped = await openCropper({
|
||||
const cropped = await openCropper(this.rootStore, {
|
||||
mediaType: 'photo',
|
||||
path: this.path,
|
||||
freeStyleCropEnabled: true,
|
||||
|
|
|
@ -46,6 +46,7 @@ export class PreferencesModel {
|
|||
contentLanguages: string[] =
|
||||
deviceLocales?.map?.(locale => locale.languageCode) || []
|
||||
contentLabels = new LabelPreferencesModel()
|
||||
savedFeeds: string[] = []
|
||||
pinnedFeeds: string[] = []
|
||||
|
||||
constructor(public rootStore: RootStoreModel) {
|
||||
|
@ -56,6 +57,7 @@ export class PreferencesModel {
|
|||
return {
|
||||
contentLanguages: this.contentLanguages,
|
||||
contentLabels: this.contentLabels,
|
||||
savedFeeds: this.savedFeeds,
|
||||
pinnedFeeds: this.pinnedFeeds,
|
||||
}
|
||||
}
|
||||
|
@ -75,6 +77,13 @@ export class PreferencesModel {
|
|||
// default to the device languages
|
||||
this.contentLanguages = deviceLocales.map(locale => locale.languageCode)
|
||||
}
|
||||
if (
|
||||
hasProp(v, 'savedFeeds') &&
|
||||
Array.isArray(v.savedFeeds) &&
|
||||
typeof v.savedFeeds.every(item => typeof item === 'string')
|
||||
) {
|
||||
this.savedFeeds = v.savedFeeds
|
||||
}
|
||||
if (
|
||||
hasProp(v, 'pinnedFeeds') &&
|
||||
Array.isArray(v.pinnedFeeds) &&
|
||||
|
@ -106,10 +115,11 @@ export class PreferencesModel {
|
|||
pref.visibility as LabelPreference
|
||||
}
|
||||
} else if (
|
||||
AppBskyActorDefs.isPinnedFeedsPref(pref) &&
|
||||
AppBskyActorDefs.validatePinnedFeedsPref(pref).success
|
||||
AppBskyActorDefs.isSavedFeedsPref(pref) &&
|
||||
AppBskyActorDefs.validateSavedFeedsPref(pref).success
|
||||
) {
|
||||
this.pinnedFeeds = pref.feeds
|
||||
this.savedFeeds = pref.saved
|
||||
this.pinnedFeeds = pref.pinned
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -220,38 +230,57 @@ export class PreferencesModel {
|
|||
return res
|
||||
}
|
||||
|
||||
async setPinnedFeeds(v: string[]) {
|
||||
const old = this.pinnedFeeds
|
||||
this.pinnedFeeds = v
|
||||
async setSavedFeeds(saved: string[], pinned: string[]) {
|
||||
const oldSaved = this.savedFeeds
|
||||
const oldPinned = this.pinnedFeeds
|
||||
this.savedFeeds = saved
|
||||
this.pinnedFeeds = pinned
|
||||
try {
|
||||
await this.update((prefs: AppBskyActorDefs.Preferences) => {
|
||||
const existing = prefs.find(
|
||||
pref =>
|
||||
AppBskyActorDefs.isPinnedFeedsPref(pref) &&
|
||||
AppBskyActorDefs.validatePinnedFeedsPref(pref).success,
|
||||
AppBskyActorDefs.isSavedFeedsPref(pref) &&
|
||||
AppBskyActorDefs.validateSavedFeedsPref(pref).success,
|
||||
)
|
||||
if (existing) {
|
||||
existing.feeds = v
|
||||
existing.saved = saved
|
||||
existing.pinned = pinned
|
||||
} else {
|
||||
prefs.push({
|
||||
$type: 'app.bsky.actor.defs#pinnedFeedsPref',
|
||||
feeds: v,
|
||||
$type: 'app.bsky.actor.defs#savedFeedsPref',
|
||||
saved,
|
||||
pinned,
|
||||
})
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
runInAction(() => {
|
||||
this.pinnedFeeds = old
|
||||
this.savedFeeds = oldSaved
|
||||
this.pinnedFeeds = oldPinned
|
||||
})
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
async addSavedFeed(v: string) {
|
||||
return this.setSavedFeeds([...this.savedFeeds, v], this.pinnedFeeds)
|
||||
}
|
||||
|
||||
async removeSavedFeed(v: string) {
|
||||
return this.setSavedFeeds(
|
||||
this.savedFeeds.filter(uri => uri !== v),
|
||||
this.pinnedFeeds.filter(uri => uri !== v),
|
||||
)
|
||||
}
|
||||
|
||||
async addPinnedFeed(v: string) {
|
||||
return this.setPinnedFeeds([...this.pinnedFeeds, v])
|
||||
return this.setSavedFeeds(this.savedFeeds, [...this.pinnedFeeds, v])
|
||||
}
|
||||
|
||||
async removePinnedFeed(v: string) {
|
||||
return this.setPinnedFeeds(this.pinnedFeeds.filter(uri => uri !== v))
|
||||
return this.setSavedFeeds(
|
||||
this.savedFeeds,
|
||||
this.pinnedFeeds.filter(uri => uri !== v),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,6 @@ import {bundleAsync} from 'lib/async/bundle'
|
|||
import {cleanError} from 'lib/strings/errors'
|
||||
import {CustomFeedModel} from '../feeds/custom-feed'
|
||||
|
||||
const PAGE_SIZE = 100
|
||||
|
||||
export class SavedFeedsModel {
|
||||
// state
|
||||
isLoading = false
|
||||
|
@ -69,16 +67,15 @@ export class SavedFeedsModel {
|
|||
try {
|
||||
let feeds: AppBskyFeedDefs.GeneratorView[] = []
|
||||
let cursor
|
||||
for (let i = 0; i < 100; i++) {
|
||||
const res = await this.rootStore.agent.app.bsky.feed.getSavedFeeds({
|
||||
limit: PAGE_SIZE,
|
||||
cursor,
|
||||
for (
|
||||
let i = 0;
|
||||
i < this.rootStore.preferences.savedFeeds.length;
|
||||
i += 25
|
||||
) {
|
||||
const res = await this.rootStore.agent.app.bsky.feed.getFeedGenerators({
|
||||
feeds: this.rootStore.preferences.savedFeeds.slice(i, 25),
|
||||
})
|
||||
feeds = feeds.concat(res.data.feeds)
|
||||
cursor = res.data.cursor
|
||||
if (!cursor) {
|
||||
break
|
||||
}
|
||||
}
|
||||
runInAction(() => {
|
||||
this.feeds = feeds.map(f => new CustomFeedModel(this.rootStore, f))
|
||||
|
@ -127,7 +124,8 @@ export class SavedFeedsModel {
|
|||
}
|
||||
|
||||
async reorderPinnedFeeds(feeds: CustomFeedModel[]) {
|
||||
return this.rootStore.preferences.setPinnedFeeds(
|
||||
return this.rootStore.preferences.setSavedFeeds(
|
||||
this.rootStore.preferences.savedFeeds,
|
||||
feeds.filter(feed => this.isPinned(feed)).map(feed => feed.uri),
|
||||
)
|
||||
}
|
||||
|
@ -151,7 +149,10 @@ export class SavedFeedsModel {
|
|||
pinned[index] = pinned[index + 1]
|
||||
pinned[index + 1] = temp
|
||||
}
|
||||
await this.rootStore.preferences.setPinnedFeeds(pinned)
|
||||
await this.rootStore.preferences.setSavedFeeds(
|
||||
this.rootStore.preferences.savedFeeds,
|
||||
pinned,
|
||||
)
|
||||
}
|
||||
|
||||
// state transitions
|
||||
|
|
|
@ -119,7 +119,7 @@ export type Modal =
|
|||
// Moderation
|
||||
| ReportAccountModal
|
||||
| ReportPostModal
|
||||
| CreateMuteListModal
|
||||
| CreateOrEditMuteListModal
|
||||
| ListAddRemoveUserModal
|
||||
|
||||
// Posts
|
||||
|
|
|
@ -40,7 +40,7 @@ export const CustomFeed = observer(
|
|||
const navigation = useNavigation<NavigationProp>()
|
||||
|
||||
const onToggleSaved = React.useCallback(async () => {
|
||||
if (item.data.viewer?.saved) {
|
||||
if (item.isSaved) {
|
||||
store.shell.openModal({
|
||||
name: 'confirm',
|
||||
title: 'Remove from my feeds',
|
||||
|
|
|
@ -121,7 +121,7 @@ const Container = observer(
|
|||
}: {
|
||||
children: React.ReactNode
|
||||
hideOnScroll: boolean
|
||||
showBorder: boolean
|
||||
showBorder?: boolean
|
||||
}) => {
|
||||
const store = useStores()
|
||||
const pal = usePalette('default')
|
||||
|
|
|
@ -27,6 +27,10 @@ export function ImageHider({
|
|||
setOverride(false)
|
||||
}, [setOverride])
|
||||
|
||||
if (moderation.behavior === ModerationBehaviorCode.Hide) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (moderation.behavior !== ModerationBehaviorCode.WarnImages) {
|
||||
return (
|
||||
<View testID={testID} style={style}>
|
||||
|
@ -35,10 +39,6 @@ export function ImageHider({
|
|||
)
|
||||
}
|
||||
|
||||
if (moderation.behavior === ModerationBehaviorCode.Hide) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={[styles.container, containerStyle]}>
|
||||
<View testID={testID} style={style}>
|
||||
|
|
Loading…
Reference in New Issue