mirror of
https://github.com/twofas/2fas-ios.git
synced 2024-11-25 11:50:24 +01:00
TF-250 Service view
This commit is contained in:
parent
1b43a4431f
commit
37886fb11f
@ -390,6 +390,7 @@
|
|||||||
C25E8994266402AD00A60CE5 /* SectionEntity+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = C25E8992266402AD00A60CE5 /* SectionEntity+CoreDataClass.swift */; };
|
C25E8994266402AD00A60CE5 /* SectionEntity+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = C25E8992266402AD00A60CE5 /* SectionEntity+CoreDataClass.swift */; };
|
||||||
C25E8995266402AD00A60CE5 /* SectionEntity+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = C25E8993266402AD00A60CE5 /* SectionEntity+CoreDataProperties.swift */; };
|
C25E8995266402AD00A60CE5 /* SectionEntity+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = C25E8993266402AD00A60CE5 /* SectionEntity+CoreDataProperties.swift */; };
|
||||||
C25F4FDB2622207F008F7755 /* TokensViewEmptySearchScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = C25F4FDA2622207F008F7755 /* TokensViewEmptySearchScreen.swift */; };
|
C25F4FDB2622207F008F7755 /* TokensViewEmptySearchScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = C25F4FDA2622207F008F7755 /* TokensViewEmptySearchScreen.swift */; };
|
||||||
|
C260DCC22BC885F1007807CC /* ServiceCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C260DCC12BC885F1007807CC /* ServiceCellView.swift */; };
|
||||||
C2625F8C28BB853D00D84C5C /* AboutViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2625F8B28BB853D00D84C5C /* AboutViewController.swift */; };
|
C2625F8C28BB853D00D84C5C /* AboutViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2625F8B28BB853D00D84C5C /* AboutViewController.swift */; };
|
||||||
C2625F8E28BB858600D84C5C /* AboutPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2625F8D28BB858600D84C5C /* AboutPresenter.swift */; };
|
C2625F8E28BB858600D84C5C /* AboutPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2625F8D28BB858600D84C5C /* AboutPresenter.swift */; };
|
||||||
C2625F9028BB85B100D84C5C /* AboutModuleInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2625F8F28BB85B100D84C5C /* AboutModuleInteractor.swift */; };
|
C2625F9028BB85B100D84C5C /* AboutModuleInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2625F8F28BB85B100D84C5C /* AboutModuleInteractor.swift */; };
|
||||||
@ -2273,6 +2274,8 @@
|
|||||||
C25E8992266402AD00A60CE5 /* SectionEntity+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SectionEntity+CoreDataClass.swift"; sourceTree = "<group>"; };
|
C25E8992266402AD00A60CE5 /* SectionEntity+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SectionEntity+CoreDataClass.swift"; sourceTree = "<group>"; };
|
||||||
C25E8993266402AD00A60CE5 /* SectionEntity+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SectionEntity+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
C25E8993266402AD00A60CE5 /* SectionEntity+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SectionEntity+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
||||||
C25F4FDA2622207F008F7755 /* TokensViewEmptySearchScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokensViewEmptySearchScreen.swift; sourceTree = "<group>"; };
|
C25F4FDA2622207F008F7755 /* TokensViewEmptySearchScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokensViewEmptySearchScreen.swift; sourceTree = "<group>"; };
|
||||||
|
C260DCC02BC882AD007807CC /* TwoFASWatch-Watch-App-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = "TwoFASWatch-Watch-App-Info.plist"; sourceTree = SOURCE_ROOT; };
|
||||||
|
C260DCC12BC885F1007807CC /* ServiceCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServiceCellView.swift; sourceTree = "<group>"; };
|
||||||
C261A1212A12BECC00A1519F /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/TwoFASWidget.strings; sourceTree = "<group>"; };
|
C261A1212A12BECC00A1519F /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/TwoFASWidget.strings; sourceTree = "<group>"; };
|
||||||
C261A1222A12BECC00A1519F /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = "<group>"; };
|
C261A1222A12BECC00A1519F /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
C261A1232A12BECD00A1519F /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
C261A1232A12BECD00A1519F /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||||
@ -5667,6 +5670,7 @@
|
|||||||
C274C9CE2BAB8ABB008E7212 /* TwoFASWatch Watch App */ = {
|
C274C9CE2BAB8ABB008E7212 /* TwoFASWatch Watch App */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
C260DCC02BC882AD007807CC /* TwoFASWatch-Watch-App-Info.plist */,
|
||||||
C274CAA02BAB98A5008E7212 /* TwoFASWatch Watch App.entitlements */,
|
C274CAA02BAB98A5008E7212 /* TwoFASWatch Watch App.entitlements */,
|
||||||
C274C9CF2BAB8ABB008E7212 /* TwoFASWatchApp.swift */,
|
C274C9CF2BAB8ABB008E7212 /* TwoFASWatchApp.swift */,
|
||||||
C274C9D12BAB8ABB008E7212 /* ContentView.swift */,
|
C274C9D12BAB8ABB008E7212 /* ContentView.swift */,
|
||||||
@ -5683,6 +5687,7 @@
|
|||||||
C2B86D272BC32FA300AAAC63 /* InteractorFactory.swift */,
|
C2B86D272BC32FA300AAAC63 /* InteractorFactory.swift */,
|
||||||
C2B86D292BC33D3000AAAC63 /* AppDelegateInteractor.swift */,
|
C2B86D292BC33D3000AAAC63 /* AppDelegateInteractor.swift */,
|
||||||
C2B86D2B2BC3492A00AAAC63 /* Service.swift */,
|
C2B86D2B2BC3492A00AAAC63 /* Service.swift */,
|
||||||
|
C260DCC12BC885F1007807CC /* ServiceCellView.swift */,
|
||||||
C268918E2BC4974800713078 /* Category.swift */,
|
C268918E2BC4974800713078 /* Category.swift */,
|
||||||
C268918B2BC4960C00713078 /* ServiceList */,
|
C268918B2BC4960C00713078 /* ServiceList */,
|
||||||
C2627F382BC72E19009F93A9 /* Service */,
|
C2627F382BC72E19009F93A9 /* Service */,
|
||||||
@ -10088,6 +10093,7 @@
|
|||||||
C268918F2BC4974800713078 /* Category.swift in Sources */,
|
C268918F2BC4974800713078 /* Category.swift in Sources */,
|
||||||
C2B86D302BC349AE00AAAC63 /* MainPresenter.swift in Sources */,
|
C2B86D302BC349AE00AAAC63 /* MainPresenter.swift in Sources */,
|
||||||
C2B86D262BC32F9200AAAC63 /* MainInteractor.swift in Sources */,
|
C2B86D262BC32F9200AAAC63 /* MainInteractor.swift in Sources */,
|
||||||
|
C260DCC22BC885F1007807CC /* ServiceCellView.swift in Sources */,
|
||||||
C2B86D242BC3070F00AAAC63 /* AppPIN.swift in Sources */,
|
C2B86D242BC3070F00AAAC63 /* AppPIN.swift in Sources */,
|
||||||
C2627F3C2BC72EA0009F93A9 /* ServiceInteractor.swift in Sources */,
|
C2627F3C2BC72EA0009F93A9 /* ServiceInteractor.swift in Sources */,
|
||||||
);
|
);
|
||||||
@ -11956,6 +11962,7 @@
|
|||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = "TwoFASWatch-Watch-App-Info.plist";
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = TwoFASWatch;
|
INFOPLIST_KEY_CFBundleDisplayName = TwoFASWatch;
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
|
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
|
||||||
@ -11998,6 +12005,7 @@
|
|||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = "TwoFASWatch-Watch-App-Info.plist";
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = TwoFASWatch;
|
INFOPLIST_KEY_CFBundleDisplayName = TwoFASWatch;
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
|
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
|
||||||
|
@ -26,7 +26,10 @@ final class AppDelegateInteractor: NSObject, WKApplicationDelegate {
|
|||||||
|
|
||||||
func applicationDidFinishLaunching() {
|
func applicationDidFinishLaunching() {
|
||||||
if !WKApplication.shared().isRegisteredForRemoteNotifications {
|
if !WKApplication.shared().isRegisteredForRemoteNotifications {
|
||||||
|
Log("Registering Push Notifications")
|
||||||
WKApplication.shared().registerForRemoteNotifications()
|
WKApplication.shared().registerForRemoteNotifications()
|
||||||
|
} else {
|
||||||
|
Log("Push Notifications registered")
|
||||||
}
|
}
|
||||||
mainRepository.registerForCloudStateChanges({ [weak self] state in
|
mainRepository.registerForCloudStateChanges({ [weak self] state in
|
||||||
Log("Cloud state changed: \(state)")
|
Log("Cloud state changed: \(state)")
|
||||||
|
@ -34,19 +34,8 @@ struct MainView: View {
|
|||||||
interactor: InteractorFactory.shared.serviceInteractor(service: service)
|
interactor: InteractorFactory.shared.serviceInteractor(service: service)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
VStack(alignment: .leading) {
|
ServiceCellView(service: service)
|
||||||
Text(service.name)
|
|
||||||
.font(.callout)
|
|
||||||
.padding(4)
|
|
||||||
.foregroundStyle(.primary)
|
|
||||||
if let additionalInfo = service.additionalInfo {
|
|
||||||
Text(additionalInfo)
|
|
||||||
.padding(.horizontal, 4)
|
|
||||||
.font(.caption2)
|
|
||||||
.foregroundStyle(.secondary)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,7 @@ extension ServiceInteractor: ServiceInteracting {
|
|||||||
counter: 0,
|
counter: 0,
|
||||||
tokenType: serviceData.tokenType
|
tokenType: serviceData.tokenType
|
||||||
)
|
)
|
||||||
|
.formattedValue(for: serviceData.tokenType)
|
||||||
}
|
}
|
||||||
|
|
||||||
func timeToNextDate(for date: Date) -> Date {
|
func timeToNextDate(for date: Date) -> Date {
|
||||||
|
@ -30,6 +30,8 @@ final class ServicePresenter: ObservableObject {
|
|||||||
init(interactor: ServiceInteracting) {
|
init(interactor: ServiceInteracting) {
|
||||||
self.interactor = interactor
|
self.interactor = interactor
|
||||||
|
|
||||||
|
interactor.initialize()
|
||||||
|
|
||||||
name = interactor.service.name
|
name = interactor.service.name
|
||||||
additionalInfo = interactor.service.additionalInfo
|
additionalInfo = interactor.service.additionalInfo
|
||||||
service = interactor.service
|
service = interactor.service
|
||||||
|
@ -27,41 +27,67 @@ struct ServiceView: View {
|
|||||||
var presenter: ServicePresenter
|
var presenter: ServicePresenter
|
||||||
|
|
||||||
private let spacing: CGFloat = 8
|
private let spacing: CGFloat = 8
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading, spacing: nil) {
|
// Spacer()
|
||||||
Spacer()
|
|
||||||
TimelineView(.explicit(presenter.timelineEntries())) { context in
|
TimelineView(.explicit(presenter.timelineEntries())) { context in
|
||||||
HStack(alignment: .center, spacing: nil) {
|
VStack(alignment: .leading, spacing: nil) {
|
||||||
IconRenderer(service: presenter.service)
|
HStack(alignment: .center, spacing: nil) {
|
||||||
Spacer()
|
IconRenderer(service: presenter.service)
|
||||||
counterText(for: presenter.timeToNextDate(for: context.date))
|
Spacer()
|
||||||
.multilineTextAlignment(.trailing)
|
counterText(for: presenter.timeToNextDate(for: context.date))
|
||||||
.font(Font.body.monospacedDigit())
|
.multilineTextAlignment(.trailing)
|
||||||
.lineLimit(1)
|
.font(Font.body.monospacedDigit())
|
||||||
.contentTransition(.numericText(countsDown: true))
|
|
||||||
}
|
|
||||||
Spacer(minLength: spacing * 3)
|
|
||||||
VStack(alignment: .leading, spacing: 3) {
|
|
||||||
Text(presenter.name)
|
|
||||||
.font(.caption)
|
|
||||||
.multilineTextAlignment(.leading)
|
|
||||||
Text(presenter.calculateToken(for: context.date))
|
|
||||||
.font(Font.system(.title).weight(.light).monospacedDigit())
|
|
||||||
.multilineTextAlignment(.leading)
|
|
||||||
.minimumScaleFactor(0.2)
|
|
||||||
.contentTransition(.numericText())
|
|
||||||
if let info = presenter.additionalInfo {
|
|
||||||
Text(info)
|
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
.font(.caption)
|
.contentTransition(.numericText(countsDown: true))
|
||||||
.foregroundColor(.gray)
|
|
||||||
}
|
}
|
||||||
|
// Spacer(minLength: spacing * 3)
|
||||||
|
Spacer()
|
||||||
|
VStack(alignment: .leading, spacing: 3) {
|
||||||
|
// Text(presenter.name)
|
||||||
|
// .font(.caption)
|
||||||
|
// .multilineTextAlignment(.leading)
|
||||||
|
// .lineLimit(1)
|
||||||
|
Text(presenter.calculateToken(for: context.date))
|
||||||
|
.font(Font.system(.title).weight(.light).monospacedDigit())
|
||||||
|
.multilineTextAlignment(.leading)
|
||||||
|
.minimumScaleFactor(0.2)
|
||||||
|
.contentTransition(.numericText())
|
||||||
|
.foregroundColor(.primary)
|
||||||
|
.layoutPriority(1)
|
||||||
|
// .background(Material.ultraThin, in: RoundedRectangle(cornerRadius: 8))
|
||||||
|
if let info = presenter.additionalInfo {
|
||||||
|
Text(info)
|
||||||
|
.lineLimit(1)
|
||||||
|
.font(.caption2)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
.multilineTextAlignment(.leading)
|
||||||
|
}
|
||||||
|
Spacer()
|
||||||
|
.frame(maxHeight: .infinity)
|
||||||
|
}
|
||||||
|
.frame(alignment: .leading)
|
||||||
|
.padding(.top, 4)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Spacer()
|
|
||||||
}
|
}
|
||||||
|
.navigationTitle {
|
||||||
|
Text(presenter.name)
|
||||||
|
.lineLimit(1)
|
||||||
|
}
|
||||||
|
.toolbar {
|
||||||
|
ToolbarItem(placement: .bottomBar) {
|
||||||
|
Button {
|
||||||
|
print("Test")
|
||||||
|
} label: {
|
||||||
|
Image(systemName:"star")
|
||||||
|
}
|
||||||
|
.controlSize(.mini)
|
||||||
|
.background(Color.accentColor, in: Circle())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.scenePadding()
|
||||||
|
// .background(Color.accentColor.gradient)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
|
45
TwoFAS/TwoFASWatch Watch App/ServiceCellView.swift
Normal file
45
TwoFAS/TwoFASWatch Watch App/ServiceCellView.swift
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
//
|
||||||
|
// This file is part of the 2FAS iOS app (https://github.com/twofas/2fas-ios)
|
||||||
|
// Copyright © 2024 Two Factor Authentication Service, Inc.
|
||||||
|
// Contributed by Zbigniew Cisiński. All rights reserved.
|
||||||
|
//
|
||||||
|
// This program 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
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program 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 this program. If not, see <https://www.gnu.org/licenses/>
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct ServiceCellView: View {
|
||||||
|
let service: Service
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
HStack(alignment: .center, spacing: 8) {
|
||||||
|
Rectangle()
|
||||||
|
.fill(service.badgeColor)
|
||||||
|
.frame(width: 20)
|
||||||
|
IconRenderer(service: service)
|
||||||
|
VStack(alignment: .leading, spacing: 8) {
|
||||||
|
Text(service.name)
|
||||||
|
.font(.callout)
|
||||||
|
.padding(4)
|
||||||
|
.foregroundStyle(.primary)
|
||||||
|
if let additionalInfo = service.additionalInfo {
|
||||||
|
Text(additionalInfo)
|
||||||
|
.padding(.horizontal, 4)
|
||||||
|
.font(.caption2)
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -35,18 +35,7 @@ struct ServiceListView: View {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
VStack(alignment: .leading) {
|
ServiceCellView(service: service)
|
||||||
Text(service.name)
|
|
||||||
.font(.callout)
|
|
||||||
.padding(4)
|
|
||||||
.foregroundStyle(.primary)
|
|
||||||
if let additionalInfo = service.additionalInfo {
|
|
||||||
Text(additionalInfo)
|
|
||||||
.padding(.horizontal, 4)
|
|
||||||
.font(.caption2)
|
|
||||||
.foregroundStyle(.secondary)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
10
TwoFAS/TwoFASWatch-Watch-App-Info.plist
Normal file
10
TwoFAS/TwoFASWatch-Watch-App-Info.plist
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>UIBackgroundModes</key>
|
||||||
|
<array>
|
||||||
|
<string>remote-notification</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
Loading…
Reference in New Issue
Block a user