Skip to content

Commit

Permalink
Merge pull request #161 from simple-login/feat/show-stats
Browse files Browse the repository at this point in the history
feat: show stats
  • Loading branch information
ntnhon authored Feb 7, 2024
2 parents c849a1c + 7a40b9d commit cea39d7
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 11 deletions.
4 changes: 4 additions & 0 deletions SimpleLogin/SimpleLogin.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
357B504A2892B9AA0080326A /* BetterSafariViewModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFFBBDE527C96CCA00C8E6DD /* BetterSafariViewModifier.swift */; };
357B504C2892BAB80080326A /* BetterSafariView in Frameworks */ = {isa = PBXBuildFile; productRef = 357B504B2892BAB80080326A /* BetterSafariView */; };
357F16BA28FECF1C0096C81E /* FeatureFlags.swift in Sources */ = {isa = PBXBuildFile; fileRef = 357F16B928FECF1C0096C81E /* FeatureFlags.swift */; };
35C72EE62B734C46002C93BD /* StatsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C72EE52B734C46002C93BD /* StatsView.swift */; };
C00874AF27A98748004F32FA /* ErrorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C00874AE27A98748004F32FA /* ErrorExtensions.swift */; };
C00874B027A98748004F32FA /* ErrorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C00874AE27A98748004F32FA /* ErrorExtensions.swift */; };
C00874B127A98748004F32FA /* ErrorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C00874AE27A98748004F32FA /* ErrorExtensions.swift */; };
Expand Down Expand Up @@ -240,6 +241,7 @@
353E8272290150D7004C9154 /* DeletedAliasesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeletedAliasesView.swift; sourceTree = "<group>"; };
353E8274290150F6004C9154 /* DeletedAliasesViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeletedAliasesViewModel.swift; sourceTree = "<group>"; };
357F16B928FECF1C0096C81E /* FeatureFlags.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureFlags.swift; sourceTree = "<group>"; };
35C72EE52B734C46002C93BD /* StatsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatsView.swift; sourceTree = "<group>"; };
C00874AE27A98748004F32FA /* ErrorExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorExtensions.swift; sourceTree = "<group>"; };
C00874B227A989D3004F32FA /* SLError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SLError.swift; sourceTree = "<group>"; };
C00A563326DABC3900A550A2 /* ErrorMessageModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorMessageModifier.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -592,6 +594,7 @@
C0F1963F27348EDA0062B418 /* AliasDetailViewModel.swift */,
EF9FE0E02813FCC1003B3CB8 /* AliasEmailView.swift */,
EF9FE0DE2813F6BB003B3CB8 /* AliasNavigationTitleView.swift */,
35C72EE52B734C46002C93BD /* StatsView.swift */,
EFF7779327F3979F0084D6B4 /* UpgradeNeededView.swift */,
);
path = Aliases;
Expand Down Expand Up @@ -1095,6 +1098,7 @@
C00E66692792C687002DBA67 /* ClearButtonModeModifier.swift in Sources */,
C087656027AE7A5C00FF26E6 /* SearchAliasesResultView.swift in Sources */,
EF89C3602808BBB000F48743 /* SuffixExtensions.swift in Sources */,
35C72EE62B734C46002C93BD /* StatsView.swift in Sources */,
EFA52AE827CA39B000994547 /* HowItWorksView.swift in Sources */,
C0FE7B2D27A9CFD7005D53DF /* SignUpViewModel.swift in Sources */,
357F16BA28FECF1C0096C81E /* FeatureFlags.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/simple-login/swift-package",
"state" : {
"revision" : "b682be9c14af4b4b660ad2213b3601d899236977",
"version" : "2.1.2"
"revision" : "3de24a3d55b012753622e2d15f3df637c47b7b91",
"version" : "2.1.4"
}
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ struct AliasContactsView: View {
ContactView(viewModel: viewModel,
copiedText: $copiedText,
contact: contact)
.onAppear {
viewModel.getMoreContactsIfNeed(currentContact: contact)
}
.onAppear {
viewModel.getMoreContactsIfNeed(currentContact: contact)
}
}
} else if !viewModel.isFetchingContacts {
Text("No contacts")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ struct AliasDetailWrapperView: View {

var body: some View {
if let selectedAlias = selectedAlias {
// swiftlint:disable:next trailing_closure
AliasDetailView(
alias: selectedAlias,
session: session,
Expand Down
11 changes: 8 additions & 3 deletions SimpleLogin/SimpleLogin/Modules/Main/Aliases/AliasesView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ struct AliasesView: View {
createdAlias = nil
}
viewModel.remove(alias: deletedAlias)
},
},
onUpgrade: onUpgrade)
.ignoresSafeArea(.keyboard)
.onAppear {
Expand All @@ -90,7 +90,7 @@ struct AliasesView: View {
selection: $selectedLink,
destination: {
if let selectedAlias = selectedAlias {
AliasContactsView(alias: selectedAlias,
AliasContactsView(alias: selectedAlias,
session: viewModel.session,
onUpgrade: onUpgrade)
.onAppear {
Expand All @@ -108,6 +108,10 @@ struct AliasesView: View {

ScrollViewReader { proxy in
List {
if let stats = viewModel.stats {
StatsView(stats: stats)
}

if !viewModel.aliases.isEmpty {
if let createdAlias = createdAlias {
switch (createdAlias.enabled, viewModel.selectedStatus) {
Expand Down Expand Up @@ -143,6 +147,7 @@ struct AliasesView: View {
}
.listStyle(.plain)
.refreshable { await viewModel.refresh() }
.animation(.default, value: viewModel.stats != nil)
.onReceive(Just(createdAlias)) { createdAlias in
if let createdAlias = createdAlias {
if !viewModel.isHandled(createdAlias) {
Expand Down Expand Up @@ -197,7 +202,7 @@ struct AliasesView: View {
createdAlias = nil
}
viewModel.remove(alias: deletedAlias)
},
},
onUpgrade: onUpgrade)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ final class AliasesViewModel: BaseReachabilitySessionViewModel, ObservableObject

@Published private(set) var aliases: [Alias] = []
@Published private(set) var updatedAlias: Alias?
@Published private(set) var stats: Stats?
@Published private(set) var isLoading = false
@Published private(set) var isUpdating = false
@Published var error: Error?
Expand Down Expand Up @@ -101,6 +102,7 @@ final class AliasesViewModel: BaseReachabilitySessionViewModel, ObservableObject
defer { isLoading = false }
isLoading = true
do {
self.stats = try await getStats()
let newAliases = try await getAliases(page: currentPage)
self.aliases.append(contentsOf: newAliases)
self.currentPage += 1
Expand All @@ -116,6 +118,7 @@ final class AliasesViewModel: BaseReachabilitySessionViewModel, ObservableObject
func refresh() async {
do {
aliases = try await getAliases(page: 0)
stats = try await getStats()
currentPage = 1
canLoadMorePages = aliases.count == kDefaultPageSize
} catch {
Expand All @@ -130,6 +133,11 @@ final class AliasesViewModel: BaseReachabilitySessionViewModel, ObservableObject
return try await session.execute(getAliasesEndpoint).aliases
}

private func getStats() async throws -> Stats {
let endpoint = GetStatsEndpoint(apiKey: session.apiKey.value)
return try await session.execute(endpoint)
}

func update(alias: Alias) {
guard let index = aliases.firstIndex(where: { $0.id == alias.id }) else { return }
aliases[index] = alias
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct SearchAliasesView: UIViewControllerRepresentable {
reachabilityObserver: reachabilityObserver,
managedObjectContext: managedObjectContext,
onUpdateAlias: onUpdateAlias,
onDeleteAlias: onDeleteAlias,
onDeleteAlias: onDeleteAlias,
onUpgrade: onUpgrade)
let navigationController = UINavigationController(rootViewController: viewController)
navigationController.view.tintColor = .slPurple
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ final class SearchAliasesViewController: BaseViewController {
guard let self = self else { return }
self.onDeleteAlias(deletedAlias)
self.viewModel.remove(alias: alias)
},
},
onUpgrade: onUpgrade)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Expand Down
62 changes: 62 additions & 0 deletions SimpleLogin/SimpleLogin/Modules/Main/Aliases/StatsView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//
// StatsView.swift
// SimpleLogin - Created on 07/02/2024.
// Copyright (c) 2024 Proton Technologies AG
//
// This file is part of SimpleLogin.
//
// SimpleLogin is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// SimpleLogin is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with SimpleLogin. If not, see https://www.gnu.org/licenses/.
//

import SimpleLoginPackage
import SwiftUI

struct StatsView: View {
let stats: Stats

var body: some View {
VStack {
HStack {
cell(title: "Aliases", description: "All time", count: stats.aliasCount)
cell(title: "Forwarded", description: "Last 14 days", count: stats.forwardCount)
}

HStack {
cell(title: "Replies/send", description: "Last 14 days", count: stats.replyCount)
cell(title: "Blocked", description: "Last 14 days", count: stats.blockCount)
}
}
}
}

private extension StatsView {
func cell(title: String, description: String, count: Int) -> some View {
VStack(alignment: .leading) {
HStack {
Text(title)
.font(.footnote.weight(.medium))
Spacer()
Text(description)
.font(.caption)
.foregroundStyle(Color.secondary)
}
Text("\(count)")
.font(.title2.bold())
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding(10)
.background(Color.secondary.opacity(0.1))
.clipShape(RoundedRectangle(cornerRadius: 8))
}
}

0 comments on commit cea39d7

Please sign in to comment.