Add support for iOS 14.0
This commit is contained in:
parent
30dd10bb80
commit
573acb561c
5 changed files with 295 additions and 207 deletions
|
|
@ -7,6 +7,7 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
02024E60283D7CBB0064224A /* View.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02024E5F283D7CBB0064224A /* View.swift */; };
|
||||
9474F1C1282F2AA700CDE4DD /* AppMain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9474F1C0282F2AA700CDE4DD /* AppMain.swift */; };
|
||||
9474F1C3282F2AA700CDE4DD /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9474F1C2282F2AA700CDE4DD /* ContentView.swift */; };
|
||||
9474F1C5282F2AA800CDE4DD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9474F1C4282F2AA800CDE4DD /* Assets.xcassets */; };
|
||||
|
|
@ -62,6 +63,7 @@
|
|||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
02024E5F283D7CBB0064224A /* View.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = View.swift; sourceTree = "<group>"; };
|
||||
9474F1BD282F2AA700CDE4DD /* ntfy.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ntfy.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
9474F1C0282F2AA700CDE4DD /* AppMain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppMain.swift; sourceTree = "<group>"; };
|
||||
9474F1C2282F2AA700CDE4DD /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -108,6 +110,14 @@
|
|||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
02024E5E283D7CBB0064224A /* Extensions */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
02024E5F283D7CBB0064224A /* View.swift */,
|
||||
);
|
||||
path = Extensions;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9474F1B4282F2AA700CDE4DD = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
|
@ -130,6 +140,7 @@
|
|||
9474F1BF282F2AA700CDE4DD /* ntfy */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
02024E5E283D7CBB0064224A /* Extensions */,
|
||||
9474F210283326E000CDE4DD /* Utils */,
|
||||
9474F20D2833264F00CDE4DD /* App */,
|
||||
9474F1C4282F2AA800CDE4DD /* Assets.xcassets */,
|
||||
|
|
@ -318,6 +329,7 @@
|
|||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
02024E60283D7CBB0064224A /* View.swift in Sources */,
|
||||
9474F1F92830835400CDE4DD /* Store.swift in Sources */,
|
||||
9474F212283327C200CDE4DD /* Helpers.swift in Sources */,
|
||||
9474F217283531A300CDE4DD /* Log.swift in Sources */,
|
||||
|
|
@ -413,7 +425,7 @@
|
|||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
|
|
@ -468,7 +480,7 @@
|
|||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
|
|
@ -497,6 +509,7 @@
|
|||
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
|
@ -529,6 +542,7 @@
|
|||
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
|
@ -553,7 +567,7 @@
|
|||
INFOPLIST_FILE = ntfyNSE/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = ntfyNSE;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.4;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
|
@ -580,7 +594,7 @@
|
|||
INFOPLIST_FILE = ntfyNSE/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = ntfyNSE;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.4;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
|
|
|||
26
ntfy/Extensions/View.swift
Normal file
26
ntfy/Extensions/View.swift
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// View.swift
|
||||
// ntfy
|
||||
//
|
||||
// Created by Callum Yarnold on 24/05/2022.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct disableAutoCapitalisationModifier: ViewModifier {
|
||||
func body(content: Content) -> some View {
|
||||
if #available(iOS 15.0, *) {
|
||||
content
|
||||
.textInputAutocapitalization(.never)
|
||||
} else {
|
||||
content
|
||||
.autocapitalization(.none)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension View {
|
||||
func disableAutoCapitalisation() -> some View {
|
||||
modifier(disableAutoCapitalisationModifier())
|
||||
}
|
||||
}
|
||||
|
|
@ -23,121 +23,133 @@ struct NotificationListView: View {
|
|||
}
|
||||
|
||||
var body: some View {
|
||||
List(selection: $selection) {
|
||||
ForEach(subscription.notificationsSorted(), id: \.self) { notification in
|
||||
NotificationRowView(notification: notification)
|
||||
}
|
||||
}
|
||||
.listStyle(PlainListStyle())
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.environment(\.editMode, self.$editMode)
|
||||
.navigationBarBackButtonHidden(true)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .navigationBarLeading) {
|
||||
if (self.editMode != .active) {
|
||||
Button(action: {
|
||||
// iOS bug (?): We create a custom back button, because when we return using the original
|
||||
// back button, and the navigation is popped that way, the row stays highlighted for a long
|
||||
// time, which is weird and feels wrong. This avoids that behavior.
|
||||
|
||||
self.delegate.selectedBaseUrl = nil
|
||||
}){
|
||||
Image(systemName: "chevron.left")
|
||||
}
|
||||
.padding([.top, .bottom, .trailing], 20)
|
||||
}
|
||||
}
|
||||
ToolbarItem(placement: .principal) {
|
||||
Text(subscription.displayName()).font(.headline)
|
||||
}
|
||||
ToolbarItem(placement: .navigationBarTrailing) {
|
||||
if (self.editMode == .active) {
|
||||
editButton
|
||||
} else {
|
||||
Menu {
|
||||
if subscription.notificationCount() > 0 {
|
||||
editButton
|
||||
}
|
||||
Button("Send test notification") {
|
||||
self.sendTestNotification()
|
||||
}
|
||||
if subscription.notificationCount() > 0 {
|
||||
Button("Clear all notifications") {
|
||||
self.showAlert = true
|
||||
self.activeAlert = .clear
|
||||
}
|
||||
}
|
||||
Button("Unsubscribe") {
|
||||
self.showAlert = true
|
||||
self.activeAlert = .unsubscribe
|
||||
}
|
||||
} label: {
|
||||
Image(systemName: "ellipsis.circle")
|
||||
.padding([.top, .bottom, .leading], 20)
|
||||
}
|
||||
}
|
||||
}
|
||||
ToolbarItem(placement: .navigationBarLeading) {
|
||||
if (self.editMode == .active) {
|
||||
Button(action: {
|
||||
self.showAlert = true
|
||||
self.activeAlert = .selected
|
||||
}) {
|
||||
Text("Delete")
|
||||
.foregroundColor(.red)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.alert(isPresented: $showAlert) {
|
||||
switch activeAlert {
|
||||
case .clear:
|
||||
return Alert(
|
||||
title: Text("Clear notifications"),
|
||||
message: Text("Do you really want to delete all of the notifications in this topic?"),
|
||||
primaryButton: .destructive(
|
||||
Text("Permanently delete"),
|
||||
action: deleteAll
|
||||
),
|
||||
secondaryButton: .cancel())
|
||||
case .unsubscribe:
|
||||
return Alert(
|
||||
title: Text("Unsubscribe"),
|
||||
message: Text("Do you really want to unsubscribe from this topic and delete all of the notifications you received?"),
|
||||
primaryButton: .destructive(
|
||||
Text("Unsubscribe"),
|
||||
action: unsubscribe
|
||||
),
|
||||
secondaryButton: .cancel())
|
||||
case .selected:
|
||||
return Alert(
|
||||
title: Text("Delete"),
|
||||
message: Text("Do you really want to delete these selected notifications?"),
|
||||
primaryButton: .destructive(
|
||||
Text("Delete"),
|
||||
action: deleteSelected
|
||||
),
|
||||
secondaryButton: .cancel())
|
||||
}
|
||||
}
|
||||
.overlay(Group {
|
||||
if subscription.notificationCount() == 0 {
|
||||
VStack {
|
||||
Text("You haven't received any notifications for this topic yet.")
|
||||
.font(.title2)
|
||||
.foregroundColor(.gray)
|
||||
.multilineTextAlignment(.center)
|
||||
.padding(.bottom)
|
||||
Text("To send notifications to this topic, simply PUT or POST to the topic URL.\n\nExample:\n`$ curl -d \"hi\" ntfy.sh/\(subscription.topicName())`\n\nDetailed instructions are available on [ntfy.sh](https;//ntfy.sh) and [in the docs](https:ntfy.sh/docs).")
|
||||
.foregroundColor(.gray)
|
||||
}
|
||||
.padding(40)
|
||||
}
|
||||
})
|
||||
.refreshable {
|
||||
subscriptionManager.poll(subscription)
|
||||
}
|
||||
notificationlist
|
||||
if #available(iOS 15.0, *) {
|
||||
notificationlist
|
||||
.refreshable {
|
||||
subscriptionManager.poll(subscription)
|
||||
}
|
||||
} else {
|
||||
notificationlist
|
||||
}
|
||||
}
|
||||
|
||||
private var notificationlist: some View {
|
||||
List(selection: $selection) {
|
||||
ForEach(subscription.notificationsSorted(), id: \.self) { notification in
|
||||
NotificationRowView(notification: notification)
|
||||
}
|
||||
}
|
||||
.listStyle(PlainListStyle())
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.environment(\.editMode, self.$editMode)
|
||||
.navigationBarBackButtonHidden(true)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .navigationBarLeading) {
|
||||
if (self.editMode != .active) {
|
||||
Button(action: {
|
||||
// iOS bug (?): We create a custom back button, because when we return using the original
|
||||
// back button, and the navigation is popped that way, the row stays highlighted for a long
|
||||
// time, which is weird and feels wrong. This avoids that behavior.
|
||||
|
||||
self.delegate.selectedBaseUrl = nil
|
||||
}){
|
||||
Image(systemName: "chevron.left")
|
||||
}
|
||||
.padding([.top, .bottom, .trailing], 20)
|
||||
}
|
||||
}
|
||||
ToolbarItem(placement: .principal) {
|
||||
Text(subscription.displayName()).font(.headline)
|
||||
}
|
||||
ToolbarItem(placement: .navigationBarTrailing) {
|
||||
if (self.editMode == .active) {
|
||||
editButton
|
||||
} else {
|
||||
Menu {
|
||||
Button("Refresh") {
|
||||
subscriptionManager.poll(subscription)
|
||||
}
|
||||
if subscription.notificationCount() > 0 {
|
||||
editButton
|
||||
}
|
||||
Button("Send test notification") {
|
||||
self.sendTestNotification()
|
||||
}
|
||||
if subscription.notificationCount() > 0 {
|
||||
Button("Clear all notifications") {
|
||||
self.showAlert = true
|
||||
self.activeAlert = .clear
|
||||
}
|
||||
}
|
||||
Button("Unsubscribe") {
|
||||
self.showAlert = true
|
||||
self.activeAlert = .unsubscribe
|
||||
}
|
||||
} label: {
|
||||
Image(systemName: "ellipsis.circle")
|
||||
.padding([.top, .bottom, .leading], 20)
|
||||
}
|
||||
}
|
||||
}
|
||||
ToolbarItem(placement: .navigationBarLeading) {
|
||||
if (self.editMode == .active) {
|
||||
Button(action: {
|
||||
self.showAlert = true
|
||||
self.activeAlert = .selected
|
||||
}) {
|
||||
Text("Delete")
|
||||
.foregroundColor(.red)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.alert(isPresented: $showAlert) {
|
||||
switch activeAlert {
|
||||
case .clear:
|
||||
return Alert(
|
||||
title: Text("Clear notifications"),
|
||||
message: Text("Do you really want to delete all of the notifications in this topic?"),
|
||||
primaryButton: .destructive(
|
||||
Text("Permanently delete"),
|
||||
action: deleteAll
|
||||
),
|
||||
secondaryButton: .cancel())
|
||||
case .unsubscribe:
|
||||
return Alert(
|
||||
title: Text("Unsubscribe"),
|
||||
message: Text("Do you really want to unsubscribe from this topic and delete all of the notifications you received?"),
|
||||
primaryButton: .destructive(
|
||||
Text("Unsubscribe"),
|
||||
action: unsubscribe
|
||||
),
|
||||
secondaryButton: .cancel())
|
||||
case .selected:
|
||||
return Alert(
|
||||
title: Text("Delete"),
|
||||
message: Text("Do you really want to delete these selected notifications?"),
|
||||
primaryButton: .destructive(
|
||||
Text("Delete"),
|
||||
action: deleteSelected
|
||||
),
|
||||
secondaryButton: .cancel())
|
||||
}
|
||||
}
|
||||
.overlay(Group {
|
||||
if subscription.notificationCount() == 0 {
|
||||
VStack {
|
||||
Text("You haven't received any notifications for this topic yet.")
|
||||
.font(.title2)
|
||||
.foregroundColor(.gray)
|
||||
.multilineTextAlignment(.center)
|
||||
.padding(.bottom)
|
||||
Text("To send notifications to this topic, simply PUT or POST to the topic URL.\n\nExample:\n`$ curl -d \"hi\" ntfy.sh/\(subscription.topicName())`\n\nDetailed instructions are available on [ntfy.sh](https;//ntfy.sh) and [in the docs](https:ntfy.sh/docs).")
|
||||
.foregroundColor(.gray)
|
||||
}
|
||||
.padding(40)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private var editButton: some View {
|
||||
if editMode == .inactive {
|
||||
|
|
@ -199,27 +211,35 @@ struct NotificationRowView: View {
|
|||
@ObservedObject var notification: Notification
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
Text(notification.shortDateTime())
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.gray)
|
||||
if let title = notification.title, title != "" {
|
||||
Text(title)
|
||||
.font(.headline)
|
||||
.bold()
|
||||
}
|
||||
Text(notification.message ?? "")
|
||||
.font(.body)
|
||||
}
|
||||
.padding(.all, 4)
|
||||
.swipeActions(edge: .trailing) {
|
||||
Button(role: .destructive) {
|
||||
store.delete(notification: notification)
|
||||
} label: {
|
||||
Label("Delete", systemImage: "trash.circle")
|
||||
}
|
||||
}
|
||||
if #available(iOS 15.0, *) {
|
||||
notificationRow
|
||||
.swipeActions(edge: .trailing) {
|
||||
Button(role: .destructive) {
|
||||
store.delete(notification: notification)
|
||||
} label: {
|
||||
Label("Delete", systemImage: "trash.circle")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
notificationRow
|
||||
}
|
||||
}
|
||||
|
||||
private var notificationRow: some View {
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
Text(notification.shortDateTime())
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.gray)
|
||||
if let title = notification.title, title != "" {
|
||||
Text(title)
|
||||
.font(.headline)
|
||||
.bold()
|
||||
}
|
||||
Text(notification.message ?? "")
|
||||
.font(.body)
|
||||
}
|
||||
.padding(.all, 4)
|
||||
}
|
||||
}
|
||||
|
||||
struct NotificationListView_Previews: PreviewProvider {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,8 @@ struct SubscriptionAddView: View {
|
|||
footer: Text("Topics may not be password protected, so choose a name that's not easy to guess. Once subscribed, you can PUT/POST notifications")
|
||||
) {
|
||||
TextField("Topic name, e.g. phil_alerts", text: $topic)
|
||||
.textInputAutocapitalization(.never)
|
||||
.disableAutoCapitalisation()
|
||||
.disableAutocorrection(true)
|
||||
}
|
||||
}
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
|
|
|
|||
|
|
@ -15,42 +15,61 @@ struct SubscriptionListView: View {
|
|||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
List {
|
||||
ForEach(subscriptions) { subscription in
|
||||
SubscriptionItemNavView(subscription: subscription)
|
||||
}
|
||||
}
|
||||
.listStyle(PlainListStyle())
|
||||
.navigationTitle("Subscribed topics")
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .navigationBarTrailing) {
|
||||
NavigationLink(destination: SubscriptionAddView()) {
|
||||
Image(systemName: "plus")
|
||||
}
|
||||
}
|
||||
}
|
||||
.overlay(Group {
|
||||
if subscriptions.isEmpty {
|
||||
VStack {
|
||||
Text("It looks like you don't have any subscriptions yet")
|
||||
.font(.title2)
|
||||
.foregroundColor(.gray)
|
||||
.multilineTextAlignment(.center)
|
||||
.padding(.bottom)
|
||||
Text("Click the + to create or subscribe to a topic. Afterwards, you receive notifications on your device when sending messages via PUT or POST.\n\nDetailed instructions are available on [ntfy.sh](https;//ntfy.sh) and [in the docs](https:ntfy.sh/docs).")
|
||||
.foregroundColor(.gray)
|
||||
}
|
||||
.padding(40)
|
||||
}
|
||||
})
|
||||
.refreshable {
|
||||
subscriptions.forEach { subscription in
|
||||
subscriptionManager.poll(subscription)
|
||||
}
|
||||
}
|
||||
if #available(iOS 15.0, *) {
|
||||
subscriptionList
|
||||
.refreshable {
|
||||
subscriptions.forEach { subscription in
|
||||
subscriptionManager.poll(subscription)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
subscriptionList
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .navigationBarLeading) {
|
||||
Button {
|
||||
subscriptions.forEach { subscription in
|
||||
subscriptionManager.poll(subscription)
|
||||
}
|
||||
} label: {
|
||||
Image(systemName: "arrow.clockwise")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationViewStyle(StackNavigationViewStyle())
|
||||
}
|
||||
|
||||
private var subscriptionList: some View {
|
||||
List {
|
||||
ForEach(subscriptions) { subscription in
|
||||
SubscriptionItemNavView(subscription: subscription)
|
||||
}
|
||||
}
|
||||
.listStyle(PlainListStyle())
|
||||
.navigationTitle("Subscribed topics")
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .navigationBarTrailing) {
|
||||
NavigationLink(destination: SubscriptionAddView()) {
|
||||
Image(systemName: "plus")
|
||||
}
|
||||
}
|
||||
}
|
||||
.overlay(Group {
|
||||
if subscriptions.isEmpty {
|
||||
VStack {
|
||||
Text("It looks like you don't have any subscriptions yet")
|
||||
.font(.title2)
|
||||
.foregroundColor(.gray)
|
||||
.multilineTextAlignment(.center)
|
||||
.padding(.bottom)
|
||||
Text("Click the + to create or subscribe to a topic. Afterwards, you receive notifications on your device when sending messages via PUT or POST.\n\nDetailed instructions are available on [ntfy.sh](https;//ntfy.sh) and [in the docs](https:ntfy.sh/docs).")
|
||||
.foregroundColor(.gray)
|
||||
}
|
||||
.padding(40)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
struct SubscriptionItemNavView: View {
|
||||
|
|
@ -64,41 +83,49 @@ struct SubscriptionItemNavView: View {
|
|||
}
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
NavigationLink(
|
||||
destination: NotificationListView(subscription: subscription),
|
||||
tag: subscription.urlString(),
|
||||
selection: $delegate.selectedBaseUrl
|
||||
) {
|
||||
EmptyView()
|
||||
}
|
||||
.opacity(0.0)
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
|
||||
SubscriptionItemRowView(subscription: subscription)
|
||||
}
|
||||
.swipeActions(edge: .trailing) {
|
||||
Button(role: .destructive) {
|
||||
self.unsubscribeAlert = true
|
||||
} label: {
|
||||
Label("Delete", systemImage: "trash.circle")
|
||||
}
|
||||
}
|
||||
.alert(isPresented: $unsubscribeAlert) {
|
||||
Alert(
|
||||
title: Text("Unsubscribe"),
|
||||
message: Text("Do you really want to unsubscribe from this topic and delete all of the notifications you received?"),
|
||||
primaryButton: .destructive(
|
||||
Text("Unsubscribe"),
|
||||
action: {
|
||||
self.subscriptionManager.unsubscribe(subscription)
|
||||
self.unsubscribeAlert = false
|
||||
}
|
||||
),
|
||||
secondaryButton: .cancel()
|
||||
)
|
||||
}
|
||||
}
|
||||
if #available(iOS 15.0, *) {
|
||||
subscriptionRow
|
||||
.swipeActions(edge: .trailing) {
|
||||
Button(role: .destructive) {
|
||||
self.unsubscribeAlert = true
|
||||
} label: {
|
||||
Label("Delete", systemImage: "trash.circle")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
subscriptionRow
|
||||
}
|
||||
}
|
||||
|
||||
private var subscriptionRow: some View {
|
||||
ZStack {
|
||||
NavigationLink(
|
||||
destination: NotificationListView(subscription: subscription),
|
||||
tag: subscription.urlString(),
|
||||
selection: $delegate.selectedBaseUrl
|
||||
) {
|
||||
EmptyView()
|
||||
}
|
||||
.opacity(0.0)
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
|
||||
SubscriptionItemRowView(subscription: subscription)
|
||||
}
|
||||
.alert(isPresented: $unsubscribeAlert) {
|
||||
Alert(
|
||||
title: Text("Unsubscribe"),
|
||||
message: Text("Do you really want to unsubscribe from this topic and delete all of the notifications you received?"),
|
||||
primaryButton: .destructive(
|
||||
Text("Unsubscribe"),
|
||||
action: {
|
||||
self.subscriptionManager.unsubscribe(subscription)
|
||||
self.unsubscribeAlert = false
|
||||
}
|
||||
),
|
||||
secondaryButton: .cancel()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SubscriptionItemRowView: View {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue