mirror of
https://github.com/neon443/NearFuture.git
synced 2026-03-11 06:49:12 +00:00
rerewrote daysUntillEvent, now acc can count days
inlineLarge titlebar, backwards compatible view extension competed events go to archive fix long event name and notes alignemnts can refresh icloud settings to sync
This commit is contained in:
@@ -12,6 +12,6 @@ TEAM_ID = 8JGND254B7
|
|||||||
BUNDLE_ID = com.neon443.NearFuture
|
BUNDLE_ID = com.neon443.NearFuture
|
||||||
BUNDLE_ID_WIDGETS = com.neon443.NearFuture.widgets
|
BUNDLE_ID_WIDGETS = com.neon443.NearFuture.widgets
|
||||||
GROUP_ID = group.NearFuture
|
GROUP_ID = group.NearFuture
|
||||||
VERSION = 3.1.1
|
VERSION = 3.2.1
|
||||||
NAME = Near Future
|
NAME = Near Future
|
||||||
BUILD_NUMBER = 5
|
BUILD_NUMBER = 5
|
||||||
|
|||||||
@@ -94,8 +94,10 @@ struct AddEventView: View {
|
|||||||
|
|
||||||
// date picker
|
// date picker
|
||||||
HStack {
|
HStack {
|
||||||
|
Spacer()
|
||||||
DatePicker("", selection: $eventDate, displayedComponents: .date)
|
DatePicker("", selection: $eventDate, displayedComponents: .date)
|
||||||
.datePickerStyle(WheelDatePickerStyle())
|
.datePickerStyle(WheelDatePickerStyle())
|
||||||
|
Spacer()
|
||||||
Button() {
|
Button() {
|
||||||
eventDate = Date()
|
eventDate = Date()
|
||||||
} label: {
|
} label: {
|
||||||
|
|||||||
@@ -36,6 +36,14 @@ struct ArchiveView: View {
|
|||||||
AddEventButton(showingAddEventView: $showAddEvent)
|
AddEventButton(showingAddEventView: $showAddEvent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.navigationTitle("Archive")
|
||||||
|
.apply {
|
||||||
|
if #available(iOS 17, *) {
|
||||||
|
$0.toolbarTitleDisplayMode(.inlineLarge)
|
||||||
|
} else {
|
||||||
|
$0.navigationBarTitleDisplayMode(.inline)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.sheet(isPresented: $showAddEvent) {
|
.sheet(isPresented: $showAddEvent) {
|
||||||
AddEventView(
|
AddEventView(
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ struct ContentView: View {
|
|||||||
@State private var searchInput: String = ""
|
@State private var searchInput: String = ""
|
||||||
var filteredEvents: [Event] {
|
var filteredEvents: [Event] {
|
||||||
if searchInput.isEmpty {
|
if searchInput.isEmpty {
|
||||||
return viewModel.events
|
return viewModel.events.filter() {!$0.complete}
|
||||||
} else {
|
} else {
|
||||||
return viewModel.events.filter {
|
return viewModel.events.filter {
|
||||||
$0.name.localizedCaseInsensitiveContains(searchInput) ||
|
$0.name.localizedCaseInsensitiveContains(searchInput) ||
|
||||||
@@ -86,14 +86,23 @@ struct ContentView: View {
|
|||||||
}
|
}
|
||||||
.padding(.horizontal)
|
.padding(.horizontal)
|
||||||
if /*!searchInput.isEmpty && */filteredEvents.isEmpty {
|
if /*!searchInput.isEmpty && */filteredEvents.isEmpty {
|
||||||
HelpView(searchInput: $searchInput, focusedField: focusedField)
|
HelpView(
|
||||||
|
searchInput: $searchInput,
|
||||||
|
focusedField: focusedField
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.navigationTitle("Near Future")
|
.navigationTitle("Near Future")
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.apply {
|
||||||
|
if #available(iOS 17, *) {
|
||||||
|
$0.toolbarTitleDisplayMode(.inlineLarge)
|
||||||
|
} else {
|
||||||
|
$0.navigationBarTitleDisplayMode(.inline)
|
||||||
|
}
|
||||||
|
}
|
||||||
.sheet(isPresented: $showingAddEventView) {
|
.sheet(isPresented: $showingAddEventView) {
|
||||||
AddEventView(
|
AddEventView(
|
||||||
viewModel: viewModel,
|
viewModel: viewModel,
|
||||||
@@ -193,3 +202,7 @@ extension View {
|
|||||||
.ignoresSafeArea(.all)
|
.ignoresSafeArea(.all)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension View {
|
||||||
|
func apply<V: View>(@ViewBuilder _ block: (Self) -> V) -> V { block(self) }
|
||||||
|
}
|
||||||
|
|||||||
@@ -44,11 +44,13 @@ struct EventListView: View {
|
|||||||
.font(.headline)
|
.font(.headline)
|
||||||
.foregroundStyle(.one)
|
.foregroundStyle(.one)
|
||||||
.strikethrough(event.complete)
|
.strikethrough(event.complete)
|
||||||
|
.multilineTextAlignment(.leading)
|
||||||
}
|
}
|
||||||
if !event.notes.isEmpty {
|
if !event.notes.isEmpty {
|
||||||
Text(event.notes)
|
Text(event.notes)
|
||||||
.font(.subheadline)
|
.font(.subheadline)
|
||||||
.foregroundStyle(.one.opacity(0.8))
|
.foregroundStyle(.one.opacity(0.8))
|
||||||
|
.multilineTextAlignment(.leading)
|
||||||
}
|
}
|
||||||
Text(
|
Text(
|
||||||
event.date.formatted(
|
event.date.formatted(
|
||||||
|
|||||||
@@ -76,30 +76,24 @@ struct ColorCodable: Codable, Equatable {
|
|||||||
|
|
||||||
func daysUntilEvent(_ eventDate: Date) -> (long: String, short: String) {
|
func daysUntilEvent(_ eventDate: Date) -> (long: String, short: String) {
|
||||||
let calendar = Calendar.current
|
let calendar = Calendar.current
|
||||||
let now = Date()
|
let startOfDayNow = calendar.startOfDay(for: Date())
|
||||||
|
let startOfDayEvent = calendar.startOfDay(for: eventDate)
|
||||||
let isToday = calendar.isDate(now, inSameDayAs: eventDate)
|
let components = calendar.dateComponents([.day], from: startOfDayNow, to: startOfDayEvent)
|
||||||
let components = calendar.dateComponents([.second, .day], from: now, to: eventDate)
|
guard let days = components.day else { return ("N/A", "N/A") }
|
||||||
|
guard days != 0 else { return ("Today", "Today") }
|
||||||
guard !isToday else { return ("Today", "Today") }
|
if days < 0 {
|
||||||
let secsComponents = eventDate.timeIntervalSinceNow
|
|
||||||
guard let daysCompontents = components.day else { return ("N/A", "N/A") }
|
|
||||||
let secs = Double(secsComponents)
|
|
||||||
var days = 0
|
|
||||||
var long = ""
|
|
||||||
var short = ""
|
|
||||||
if secs < 0 {
|
|
||||||
//past
|
//past
|
||||||
days = Int(floor(secs/86400))
|
return (
|
||||||
long = "\(-days) day\(plu(days)) ago"
|
"\(-days) day\(plu(days)) ago",
|
||||||
short = "\(days)d"
|
"\(days)d"
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
//future
|
//future
|
||||||
days = Int(ceil(secs/86400))
|
return (
|
||||||
long = "\(days) day\(plu(days))"
|
"\(days) day\(plu(days))",
|
||||||
short = "\(days)d"
|
"\(days)d"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return (long, short)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class EventViewModel: ObservableObject {
|
class EventViewModel: ObservableObject {
|
||||||
|
|||||||
@@ -108,7 +108,13 @@ struct SettingsView: View {
|
|||||||
}
|
}
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
.navigationTitle("Settings")
|
.navigationTitle("Settings")
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.apply {
|
||||||
|
if #available(iOS 17, *) {
|
||||||
|
$0.toolbarTitleDisplayMode(.inlineLarge)
|
||||||
|
} else {
|
||||||
|
$0.navigationBarTitleDisplayMode(.inline)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,13 @@ struct StatsView: View {
|
|||||||
}
|
}
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
.navigationTitle("Statistics")
|
.navigationTitle("Statistics")
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.apply {
|
||||||
|
if #available(iOS 17, *) {
|
||||||
|
$0.toolbarTitleDisplayMode(.inlineLarge)
|
||||||
|
} else {
|
||||||
|
$0.navigationBarTitleDisplayMode(.inline)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ struct iCloudSettingsView: View {
|
|||||||
ZStack {
|
ZStack {
|
||||||
backgroundGradient
|
backgroundGradient
|
||||||
List {
|
List {
|
||||||
|
Section {
|
||||||
HStack {
|
HStack {
|
||||||
Spacer()
|
Spacer()
|
||||||
VStack {
|
VStack {
|
||||||
@@ -152,7 +153,7 @@ struct iCloudSettingsView: View {
|
|||||||
.foregroundStyle(lastSyncWasNormalAgo ? .green : .red)
|
.foregroundStyle(lastSyncWasNormalAgo ? .green : .red)
|
||||||
Text("Last Sync")
|
Text("Last Sync")
|
||||||
Spacer()
|
Spacer()
|
||||||
Text("\(viewModel.lastSync?.formatted() ?? "Never")")
|
Text("\(viewModel.lastSync?.formatted(date: .long, time: .standard) ?? "Never")")
|
||||||
.bold()
|
.bold()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,6 +176,15 @@ struct iCloudSettingsView: View {
|
|||||||
Text("\(viewModel.icloudEventCount)")
|
Text("\(viewModel.icloudEventCount)")
|
||||||
.bold()
|
.bold()
|
||||||
}
|
}
|
||||||
|
} header: {
|
||||||
|
Text("Sync Status")
|
||||||
|
} footer: {
|
||||||
|
Text("Pull to sync\nOr use the arrows to force push/pull")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.refreshable {
|
||||||
|
viewModel.sync()
|
||||||
|
updateStatus()
|
||||||
}
|
}
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
.navigationTitle("iCloud")
|
.navigationTitle("iCloud")
|
||||||
|
|||||||
Reference in New Issue
Block a user