mirror of
https://github.com/lumaa-dev/BubbleApp.git
synced 2025-01-29 01:39:16 +01:00
Blocklist and mutelist
This commit is contained in:
parent
af2d85dcc1
commit
81f2814374
@ -10,6 +10,7 @@
|
||||
B9029FC22B81259400AA9B68 /* Secret.plist in Resources */ = {isa = PBXBuildFile; fileRef = B9029FC12B81259400AA9B68 /* Secret.plist */; };
|
||||
B9029FC42B8125CE00AA9B68 /* HuggingFace.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9029FC32B8125CE00AA9B68 /* HuggingFace.swift */; };
|
||||
B915C4422B6F908C00042DDB /* ProfileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B915C4412B6F908C00042DDB /* ProfileView.swift */; };
|
||||
B934EA242BAB5E7F001F4345 /* RestrictedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B934EA232BAB5E7F001F4345 /* RestrictedView.swift */; };
|
||||
B93757112B7FB8D400652F91 /* AltClients.swift in Sources */ = {isa = PBXBuildFile; fileRef = B93757102B7FB8D400652F91 /* AltClients.swift */; };
|
||||
B93ADFCB2B7625CD00FF9172 /* DiscoveryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B93ADFCA2B7625CD00FF9172 /* DiscoveryView.swift */; };
|
||||
B93B676D2B42C94F000892E9 /* Nuke in Frameworks */ = {isa = PBXBuildFile; productRef = B93B676C2B42C94F000892E9 /* Nuke */; };
|
||||
@ -190,6 +191,7 @@
|
||||
B9029FC12B81259400AA9B68 /* Secret.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Secret.plist; sourceTree = "<group>"; };
|
||||
B9029FC32B8125CE00AA9B68 /* HuggingFace.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HuggingFace.swift; sourceTree = "<group>"; };
|
||||
B915C4412B6F908C00042DDB /* ProfileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileView.swift; sourceTree = "<group>"; };
|
||||
B934EA232BAB5E7F001F4345 /* RestrictedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RestrictedView.swift; sourceTree = "<group>"; };
|
||||
B93757102B7FB8D400652F91 /* AltClients.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AltClients.swift; sourceTree = "<group>"; };
|
||||
B93ADFCA2B7625CD00FF9172 /* DiscoveryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiscoveryView.swift; sourceTree = "<group>"; };
|
||||
B93B67772B42E8F0000892E9 /* TextEmoji.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEmoji.swift; sourceTree = "<group>"; };
|
||||
@ -569,6 +571,7 @@
|
||||
B98BC7482B46CEDA00595441 /* AppearenceView.swift */,
|
||||
B97798882B853E6600DC869F /* UpdateView.swift */,
|
||||
B9B469B12B9A6E8300AD5585 /* PrivacyView.swift */,
|
||||
B934EA232BAB5E7F001F4345 /* RestrictedView.swift */,
|
||||
);
|
||||
path = Settings;
|
||||
sourceTree = "<group>";
|
||||
@ -870,6 +873,7 @@
|
||||
B93B677A2B42EC51000892E9 /* MetaPicker.swift in Sources */,
|
||||
B9D9C6C32B6A576C00C26A41 /* NotificationsView.swift in Sources */,
|
||||
B9FA6E772B82788A00D63E30 /* AccountRow.swift in Sources */,
|
||||
B934EA242BAB5E7F001F4345 /* RestrictedView.swift in Sources */,
|
||||
B9FB94722B2DF49700D81C07 /* ConnectView.swift in Sources */,
|
||||
B9FB945B2B2DEECE00D81C07 /* ThreadedApp.swift in Sources */,
|
||||
B9FB94862B2E211200D81C07 /* Account+Elms.swift in Sources */,
|
||||
|
@ -741,3 +741,33 @@ public enum Polls: Endpoint {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum Restricted: Endpoint {
|
||||
case mutes(maxId: String?)
|
||||
case blockedUsers(maxId: String?)
|
||||
case blockedDomains(maxId: String?) // array of strings
|
||||
|
||||
public func path() -> String {
|
||||
switch self {
|
||||
case .mutes:
|
||||
"mutes"
|
||||
case .blockedUsers:
|
||||
"blocks"
|
||||
case .blockedDomains:
|
||||
"domain_blocks"
|
||||
}
|
||||
}
|
||||
|
||||
public func queryItems() -> [URLQueryItem]? {
|
||||
switch self {
|
||||
case let .mutes(maxId):
|
||||
return makePaginationParam(sinceId: nil, maxId: maxId, mindId: nil)
|
||||
|
||||
case let .blockedUsers(maxId):
|
||||
return makePaginationParam(sinceId: nil, maxId: maxId, mindId: nil)
|
||||
|
||||
case let .blockedDomains(maxId):
|
||||
return makePaginationParam(sinceId: nil, maxId: maxId, mindId: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -127,6 +127,7 @@ public enum RouterDestination: Hashable {
|
||||
case appearence
|
||||
case about
|
||||
case privacy
|
||||
case restricted
|
||||
|
||||
case account(acc: Account)
|
||||
case post(status: Status)
|
||||
@ -135,7 +136,7 @@ public enum RouterDestination: Hashable {
|
||||
}
|
||||
|
||||
extension RouterDestination {
|
||||
static let allSettings: [RouterDestination] = [.settings, .support, .about, .appearence]
|
||||
static let allSettings: [RouterDestination] = [.settings, .support, .about, .appearence, .privacy, .restricted]
|
||||
}
|
||||
|
||||
extension View {
|
||||
@ -143,7 +144,7 @@ extension View {
|
||||
navigationDestination(for: RouterDestination.self) { destination in
|
||||
switch destination {
|
||||
case .settings:
|
||||
SettingsView(navigator: navigator)
|
||||
SettingsView()
|
||||
case .support:
|
||||
SupportView()
|
||||
case .appearence:
|
||||
@ -158,6 +159,8 @@ extension View {
|
||||
ContactsView()
|
||||
case .privacy:
|
||||
PrivacyView()
|
||||
case .restricted:
|
||||
RestrictedView()
|
||||
case .timeline(let timeline):
|
||||
PostsView(filter: timeline ?? .home, showHero: false)
|
||||
}
|
||||
|
@ -1415,6 +1415,89 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"restricted.blocked-domain" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Hidden"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Caché"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"restricted.blocked-user" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Blocked"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Bloqué(e)"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"restricted.muted" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Muted"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Muet(te)"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"restricted.no-restricted" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "No restrictions"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Aucun restreints"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"restricted.no-restricted.description" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "You have no mutes and blocks, it means you are peaceful."
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Vous n'avez aucun muets ou bloqués, vous ne faites qu'un avec la paix."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"setting.appearence" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
@ -1847,6 +1930,38 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings.privacy.restricted" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Restricted"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Restreints"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings.restart-app" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Some settings might require the app to be restarted"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Certains paramètres nécessite le redémarrage de l'application"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"shop.best" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
@ -3384,4 +3499,4 @@
|
||||
}
|
||||
},
|
||||
"version" : "1.0"
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,16 @@ struct PrivacyView: View {
|
||||
|
||||
var body: some View {
|
||||
List {
|
||||
//TODO: Blocklist & Mutelist
|
||||
Button {
|
||||
navigator.navigate(to: .restricted)
|
||||
} label: {
|
||||
Label("settings.privacy.restricted", systemImage: "speaker.badge.exclamationmark")
|
||||
}
|
||||
.listRowThreaded()
|
||||
|
||||
Spacer()
|
||||
.frame(height: 30)
|
||||
.listRowThreaded()
|
||||
|
||||
Picker(LocalizedStringKey("setting.privacy.default-visibility"), selection: $userPreferences.defaultVisibility) {
|
||||
ForEach(Visibility.allCases, id: \.self) { visibility in
|
||||
@ -100,7 +109,3 @@ struct PrivacyView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
PrivacyView()
|
||||
}
|
||||
|
@ -3,11 +3,155 @@
|
||||
import SwiftUI
|
||||
|
||||
struct RestrictedView: View {
|
||||
@Environment(AccountManager.self) private var accountManager: AccountManager
|
||||
@EnvironmentObject private var navigator: Navigator
|
||||
|
||||
@State private var foundAccounts: [Account] = []
|
||||
@State private var foundRelations: [Relationship] = []
|
||||
@State private var blockedDomains: [String] = []
|
||||
|
||||
var body: some View {
|
||||
Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
|
||||
List {
|
||||
if foundAccounts.count > 0 && foundRelations.count > 0 {
|
||||
ForEach(foundAccounts) { acc in
|
||||
let correctRelation: Relationship = foundRelations.filter({ $0.id == acc.id })[0]
|
||||
let restrictionType: RestrictionType = .find(isMuted: correctRelation.muting, isBlocked: correctRelation.blocking)
|
||||
|
||||
AccountRow(acct: acc.acct) {
|
||||
restrictionType.rowLabel()
|
||||
}
|
||||
.listRowThreaded()
|
||||
}
|
||||
}
|
||||
if blockedDomains.count > 0 {
|
||||
ForEach(blockedDomains, id: \.self) { dom in
|
||||
let restrictionType: RestrictionType = .blockedDomains
|
||||
|
||||
HStack {
|
||||
VStack(alignment: .leading, spacing: 3.5) {
|
||||
restrictionType.rowLabel()
|
||||
|
||||
Text(dom)
|
||||
.multilineTextAlignment(.leading)
|
||||
}
|
||||
|
||||
Spacer()
|
||||
}
|
||||
.listRowThreaded()
|
||||
}
|
||||
}
|
||||
if foundAccounts.count <= 0 && blockedDomains.count <= 0 {
|
||||
ContentUnavailableView("restricted.no-restricted", systemImage: "person.and.background.dotted", description: Text("restricted.no-restricted.description"))
|
||||
.listRowThreaded()
|
||||
}
|
||||
}
|
||||
.task {
|
||||
await refresh()
|
||||
}
|
||||
.refreshable {
|
||||
await refresh()
|
||||
}
|
||||
.navigationTitle(Text("settings.privacy.restricted"))
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.listThreaded()
|
||||
}
|
||||
|
||||
private func refresh() async {
|
||||
guard let client = accountManager.getClient() else { return }
|
||||
foundAccounts = []
|
||||
|
||||
do {
|
||||
let muted: [Account] = try await client.get(endpoint: Restricted.mutes(maxId: nil))
|
||||
let blocked: [Account] = try await client.get(endpoint: Restricted.blockedUsers(maxId: nil))
|
||||
|
||||
blockedDomains = try await client.get(endpoint: Restricted.blockedDomains(maxId: nil))
|
||||
foundAccounts.append(contentsOf: muted)
|
||||
foundAccounts.append(contentsOf: blocked)
|
||||
|
||||
foundRelations = try await client.get(endpoint: Accounts.relationships(ids: foundAccounts.map({ $0.id })))
|
||||
} catch {
|
||||
print(error)
|
||||
}
|
||||
}
|
||||
|
||||
func asyncAction(endpoint: Endpoint) {
|
||||
guard let client = accountManager.getClient() else { return }
|
||||
|
||||
Task {
|
||||
_ = try await client.post(endpoint: endpoint)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
RestrictedView()
|
||||
public enum RestrictionType {
|
||||
case muted
|
||||
case blockedUsers
|
||||
case blockedDomains
|
||||
|
||||
static func find(isMuted: Bool = false, isBlocked: Bool = false, isBlockedDomain: Bool = false) -> RestrictionType {
|
||||
if isMuted && !isBlocked {
|
||||
return RestrictionType.muted
|
||||
} else if isBlocked {
|
||||
return RestrictionType.blockedUsers
|
||||
} else if isBlockedDomain {
|
||||
return RestrictionType.blockedDomains
|
||||
}
|
||||
return RestrictionType.muted
|
||||
}
|
||||
|
||||
func localizedTitle() -> LocalizedStringKey {
|
||||
switch self {
|
||||
case .muted:
|
||||
return .init("restricted.mutes")
|
||||
case .blockedUsers:
|
||||
return .init("restricted.users")
|
||||
case .blockedDomains:
|
||||
return .init("restricted.domains")
|
||||
}
|
||||
}
|
||||
|
||||
func localizedType() -> LocalizedStringKey {
|
||||
switch self {
|
||||
case .muted:
|
||||
return .init("restricted.muted")
|
||||
case .blockedUsers:
|
||||
return .init("restricted.blocked-user")
|
||||
case .blockedDomains:
|
||||
return .init("restricted.blocked-domain")
|
||||
}
|
||||
}
|
||||
|
||||
func assimilatedIcon() -> String {
|
||||
switch self {
|
||||
case .muted:
|
||||
return "speaker.slash.fill"
|
||||
case .blockedUsers:
|
||||
return "hand.raised.slash.fill"
|
||||
case .blockedDomains:
|
||||
return "network.slash"
|
||||
}
|
||||
}
|
||||
|
||||
func assimilatedColor() -> Color {
|
||||
switch self {
|
||||
case .muted:
|
||||
return Color.yellow
|
||||
case .blockedUsers:
|
||||
return Color.orange
|
||||
case .blockedDomains:
|
||||
return Color.red
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
func rowLabel() -> some View {
|
||||
HStack {
|
||||
Image(systemName: self.assimilatedIcon())
|
||||
.font(.body.bold())
|
||||
.foregroundStyle(self.assimilatedColor())
|
||||
|
||||
Text(self.localizedType())
|
||||
.accountRowLabel(self.assimilatedColor())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user