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

Sort Menu Changes #589

Closed
wants to merge 21 commits into from
12 changes: 12 additions & 0 deletions Mlem.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
030AC0522A64666C00037155 /* UserSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 030AC0512A64666C00037155 /* UserSettingsView.swift */; };
030D4AE62AA1273200A3393D /* ErrorDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = 030D4AE52AA1273200A3393D /* ErrorDetails.swift */; };
030D4AE82AA1278400A3393D /* ErrorDetails+Mock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 030D4AE72AA1278400A3393D /* ErrorDetails+Mock.swift */; };
032109522AACEFCF00912DFC /* APISiteVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 032109512AACEFCF00912DFC /* APISiteVersion.swift */; };
032109542AAD174000912DFC /* CommentSortMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 032109532AAD174000912DFC /* CommentSortMenu.swift */; };
032109562AAD17B900912DFC /* SortMenuButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 032109552AAD17B900912DFC /* SortMenuButtonStyle.swift */; };
034C724F2A82B61200B8A4B8 /* LayoutWidgetTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 034C724E2A82B61200B8A4B8 /* LayoutWidgetTracker.swift */; };
035EB0CA2A8687C200227859 /* JumpButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035EB0C92A8687C200227859 /* JumpButtonView.swift */; };
038A16DF2A75172C0087987E /* LayoutWidgetEditView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 038A16DE2A75172C0087987E /* LayoutWidgetEditView.swift */; };
Expand Down Expand Up @@ -446,6 +449,9 @@
030AC0512A64666C00037155 /* UserSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSettingsView.swift; sourceTree = "<group>"; };
030D4AE52AA1273200A3393D /* ErrorDetails.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorDetails.swift; sourceTree = "<group>"; };
030D4AE72AA1278400A3393D /* ErrorDetails+Mock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ErrorDetails+Mock.swift"; sourceTree = "<group>"; };
032109512AACEFCF00912DFC /* APISiteVersion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APISiteVersion.swift; sourceTree = "<group>"; };
032109532AAD174000912DFC /* CommentSortMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommentSortMenu.swift; sourceTree = "<group>"; };
032109552AAD17B900912DFC /* SortMenuButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SortMenuButtonStyle.swift; sourceTree = "<group>"; };
034C724E2A82B61200B8A4B8 /* LayoutWidgetTracker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LayoutWidgetTracker.swift; sourceTree = "<group>"; };
035EB0C92A8687C200227859 /* JumpButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JumpButtonView.swift; sourceTree = "<group>"; };
038A16DE2A75172C0087987E /* LayoutWidgetEditView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LayoutWidgetEditView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1364,6 +1370,8 @@
isa = PBXGroup;
children = (
632578172A29F83C00446A66 /* PostSortMenu.swift */,
032109532AAD174000912DFC /* CommentSortMenu.swift */,
032109552AAD17B900912DFC /* SortMenuButtonStyle.swift */,
63344C702A098060001BC616 /* Sidebar View.swift */,
6D405B002A43E79400C65F9C /* Sidebar Header Avatar.swift */,
6D405B022A43E7DB00C65F9C /* Sidebar Header Label.swift */,
Expand Down Expand Up @@ -1568,6 +1576,7 @@
637218152A3A2AAD008C4816 /* APILocalSiteRateLimit.swift */,
637218162A3A2AAD008C4816 /* APIFederatedInstances.swift */,
637218172A3A2AAD008C4816 /* APIMyUserInfo.swift */,
032109512AACEFCF00912DFC /* APISiteVersion.swift */,
637218182A3A2AAD008C4816 /* APILanguage.swift */,
637218192A3A2AAD008C4816 /* APITagline.swift */,
6372181A2A3A2AAD008C4816 /* APILocalSite.swift */,
Expand Down Expand Up @@ -2702,6 +2711,7 @@
637218602A3A2AAD008C4816 /* EditPost.swift in Sources */,
6D693A402A51147E009E2D76 /* APIPostReportView.swift in Sources */,
637218562A3A2AAD008C4816 /* APILocalSite.swift in Sources */,
032109562AAD17B900912DFC /* SortMenuButtonStyle.swift in Sources */,
CDA217EE2A630F3300BDA173 /* ReportPost.swift in Sources */,
CDCBD7262A8D69A200387A2C /* Instance Picker View.swift in Sources */,
6372185B2A3A2AAD008C4816 /* APICommunityView.swift in Sources */,
Expand All @@ -2713,6 +2723,7 @@
88B165B82A8643F4007C9115 /* View - NavigationBar Color.swift in Sources */,
030AC0522A64666C00037155 /* UserSettingsView.swift in Sources */,
CDA2C5262A705D6000649D5A /* PostEditor.swift in Sources */,
032109542AAD174000912DFC /* CommentSortMenu.swift in Sources */,
6372184A2A3A2AAD008C4816 /* APIPost.swift in Sources */,
6D693A3E2A5113DF009E2D76 /* CreatePostReport.swift in Sources */,
CD391F942A533B7700E213B5 /* EditorModelProtocol.swift in Sources */,
Expand All @@ -2731,6 +2742,7 @@
637218462A3A2AAD008C4816 /* APIComment.swift in Sources */,
CDCBD7282A8D6B7700387A2C /* Instance Picker View Logic.swift in Sources */,
637457102A18CB6600B69C03 /* Custom Text Field.swift in Sources */,
032109522AACEFCF00912DFC /* APISiteVersion.swift in Sources */,
038A16E12A75AA880087987E /* LayoutWidgetModel.swift in Sources */,
63344C4F2A07BD2A001BC616 /* Filters Tracker.swift in Sources */,
50811B2C2A920443006BA3F2 /* Date+Mock.swift in Sources */,
Expand Down
54 changes: 54 additions & 0 deletions Mlem/API/Models/Site/APISiteVersion.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//
// APISiteVersionNumber.swift
// Mlem
//
// Created by Sjmarf on 09/09/2023.
//

import Foundation

struct APISiteVersion {
Sjmarf marked this conversation as resolved.
Show resolved Hide resolved
let major: Int
let minor: Int
let patch: Int

static let infinity: APISiteVersion = .init(major: 999, minor: 0, patch: 0)
static let zero: APISiteVersion = .init(major: 0, minor: 0, patch: 0)
}

extension APISiteVersion: Codable {
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let versionString = try container.decode(String.self)
let components = versionString.split(separator: ".").compactMap { Int($0) }

guard components.count == 3 else {
throw DecodingError.dataCorruptedError(
in: container,
debugDescription: "Invalid site version number format. Must be formatted as \"x.x.x\", not \"\(versionString)\"."
)
}

major = components[0]
minor = components[1]
patch = components[2]
}

func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
let versionString = "\(major).\(minor).\(patch)"
try container.encode(versionString)
}
}

extension APISiteVersion: Equatable, Comparable {
static func < (lhs: APISiteVersion, rhs: APISiteVersion) -> Bool {
if lhs.major != rhs.major {
return lhs.major < rhs.major
}
if lhs.minor != rhs.minor {
return lhs.minor < rhs.minor
}
return lhs.patch < rhs.patch
}
}
2 changes: 1 addition & 1 deletion Mlem/API/Requests/Site/GetSite.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ struct GetSiteRequest: APIGetRequest {
struct SiteResponse: Decodable {
let siteView: APISiteView
let admins: [APIPersonView]
let version: String
let version: APISiteVersion
let myUser: APIMyUserInfo?
let federatedInstances: APIFederatedInstances?
let allLanguages: [APILanguage]
Expand Down
2 changes: 0 additions & 2 deletions Mlem/App Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,6 @@ struct AppConstants {
static let mostCommentsSymbolNameFill: String = "bubble.left.and.bubble.right.fill"
static let topSymbolName: String = "trophy"
static let topSymbolNameFill: String = "trophy.fill"
static let timeSymbolName: String = "calendar.day.timeline.leading"
static let timeSymbolNameFill: String = "calendar.day.timeline.leading.fill"

// common operations
static let shareSymbolName: String = "square.and.arrow.up"
Expand Down
43 changes: 36 additions & 7 deletions Mlem/Enums/Settings/PostSortType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,16 @@ enum PostSortType: String, Codable, CaseIterable, Identifiable {
case old = "Old"
case newComments = "NewComments"
case mostComments = "MostComments"

case topHour = "TopHour"
case topSixHour = "TopSixHour"
case topTwelveHour = "TopTwelveHour"
case topDay = "TopDay"
case topWeek = "TopWeek"
case topMonth = "TopMonth"
case topThreeMonth = "TopThreeMonth"
case topSixMonth = "TopSixMonth"
case topNineMonth = "TopNineMonth"
case topYear = "TopYear"
case topAll = "TopAll"

Expand All @@ -30,6 +34,10 @@ enum PostSortType: String, Codable, CaseIterable, Identifiable {

var description: String {
switch self {
case .newComments:
return "New comments"
case .mostComments:
return "Most comments"
case .topHour:
return "Top of the last hour"
case .topSixHour:
Expand All @@ -42,6 +50,12 @@ enum PostSortType: String, Codable, CaseIterable, Identifiable {
return "Top of the week"
case .topMonth:
return "Top of the month"
case .topThreeMonth:
return "Top of the last three months"
case .topSixMonth:
return "Top of the last six months"
case .topNineMonth:
return "Top of the last nine months"
case .topYear:
return "Top of the year"
case .topAll:
Expand All @@ -50,31 +64,46 @@ enum PostSortType: String, Codable, CaseIterable, Identifiable {
return label
}
}

var minimumVersion: APISiteVersion {
switch self {
case .topThreeMonth, .topSixMonth, .topNineMonth:
return APISiteVersion(major: 0, minor: 18, patch: 1)
default:
return .zero
}
}
}

extension PostSortType: SettingsOptions {
var label: String {
switch self {
case .newComments:
return "New comments"
return "New"
case .mostComments:
return "Most comments"
return "Most"
case .topHour:
return "Hour"
case .topSixHour:
return "Six hours"
return "6 Hours"
case .topTwelveHour:
return "Twelve hours"
return "12 Hours"
case .topDay:
return "Day"
case .topWeek:
return "Week"
case .topMonth:
return "Month"
case .topThreeMonth:
return "3 Months"
case .topSixMonth:
return "6 Months"
case .topNineMonth:
return "9 Months"
case .topYear:
return "Year"
case .topAll:
return "All time"
return "All Time"
default:
return rawValue
}
Expand All @@ -90,7 +119,7 @@ extension PostSortType: AssociatedIcon {
case .old: return AppConstants.oldSortSymbolName
case .newComments: return AppConstants.newCommentsSymbolName
case .mostComments: return AppConstants.mostCommentsSymbolName
default: return AppConstants.timeSymbolName
default: return AppConstants.topSymbolName
}
}

Expand All @@ -102,7 +131,7 @@ extension PostSortType: AssociatedIcon {
case .old: return AppConstants.oldSortSymbolNameFill
case .newComments: return AppConstants.newCommentsSymbolNameFill
case .mostComments: return AppConstants.mostCommentsSymbolNameFill
default: return AppConstants.timeSymbolNameFill
default: return AppConstants.topSymbolNameFill
}
}
}
2 changes: 2 additions & 0 deletions Mlem/Models/Trackers/SiteInformationTracker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ class SiteInformationTracker: ObservableObject {
@Dependency(\.apiClient) var apiClient

@Published private(set) var enableDownvotes = true
@Published private(set) var version: APISiteVersion?

func load() {
Task {
let information = try await apiClient.loadSiteInformation()
enableDownvotes = information.siteView.localSite.enableDownvotes
version = information.version
}
}
}
17 changes: 7 additions & 10 deletions Mlem/Views/Shared/Posts/Expanded Post.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ struct ExpandedPost: View {
@State var commentSortingType: CommentSortType = .appStorageValue()
@State private var postLayoutMode: LargePost.LayoutMode = .maximize

@State var showingSortMenu: Bool = false

var body: some View {
contentView
.environmentObject(commentTracker)
Expand All @@ -86,6 +88,9 @@ struct ExpandedPost: View {
commentTracker.comments = sortComments(commentTracker.comments, by: newSortingType)
}
}
.sheet(isPresented: $showingSortMenu) {
CommentSortMenu(isPresented: $showingSortMenu, selected: $commentSortingType)
}
}

private var contentView: some View {
Expand Down Expand Up @@ -306,16 +311,8 @@ struct ExpandedPost: View {
}

private var toolbarMenu: some View {
Menu {
ForEach(CommentSortType.allCases, id: \.self) { type in
Button {
commentSortingType = type
} label: {
Label(type.description, systemImage: type.iconName)
}
.disabled(type == commentSortingType)
}

Button {
showingSortMenu = true
} label: {
Label(commentSortingType.description, systemImage: commentSortingType.iconName)
}
Expand Down
44 changes: 44 additions & 0 deletions Mlem/Views/Tabs/Feeds/Components/CommentSortMenu.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// CommentSortMenu.swift
// Mlem
//
// Created by Sjmarf on 09/09/2023
//

import SwiftUI
import Dependencies

struct CommentSortMenu: View {
@Dependency(\.siteInformation) var siteInformation

@Binding var isPresented: Bool
@Binding var selected: CommentSortType

var body: some View {
VStack {
VStack(spacing: 15) {
sortOption(.hot)
sortOption(.new)
sortOption(.old)
sortOption(.top)
}
Spacer()
}
.padding(20)
.presentationDetents([.height(300)])
.background(Color(UIColor.systemGroupedBackground))
}

@ViewBuilder
private func sortOption(_ sortType: CommentSortType) -> some View {
Button {
isPresented = false
selected = sortType
} label: {
Label(sortType.label, systemImage: sortType.iconName)
}
.buttonStyle(SortMenuButtonStyle(isSelected: sortType == selected))
.accessibilityLabel(sortType.description)
.accessibilityHint("Double-tap to select")
Sjmarf marked this conversation as resolved.
Show resolved Hide resolved
}
}
Loading