-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Eric Andrews <eric.b.andrews.auto@protonmail.com>
- Loading branch information
1 parent
c38727f
commit 6cf19de
Showing
29 changed files
with
774 additions
and
135 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
Mlem/App/Utility/Extensions/Content Models/CommunityOrPersonStub+Extensions.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// | ||
// CommunityOrPersonStub+Extensions.swift | ||
// Mlem | ||
// | ||
// Created by Sjmarf on 30/05/2024. | ||
// | ||
|
||
import MlemMiddleware | ||
import UIKit | ||
|
||
extension CommunityOrPersonStub { | ||
func copyFullNameWithPrefix() { | ||
UIPasteboard.general.string = fullNameWithPrefix | ||
ToastModel.main.add(.success("Copied")) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// | ||
// Date+Extensions.swift | ||
// Mlem | ||
// | ||
// Created by Jake Shirley on 6/22/23. | ||
// | ||
|
||
import SwiftUI | ||
|
||
extension Date { | ||
// Returns strings like "3 seconds ago" and "10 days ago" | ||
func getRelativeTime(date: Date = .now, unitsStyle: RelativeDateTimeFormatter.UnitsStyle = .full) -> String { | ||
let formatter = RelativeDateTimeFormatter() | ||
formatter.unitsStyle = unitsStyle | ||
|
||
return formatter.localizedString(for: self, relativeTo: date) | ||
} | ||
|
||
// Returns strings like "5/10/2023" | ||
var dateString: String { | ||
let dateFormatter = DateFormatter() | ||
dateFormatter.dateFormat = DateFormatter.dateFormat(fromTemplate: "ddMMYY", options: 0, locale: Locale.current) | ||
return dateFormatter.string(from: self) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// | ||
// Int+Extensions.swift | ||
// Mlem | ||
// | ||
// Created by Sjmarf on 13/04/2024. | ||
// | ||
|
||
import Foundation | ||
|
||
extension Int { | ||
var abbreviated: String { | ||
if self >= 10_000_000 { | ||
return "\(Int(floor(Double(self) / 1_000_000)))M" | ||
} | ||
if self >= 1_000_000 { | ||
return "\(Double(floor(Double(self) / 100_000) / 10))M" | ||
} | ||
if self >= 10000 { | ||
return "\(Int(floor(Double(self) / 1000)))K" | ||
} | ||
if self >= 1000 { | ||
return "\(Double(floor(Double(self) / 100) / 10))K" | ||
} | ||
return String(self) | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
Mlem/App/Utility/Extensions/MarkdownConfiguration+Extensions.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// | ||
// MarkdownConfiguration+Extensions.swift | ||
// Mlem | ||
// | ||
// Created by Sjmarf on 30/05/2024. | ||
// | ||
|
||
import LemmyMarkdownUI | ||
import Nuke | ||
import SwiftUI | ||
|
||
extension MarkdownConfiguration { | ||
static let `default`: Self = .init( | ||
inlineImageLoader: loadInlineImage, | ||
imageBlockView: { AnyView(MarkdownImageView(image: $0)) } | ||
) | ||
} | ||
|
||
private func loadInlineImage(inlineImage: InlineImage) async { | ||
guard inlineImage.image == nil else { return } | ||
let imageTask = ImagePipeline.shared.imageTask(with: inlineImage.url) | ||
guard let image: UIImage = try? await imageTask.image else { return } | ||
let height = inlineImage.fontSize | ||
let width = image.size.width * (height / image.size.height) | ||
UIGraphicsBeginImageContextWithOptions(CGSize(width: width, height: height), false, 2.0) | ||
defer { UIGraphicsEndImageContext() } | ||
image.draw(in: CGRect(x: 0, y: 0, width: width, height: height)) | ||
let newImage = UIGraphicsGetImageFromCurrentImageContext() | ||
if let newImage { | ||
DispatchQueue.main.async { | ||
inlineImage.image = Image(uiImage: newImage) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
// | ||
// PersonView.swift | ||
// Mlem | ||
// | ||
// Created by Sjmarf on 30/05/2024. | ||
// | ||
|
||
import LemmyMarkdownUI | ||
import MlemMiddleware | ||
import SwiftUI | ||
|
||
struct PersonView: View { | ||
enum Tab: String, CaseIterable, Identifiable { | ||
case overview, comments, posts, communities | ||
|
||
var id: Self { self } | ||
var label: String { rawValue.capitalized } | ||
} | ||
|
||
@State var person: AnyPerson | ||
@State var selectedTab: Tab = .overview | ||
@State var isAtTop: Bool = true | ||
|
||
var body: some View { | ||
ContentLoader(model: person) { person in | ||
content(person: person) | ||
} | ||
.navigationTitle(isAtTop ? "" : (person.wrappedValue.displayName_ ?? person.wrappedValue.name)) | ||
.navigationBarTitleDisplayMode(.inline) | ||
} | ||
|
||
@ViewBuilder | ||
func content(person: any Person) -> some View { | ||
FancyScrollView(isAtTop: $isAtTop) { | ||
VStack(spacing: AppConstants.standardSpacing) { | ||
ProfileHeaderView(person, type: .person) | ||
.padding(.horizontal, AppConstants.standardSpacing) | ||
bio(person: person) | ||
if let person = person as? any Person3Providing { | ||
VStack(spacing: 0) { | ||
personContent(person: person) | ||
} | ||
.transition(.opacity) | ||
} else { | ||
VStack(spacing: 0) { | ||
Divider() | ||
ProgressView() | ||
.padding(.top) | ||
} | ||
.transition(.opacity) | ||
} | ||
} | ||
.animation(.easeOut(duration: 0.2), value: person is any Person3Providing) | ||
} | ||
.toolbar { | ||
ToolbarItem(placement: .topBarTrailing) { | ||
// TODO: | ||
ToolbarEllipsisMenu {} | ||
} | ||
} | ||
} | ||
|
||
@ViewBuilder | ||
func bio(person: any Person) -> some View { | ||
if let bio = person.description_ { | ||
Divider() | ||
VStack(spacing: AppConstants.standardSpacing) { | ||
let blocks: [BlockNode] = .init(bio) | ||
if blocks.isSimpleParagraphs, bio.count < 300 { | ||
MarkdownText(blocks, configuration: .default) | ||
.multilineTextAlignment(.center) | ||
.padding(.horizontal, AppConstants.standardSpacing) | ||
dateLabel(person: person) | ||
.frame(maxWidth: .infinity, alignment: .center) | ||
} else { | ||
Markdown(blocks, configuration: .default) | ||
.padding(.horizontal, AppConstants.standardSpacing) | ||
dateLabel(person: person) | ||
.frame(maxWidth: .infinity, alignment: .leading) | ||
} | ||
} | ||
.padding(.top, AppConstants.halfSpacing) | ||
} else { | ||
dateLabel(person: person) | ||
.frame(maxWidth: .infinity, alignment: .center) | ||
} | ||
} | ||
|
||
@ViewBuilder | ||
func dateLabel(person: any Person) -> some View { | ||
ProfileDateView(profilable: person) | ||
.padding(.horizontal, AppConstants.standardSpacing) | ||
.padding(.vertical, 2) | ||
} | ||
|
||
@ViewBuilder | ||
func personContent(person: any Person3Providing) -> some View { | ||
BubblePicker( | ||
tabs(person: person), | ||
selected: $selectedTab, | ||
withDividers: [.top, .bottom], | ||
label: \.label, | ||
value: { tab in | ||
switch tab { | ||
case .posts: | ||
person.postCount | ||
case .comments: | ||
person.commentCount | ||
case .communities: | ||
person.moderatedCommunities.count | ||
default: | ||
nil | ||
} | ||
} | ||
) | ||
} | ||
|
||
func tabs(person: any Person3Providing) -> [Tab] { | ||
var output: [Tab] = [.overview, .posts, .comments] | ||
if !person.moderatedCommunities.isEmpty { | ||
output.append(.communities) | ||
} | ||
return output | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.