Hide account boosts

This commit is contained in:
Marcin Czachurski 2023-10-10 10:10:24 +02:00
parent 8721c9b1ca
commit 4d9ac983ad
14 changed files with 326 additions and 8 deletions

View File

@ -35,6 +35,7 @@ extension AccountData {
@NSManaged public var username: String
@NSManaged public var statuses: Set<StatusData>?
@NSManaged public var viewedStatuses: Set<ViewedStatus>?
@NSManaged public var accountRelationships: Set<AccountRelationship>?
@NSManaged public var lastSeenStatusId: String?
}
@ -64,6 +65,19 @@ extension AccountData {
@objc(removeViewedStatuses:)
@NSManaged public func removeFromViewedStatuses(_ values: NSSet)
@objc(addAccountRelationshipsObject:)
@NSManaged public func addToAccountRelationships(_ value: AccountRelationship)
@objc(removeAccountRelationshipsObject:)
@NSManaged public func removeFromVAccountRelationships(_ value: AccountRelationship)
@objc(addAccountRelationships:)
@NSManaged public func addToAccountRelationships(_ values: NSSet)
@objc(removeAccountRelationships:)
@NSManaged public func removeFromAccountRelationships(_ values: NSSet)
}
extension AccountData: Identifiable {

View File

@ -0,0 +1,12 @@
//
// https://mczachurski.dev
// Copyright © 2023 Marcin Czachurski and the repository contributors.
// Licensed under the Apache License 2.0.
//
import Foundation
import CoreData
@objc(AccountRelationship)
public class AccountRelationship: NSManagedObject {
}

View File

@ -0,0 +1,22 @@
//
// https://mczachurski.dev
// Copyright © 2023 Marcin Czachurski and the repository contributors.
// Licensed under the Apache License 2.0.
//
import Foundation
import CoreData
extension AccountRelationship {
@nonobjc public class func fetchRequest() -> NSFetchRequest<AccountRelationship> {
return NSFetchRequest<AccountRelationship>(entityName: "AccountRelationship")
}
@NSManaged public var accountId: String
@NSManaged public var boostedStatusesMuted: Bool
@NSManaged public var pixelfedAccount: AccountData
}
extension AccountRelationship: Identifiable {
}

View File

@ -0,0 +1,72 @@
//
// https://mczachurski.dev
// Copyright © 2023 Marcin Czachurski and the repository contributors.
// Licensed under the Apache License 2.0.
//
import Foundation
import CoreData
import PixelfedKit
class AccountRelationshipHandler {
public static let shared = AccountRelationshipHandler()
private init() { }
func createAccountRelationshipEntity(viewContext: NSManagedObjectContext? = nil) -> AccountRelationship {
let context = viewContext ?? CoreDataHandler.shared.container.viewContext
return AccountRelationship(context: context)
}
/// Check if boosted statuses from given account are muted.
func isBoostedStatusesMuted(accountId: String, status: Status, viewContext: NSManagedObjectContext? = nil) -> Bool {
if status.reblog == nil {
return false
}
let accountRelationship = self.getAccountRelationship(for: accountId, relation: status.account.id, viewContext: viewContext)
return accountRelationship?.boostedStatusesMuted ?? false
}
func isBoostedStatusesMuted(for accountId: String, relation relationAccountId: String, viewContext: NSManagedObjectContext? = nil) -> Bool {
let accountRelationship = self.getAccountRelationship(for: accountId, relation: relationAccountId, viewContext: viewContext)
return accountRelationship?.boostedStatusesMuted ?? false
}
func setBoostedStatusesMuted(for accountId: String, relation relationAccountId: String, boostedStatusesMuted: Bool, viewContext: NSManagedObjectContext? = nil) {
let context = viewContext ?? CoreDataHandler.shared.container.viewContext
var accountRelationship = self.getAccountRelationship(for: accountId, relation: relationAccountId, viewContext: context)
if accountRelationship == nil {
guard let accountDataFromDb = AccountDataHandler.shared.getAccountData(accountId: accountId, viewContext: context) else {
return
}
let newAccountRelationship = AccountRelationshipHandler.shared.createAccountRelationshipEntity(viewContext: context)
newAccountRelationship.accountId = relationAccountId
newAccountRelationship.pixelfedAccount = accountDataFromDb
accountDataFromDb.addToAccountRelationships(newAccountRelationship)
accountRelationship = newAccountRelationship
}
accountRelationship?.boostedStatusesMuted = boostedStatusesMuted
CoreDataHandler.shared.save(viewContext: context)
}
private func getAccountRelationship(for accountId: String, relation relationAccountId: String, viewContext: NSManagedObjectContext? = nil) -> AccountRelationship? {
let context = viewContext ?? CoreDataHandler.shared.container.viewContext
let fetchRequest = AccountRelationship.fetchRequest()
fetchRequest.fetchLimit = 1
let statusAccountIddPredicate = NSPredicate(format: "accountId = %@", relationAccountId)
let accountPredicate = NSPredicate(format: "pixelfedAccount.id = %@", accountId)
fetchRequest.predicate = NSCompoundPredicate.init(type: .and, subpredicates: [statusAccountIddPredicate, accountPredicate])
do {
return try context.fetch(fetchRequest).first
} catch {
CoreDataError.shared.handle(error, message: "Error during fetching account relationship (isBoostedMutedForAccount).")
return nil
}
}
}

View File

@ -3,6 +3,6 @@
<plist version="1.0">
<dict>
<key>_XCCurrentVersionName</key>
<string>Vernissage-017.xcdatamodel</string>
<string>Vernissage-018.xcdatamodel</string>
</dict>
</plist>

View File

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="22222" systemVersion="23A344" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="AccountData" representedClassName="AccountData" syncable="YES">
<attribute name="accessToken" optional="YES" attributeType="String"/>
<attribute name="acct" attributeType="String"/>
<attribute name="avatar" optional="YES" attributeType="URI"/>
<attribute name="avatarData" optional="YES" attributeType="Binary"/>
<attribute name="clientId" attributeType="String"/>
<attribute name="clientSecret" attributeType="String"/>
<attribute name="clientVapidKey" attributeType="String"/>
<attribute name="createdAt" attributeType="String"/>
<attribute name="displayName" optional="YES" attributeType="String"/>
<attribute name="followersCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="followingCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="header" optional="YES" attributeType="URI"/>
<attribute name="id" attributeType="String"/>
<attribute name="lastSeenStatusId" optional="YES" attributeType="String"/>
<attribute name="locked" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="note" optional="YES" attributeType="String"/>
<attribute name="refreshToken" optional="YES" attributeType="String"/>
<attribute name="serverUrl" attributeType="URI"/>
<attribute name="statusesCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="url" optional="YES" attributeType="URI"/>
<attribute name="username" attributeType="String"/>
<relationship name="accountRelationships" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="AccountRelationship" inverseName="pixelfedAccount" inverseEntity="AccountRelationship"/>
<relationship name="statuses" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="StatusData" inverseName="pixelfedAccount" inverseEntity="StatusData"/>
<relationship name="viewedStatuses" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="ViewedStatus" inverseName="pixelfedAccount" inverseEntity="ViewedStatus"/>
</entity>
<entity name="AccountRelationship" representedClassName="AccountRelationship" syncable="YES">
<attribute name="accountId" attributeType="String"/>
<attribute name="boostedStatusesMuted" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<relationship name="pixelfedAccount" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="AccountData" inverseName="accountRelationships" inverseEntity="AccountData"/>
</entity>
<entity name="ApplicationSettings" representedClassName="ApplicationSettings" syncable="YES">
<attribute name="activeIcon" attributeType="String" defaultValueString="Default"/>
<attribute name="avatarShape" attributeType="Integer 32" defaultValueString="1" usesScalarValueType="YES"/>
<attribute name="currentAccount" optional="YES" attributeType="String"/>
<attribute name="customNavigationMenuItem1" attributeType="Integer 32" defaultValueString="1" usesScalarValueType="YES"/>
<attribute name="customNavigationMenuItem2" attributeType="Integer 32" defaultValueString="2" usesScalarValueType="YES"/>
<attribute name="customNavigationMenuItem3" attributeType="Integer 32" defaultValueString="5" usesScalarValueType="YES"/>
<attribute name="hapticAnimationEnabled" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
<attribute name="hapticButtonPressEnabled" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
<attribute name="hapticNotificationEnabled" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
<attribute name="hapticRefreshEnabled" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
<attribute name="hapticTabSelectionEnabled" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
<attribute name="lastRefreshTokens" attributeType="Date" defaultDateTimeInterval="694256400" usesScalarValueType="NO"/>
<attribute name="menuPosition" attributeType="Integer 32" defaultValueString="1" usesScalarValueType="YES"/>
<attribute name="showAltIconOnTimeline" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="showAvatarsOnTimeline" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="showFavouritesOnTimeline" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="showGridOnUserProfile" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="showPhotoDescription" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="showReboostedStatuses" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="showSensitive" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="theme" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="tintColor" attributeType="Integer 32" defaultValueString="2" usesScalarValueType="YES"/>
<attribute name="warnAboutMissingAlt" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
</entity>
<entity name="AttachmentData" representedClassName="AttachmentData" syncable="YES">
<attribute name="blurhash" optional="YES" attributeType="String"/>
<attribute name="data" optional="YES" attributeType="Binary" allowsExternalBinaryDataStorage="YES"/>
<attribute name="exifCamera" optional="YES" attributeType="String"/>
<attribute name="exifCreatedDate" optional="YES" attributeType="String"/>
<attribute name="exifExposure" optional="YES" attributeType="String"/>
<attribute name="exifLens" optional="YES" attributeType="String"/>
<attribute name="id" attributeType="String"/>
<attribute name="metaImageHeight" optional="YES" attributeType="Integer 32" defaultValueString="0.0" usesScalarValueType="YES"/>
<attribute name="metaImageWidth" optional="YES" attributeType="Integer 32" defaultValueString="0.0" usesScalarValueType="YES"/>
<attribute name="order" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="previewUrl" optional="YES" attributeType="URI"/>
<attribute name="remoteUrl" optional="YES" attributeType="URI"/>
<attribute name="statusId" attributeType="String"/>
<attribute name="text" optional="YES" attributeType="String"/>
<attribute name="type" attributeType="String"/>
<attribute name="url" attributeType="URI"/>
<relationship name="statusRelation" maxCount="1" deletionRule="Nullify" destinationEntity="StatusData" inverseName="attachmentsRelation" inverseEntity="StatusData"/>
</entity>
<entity name="StatusData" representedClassName="StatusData" syncable="YES">
<attribute name="accountAvatar" optional="YES" attributeType="URI"/>
<attribute name="accountDisplayName" optional="YES" attributeType="String"/>
<attribute name="accountId" attributeType="String"/>
<attribute name="accountUsername" optional="YES" attributeType="String"/>
<attribute name="applicationName" optional="YES" attributeType="String"/>
<attribute name="applicationWebsite" optional="YES" attributeType="URI"/>
<attribute name="bookmarked" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="content" attributeType="String"/>
<attribute name="createdAt" attributeType="String"/>
<attribute name="favourited" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="favouritesCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="id" attributeType="String"/>
<attribute name="inReplyToAccount" optional="YES" attributeType="String"/>
<attribute name="inReplyToId" optional="YES" attributeType="String"/>
<attribute name="muted" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="pinned" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="reblogged" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="rebloggedAccountAvatar" optional="YES" attributeType="URI"/>
<attribute name="rebloggedAccountDisplayName" optional="YES" attributeType="String"/>
<attribute name="rebloggedAccountId" optional="YES" attributeType="String"/>
<attribute name="rebloggedAccountUsername" optional="YES" attributeType="String"/>
<attribute name="rebloggedStatusId" optional="YES" attributeType="String"/>
<attribute name="reblogsCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="repliesCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="sensitive" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="spoilerText" optional="YES" attributeType="String"/>
<attribute name="uri" attributeType="String"/>
<attribute name="url" optional="YES" attributeType="URI"/>
<attribute name="visibility" attributeType="String"/>
<relationship name="attachmentsRelation" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="AttachmentData" inverseName="statusRelation" inverseEntity="AttachmentData"/>
<relationship name="pixelfedAccount" maxCount="1" deletionRule="Nullify" destinationEntity="AccountData" inverseName="statuses" inverseEntity="AccountData"/>
</entity>
<entity name="ViewedStatus" representedClassName="ViewedStatus" syncable="YES">
<attribute name="date" attributeType="Date" usesScalarValueType="NO"/>
<attribute name="id" attributeType="String"/>
<attribute name="reblogId" optional="YES" attributeType="String"/>
<relationship name="pixelfedAccount" maxCount="1" deletionRule="Nullify" destinationEntity="AccountData" inverseName="viewedStatuses" inverseEntity="AccountData"/>
</entity>
</model>

View File

@ -128,6 +128,8 @@
"userProfile.title.edit" = "Edit";
"userProfile.title.muted" = "Muted";
"userProfile.title.blocked" = "Blocked";
"userProfile.title.enableBoosts" = "Enable boosts";
"userProfile.title.disableBoosts" = "Disable boosts";
// Mark: Notifications view.
"notifications.navigationBar.title" = "Notifications";

View File

@ -128,6 +128,8 @@
"userProfile.title.edit" = "Editatu";
"userProfile.title.muted" = "Mutututa";
"userProfile.title.blocked" = "Blokeatuta";
"userProfile.title.enableBoosts" = "Enable boosts";
"userProfile.title.disableBoosts" = "Disable boosts";
// Mark: Notifications view.
"notifications.navigationBar.title" = "Jakinarazpenak";

View File

@ -128,6 +128,8 @@
"userProfile.title.edit" = "Editer";
"userProfile.title.muted" = "Sourdine";
"userProfile.title.blocked" = "Bloquer";
"userProfile.title.enableBoosts" = "Enable boosts";
"userProfile.title.disableBoosts" = "Disable boosts";
// Mark: Notifications view.
"notifications.navigationBar.title" = "Notifications";

View File

@ -128,6 +128,8 @@
"userProfile.title.edit" = "Edytuj";
"userProfile.title.muted" = "Wyciszony";
"userProfile.title.blocked" = "Zablokowany";
"userProfile.title.enableBoosts" = "Wyświetl podbicia";
"userProfile.title.disableBoosts" = "Ukryj podbicia";
// Mark: Notifications view.
"notifications.navigationBar.title" = "Powiadomienia";

View File

@ -208,6 +208,15 @@
F8E36E462AB8745300769C55 /* Sizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8E36E452AB8745300769C55 /* Sizable.swift */; };
F8E36E482AB874A500769C55 /* StatusModel+Sizeable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8E36E472AB874A500769C55 /* StatusModel+Sizeable.swift */; };
F8E6D03329CDD52500416CCA /* EditProfileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8E6D03229CDD52500416CCA /* EditProfileView.swift */; };
F8E7ADFA2AD44CC00038FFFD /* AccountRelationship+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8E7ADF92AD44CC00038FFFD /* AccountRelationship+CoreDataClass.swift */; };
F8E7ADFB2AD44CC00038FFFD /* AccountRelationship+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8E7ADF92AD44CC00038FFFD /* AccountRelationship+CoreDataClass.swift */; };
F8E7ADFC2AD44CC00038FFFD /* AccountRelationship+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8E7ADF92AD44CC00038FFFD /* AccountRelationship+CoreDataClass.swift */; };
F8E7ADFE2AD44CEB0038FFFD /* AccountRelationship+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8E7ADFD2AD44CEB0038FFFD /* AccountRelationship+CoreDataProperties.swift */; };
F8E7ADFF2AD44CEB0038FFFD /* AccountRelationship+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8E7ADFD2AD44CEB0038FFFD /* AccountRelationship+CoreDataProperties.swift */; };
F8E7AE002AD44CEB0038FFFD /* AccountRelationship+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8E7ADFD2AD44CEB0038FFFD /* AccountRelationship+CoreDataProperties.swift */; };
F8E7AE022AD44D600038FFFD /* AccountRelationshipHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8E7AE012AD44D600038FFFD /* AccountRelationshipHandler.swift */; };
F8E7AE032AD44D600038FFFD /* AccountRelationshipHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8E7AE012AD44D600038FFFD /* AccountRelationshipHandler.swift */; };
F8E7AE042AD44D600038FFFD /* AccountRelationshipHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8E7AE012AD44D600038FFFD /* AccountRelationshipHandler.swift */; };
F8F6E44229BC58F20004795E /* Vernissage.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = F88C2476295C37BB0006098B /* Vernissage.xcdatamodeld */; };
F8F6E44C29BCC1F70004795E /* PhotoSmallWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8F6E44629BCC0DC0004795E /* PhotoSmallWidgetView.swift */; };
F8F6E44D29BCC1F90004795E /* PhotoMediumWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8F6E44829BCC0F00004795E /* PhotoMediumWidgetView.swift */; };
@ -422,6 +431,10 @@
F8E36E452AB8745300769C55 /* Sizable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sizable.swift; sourceTree = "<group>"; };
F8E36E472AB874A500769C55 /* StatusModel+Sizeable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "StatusModel+Sizeable.swift"; sourceTree = "<group>"; };
F8E6D03229CDD52500416CCA /* EditProfileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditProfileView.swift; sourceTree = "<group>"; };
F8E7ADF82AD44AFD0038FFFD /* Vernissage-018.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Vernissage-018.xcdatamodel"; sourceTree = "<group>"; };
F8E7ADF92AD44CC00038FFFD /* AccountRelationship+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AccountRelationship+CoreDataClass.swift"; sourceTree = "<group>"; };
F8E7ADFD2AD44CEB0038FFFD /* AccountRelationship+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AccountRelationship+CoreDataProperties.swift"; sourceTree = "<group>"; };
F8E7AE012AD44D600038FFFD /* AccountRelationshipHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountRelationshipHandler.swift; sourceTree = "<group>"; };
F8EF371429C624DA00669F45 /* Vernissage-006.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Vernissage-006.xcdatamodel"; sourceTree = "<group>"; };
F8EF3C8B29FC3A5F00CBFF7C /* Vernissage-012.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Vernissage-012.xcdatamodel"; sourceTree = "<group>"; };
F8F6E44329BC5CAA0004795E /* VernissageWidgetExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = VernissageWidgetExtension.entitlements; sourceTree = "<group>"; };
@ -586,12 +599,15 @@
F88BC51C29E0377B00CE6141 /* AccountData+AccountModel.swift */,
F8D8E0C62ACC234A00AA1374 /* ViewedStatus+CoreDataClass.swift */,
F8D8E0CA2ACC237000AA1374 /* ViewedStatus+CoreDataProperties.swift */,
F8E7ADF92AD44CC00038FFFD /* AccountRelationship+CoreDataClass.swift */,
F8E7ADFD2AD44CEB0038FFFD /* AccountRelationship+CoreDataProperties.swift */,
F88C2474295C37BB0006098B /* CoreDataHandler.swift */,
F866F6A229604161002E8F88 /* AccountDataHandler.swift */,
F866F6A429604194002E8F88 /* ApplicationSettingsHandler.swift */,
F80048072961E6DE00E6868A /* StatusDataHandler.swift */,
F80048092961EA1900E6868A /* AttachmentDataHandler.swift */,
F8D8E0CE2ACC23B300AA1374 /* ViewedStatusHandler.swift */,
F8E7AE012AD44D600038FFFD /* AccountRelationshipHandler.swift */,
F864F7A429BBA01D00B13921 /* CoreDataError.swift */,
);
path = CoreData;
@ -1124,12 +1140,14 @@
F8F6E44229BC58F20004795E /* Vernissage.xcdatamodeld in Sources */,
F8F6E44C29BCC1F70004795E /* PhotoSmallWidgetView.swift in Sources */,
F864F76629BB91B400B13921 /* PhotoWidget.swift in Sources */,
F8E7ADFB2AD44CC00038FFFD /* AccountRelationship+CoreDataClass.swift in Sources */,
F8F6E44D29BCC1F90004795E /* PhotoMediumWidgetView.swift in Sources */,
F815F60C29E49CF20044566B /* Avatar.swift in Sources */,
F8F6E44E29BCC1FB0004795E /* PhotoLargeWidgetView.swift in Sources */,
F864F76429BB91B400B13921 /* VernissageWidgetBundle.swift in Sources */,
F864F77D29BB9A4600B13921 /* AttachmentData+CoreDataClass.swift in Sources */,
F8D8E0C82ACC234A00AA1374 /* ViewedStatus+CoreDataClass.swift in Sources */,
F8E7ADFF2AD44CEB0038FFFD /* AccountRelationship+CoreDataProperties.swift in Sources */,
F8D8E0CC2ACC237000AA1374 /* ViewedStatus+CoreDataProperties.swift in Sources */,
F864F7A629BBA01D00B13921 /* CoreDataError.swift in Sources */,
F864F77E29BB9A4900B13921 /* AttachmentData+CoreDataProperties.swift in Sources */,
@ -1145,6 +1163,7 @@
F864F78529BB9A7100B13921 /* ApplicationSettings+CoreDataProperties.swift in Sources */,
F84625E929FE2788002D3AF4 /* QRCodeWidget.swift in Sources */,
F864F78729BB9A7700B13921 /* AccountData+CoreDataProperties.swift in Sources */,
F8E7AE032AD44D600038FFFD /* AccountRelationshipHandler.swift in Sources */,
F864F78829BB9A7B00B13921 /* CoreDataHandler.swift in Sources */,
F8F6E45129BCE9190004795E /* UIImage+Resize.swift in Sources */,
F864F78929BB9A7D00B13921 /* AccountDataHandler.swift in Sources */,
@ -1164,9 +1183,11 @@
buildActionMask = 2147483647;
files = (
F88BC54529E072B200CE6141 /* AccountDataHandler.swift in Sources */,
F8E7ADFC2AD44CC00038FFFD /* AccountRelationship+CoreDataClass.swift in Sources */,
F88BC54729E072B800CE6141 /* AccountData+CoreDataProperties.swift in Sources */,
F8D8E0D12ACC23B300AA1374 /* ViewedStatusHandler.swift in Sources */,
F88BC54D29E072D600CE6141 /* AttachmentData+CoreDataProperties.swift in Sources */,
F8E7AE002AD44CEB0038FFFD /* AccountRelationship+CoreDataProperties.swift in Sources */,
F88BC54F29E073BC00CE6141 /* AccountData+AccountModel.swift in Sources */,
F865B4D32A024AFE008ACDFC /* AttachmentData+Faulty.swift in Sources */,
F88BC54629E072B500CE6141 /* CoreDataHandler.swift in Sources */,
@ -1176,6 +1197,7 @@
F88BC54429E072AF00CE6141 /* ApplicationSettingsHandler.swift in Sources */,
F8D8E0CD2ACC237000AA1374 /* ViewedStatus+CoreDataProperties.swift in Sources */,
F88BC51629E0307F00CE6141 /* NotificationsName.swift in Sources */,
F8E7AE042AD44D600038FFFD /* AccountRelationshipHandler.swift in Sources */,
F88BC54829E072BC00CE6141 /* AccountData+CoreDataClass.swift in Sources */,
F88BC51329E02FD800CE6141 /* ComposeView.swift in Sources */,
F88BC54E29E072D900CE6141 /* AttachmentData+CoreDataClass.swift in Sources */,
@ -1247,6 +1269,7 @@
F89D6C4A297196FF001DA3D4 /* ImageViewer.swift in Sources */,
F8A93D7E2965FD89001D8331 /* UserProfileView.swift in Sources */,
F88C246E295C37B80006098B /* MainView.swift in Sources */,
F8E7ADFA2AD44CC00038FFFD /* AccountRelationship+CoreDataClass.swift in Sources */,
F8AFF7C429B25EF40087D083 /* ImagesGrid.swift in Sources */,
F88C2478295C37BB0006098B /* Vernissage.xcdatamodeld in Sources */,
F8AFF7C129B259150087D083 /* HashtagsView.swift in Sources */,
@ -1292,8 +1315,10 @@
F86B7216296BFFDA00EE59EC /* UserProfileStatusesView.swift in Sources */,
F8D8E0CB2ACC237000AA1374 /* ViewedStatus+CoreDataProperties.swift in Sources */,
F897978F29684BCB00B22335 /* LoadingView.swift in Sources */,
F8E7ADFE2AD44CEB0038FFFD /* AccountRelationship+CoreDataProperties.swift in Sources */,
F89992C9296D6DC7005994BF /* CommentBodyView.swift in Sources */,
F866F6A1296040A8002E8F88 /* ApplicationSettings+CoreDataProperties.swift in Sources */,
F8E7AE022AD44D600038FFFD /* AccountRelationshipHandler.swift in Sources */,
F86A4303299A9AF500DF7645 /* TipsStore.swift in Sources */,
F8DF38E629DDB98A0047F1AA /* SocialsSectionView.swift in Sources */,
F88BC53B29E06A5100CE6141 /* ImageContextMenu.swift in Sources */,
@ -1348,7 +1373,7 @@
CODE_SIGN_ENTITLEMENTS = VernissageWidget/VernissageWidgetExtension.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 301;
CURRENT_PROJECT_VERSION = 302;
DEVELOPMENT_TEAM = B2U9FEKYP8;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = VernissageWidget/Info.plist;
@ -1379,7 +1404,7 @@
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CODE_SIGN_ENTITLEMENTS = VernissageWidget/VernissageWidgetExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 301;
CURRENT_PROJECT_VERSION = 302;
DEVELOPMENT_TEAM = B2U9FEKYP8;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = VernissageWidget/Info.plist;
@ -1409,7 +1434,7 @@
CODE_SIGN_ENTITLEMENTS = VernissageShare/VernissageShareExtension.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 301;
CURRENT_PROJECT_VERSION = 302;
DEVELOPMENT_TEAM = B2U9FEKYP8;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = VernissageShare/Info.plist;
@ -1438,7 +1463,7 @@
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = NO;
CODE_SIGN_ENTITLEMENTS = VernissageShare/VernissageShareExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 301;
CURRENT_PROJECT_VERSION = 302;
DEVELOPMENT_TEAM = B2U9FEKYP8;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = VernissageShare/Info.plist;
@ -1592,7 +1617,7 @@
CODE_SIGN_ENTITLEMENTS = Vernissage/Vernissage.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 301;
CURRENT_PROJECT_VERSION = 302;
DEVELOPMENT_ASSET_PATHS = "\"Vernissage/Preview Content\"";
DEVELOPMENT_TEAM = B2U9FEKYP8;
ENABLE_PREVIEWS = YES;
@ -1635,7 +1660,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = Vernissage/Vernissage.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 301;
CURRENT_PROJECT_VERSION = 302;
DEVELOPMENT_ASSET_PATHS = "\"Vernissage/Preview Content\"";
DEVELOPMENT_TEAM = B2U9FEKYP8;
ENABLE_PREVIEWS = YES;
@ -1832,6 +1857,7 @@
F88C2476295C37BB0006098B /* Vernissage.xcdatamodeld */ = {
isa = XCVersionGroup;
children = (
F8E7ADF82AD44AFD0038FFFD /* Vernissage-018.xcdatamodel */,
F8D8E0D22ACC89CB00AA1374 /* Vernissage-017.xcdatamodel */,
F8BD04192ACC2280004B8E2C /* Vernissage-016.xcdatamodel */,
F880EECE2AC70A2B00C09C31 /* Vernissage-015.xcdatamodel */,
@ -1851,7 +1877,7 @@
F8C937A929882CA90004D782 /* Vernissage-001.xcdatamodel */,
F88C2477295C37BB0006098B /* Vernissage.xcdatamodel */,
);
currentVersion = F8D8E0D22ACC89CB00AA1374 /* Vernissage-017.xcdatamodel */;
currentVersion = F8E7ADF82AD44AFD0038FFFD /* Vernissage-018.xcdatamodel */;
path = Vernissage.xcdatamodeld;
sourceTree = "<group>";
versionGroupType = wrapper.xcdatamodel;

View File

@ -131,6 +131,11 @@ public class HomeTimelineService {
let statusesWithImagesOnly = downloadedStatuses.getStatusesWithImagesOnly()
for status in statusesWithImagesOnly {
// We shouldn't add statuses that are boosted by muted accounts.
if AccountRelationshipHandler.shared.isBoostedStatusesMuted(accountId: account.id, status: status, viewContext: backgroundContext) {
continue
}
// We should add to timeline only statuses that has not been showned to the user already.
guard self.hasBeenAlreadyOnTimeline(accountId: account.id, status: status, on: backgroundContext) == false else {
continue
@ -366,6 +371,11 @@ public class HomeTimelineService {
let statusesWithImagesOnly = downloadedStatuses.getStatusesWithImagesOnly()
for status in statusesWithImagesOnly {
// We shouldn't add statuses that are boosted by muted accounts.
if AccountRelationshipHandler.shared.isBoostedStatusesMuted(accountId: account.id, status: status, viewContext: backgroundContext) {
continue
}
// We should add to timeline only statuses that has not been showned to the user already.
guard self.hasBeenAlreadyOnTimeline(accountId: account.id, status: status, on: backgroundContext) == false else {
continue

View File

@ -185,6 +185,11 @@ struct StatusesView: View {
// Get only statuses with images.
var inPlaceStatuses: [StatusModel] = []
for item in statuses.getStatusesWithImagesOnly() {
// We have to skip statuses that are boosted from muted accounts.
if let accountId = self.applicationState.account?.id, AccountRelationshipHandler.shared.isBoostedStatusesMuted(accountId: accountId, status: item) {
continue
}
inPlaceStatuses.append(StatusModel(status: item))
}
@ -212,6 +217,11 @@ struct StatusesView: View {
// Get only statuses with images.
var inPlaceStatuses: [StatusModel] = []
for item in previousStatuses.getStatusesWithImagesOnly() {
// We have to skip statuses that are boosted from muted accounts.
if let accountId = self.applicationState.account?.id, AccountRelationshipHandler.shared.isBoostedStatusesMuted(accountId: accountId, status: item) {
continue
}
inPlaceStatuses.append(StatusModel(status: item))
}
@ -237,6 +247,11 @@ struct StatusesView: View {
// Get only statuses with images.
var inPlaceStatuses: [StatusModel] = []
for item in statuses.getStatusesWithImagesOnly() {
// We have to skip statuses that are boosted from muted accounts.
if let accountId = self.applicationState.account?.id, AccountRelationshipHandler.shared.isBoostedStatusesMuted(accountId: accountId, status: item) {
continue
}
inPlaceStatuses.append(StatusModel(status: item))
}

View File

@ -26,6 +26,7 @@ struct UserProfileView: View {
@State private var account: Account?
@State private var state: ViewState = .loading
@State private var viewId = UUID().uuidString
@State private var boostsDisabled = false
// Gallery parameters.
@State private var imageColumns = 3
@ -118,6 +119,10 @@ struct UserProfileView: View {
} else {
self.relationship.update(relationship: RelationshipModel())
}
if let signedInAccountId = self.applicationState.account?.id {
self.boostsDisabled = AccountRelationshipHandler.shared.isBoostedStatusesMuted(for: signedInAccountId, relation: self.accountId)
}
self.account = accountFromApi
@ -167,6 +172,23 @@ struct UserProfileView: View {
Label(NSLocalizedString("userProfile.title.block", comment: "Block"), systemImage: "hand.raised")
}
}
Button {
Task {
if let signedInAccoountId = self.applicationState.account?.id {
self.boostsDisabled.toggle()
AccountRelationshipHandler.shared.setBoostedStatusesMuted(for: signedInAccoountId,
relation: self.accountId,
boostedStatusesMuted: self.boostsDisabled)
}
}
} label: {
if self.boostsDisabled == true {
Label(NSLocalizedString("userProfile.title.enableBoosts", comment: "Enable boosts"), image: "custom.rocket.fill")
} else {
Label(NSLocalizedString("userProfile.title.disableBoosts", comment: "Disable boosts"), image: "custom.rocket")
}
}
Button {
self.routerPath.presentedSheet = .report(objectType: .user, objectId: self.accountId)