Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Search Instances #873

Merged
merged 60 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
5cf1c2b
Update
Sjmarf Jan 14, 2024
fe8c799
Show instance version
Sjmarf Jan 14, 2024
84c9e38
Rewrite CommunityResultView and UserResultView
Sjmarf Jan 14, 2024
e298d1d
Remove extra divider
Sjmarf Jan 14, 2024
95a4671
Don't show instance in admin list
Sjmarf Jan 14, 2024
e7cb5bf
Merge branch 'dev' into sjmarf/instance-page
Sjmarf Jan 17, 2024
4a81fc3
Use existing `GetSiteRequest(instanceURL: URL)` system
Sjmarf Jan 17, 2024
672a9ba
Bug fix
Sjmarf Jan 19, 2024
85e7d44
Fix
Sjmarf Jan 19, 2024
9129886
KBin fix
Sjmarf Jan 20, 2024
cf282dd
Update InstanceView.swift
Sjmarf Jan 20, 2024
31acf9c
Update InstanceView.swift
Sjmarf Jan 20, 2024
fa2f0f9
Update InstanceView.swift
Sjmarf Jan 20, 2024
d416622
Faster loading for own instance page
Sjmarf Jan 20, 2024
a385c1d
Update
Sjmarf Jan 20, 2024
30186f7
Update project.pbxproj
Sjmarf Jan 20, 2024
c2f59e0
Fix again
Sjmarf Jan 20, 2024
401add5
Remove unnecessary code
Sjmarf Jan 20, 2024
0703e89
Merge branch 'sjmarf/instance-page' into sjmarf/instance-stats
Sjmarf Jan 21, 2024
0840ead
Update
Sjmarf Jan 21, 2024
563e340
Update
Sjmarf Jan 21, 2024
7f792fa
Update project.pbxproj
Sjmarf Jan 21, 2024
b97ea61
Rename "Statistics" tab to "Details"
Sjmarf Jan 21, 2024
597a24b
Bug fix
Sjmarf Jan 22, 2024
6f777f7
Merge branch 'sjmarf/instance-stats' into sjmarf/instance-search
Sjmarf Jan 22, 2024
d8a9901
Update
Sjmarf Jan 22, 2024
06837fd
Fix background on light mode
Sjmarf Jan 22, 2024
9291310
Merge branch 'sjmarf/instance-stats' into sjmarf/instance-search
Sjmarf Jan 22, 2024
b5dd5bd
Update
Sjmarf Jan 22, 2024
2b654ca
Update RecentSearchesView.swift
Sjmarf Jan 22, 2024
19f7e4c
Add pre-emptive support for `GetPersonDetailsResponse.site`
Sjmarf Jan 24, 2024
16de9ef
Merge branch 'sjmarf/instance-page' into sjmarf/instance-stats
Sjmarf Jan 24, 2024
86119c3
Merge branch 'sjmarf/instance-stats' into sjmarf/instance-search
Sjmarf Jan 24, 2024
b210e58
Design tweak
Sjmarf Jan 24, 2024
51e7868
Design tweak
Sjmarf Jan 24, 2024
50ccbf3
Remove debug print
Sjmarf Jan 24, 2024
e8d6c1f
Merge branch 'dev' into sjmarf/instance-stats
Sjmarf Jan 25, 2024
0fc3e09
Merge branch 'dev' into sjmarf/instance-stats
Sjmarf Jan 27, 2024
a8d31b8
Update project.pbxproj
Sjmarf Jan 27, 2024
513f3a2
Bug fixes
Sjmarf Jan 27, 2024
51a1c8a
Tweak
Sjmarf Jan 27, 2024
634b24e
Merge branch 'sjmarf/instance-stats' into sjmarf/instance-search
Sjmarf Jan 27, 2024
6ee52e0
Add context menu to search results
Sjmarf Jan 27, 2024
cfee83e
Merge branch 'dev' into sjmarf/instance-stats
Sjmarf Jan 27, 2024
ebae6dd
Merge branch 'dev' into sjmarf/instance-stats
Sjmarf Jan 28, 2024
e85f37b
Show/hide slur filter with animation
Sjmarf Jan 28, 2024
37d06c2
Make some settings always show
Sjmarf Jan 28, 2024
f0a025e
Merge branch 'dev' into sjmarf/instance-stats
Sjmarf Jan 28, 2024
2c64908
Merge branch 'sjmarf/instance-stats' into sjmarf/instance-search
Sjmarf Jan 28, 2024
e73c7a1
Update InstanceModel.swift
Sjmarf Jan 28, 2024
e59ca40
Merge branch 'sjmarf/instance-stats' into sjmarf/instance-search
Sjmarf Jan 28, 2024
eee8677
Merge branch 'dev' into sjmarf/instance-stats
Sjmarf Jan 30, 2024
64b6428
Update
Sjmarf Jan 30, 2024
483a9c8
Merge branch 'sjmarf/instance-stats' into sjmarf/instance-search
Sjmarf Jan 30, 2024
cba9293
Merge branch 'dev' into sjmarf/instance-stats
Sjmarf Jan 30, 2024
d846319
Merge branch 'sjmarf/instance-stats' into sjmarf/instance-search
Sjmarf Jan 30, 2024
6ec86a4
Merge branch 'dev' into sjmarf/instance-search
Sjmarf Jan 31, 2024
fdbf279
Merge branch 'dev' into sjmarf/instance-search
Sjmarf Jan 31, 2024
49fe30d
Bug fix
Sjmarf Jan 31, 2024
b1d90e7
Fix another bug
Sjmarf Jan 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Mlem.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
032C1E062B5DBDB100FB4F23 /* LocalAccountSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 032C1E052B5DBDB100FB4F23 /* LocalAccountSettingsView.swift */; };
032DD2FD2AC3594B00F1B33D /* LinkAttatchmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 032DD2FC2AC3594B00F1B33D /* LinkAttatchmentView.swift */; };
034C724F2A82B61200B8A4B8 /* LayoutWidgetTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 034C724E2A82B61200B8A4B8 /* LayoutWidgetTracker.swift */; };
0355DA4D2B5EB51900CDF5A5 /* InstanceModel+ContentModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0355DA4C2B5EB51900CDF5A5 /* InstanceModel+ContentModel.swift */; };
0355DA4F2B5EB63600CDF5A5 /* InstanceStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0355DA4E2B5EB63600CDF5A5 /* InstanceStub.swift */; };
0355DA512B5EB87700CDF5A5 /* InstanceResultView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0355DA502B5EB87700CDF5A5 /* InstanceResultView.swift */; };
035EB0CA2A8687C200227859 /* JumpButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035EB0C92A8687C200227859 /* JumpButtonView.swift */; };
036ED3BC2ABF1058009664BC /* SearchModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 036ED3BB2ABF1058009664BC /* SearchModel.swift */; };
038A16DF2A75172C0087987E /* LayoutWidgetEditView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 038A16DE2A75172C0087987E /* LayoutWidgetEditView.swift */; };
Expand Down Expand Up @@ -601,6 +604,9 @@
032C1E052B5DBDB100FB4F23 /* LocalAccountSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalAccountSettingsView.swift; sourceTree = "<group>"; };
032DD2FC2AC3594B00F1B33D /* LinkAttatchmentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkAttatchmentView.swift; sourceTree = "<group>"; };
034C724E2A82B61200B8A4B8 /* LayoutWidgetTracker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LayoutWidgetTracker.swift; sourceTree = "<group>"; };
0355DA4C2B5EB51900CDF5A5 /* InstanceModel+ContentModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "InstanceModel+ContentModel.swift"; sourceTree = "<group>"; };
0355DA4E2B5EB63600CDF5A5 /* InstanceStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstanceStub.swift; sourceTree = "<group>"; };
0355DA502B5EB87700CDF5A5 /* InstanceResultView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstanceResultView.swift; sourceTree = "<group>"; };
035EB0C92A8687C200227859 /* JumpButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JumpButtonView.swift; sourceTree = "<group>"; };
036ED3BB2ABF1058009664BC /* SearchModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchModel.swift; sourceTree = "<group>"; };
038A16DE2A75172C0087987E /* LayoutWidgetEditView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LayoutWidgetEditView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1260,6 +1266,7 @@
isa = PBXGroup;
children = (
03EEEAF22AB8DCDF0087F8D8 /* CommunityResultView.swift */,
0355DA502B5EB87700CDF5A5 /* InstanceResultView.swift */,
03B7AAF42ABEFA7A00068B23 /* UserResultView.swift */,
);
path = Results;
Expand Down Expand Up @@ -1377,6 +1384,8 @@
isa = PBXGroup;
children = (
03A54C342B533BC50064CCDE /* InstanceModel.swift */,
0355DA4E2B5EB63600CDF5A5 /* InstanceStub.swift */,
0355DA4C2B5EB51900CDF5A5 /* InstanceModel+ContentModel.swift */,
03A54C362B545A430064CCDE /* InstanceModel+MenuFunctions.swift */,
);
path = Instance;
Expand Down Expand Up @@ -3126,6 +3135,7 @@
5064D0432A6E645D00B22EE3 /* Notifiable.swift in Sources */,
039439932A99098900463032 /* InternetConnectionManager.swift in Sources */,
CD82A2592A71775E00111034 /* UnreadTracker.swift in Sources */,
0355DA4F2B5EB63600CDF5A5 /* InstanceStub.swift in Sources */,
CD4368CA2AE2428C00BD8BD1 /* ContentIdentifiable.swift in Sources */,
CD3FBCE32A4A844800B2063F /* Replies Feed View.swift in Sources */,
637218652A3A2AAD008C4816 /* GetPosts.swift in Sources */,
Expand Down Expand Up @@ -3492,6 +3502,7 @@
CD6A2A792B1A553500003E23 /* SuccessResponse.swift in Sources */,
031A61802B1CEA7300ABF23B /* ChangePassword.swift in Sources */,
CD4368B42AE23F3500BD8BD1 /* ChildTrackerProtocol.swift in Sources */,
0355DA512B5EB87700CDF5A5 /* InstanceResultView.swift in Sources */,
CD4368D92AE2478300BD8BD1 /* MentionModel+InboxItem.swift in Sources */,
CDB45C5A2AF0AEFE00A1FF08 /* AlternativeIconLabel.swift in Sources */,
50811B302A92049B006BA3F2 /* APICommunityView+Mock.swift in Sources */,
Expand Down Expand Up @@ -3525,6 +3536,7 @@
CD4DBC032A6F803C001A1E61 /* ReplyToPost.swift in Sources */,
CD6483302A38D31C00EE6CA3 /* UpvoteCounterView.swift in Sources */,
032DD2FD2AC3594B00F1B33D /* LinkAttatchmentView.swift in Sources */,
0355DA4D2B5EB51900CDF5A5 /* InstanceModel+ContentModel.swift in Sources */,
88B165B82A8643F4007C9115 /* View+NavigationBarColor.swift in Sources */,
030AC0522A64666C00037155 /* UserSettingsView.swift in Sources */,
CDA2C5262A705D6000649D5A /* PostEditor.swift in Sources */,
Expand Down
10 changes: 10 additions & 0 deletions Mlem/API/APIClient/APIClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,16 @@ extension APIClient {
)
return try await perform(request: request)
}

@discardableResult
func fetchInstanceList() async throws -> [InstanceStub] {
if let url = URL(string: "https://raw.githubusercontent.com/mlemgroup/mlem-stats/master/output/instances_by_score.json") {
if let data = try? await urlSession.data(from: url).0 {
return try decode([InstanceStub].self, from: data)
}
}
return []
}
}

// MARK: - Object Resolving methods
Expand Down
2 changes: 1 addition & 1 deletion Mlem/Enums/Content Type.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
import Foundation

enum ContentType: Int, Codable {
case post, comment, community, user, message, mention, reply
case post, comment, community, user, message, mention, reply, instance
}
4 changes: 2 additions & 2 deletions Mlem/Enums/SearchTab.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//

enum SearchTab: String, CaseIterable, Identifiable {
case topResults, communities, users
case topResults, communities, users, instances

var id: Self { self }

Expand All @@ -19,5 +19,5 @@ enum SearchTab: String, CaseIterable, Identifiable {
}
}

static var homePageCases: [SearchTab] = [.communities, .users]
static var homePageCases: [SearchTab] = [.communities, .users, .instances]
}
19 changes: 19 additions & 0 deletions Mlem/Models/Content/Instance/InstanceModel+ContentModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// InstanceModel+ContentModel.swift
// Mlem
//
// Created by Sjmarf on 22/01/2024.
//

import Foundation

extension InstanceModel: ContentModel {
var uid: ContentModelIdentifier { .init(contentType: .instance, contentId: name.hash) }
var imageUrls: [URL] {
if let url = avatar {
return [url.withIconSize(128)]
}
return []
}
var searchResultScore: Int { self.userCount ?? 0 }
}
27 changes: 21 additions & 6 deletions Mlem/Models/Content/Instance/InstanceModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,14 @@
import SwiftUI

struct InstanceModel {
var instanceId: Int!
var name: String!
var displayName: String!
var description: String?
var avatar: URL?
var banner: URL?
var administrators: [UserModel]?
var url: URL!
var version: SiteVersion?
var creationDate: Date!
var creationDate: Date?

// From APISiteView
var userCount: Int?
Expand Down Expand Up @@ -54,6 +53,12 @@ struct InstanceModel {
update(with: site)
}

init(from stub: InstanceStub) {
self.update(with: stub)
}

var name: String { url.host() ?? displayName }

mutating func update(with response: SiteResponse) {
administrators = response.admins.map {
var user = UserModel(from: $0)
Expand Down Expand Up @@ -107,8 +112,7 @@ struct InstanceModel {
}

mutating func update(with site: APISite) {
instanceId = site.id
name = site.name
displayName = site.name
description = site.sidebar
avatar = site.iconUrl
banner = site.bannerUrl
Expand All @@ -120,6 +124,16 @@ struct InstanceModel {
}
}

mutating func update(with stub: InstanceStub) {
displayName = stub.name
url = URL(string: "https://\(stub.host)")
version = stub.version
userCount = stub.userCount
if let avatar = stub.avatar {
self.avatar = URL(string: avatar)
}
}

func firstSlurFilterMatch(_ input: String) -> String? {
do {
if let slurFilterRegex {
Expand All @@ -145,6 +159,7 @@ extension InstanceModel: Hashable {

/// Hashes all fields for which state changes should trigger view updates.
func hash(into hasher: inout Hasher) {
hasher.combine(instanceId)
hasher.combine(url)
hasher.combine(creationDate)
}
}
16 changes: 16 additions & 0 deletions Mlem/Models/Content/Instance/InstanceStub.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// InstanceStub.swift
// Mlem
//
// Created by Sjmarf on 22/01/2024.
//

import Foundation

struct InstanceStub: Codable {
let name: String
let host: String
let avatar: String?
let version: SiteVersion
let userCount: Int
}
2 changes: 1 addition & 1 deletion Mlem/Models/Trackers/ContentTracker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class ContentTracker<Content: ContentModel>: ObservableObject {
}
currentTask = Task(priority: .userInitiated) { [self] in
do {
let items = try await self.loadItems(page)
let items = try await self.loadItems(1)
RunLoop.main.perform { [self] in
self.replaceAll(with: items)
}
Expand Down
8 changes: 7 additions & 1 deletion Mlem/Models/Trackers/RecentSearchesTracker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class RecentSearchesTracker: ObservableObject {
@Published var recentSearches: [AnyContentModel] = .init()

/// clears recentSearches and loads new values based on the current account
func reloadRecentSearches(accountId: String?) async throws {
func reloadRecentSearches(accountId: String?, instances: [InstanceModel]) async throws {
defer { hasLoaded = true }

if let accountId {
Expand All @@ -36,6 +36,12 @@ class RecentSearchesTracker: ObservableObject {
case .user:
let user = try await personRepository.loadUser(for: id.contentId)
newSearches.append(AnyContentModel(user))
case .instance:
if let instance = instances.first(where: { $0.name.hash == id.contentId }) {
newSearches.append(AnyContentModel(instance))
} else {
print("Recent search error: cannot find instance sub")
}
default:
assertionFailure("Received unexpected content type in recent searches \(id.contentType)")
return
Expand Down
2 changes: 1 addition & 1 deletion Mlem/Navigation/Routes/AppRoutes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import Foundation
///
enum AppRoute: Routable {
case community(CommunityModel)
case instance(String, InstanceModel? = nil)
case instance(String? = nil, InstanceModel? = nil)

@available(*, deprecated, message: "Use .userProfile instead.")
case apiPerson(APIPerson)
Expand Down
32 changes: 17 additions & 15 deletions Mlem/Views/Shared/BadgeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,22 +76,24 @@ struct BadgeView: View {
self.label = "Unsupported Badge"
if let host = url.host(), host == "img.shields.io" {
let path = url.pathComponents
decodeBadgeType(path)
decodeLabel(path[2])
if let components = URLComponents(url: url, resolvingAgainstBaseURL: false) {
if let parameters = components.queryItems {
for parameter in parameters {
switch parameter.name {
case "logo":
if let value = parameter.value {
decodeLogo(name: value)
if path.count >= 3 {
decodeBadgeType(path)
decodeLabel(path[2])
if let components = URLComponents(url: url, resolvingAgainstBaseURL: false) {
if let parameters = components.queryItems {
for parameter in parameters {
switch parameter.name {
case "logo":
if let value = parameter.value {
decodeLogo(name: value)
}
case "color":
if let value = parameter.value {
decodeColor(value)
}
default:
break
}
case "color":
if let value = parameter.value {
decodeColor(value)
}
default:
break
}
}
}
Expand Down
16 changes: 9 additions & 7 deletions Mlem/Views/Shared/Instance/InstanceDetailsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@ struct InstanceDetailsView: View {

var body: some View {
VStack(spacing: 16) {
box {
HStack {
Label(instance.creationDate.dateString, systemImage: Icons.cakeDay)
Text("•")
Label(instance.creationDate.getRelativeTime(unitsStyle: .abbreviated), systemImage: Icons.time)
if let date = instance.creationDate {
box {
HStack {
Label(date.dateString, systemImage: Icons.cakeDay)
Text("•")
Label(date.getRelativeTime(unitsStyle: .abbreviated), systemImage: Icons.time)
}
.foregroundStyle(.secondary)
.font(.footnote)
}
.foregroundStyle(.secondary)
.font(.footnote)
}
HStack(spacing: 16) {
box {
Expand Down
11 changes: 6 additions & 5 deletions Mlem/Views/Shared/Instance/InstanceView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ struct InstanceView: View {

@State var selectedTab: InstanceViewTab = .about

init(domainName: String, instance: InstanceModel? = nil) {
_domainName = State(wrappedValue: domainName)
init(domainName: String? = nil, instance: InstanceModel? = nil) {
_domainName = State(wrappedValue: domainName ?? instance?.name ?? "")
var instance = instance
if domainName == siteInformation.instance?.url.host() {
instance = siteInformation.instance ?? instance
Expand All @@ -71,7 +71,7 @@ struct InstanceView: View {
VStack(spacing: 5) {
if errorDetails == nil {
if let instance {
Text(instance.name)
Text(instance.displayName)
.font(.title)
.fontWeight(.semibold)
.lineLimit(1)
Expand All @@ -94,7 +94,7 @@ struct InstanceView: View {
.padding(.bottom, 5)
if let errorDetails {
ErrorView(errorDetails)
} else if let instance {
} else if let instance, instance.creationDate != nil {
VStack(spacing: 0) {
VStack(spacing: 4) {
Divider()
Expand All @@ -112,6 +112,7 @@ struct InstanceView: View {
} else {
Text("No Description")
.foregroundStyle(.secondary)
.padding(.top)
}
case .administrators:
if let administrators = instance.administrators {
Expand Down Expand Up @@ -215,7 +216,7 @@ struct InstanceView: View {
}
}
.navigationBarColor()
.navigationTitle(instance?.name ?? domainName)
.navigationTitle(instance?.displayName ?? domainName)
.navigationBarTitleDisplayMode(.inline)
}
}
6 changes: 6 additions & 0 deletions Mlem/Views/Tabs/Search/RecentSearchesView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ struct RecentSearchesView: View {
contentTracker.update(with: AnyContentModel($0))
}
)
} else if let instance = contentModel.wrappedValue as? InstanceModel {
InstanceResultView(
instance,
complications: .withTypeLabel,
swipeActions: .init(trailingActions: [deleteSwipeAction(contentModel)])
)
}
}
.simultaneousGesture(TapGesture().onEnded {
Expand Down
Loading
Loading