mirror of
git://jb55.com/damus
synced 2024-09-30 00:40:45 +00:00
Add indication of followers you know in a profile
Changelog-Added: Add indication of followers you know in a profile
This commit is contained in:
parent
de84456a57
commit
422167f7aa
@ -18,6 +18,7 @@
|
|||||||
3A3040F329A91366008A0F29 /* ProfileViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A3040F229A91366008A0F29 /* ProfileViewTests.swift */; };
|
3A3040F329A91366008A0F29 /* ProfileViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A3040F229A91366008A0F29 /* ProfileViewTests.swift */; };
|
||||||
3A30410129AB12AA008A0F29 /* EventGroupViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A30410029AB12AA008A0F29 /* EventGroupViewTests.swift */; };
|
3A30410129AB12AA008A0F29 /* EventGroupViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A30410029AB12AA008A0F29 /* EventGroupViewTests.swift */; };
|
||||||
3A4325A82961E11400BFCD9D /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 3A4325AA2961E11400BFCD9D /* Localizable.stringsdict */; };
|
3A4325A82961E11400BFCD9D /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 3A4325AA2961E11400BFCD9D /* Localizable.stringsdict */; };
|
||||||
|
3A4647CF2A413ADC00386AD8 /* CondensedProfilePicturesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A4647CE2A413ADC00386AD8 /* CondensedProfilePicturesView.swift */; };
|
||||||
3A48E7B029DFBE9D006E787E /* MutedThreadsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A48E7AF29DFBE9D006E787E /* MutedThreadsManager.swift */; };
|
3A48E7B029DFBE9D006E787E /* MutedThreadsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A48E7AF29DFBE9D006E787E /* MutedThreadsManager.swift */; };
|
||||||
3A8CC6CC2A2CFEF900940F5F /* StringUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A8CC6CB2A2CFEF900940F5F /* StringUtil.swift */; };
|
3A8CC6CC2A2CFEF900940F5F /* StringUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A8CC6CB2A2CFEF900940F5F /* StringUtil.swift */; };
|
||||||
3AA247FD297E3CFF0090C62D /* RepostsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AA247FC297E3CFF0090C62D /* RepostsModel.swift */; };
|
3AA247FD297E3CFF0090C62D /* RepostsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AA247FC297E3CFF0090C62D /* RepostsModel.swift */; };
|
||||||
@ -369,6 +370,7 @@
|
|||||||
3A41E559299D52BE001FA465 /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = id.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
3A41E559299D52BE001FA465 /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = id.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||||
3A41E55A299D52BE001FA465 /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = id.lproj/Localizable.strings; sourceTree = "<group>"; };
|
3A41E55A299D52BE001FA465 /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = id.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
3A41E55B299D52BE001FA465 /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = id; path = id.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
3A41E55B299D52BE001FA465 /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = id; path = id.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
|
3A4647CE2A413ADC00386AD8 /* CondensedProfilePicturesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CondensedProfilePicturesView.swift; sourceTree = "<group>"; };
|
||||||
3A48E7AF29DFBE9D006E787E /* MutedThreadsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MutedThreadsManager.swift; sourceTree = "<group>"; };
|
3A48E7AF29DFBE9D006E787E /* MutedThreadsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MutedThreadsManager.swift; sourceTree = "<group>"; };
|
||||||
3A5C4575296A879E0032D398 /* es-419 */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "es-419"; path = "es-419.lproj/Localizable.stringsdict"; sourceTree = "<group>"; };
|
3A5C4575296A879E0032D398 /* es-419 */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "es-419"; path = "es-419.lproj/Localizable.stringsdict"; sourceTree = "<group>"; };
|
||||||
3A5CAE1D298DC0DB00B5334F /* zh-CN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-CN"; path = "zh-CN.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
|
3A5CAE1D298DC0DB00B5334F /* zh-CN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-CN"; path = "zh-CN.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
|
||||||
@ -1226,6 +1228,7 @@
|
|||||||
4C9F18E329ABDE6D008C55EC /* MaybeAnonPfpView.swift */,
|
4C9F18E329ABDE6D008C55EC /* MaybeAnonPfpView.swift */,
|
||||||
4C9BB83329C12D9900FC4E37 /* EventProfileName.swift */,
|
4C9BB83329C12D9900FC4E37 /* EventProfileName.swift */,
|
||||||
4C8D1A6B29F1DFC200ACDF75 /* FriendIcon.swift */,
|
4C8D1A6B29F1DFC200ACDF75 /* FriendIcon.swift */,
|
||||||
|
3A4647CE2A413ADC00386AD8 /* CondensedProfilePicturesView.swift */,
|
||||||
);
|
);
|
||||||
path = Profile;
|
path = Profile;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1857,6 +1860,7 @@
|
|||||||
4C30AC8029A6A53F00E2BD5A /* ProfilePicturesView.swift in Sources */,
|
4C30AC8029A6A53F00E2BD5A /* ProfilePicturesView.swift in Sources */,
|
||||||
5C6E1DAD2A193EC2008FC15A /* GradientButtonStyle.swift in Sources */,
|
5C6E1DAD2A193EC2008FC15A /* GradientButtonStyle.swift in Sources */,
|
||||||
4C8EC52529D1FA6C0085D9A8 /* DamusColors.swift in Sources */,
|
4C8EC52529D1FA6C0085D9A8 /* DamusColors.swift in Sources */,
|
||||||
|
3A4647CF2A413ADC00386AD8 /* CondensedProfilePicturesView.swift in Sources */,
|
||||||
4C5C7E6A284EDE2E00A22DF5 /* SearchResultsView.swift in Sources */,
|
4C5C7E6A284EDE2E00A22DF5 /* SearchResultsView.swift in Sources */,
|
||||||
4CE1399429F0669900AC6A0B /* BigButton.swift in Sources */,
|
4CE1399429F0669900AC6A0B /* BigButton.swift in Sources */,
|
||||||
7C60CAEF298471A1009C80D6 /* CoreSVG.swift in Sources */,
|
7C60CAEF298471A1009C80D6 /* CoreSVG.swift in Sources */,
|
||||||
|
@ -11,6 +11,8 @@ import Foundation
|
|||||||
class Contacts {
|
class Contacts {
|
||||||
private var friends: Set<String> = Set()
|
private var friends: Set<String> = Set()
|
||||||
private var friend_of_friends: Set<String> = Set()
|
private var friend_of_friends: Set<String> = Set()
|
||||||
|
/// Tracks which friends are friends of a given pubkey.
|
||||||
|
private var pubkey_to_our_friends = [String : Set<String>]()
|
||||||
private var muted: Set<String> = Set()
|
private var muted: Set<String> = Set()
|
||||||
|
|
||||||
let our_pubkey: String
|
let our_pubkey: String
|
||||||
@ -58,6 +60,10 @@ class Contacts {
|
|||||||
|
|
||||||
func remove_friend(_ pubkey: String) {
|
func remove_friend(_ pubkey: String) {
|
||||||
friends.remove(pubkey)
|
friends.remove(pubkey)
|
||||||
|
|
||||||
|
pubkey_to_our_friends.forEach {
|
||||||
|
pubkey_to_our_friends[$0.key]?.remove(pubkey)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func get_friend_list() -> [String] {
|
func get_friend_list() -> [String] {
|
||||||
@ -73,6 +79,15 @@ class Contacts {
|
|||||||
for tag in contact.tags {
|
for tag in contact.tags {
|
||||||
if tag.count >= 2 && tag[0] == "p" {
|
if tag.count >= 2 && tag[0] == "p" {
|
||||||
friend_of_friends.insert(tag[1])
|
friend_of_friends.insert(tag[1])
|
||||||
|
|
||||||
|
// Exclude themself and us.
|
||||||
|
if contact.pubkey != our_pubkey && contact.pubkey != tag[1] {
|
||||||
|
if pubkey_to_our_friends[tag[1]] == nil {
|
||||||
|
pubkey_to_our_friends[tag[1]] = Set<String>()
|
||||||
|
}
|
||||||
|
|
||||||
|
pubkey_to_our_friends[tag[1]]?.insert(contact.pubkey)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,6 +111,11 @@ class Contacts {
|
|||||||
func follow_state(_ pubkey: String) -> FollowState {
|
func follow_state(_ pubkey: String) -> FollowState {
|
||||||
return is_friend(pubkey) ? .follows : .unfollows
|
return is_friend(pubkey) ? .follows : .unfollows
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the list of pubkeys of our friends who follow the given pubkey.
|
||||||
|
func get_friended_followers(_ pubkey: String) -> [String] {
|
||||||
|
return Array((pubkey_to_our_friends[pubkey] ?? Set()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func follow_user(pool: RelayPool, our_contacts: NostrEvent?, pubkey: String, privkey: String, follow: ReferencedId) -> NostrEvent? {
|
func follow_user(pool: RelayPool, our_contacts: NostrEvent?, pubkey: String, privkey: String, follow: ReferencedId) -> NostrEvent? {
|
||||||
|
@ -386,7 +386,7 @@ class HomeModel {
|
|||||||
|
|
||||||
var contacts_filter = NostrFilter(kinds: [.metadata])
|
var contacts_filter = NostrFilter(kinds: [.metadata])
|
||||||
contacts_filter.authors = friends
|
contacts_filter.authors = friends
|
||||||
|
|
||||||
var our_contacts_filter = NostrFilter(kinds: [.contacts, .metadata])
|
var our_contacts_filter = NostrFilter(kinds: [.contacts, .metadata])
|
||||||
our_contacts_filter.authors = [damus_state.pubkey]
|
our_contacts_filter.authors = [damus_state.pubkey]
|
||||||
|
|
||||||
|
@ -29,9 +29,27 @@ struct FollowUserView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct FollowersYouKnowView: View {
|
||||||
|
let damus_state: DamusState
|
||||||
|
let friended_followers: [String]
|
||||||
|
|
||||||
|
@EnvironmentObject var followers: FollowersModel
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ScrollView {
|
||||||
|
LazyVStack(alignment: .leading) {
|
||||||
|
ForEach(friended_followers, id: \.self) { pk in
|
||||||
|
FollowUserView(target: .pubkey(pk), damus_state: damus_state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding(.horizontal)
|
||||||
|
}
|
||||||
|
.navigationBarTitle(NSLocalizedString("Followers You Know", comment: "Navigation bar title for view that shows who is following a user."))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct FollowersView: View {
|
struct FollowersView: View {
|
||||||
let damus_state: DamusState
|
let damus_state: DamusState
|
||||||
let whos: String
|
|
||||||
|
|
||||||
@EnvironmentObject var followers: FollowersModel
|
@EnvironmentObject var followers: FollowersModel
|
||||||
|
|
||||||
@ -58,7 +76,6 @@ struct FollowingView: View {
|
|||||||
let damus_state: DamusState
|
let damus_state: DamusState
|
||||||
|
|
||||||
let following: FollowingModel
|
let following: FollowingModel
|
||||||
let whos: String
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ScrollView {
|
ScrollView {
|
||||||
|
38
damus/Views/Profile/CondensedProfilePicturesView.swift
Normal file
38
damus/Views/Profile/CondensedProfilePicturesView.swift
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
//
|
||||||
|
// CondensedProfilePicturesView.swift
|
||||||
|
// damus
|
||||||
|
//
|
||||||
|
// Created by Terry Yiu on 6/19/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct CondensedProfilePicturesView: View {
|
||||||
|
let state: DamusState
|
||||||
|
let pubkeys: [String]
|
||||||
|
let maxPictures: Int
|
||||||
|
|
||||||
|
init(state: DamusState, pubkeys: [String], maxPictures: Int) {
|
||||||
|
self.state = state
|
||||||
|
self.pubkeys = pubkeys
|
||||||
|
self.maxPictures = min(maxPictures, pubkeys.count)
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
// Using ZStack to make profile pictures floating and stacked on top of each other.
|
||||||
|
ZStack {
|
||||||
|
ForEach((0..<maxPictures).reversed(), id: \.self) { index in
|
||||||
|
ProfilePicView(pubkey: pubkeys[index], size: 32.0, highlight: .none, profiles: state.profiles, disable_animation: state.settings.disable_animation)
|
||||||
|
.offset(x: CGFloat(index) * 20)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Padding is needed so that other components drawn adjacent to this view don't get drawn on top.
|
||||||
|
.padding(.trailing, CGFloat((maxPictures - 1) * 20))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CondensedProfilePicturesView_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
CondensedProfilePicturesView(state: test_damus_state(), pubkeys: ["a", "b", "c", "d"], maxPictures: 3)
|
||||||
|
}
|
||||||
|
}
|
@ -46,6 +46,31 @@ func relaysCountString(_ count: Int, locale: Locale = Locale.current) -> String
|
|||||||
return String(format: format, locale: locale, count)
|
return String(format: format, locale: locale, count)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func followedByString(_ friend_intersection: [String], profiles: Profiles, locale: Locale = Locale.current) -> String {
|
||||||
|
let bundle = bundleForLocale(locale: locale)
|
||||||
|
let names: [String] = friend_intersection.prefix(3).map {
|
||||||
|
let profile = profiles.lookup(id: $0)
|
||||||
|
return Profile.displayName(profile: profile, pubkey: $0).username.truncate(maxLength: 20)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch friend_intersection.count {
|
||||||
|
case 0:
|
||||||
|
return ""
|
||||||
|
case 1:
|
||||||
|
let format = NSLocalizedString("Followed by %@", bundle: bundle, comment: "Text to indicate that the user is followed by one of our follows.")
|
||||||
|
return String(format: format, locale: locale, names[0])
|
||||||
|
case 2:
|
||||||
|
let format = NSLocalizedString("Followed by %@ & %@", bundle: bundle, comment: "Text to indicate that the user is followed by two of our follows.")
|
||||||
|
return String(format: format, locale: locale, names[0], names[1])
|
||||||
|
case 3:
|
||||||
|
let format = NSLocalizedString("Followed by %@, %@ & %@", bundle: bundle, comment: "Text to indicate that the user is followed by three of our follows.")
|
||||||
|
return String(format: format, locale: locale, names[0], names[1], names[2])
|
||||||
|
default:
|
||||||
|
let format = localizedStringFormat(key: "followed_by_three_and_others", locale: locale)
|
||||||
|
return String(format: format, locale: locale, friend_intersection.count - 3, names[0], names[1], names[2])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct EditButton: View {
|
struct EditButton: View {
|
||||||
let damus_state: DamusState
|
let damus_state: DamusState
|
||||||
|
|
||||||
@ -379,7 +404,7 @@ struct ProfileView: View {
|
|||||||
if let contact = profile.contacts {
|
if let contact = profile.contacts {
|
||||||
let contacts = contact.referenced_pubkeys.map { $0.ref_id }
|
let contacts = contact.referenced_pubkeys.map { $0.ref_id }
|
||||||
let following_model = FollowingModel(damus_state: damus_state, contacts: contacts)
|
let following_model = FollowingModel(damus_state: damus_state, contacts: contacts)
|
||||||
NavigationLink(destination: FollowingView(damus_state: damus_state, following: following_model, whos: profile.pubkey)) {
|
NavigationLink(destination: FollowingView(damus_state: damus_state, following: following_model)) {
|
||||||
HStack {
|
HStack {
|
||||||
let noun_text = Text(verbatim: "\(followingCountString(profile.following))").font(.subheadline).foregroundColor(.gray)
|
let noun_text = Text(verbatim: "\(followingCountString(profile.following))").font(.subheadline).foregroundColor(.gray)
|
||||||
Text("\(Text(verbatim: profile.following.formatted()).font(.subheadline.weight(.medium))) \(noun_text)", comment: "Sentence composed of 2 variables to describe how many profiles a user is following. In source English, the first variable is the number of profiles being followed, and the second variable is 'Following'.")
|
Text("\(Text(verbatim: profile.following.formatted()).font(.subheadline.weight(.medium))) \(noun_text)", comment: "Sentence composed of 2 variables to describe how many profiles a user is following. In source English, the first variable is the number of profiles being followed, and the second variable is 'Following'.")
|
||||||
@ -387,7 +412,7 @@ struct ProfileView: View {
|
|||||||
}
|
}
|
||||||
.buttonStyle(PlainButtonStyle())
|
.buttonStyle(PlainButtonStyle())
|
||||||
}
|
}
|
||||||
let fview = FollowersView(damus_state: damus_state, whos: profile.pubkey)
|
let fview = FollowersView(damus_state: damus_state)
|
||||||
.environmentObject(followers)
|
.environmentObject(followers)
|
||||||
if followers.contacts != nil {
|
if followers.contacts != nil {
|
||||||
NavigationLink(destination: fview) {
|
NavigationLink(destination: fview) {
|
||||||
@ -420,6 +445,22 @@ struct ProfileView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if profile.pubkey != damus_state.pubkey {
|
||||||
|
let friended_followers = damus_state.contacts.get_friended_followers(profile.pubkey)
|
||||||
|
if !friended_followers.isEmpty {
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
NavigationLink(destination: FollowersYouKnowView(damus_state: damus_state, friended_followers: friended_followers)) {
|
||||||
|
HStack {
|
||||||
|
CondensedProfilePicturesView(state: damus_state, pubkeys: friended_followers, maxPictures: 3)
|
||||||
|
Text(followedByString(friended_followers, profiles: damus_state.profiles))
|
||||||
|
.font(.subheadline).foregroundColor(.gray)
|
||||||
|
.multilineTextAlignment(.leading)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.padding(.horizontal)
|
.padding(.horizontal)
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,22 @@
|
|||||||
<string>... %d other notes ...</string>
|
<string>... %d other notes ...</string>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
|
<key>followed_by_three_and_others</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSStringLocalizedFormatKey</key>
|
||||||
|
<string>%#@OTHERS@</string>
|
||||||
|
<key>OTHERS</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSStringFormatSpecTypeKey</key>
|
||||||
|
<string>NSStringPluralRuleType</string>
|
||||||
|
<key>NSStringFormatValueTypeKey</key>
|
||||||
|
<string>d</string>
|
||||||
|
<key>one</key>
|
||||||
|
<string>Followed by %2$@, %3$@, %4$@ & %1$d other</string>
|
||||||
|
<key>other</key>
|
||||||
|
<string>Followed by %2$@, %3$@, %4$@ & %1$d others</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
<key>followers_count</key>
|
<key>followers_count</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>NSStringLocalizedFormatKey</key>
|
<key>NSStringLocalizedFormatKey</key>
|
||||||
|
@ -53,4 +53,21 @@ final class ProfileViewTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testFollowedByString() throws {
|
||||||
|
let profiles = test_damus_state().profiles
|
||||||
|
|
||||||
|
XCTAssertEqual(followedByString(["pk1"], profiles: profiles, locale: enUsLocale), "Followed by pk1:pk1")
|
||||||
|
XCTAssertEqual(followedByString(["pk1", "pk2"], profiles: profiles, locale: enUsLocale), "Followed by pk1:pk1 & pk2:pk2")
|
||||||
|
XCTAssertEqual(followedByString(["pk1", "pk2", "pk3"], profiles: profiles, locale: enUsLocale), "Followed by pk1:pk1, pk2:pk2 & pk3:pk3")
|
||||||
|
XCTAssertEqual(followedByString(["pk1", "pk2", "pk3", "pk4",], profiles: profiles, locale: enUsLocale), "Followed by pk1:pk1, pk2:pk2, pk3:pk3 & 1 other")
|
||||||
|
XCTAssertEqual(followedByString(["pk1", "pk2", "pk3", "pk4", "pk5"], profiles: profiles, locale: enUsLocale), "Followed by pk1:pk1, pk2:pk2, pk3:pk3 & 2 others")
|
||||||
|
|
||||||
|
let pubkeys = ["pk1", "pk2", "pk3", "pk4", "pk5", "pk6", "pk7", "pk8", "pk9", "pk10"]
|
||||||
|
Bundle.main.localizations.map { Locale(identifier: $0) }.forEach {
|
||||||
|
for count in 1...10 {
|
||||||
|
XCTAssertNoThrow(followedByString(pubkeys.prefix(count).map { $0 }, profiles: profiles, locale: $0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user