mirror of
https://github.com/confirmedcode/Lockdown-iOS.git
synced 2025-12-25 12:13:52 +01:00
240 lines
7.8 KiB
Swift
240 lines
7.8 KiB
Swift
//
|
|
// LockdownFirewallWidget.swift
|
|
// LockdownFirewallWidget
|
|
//
|
|
// Created by Oleg Dreyman on 25.09.2020.
|
|
// Copyright © 2020 Confirmed Inc. All rights reserved.
|
|
//
|
|
|
|
import WidgetKit
|
|
import SwiftUI
|
|
|
|
struct FirewallProvider: TimelineProvider {
|
|
func placeholder(in context: Context) -> FirewallEntry {
|
|
FirewallEntry(date: Date(), size: context.displaySize, isFirewallEnabled: false, dayMetricsString: "--")
|
|
}
|
|
|
|
func getSnapshot(in context: Context, completion: @escaping (FirewallEntry) -> ()) {
|
|
let entry = FirewallEntry(date: Date(), size: context.displaySize, isFirewallEnabled: getUserWantsFirewallEnabled(), dayMetricsString: getDayMetricsString(commas: true))
|
|
completion(entry)
|
|
}
|
|
|
|
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
|
|
var entries: [FirewallEntry] = []
|
|
|
|
let currentDate = Date()
|
|
let entry = FirewallEntry(date: Date(), size: context.displaySize, isFirewallEnabled: getUserWantsFirewallEnabled(), dayMetricsString: getDayMetricsString(commas: true))
|
|
entries.append(entry)
|
|
|
|
let timeline = Timeline(
|
|
entries: entries,
|
|
policy: .after(Calendar.current.date(byAdding: .minute, value: 5, to: currentDate)!)
|
|
)
|
|
completion(timeline)
|
|
}
|
|
}
|
|
|
|
struct FirewallEntry: TimelineEntry {
|
|
let date: Date
|
|
let size: CGSize
|
|
let isFirewallEnabled: Bool
|
|
let dayMetricsString: String
|
|
|
|
var buttonColor: Color {
|
|
if isFirewallEnabled {
|
|
return .confirmedBlue
|
|
} else {
|
|
return Color(.systemGray)
|
|
}
|
|
}
|
|
}
|
|
|
|
struct LockdownFirewallWidgetEntryView : View {
|
|
var entry: FirewallProvider.Entry
|
|
|
|
var body: some View {
|
|
VStack(spacing: 0) {
|
|
LoadingCircle(
|
|
tunnelState: TunnelState(
|
|
color: entry.buttonColor,
|
|
circleColor: entry.buttonColor
|
|
),
|
|
side: entry.size.height,
|
|
link: "lockdown://"
|
|
)
|
|
.padding(EdgeInsets(top: 12, leading: 0, bottom: 2, trailing: 0))
|
|
if entry.isFirewallEnabled {
|
|
StatusLabel(text: NSLocalizedString("FIREWALL ON", comment: ""), color: .confirmedBlue)
|
|
} else {
|
|
StatusLabel(text: NSLocalizedString("FIREWALL OFF", comment: ""), color: .flatRed)
|
|
}
|
|
if entry.size.height < 160 {
|
|
Spacer().frame(minHeight: 4)
|
|
} else {
|
|
Spacer()
|
|
}
|
|
Link(destination: URL(string: "lockdown://showMetrics")!, label: {
|
|
VStack(spacing: 0) {
|
|
Text(entry.dayMetricsString)
|
|
.font(.system(size: 21, weight: .semibold))
|
|
Text(NSLocalizedString("Blocked Today", comment: ""))
|
|
.font(.system(size: 12, weight: .medium))
|
|
}
|
|
.padding(.bottom, 12)
|
|
})
|
|
}.frame(width: entry.size.height, height: entry.size.height)
|
|
}
|
|
}
|
|
|
|
struct VPNProvider: TimelineProvider {
|
|
func placeholder(in context: Context) -> VPNEntry {
|
|
VPNEntry(date: Date(), size: context.displaySize, isVPNEnabled: false, vpnRegion: VPNRegion())
|
|
}
|
|
|
|
func getSnapshot(in context: Context, completion: @escaping (VPNEntry) -> ()) {
|
|
let entry = VPNEntry(date: Date(), size: context.displaySize, isVPNEnabled: LatestKnowledge.isVPNEnabled, vpnRegion: getSavedVPNRegion())
|
|
completion(entry)
|
|
}
|
|
|
|
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
|
|
var entries: [VPNEntry] = []
|
|
|
|
let currentDate = Date()
|
|
let entry = VPNEntry(date: Date(), size: context.displaySize, isVPNEnabled: LatestKnowledge.isVPNEnabled, vpnRegion: getSavedVPNRegion())
|
|
entries.append(entry)
|
|
|
|
let timeline = Timeline(
|
|
entries: entries,
|
|
policy: .after(Calendar.current.date(byAdding: .minute, value: 5, to: currentDate)!)
|
|
)
|
|
completion(timeline)
|
|
}
|
|
}
|
|
|
|
struct VPNEntry: TimelineEntry {
|
|
let date: Date
|
|
let size: CGSize
|
|
let isVPNEnabled: Bool
|
|
let vpnRegion: VPNRegion
|
|
|
|
var buttonColor: Color {
|
|
if isVPNEnabled {
|
|
return .confirmedBlue
|
|
} else {
|
|
return Color(.systemGray)
|
|
}
|
|
}
|
|
}
|
|
|
|
struct LockdownVPNWidgetEntryView : View {
|
|
var entry: VPNProvider.Entry
|
|
|
|
var body: some View {
|
|
VStack(spacing: 0) {
|
|
LoadingCircle(
|
|
tunnelState: TunnelState(
|
|
color: entry.buttonColor,
|
|
circleColor: entry.buttonColor
|
|
),
|
|
side: entry.size.height,
|
|
link: "lockdown://"
|
|
)
|
|
.padding(EdgeInsets(top: 12, leading: 0, bottom: 2, trailing: 0))
|
|
if entry.isVPNEnabled {
|
|
StatusLabel(text: NSLocalizedString("Tunnel On", comment: "").uppercased(), color: .confirmedBlue)
|
|
} else {
|
|
StatusLabel(text: NSLocalizedString("Tunnel Off", comment: "").uppercased(), color: .flatRed)
|
|
}
|
|
if entry.size.height < 160 {
|
|
Spacer().frame(minHeight: 4)
|
|
} else {
|
|
Spacer()
|
|
}
|
|
Link(destination: URL(string: "lockdown://changeVPNregion")!, label: {
|
|
VStack(spacing: 0) {
|
|
Text(entry.vpnRegion.regionFlagEmoji)
|
|
.font(.system(size: 21, weight: .semibold))
|
|
Text(entry.vpnRegion.regionDisplayNameShort)
|
|
.font(.system(size: 12, weight: .medium))
|
|
}
|
|
.padding(.bottom, 12)
|
|
})
|
|
}.frame(width: entry.size.height, height: entry.size.height)
|
|
}
|
|
}
|
|
|
|
struct CombinedWidgetView: View {
|
|
let firewall: FirewallEntry
|
|
let vpn: VPNEntry
|
|
|
|
var body: some View {
|
|
HStack(alignment: .top, spacing: 0) {
|
|
LockdownFirewallWidgetEntryView(entry: firewall)
|
|
LockdownVPNWidgetEntryView(entry: vpn)
|
|
}
|
|
.frame(minWidth: firewall.size.width, minHeight: firewall.size.height)
|
|
}
|
|
}
|
|
|
|
@main
|
|
struct LockdownWidgetBundle: WidgetBundle {
|
|
|
|
@WidgetBundleBuilder
|
|
var body: some Widget {
|
|
LockdownFirewallWidget()
|
|
LockdownVPNWidget()
|
|
LockdownCombinedWidget()
|
|
}
|
|
}
|
|
|
|
struct LockdownFirewallWidget: Widget {
|
|
var body: some WidgetConfiguration {
|
|
StaticConfiguration(
|
|
kind: "LockdownFirewallWidget",
|
|
provider: FirewallProvider(),
|
|
content: { entry in
|
|
ZStack {
|
|
Color.panelBackground
|
|
LockdownFirewallWidgetEntryView(entry: entry)
|
|
}
|
|
}
|
|
)
|
|
.configurationDisplayName("Firewall")
|
|
.supportedFamilies([.systemSmall])
|
|
}
|
|
}
|
|
|
|
struct LockdownVPNWidget: Widget {
|
|
var body: some WidgetConfiguration {
|
|
StaticConfiguration(
|
|
kind: "LockdownVPNWidget",
|
|
provider: VPNProvider(),
|
|
content: { entry in
|
|
ZStack {
|
|
Color.panelBackground
|
|
LockdownVPNWidgetEntryView(entry: entry)
|
|
}
|
|
}
|
|
)
|
|
.configurationDisplayName("Secure Tunnel")
|
|
.supportedFamilies([.systemSmall])
|
|
}
|
|
}
|
|
|
|
struct LockdownCombinedWidget: Widget {
|
|
var body: some WidgetConfiguration {
|
|
StaticConfiguration(
|
|
kind: "LockdownCombinedWidget",
|
|
provider: CombinedProvider(main: FirewallProvider(), supplemental: VPNProvider()),
|
|
content: { entry in
|
|
ZStack {
|
|
Color.panelBackground
|
|
CombinedWidgetView(firewall: entry.main, vpn: entry.supplemental)
|
|
}
|
|
}
|
|
)
|
|
.configurationDisplayName("Firewall + Tunnel")
|
|
.supportedFamilies([.systemMedium])
|
|
}
|
|
}
|