Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
Sjmarf committed Jan 14, 2024
1 parent 2b2d4f4 commit 5cf1c2b
Show file tree
Hide file tree
Showing 20 changed files with 447 additions and 21 deletions.
28 changes: 28 additions & 0 deletions Mlem.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
03A2767B2AFE560000C0D66B /* CommunityModel+SwipeActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03A2767A2AFE560000C0D66B /* CommunityModel+SwipeActions.swift */; };
03A2767D2AFE656700C0D66B /* UserModel+MenuFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03A2767C2AFE656700C0D66B /* UserModel+MenuFunctions.swift */; };
03A40DAD2AD5EA11005F019F /* NoPostsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03A40DAC2AD5EA11005F019F /* NoPostsView.swift */; };
03A54C322B5331F30064CCDE /* InstanceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03A54C312B5331F30064CCDE /* InstanceView.swift */; };
03A54C352B533BC50064CCDE /* InstanceModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03A54C342B533BC50064CCDE /* InstanceModel.swift */; };
03A54C372B545A430064CCDE /* InstanceModel+MenuFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03A54C362B545A430064CCDE /* InstanceModel+MenuFunctions.swift */; };
03B643572A6864CD00F65700 /* TabBarSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03B643562A6864CD00F65700 /* TabBarSettingsView.swift */; };
03B7AAEF2ABCB9DC00068B23 /* ContentTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03B7AAEE2ABCB9DC00068B23 /* ContentTracker.swift */; };
03B7AAF12ABE404300068B23 /* ContentModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03B7AAF02ABE404300068B23 /* ContentModel.swift */; };
Expand Down Expand Up @@ -608,6 +611,9 @@
03A2767A2AFE560000C0D66B /* CommunityModel+SwipeActions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CommunityModel+SwipeActions.swift"; sourceTree = "<group>"; };
03A2767C2AFE656700C0D66B /* UserModel+MenuFunctions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserModel+MenuFunctions.swift"; sourceTree = "<group>"; };
03A40DAC2AD5EA11005F019F /* NoPostsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoPostsView.swift; sourceTree = "<group>"; };
03A54C312B5331F30064CCDE /* InstanceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstanceView.swift; sourceTree = "<group>"; };
03A54C342B533BC50064CCDE /* InstanceModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstanceModel.swift; sourceTree = "<group>"; };
03A54C362B545A430064CCDE /* InstanceModel+MenuFunctions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "InstanceModel+MenuFunctions.swift"; sourceTree = "<group>"; };
03B643562A6864CD00F65700 /* TabBarSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarSettingsView.swift; sourceTree = "<group>"; };
03B7AAEE2ABCB9DC00068B23 /* ContentTracker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentTracker.swift; sourceTree = "<group>"; };
03B7AAF02ABE404300068B23 /* ContentModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentModel.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1313,6 +1319,23 @@
path = Protocol;
sourceTree = "<group>";
};
03A54C302B5331D50064CCDE /* Instance */ = {
isa = PBXGroup;
children = (
03A54C312B5331F30064CCDE /* InstanceView.swift */,
);
path = Instance;
sourceTree = "<group>";
};
03A54C332B533BBA0064CCDE /* Instance */ = {
isa = PBXGroup;
children = (
03A54C342B533BC50064CCDE /* InstanceModel.swift */,
03A54C362B545A430064CCDE /* InstanceModel+MenuFunctions.swift */,
);
path = Instance;
sourceTree = "<group>";
};
03B643552A6863E800F65700 /* TabBar */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -2022,6 +2045,7 @@
6322A5CA27F77A4D00135D4F /* Loading View.swift */,
6386E03F2A045723006B3C1D /* Website Icon Complex.swift */,
63D24EDD2A169F2A005CCA81 /* Markdown View.swift */,
03A54C302B5331D50064CCDE /* Instance */,
03BAA2392A57DC1400D48252 /* PublishedTimestampView.swift */,
6374570F2A18CB6600B69C03 /* Custom Text Field.swift */,
B11D72822A49FAA7009DC22F /* Cached Image.swift */,
Expand Down Expand Up @@ -2688,6 +2712,7 @@
CD4368C22AE2409D00BD8BD1 /* Inbox */,
CDEBC3272A9A57F200518D9D /* Content Model Identifier.swift */,
CDEBC3292A9A580B00518D9D /* Post Model.swift */,
03A54C332B533BBA0064CCDE /* Instance */,
03FD64FD2AE538C600957AA9 /* Community */,
030D00862AD1BB0D00953B1D /* User */,
03B7AAF02ABE404300068B23 /* ContentModel.swift */,
Expand Down Expand Up @@ -3037,6 +3062,7 @@
03A18CBD2B1005A400BA69D2 /* SaveUserSettings.swift in Sources */,
03E0B9C82A61F0F400FED265 /* AdvancedSettingsView.swift in Sources */,
63344C622A08460D001BC616 /* View+Border.swift in Sources */,
03A54C352B533BC50064CCDE /* InstanceModel.swift in Sources */,
637218702A3A2AAD008C4816 /* ResolveObject.swift in Sources */,
CDE6A8162A490AE00062D161 /* InboxMessageBodyView.swift in Sources */,
CD04D5DD2A361564008EF95B /* ReplyButtonView.swift in Sources */,
Expand Down Expand Up @@ -3071,6 +3097,7 @@
B1955A1D2A606B950056CF99 /* Easter Rewards.swift in Sources */,
CDB0117F2A6F70A000D043EB /* Editor Tracker.swift in Sources */,
030E86482AC6FD1D000283A6 /* _assignIfNotEqual.swift in Sources */,
03A54C372B545A430064CCDE /* InstanceModel+MenuFunctions.swift in Sources */,
6354F30A2A2E20040074C08D /* View+Alert.swift in Sources */,
0315E9F52B41C3EB00E3BA88 /* CommunityView.swift in Sources */,
03EC92992AC0BF8A007BBE7E /* APIClient+Pictrs.swift in Sources */,
Expand Down Expand Up @@ -3347,6 +3374,7 @@
03EF1D0C2B434CB10056175C /* CommunityStatsView.swift in Sources */,
6363D5C727EE196700E34822 /* ContentView.swift in Sources */,
03F4DC9D2B193F4C00556C67 /* MatrixLinkView.swift in Sources */,
03A54C322B5331F30064CCDE /* InstanceView.swift in Sources */,
6D8F08FF2A4029AE003EB4FD /* Community List View.swift in Sources */,
035EB0CA2A8687C200227859 /* JumpButtonView.swift in Sources */,
5016A2B12A67EB8600B257E8 /* UIViewController+TopMostViewController.swift in Sources */,
Expand Down
2 changes: 1 addition & 1 deletion Mlem/API/APIClient/APIClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class APIClient {
let decoder: JSONDecoder
let transport: (URLSession, URLRequest) async throws -> (Data, URLResponse)

private(set) var session: APISession = .undefined
var session: APISession = .undefined

// MARK: - Initialisation

Expand Down
6 changes: 5 additions & 1 deletion Mlem/Enums/AvatarType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Foundation

/// Enum of things that can have avatars
enum AvatarType {
case user, community
case user, community, instance
}

extension AvatarType: AssociatedIcon {
Expand All @@ -19,6 +19,8 @@ extension AvatarType: AssociatedIcon {
return Icons.user
case .community:
return Icons.community
case .instance:
return Icons.instance
}
}

Expand All @@ -28,6 +30,8 @@ extension AvatarType: AssociatedIcon {
return Icons.userFill
case .community:
return Icons.communityFill
case .instance:
return Icons.instance
}
}
}
2 changes: 2 additions & 0 deletions Mlem/Extensions/View Modifiers/View+HandleLemmyLinks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ struct HandleLemmyLinksDisplay: ViewModifier {
UserView(user: user, communityContext: communityContext)
.environmentObject(appState)
.environmentObject(quickLookState)
case let .instance(domainName, instance):
InstanceView(domainName: domainName, instance: instance)
case let .postLinkWithContext(post):
ExpandedPost(post: post.post, community: post.community, scrollTarget: post.scrollTarget)
.environmentObject(post.postTracker)
Expand Down
15 changes: 15 additions & 0 deletions Mlem/Models/Content/Community/CommunityModel+MenuFunctions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,21 @@ extension CommunityModel {
functions.append(.standard(function))
functions.append(.standard(favoriteMenuFunction(callback)))
}
if let instanceHost = self.communityUrl.host() {
let instance: InstanceModel?
if let site {
instance = .init(from: site)
} else {
instance = nil
}
functions.append(
.navigationMenuFunction(
text: instanceHost,
imageName: Icons.instance,
destination: .instance(instanceHost, instance)
)
)
}
functions.append(
.standardMenuFunction(
text: "Copy Name",
Expand Down
17 changes: 17 additions & 0 deletions Mlem/Models/Content/Instance/InstanceModel+MenuFunctions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// InstanceModel+MenuFunctions.swift
// Mlem
//
// Created by Sjmarf on 14/01/2024.
//

import Foundation

extension InstanceModel {
func menuFunctions() -> [MenuFunction] {
if let url {
return [.shareMenuFunction(url: url)]
}
return []
}
}
63 changes: 63 additions & 0 deletions Mlem/Models/Content/Instance/InstanceModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//
// InstanceModel.swift
// Mlem
//
// Created by Sjmarf on 13/01/2024.
//

import SwiftUI

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

init(from response: SiteResponse) {
self.update(with: response)
}

init(from site: APISite) {
self.update(with: site)
}

mutating func update(with response: SiteResponse) {
self.administrators = response.admins.map {
var user = UserModel(from: $0, usesExternalData: true)
user.isAdmin = true
return user
}
self.update(with: response.siteView.site)
}

mutating func update(with site: APISite) {
instanceId = site.id
name = site.name
description = site.sidebar
avatar = site.iconUrl
banner = site.bannerUrl

if var components = URLComponents(string: site.inboxUrl) {
components.path = ""
url = components.url
}
}
}

extension InstanceModel: Identifiable {
var id: Int { hashValue }
}

extension InstanceModel: Hashable {
static func == (lhs: InstanceModel, rhs: InstanceModel) -> Bool {
return lhs.hashValue == rhs.hashValue
}

/// Hashes all fields for which state changes should trigger view updates.
func hash(into hasher: inout Hasher) {
hasher.combine(instanceId)
}
}
9 changes: 9 additions & 0 deletions Mlem/Models/Content/User/UserModel+MenuFunctions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ extension UserModel {

func menuFunctions(_ callback: @escaping (_ item: Self) -> Void = { _ in }) -> [MenuFunction] {
var functions: [MenuFunction] = .init()
if let instanceHost = self.profileUrl.host() {
functions.append(
.navigationMenuFunction(
text: instanceHost,
imageName: Icons.instance,
destination: .instance(instanceHost)
)
)
}
functions.append(
.standardMenuFunction(
text: "Copy Username",
Expand Down
7 changes: 6 additions & 1 deletion Mlem/Models/Content/User/UserModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ struct UserModel {
"https://lemmy.ml/u/sjmarf"
]

/// Is True when the UserModel was created using data fetched from an instance other than the logged-in instance
var usesExternalData: Bool = false

/// Creates a UserModel from an GetPersonDetailsResponse
/// - Parameter response: GetPersonDetailsResponse to create a UserModel representation of
init(from response: GetPersonDetailsResponse) {
Expand All @@ -75,11 +78,13 @@ struct UserModel {

/// Creates a UserModel from an APIPersonView
/// - Parameter apiPersonView: APIPersonView to create a UserModel representation of
init(from personView: APIPersonView) {
init(from personView: APIPersonView, usesExternalData: Bool = false) {
self.init(from: personView.person)

self.postCount = personView.counts.postCount
self.commentCount = personView.counts.commentCount

self.usesExternalData = usesExternalData

// TODO: 0.18 Deprecation
@Dependency(\.siteInformation) var siteInformation
Expand Down
23 changes: 23 additions & 0 deletions Mlem/Models/Menu Function.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@ enum MenuFunction: Identifiable {
return shareMenuFunction.id
case let .shareImage(shareImageFunction):
return shareImageFunction.id
case let .navigation(navigationMenuFunction):
return navigationMenuFunction.id
}
}

case standard(StandardMenuFunction)
case shareUrl(ShareMenuFunction)
case shareImage(ShareImageFunction)
case navigation(NavigationMenuFunction)
}

// some convenience initializers because MenuFunction.standard(StandardMenuFunction...) is ugly
Expand All @@ -43,6 +46,18 @@ extension MenuFunction {
))
}

static func navigationMenuFunction(
text: String,
imageName: String,
destination: AppRoute
) -> MenuFunction {
MenuFunction.navigation(NavigationMenuFunction(
text: text,
imageName: imageName,
destination: destination
))
}

static func shareMenuFunction(url: URL) -> MenuFunction {
MenuFunction.shareUrl(ShareMenuFunction(url: url))
}
Expand Down Expand Up @@ -79,3 +94,11 @@ struct StandardMenuFunction: Identifiable {
let enabled: Bool
let callback: () -> Void
}

struct NavigationMenuFunction: Identifiable {
var id: String { text }

let text: String
let imageName: String
let destination: AppRoute
}
1 change: 1 addition & 0 deletions Mlem/Navigation/Routes/AppRoutes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ enum AppRoute: Routable {
case apiPost(APIPost)

case community(CommunityModel)
case instance(String, InstanceModel? = nil)

@available(*, deprecated, message: "Use .userProfile instead.")
case apiPerson(APIPerson)
Expand Down
14 changes: 14 additions & 0 deletions Mlem/Repositories/PersonRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
import Dependencies
import Foundation

enum PersonRequestError: Error {
case notFound
}

class PersonRepository {
@Dependency(\.apiClient) private var apiClient

Expand Down Expand Up @@ -47,6 +51,16 @@ class PersonRepository {
try await apiClient.getPersonDetails(for: id, limit: limit, savedOnly: savedOnly)
}

func loadUserDetails(for url: URL, limit: Int, savedOnly: Bool = false) async throws -> GetPersonDetailsResponse {
let result = try await apiClient.resolve(query: url.absoluteString)
switch result {
case .person(let person):
return try await loadUserDetails(for: person.person.id, limit: limit, savedOnly: savedOnly)
default:
throw PersonRequestError.notFound
}
}

func getUnreadCounts() async throws -> APIPersonUnreadCounts {
do {
return try await apiClient.getUnreadCount()
Expand Down
28 changes: 23 additions & 5 deletions Mlem/Views/Shared/Avatars/DefaultAvatarView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,27 @@ struct DefaultAvatarView: View {
let avatarType: AvatarType

var body: some View {
Image(systemName: avatarType.iconNameFill)
.resizable()
.scaledToFill()
.symbolRenderingMode(.multicolor)
.foregroundStyle(Color.gray.gradient, .white)
switch avatarType {
case .instance:
ZStack {
Circle()
.fill(Color.gray.gradient)
GeometryReader { frame in
Image(systemName: avatarType.iconNameFill)
.resizable()
.aspectRatio(contentMode: .fit)
.padding(.horizontal, frame.size.width * 0.2)
.foregroundStyle(.white)
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
default:
Image(systemName: avatarType.iconNameFill)
.resizable()
.scaledToFill()
.symbolRenderingMode(.multicolor)
.foregroundStyle(Color.gray.gradient, .white)
}
}
}

Expand All @@ -26,6 +42,8 @@ struct DefaultAvatarView: View {
.frame(width: 100, height: 100)
DefaultAvatarView(avatarType: .community)
.frame(width: 100, height: 100)
DefaultAvatarView(avatarType: .instance)
.frame(width: 100, height: 100)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(.black)
Expand Down
Loading

0 comments on commit 5cf1c2b

Please sign in to comment.