From 5cc4ac958a52569c3b89a62aed9aee591181de1a Mon Sep 17 00:00:00 2001 From: woxtu Date: Sun, 17 Sep 2023 18:14:11 +0900 Subject: [PATCH 1/7] Group sessions by rooms --- .../Sources/Model/TimetableRoomGroupItems.swift | 15 +++++++++++++++ .../Sources/Timetable/TimetableViewModel.swift | 14 ++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 app-ios/Modules/Sources/Model/TimetableRoomGroupItems.swift diff --git a/app-ios/Modules/Sources/Model/TimetableRoomGroupItems.swift b/app-ios/Modules/Sources/Model/TimetableRoomGroupItems.swift new file mode 100644 index 000000000..5dae06238 --- /dev/null +++ b/app-ios/Modules/Sources/Model/TimetableRoomGroupItems.swift @@ -0,0 +1,15 @@ +import shared + +public struct TimetableRoomGroupItems: Identifiable, Equatable, Hashable { + public var id: String { + UUID().uuidString + } + + public var room: TimetableRoom + public var items: [TimetableItemWithFavorite] + + public init(room: TimetableRoom, items: [TimetableItemWithFavorite]) { + self.room = room + self.items = items + } +} diff --git a/app-ios/Modules/Sources/Timetable/TimetableViewModel.swift b/app-ios/Modules/Sources/Timetable/TimetableViewModel.swift index 4f206ae45..482a998fe 100644 --- a/app-ios/Modules/Sources/Timetable/TimetableViewModel.swift +++ b/app-ios/Modules/Sources/Timetable/TimetableViewModel.swift @@ -7,6 +7,7 @@ import shared struct TimetableState: ViewModelState { struct LoadedState: Equatable { var timeGroupTimetableItems: [TimetableTimeGroupItems] + var roomGroupTimetableItems: [TimetableRoomGroupItems] var bookmarks: Set } @@ -75,9 +76,22 @@ final class TimetableViewModel: ObservableObject { } var seen: [TimetableTimeGroupItems: Bool] = [:] let distinctedTimetableTimeGroupItems = timetableTimeGroupItems.filter { seen.updateValue(true, forKey: $0) == nil } + let roomGroupTimetableItems = cachedTimetable.dayTimetable(droidKaigi2023Day: state.selectedDay) + .rooms + .map { room in + let items = cachedTimetable.contents + .filter { $0.timetableItem.room == room } + .filter { $0.timetableItem.day == state.selectedDay } + .sorted { $0.timetableItem.startsAt.epochSeconds < $1.timetableItem.startsAt.epochSeconds } + return TimetableRoomGroupItems( + room: room, + items: items + ) + } state.loadedState = .loaded( .init( timeGroupTimetableItems: distinctedTimetableTimeGroupItems, + roomGroupTimetableItems: roomGroupTimetableItems, bookmarks: cachedTimetable.bookmarks ) ) From babdb597640b5dd90904d019589e7851d87edda0 Mon Sep 17 00:00:00 2001 From: woxtu Date: Sun, 17 Sep 2023 18:37:56 +0900 Subject: [PATCH 2/7] Fix date type conversion --- .../Sources/Model/Extension/Kotlinx_datetimeInstant.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app-ios/Modules/Sources/Model/Extension/Kotlinx_datetimeInstant.swift b/app-ios/Modules/Sources/Model/Extension/Kotlinx_datetimeInstant.swift index 9895a2bca..cdbcf57e4 100644 --- a/app-ios/Modules/Sources/Model/Extension/Kotlinx_datetimeInstant.swift +++ b/app-ios/Modules/Sources/Model/Extension/Kotlinx_datetimeInstant.swift @@ -1,7 +1,7 @@ import shared extension Kotlinx_datetimeInstant { - public func toDate(calendar: Calendar = .current) -> Date { - return Date(timeIntervalSince1970: TimeInterval(toEpochMilliseconds())) + public func toDate() -> Date { + return Date(timeIntervalSince1970: TimeInterval(epochSeconds)) } } From f19d101ddd155ab7146bc2ce41b729fd09f0cd5f Mon Sep 17 00:00:00 2001 From: woxtu Date: Sun, 17 Sep 2023 20:48:23 +0900 Subject: [PATCH 3/7] Show the timetable grid --- .../Sources/Timetable/TimetableGridView.swift | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 app-ios/Modules/Sources/Timetable/TimetableGridView.swift diff --git a/app-ios/Modules/Sources/Timetable/TimetableGridView.swift b/app-ios/Modules/Sources/Timetable/TimetableGridView.swift new file mode 100644 index 000000000..89892bf22 --- /dev/null +++ b/app-ios/Modules/Sources/Timetable/TimetableGridView.swift @@ -0,0 +1,106 @@ +import Model +import shared +import SwiftUI +import Theme + +struct TimetableGridView: View { + let roomHeaderSize: CGSize = .init(width: 194, height: 40) + let gridSize: CGSize = .init(width: 194, height: 310) + + let timetableRoomGroupItems: [TimetableRoomGroupItems] + let hours: [Date] + + init( + day: DroidKaigi2023Day, + timetableRoomGroupItems: [TimetableRoomGroupItems] + ) { + self.timetableRoomGroupItems = timetableRoomGroupItems + + var dateComponents = Calendar(identifier: .gregorian) + .dateComponents(in: TimeZone(identifier: "Asia/Tokyo")!, from: day.start.toDate()) + hours = (10 ... 19).compactMap { hour in + dateComponents.hour = hour + dateComponents.minute = 0 + return dateComponents.date + } + } + + var body: some View { + ScrollView(.vertical) { + HStack(alignment: .top, spacing: 0) { + VStack(spacing: 0) { + Text(hourFormatter.string(from: hours[0])) + .textStyle(TypographyTokens.labelMedium) + .frame(height: roomHeaderSize.height + 8, alignment: .bottom) + + ForEach(hours[1...], id: \.self) { hour in + Text(hourFormatter.string(from: hour)) + .textStyle(TypographyTokens.labelMedium) + .frame(height: gridSize.height, alignment: .bottom) + } + } + .padding(.leading, SpacingTokens.m) + .frame(width: 75 - 8, alignment: .leading) + + VStack(spacing: 0) { + Divider().frame(height: roomHeaderSize.height, alignment: .bottom) + + ForEach(hours[1...], id: \.self) { _ in + Divider().frame(height: gridSize.height, alignment: .bottom) + } + } + .frame(width: 8) + + ZStack(alignment: .topLeading) { + VStack(spacing: 0) { + Divider().frame(height: roomHeaderSize.height, alignment: .bottom) + + ForEach(hours[1...], id: \.self) { _ in + Divider().frame(height: gridSize.height, alignment: .bottom) + } + } + + ScrollView(.horizontal) { + HStack(alignment: .top, spacing: 0) { + Divider() + + ForEach(timetableRoomGroupItems) { timetableRoomGroupItem in + VStack(spacing: 0) { + Text(timetableRoomGroupItem.room.name.currentLangTitle) + .textStyle(TypographyTokens.titleSmall) + .frame(height: roomHeaderSize.height) + } + .frame(width: gridSize.width) + + Divider() + } + } + } + } + } + } + } +} + +private let hourFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.calendar = Calendar(identifier: .gregorian) + formatter.locale = Locale(identifier: "Asia/Tokyo") + formatter.dateStyle = .none + formatter.timeStyle = .short + return formatter +}() + +#if DEBUG +#Preview { + TimetableGridView( + day: Timetable.companion.fake().contents.first!.timetableItem.day!, + timetableRoomGroupItems: [ + TimetableRoomGroupItems( + room: Timetable.companion.fake().contents.first!.timetableItem.room, + items: [Timetable.companion.fake().contents.first!] + ), + ] + ) +} +#endif From 05847bf52cdcf91cf3e4a9f34f93e74033566c73 Mon Sep 17 00:00:00 2001 From: woxtu Date: Mon, 18 Sep 2023 21:34:04 +0900 Subject: [PATCH 4/7] Export room color extension --- .../Sources/Timetable/RoomType+Extension.swift | 18 ++++++++++++++++++ .../Timetable/TimetableListItemView.swift | 15 --------------- 2 files changed, 18 insertions(+), 15 deletions(-) create mode 100644 app-ios/Modules/Sources/Timetable/RoomType+Extension.swift diff --git a/app-ios/Modules/Sources/Timetable/RoomType+Extension.swift b/app-ios/Modules/Sources/Timetable/RoomType+Extension.swift new file mode 100644 index 000000000..e8c4903e7 --- /dev/null +++ b/app-ios/Modules/Sources/Timetable/RoomType+Extension.swift @@ -0,0 +1,18 @@ +import shared +import SwiftUI +import Theme + +extension RoomType { + func toColor() -> Color { + let colorAsset = switch self { + case .rooma: AssetColors.Custom.hallA + case .roomb: AssetColors.Custom.hallB + case .roomc: AssetColors.Custom.hallC + case .roomd: AssetColors.Custom.hallD + case .roome: AssetColors.Custom.hallE + case .roomde: AssetColors.Custom.hallD + default: AssetColors.Custom.white + } + return colorAsset.swiftUIColor + } +} diff --git a/app-ios/Modules/Sources/Timetable/TimetableListItemView.swift b/app-ios/Modules/Sources/Timetable/TimetableListItemView.swift index 6d8a3e8b9..4e6334459 100644 --- a/app-ios/Modules/Sources/Timetable/TimetableListItemView.swift +++ b/app-ios/Modules/Sources/Timetable/TimetableListItemView.swift @@ -86,21 +86,6 @@ struct TimetableListItemView: View { } } -private extension RoomType { - func toColor() -> Color { - let colorAsset = switch self { - case .rooma: AssetColors.Custom.hallA - case .roomb: AssetColors.Custom.hallB - case .roomc: AssetColors.Custom.hallC - case .roomd: AssetColors.Custom.hallD - case .roome: AssetColors.Custom.hallE - case .roomde: AssetColors.Custom.hallD - default: AssetColors.Custom.white - } - return colorAsset.swiftUIColor - } -} - #Preview { TimetableListItemView( timetableItemWithFavorite: TimetableItemWithFavorite.companion.fake(), From 0cc5c8615483fea457cb4aa8c40e9ac984cee130 Mon Sep 17 00:00:00 2001 From: woxtu Date: Mon, 18 Sep 2023 21:40:43 +0900 Subject: [PATCH 5/7] Show timetable grid items --- .../Error Container.colorset/Contents.json | 38 +++++++++ .../Timetable/TimetableGridItemView.swift | 81 +++++++++++++++++++ .../Sources/Timetable/TimetableGridView.swift | 39 +++++++++ 3 files changed, 158 insertions(+) create mode 100644 app-ios/Modules/Sources/Theme/Resources/Colors.xcassets/Error/Error Container.colorset/Contents.json create mode 100644 app-ios/Modules/Sources/Timetable/TimetableGridItemView.swift diff --git a/app-ios/Modules/Sources/Theme/Resources/Colors.xcassets/Error/Error Container.colorset/Contents.json b/app-ios/Modules/Sources/Theme/Resources/Colors.xcassets/Error/Error Container.colorset/Contents.json new file mode 100644 index 000000000..d606dce29 --- /dev/null +++ b/app-ios/Modules/Sources/Theme/Resources/Colors.xcassets/Error/Error Container.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xD6", + "green" : "0xDA", + "red" : "0xFF" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x0A", + "green" : "0x00", + "red" : "0x93" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/app-ios/Modules/Sources/Timetable/TimetableGridItemView.swift b/app-ios/Modules/Sources/Timetable/TimetableGridItemView.swift new file mode 100644 index 000000000..368c74f1a --- /dev/null +++ b/app-ios/Modules/Sources/Timetable/TimetableGridItemView.swift @@ -0,0 +1,81 @@ +import Assets +import Component +import shared +import SwiftUI +import Theme + +struct TimetableGridItemView: View { + let timetableItemWithFavorite: TimetableItemWithFavorite + + var timetableItem: TimetableItem { + self.timetableItemWithFavorite.timetableItem + } + + var body: some View { + VStack(alignment: .leading, spacing: 4) { + Text(timetableItem.title.currentLangTitle) + .textStyle(TypographyTokens.labelLarge) + .multilineTextAlignment(.leading) + + HStack(spacing: 3) { + Assets.Icons.schedule.swiftUIImage + .renderingMode(.template) + Text("\(timetableItem.startsTimeString) - \(timetableItem.endsTimeString)") + .textStyle(TypographyTokens.bodySmall) + } + + Spacer() + + if let session = timetableItem as? TimetableItem.Session { + HStack(alignment: .center, spacing: 4) { + if session.speakers.count > 1 { + ForEach(session.speakers, id: \.self) { speaker in + speakerIcon(speaker) + } + } else if let speaker = session.speakers.first { + speakerIcon(speaker) + Text(speaker.name) + .textStyle(TypographyTokens.labelMedium) + .lineLimit(2) + } + + Spacer() + + if session.message != nil { + Assets.Icons.info.swiftUIImage + .resizable() + .renderingMode(.template) + .frame(width: 16, height: 16) + .foregroundStyle(AssetColors.Error.errorContainer.swiftUIColor) + } + } + } + } + .padding(RadiusTokens.s) + .frame(maxWidth: .infinity, alignment: .leading) + .foregroundStyle(AssetColors.Custom.hallText.swiftUIColor) + .background(timetableItem.room.type.toColor()) + .clipShape(RoundedRectangle(cornerRadius: 4)) + } + + private func speakerIcon(_ speaker: TimetableSpeaker) -> some View { + CacheAsyncImage(url: URL(string: speaker.iconUrl)) { image in + image.resizable() + } placeholder: { + Color.gray + } + .frame(width: 32, height: 32) + .scaledToFill() + .clipShape(RoundedRectangle(cornerRadius: RadiusTokens.xs)) + .overlay( + RoundedRectangle(cornerRadius: RadiusTokens.xs) + .stroke(AssetColors.Outline.outline.swiftUIColor, lineWidth: 1) + ) + } +} + +#Preview { + TimetableGridItemView( + timetableItemWithFavorite: TimetableItemWithFavorite.companion.fake() + ) +} diff --git a/app-ios/Modules/Sources/Timetable/TimetableGridView.swift b/app-ios/Modules/Sources/Timetable/TimetableGridView.swift index 89892bf22..54fdf4941 100644 --- a/app-ios/Modules/Sources/Timetable/TimetableGridView.swift +++ b/app-ios/Modules/Sources/Timetable/TimetableGridView.swift @@ -69,6 +69,22 @@ struct TimetableGridView: View { Text(timetableRoomGroupItem.room.name.currentLangTitle) .textStyle(TypographyTokens.titleSmall) .frame(height: roomHeaderSize.height) + + ZStack { + ForEach(timetableRoomGroupItem.items, id: \.timetableItem.id.value) { timetableItemWithFavorite in + let frame = itemFrame( + timetableItemWithFavorite: timetableItemWithFavorite, + startTime: hours[0], + gridSize: gridSize + ) + + TimetableGridItemView( + timetableItemWithFavorite: timetableItemWithFavorite + ) + .frame(width: frame.width, height: frame.height) + .position(x: frame.origin.x, y: frame.origin.y) + } + } } .frame(width: gridSize.width) @@ -80,6 +96,29 @@ struct TimetableGridView: View { } } } + + private func itemFrame( + timetableItemWithFavorite: TimetableItemWithFavorite, + startTime: Date, + gridSize: CGSize + ) -> CGRect { + let item = timetableItemWithFavorite.timetableItem + + let heightPerSecond = gridSize.height / (60 * 60) + let itemSpacing = NSDirectionalEdgeInsets(top: 1, leading: 1, bottom: 1, trailing: 1) + + let itemSize = CGSize( + width: gridSize.width - itemSpacing.leading - itemSpacing.trailing, + height: CGFloat(item.endsAt.epochSeconds - item.startsAt.epochSeconds) * heightPerSecond + - itemSpacing.top - itemSpacing.bottom + ) + let itemPosition = CGPoint( + x: itemSize.width / 2 + itemSpacing.leading, + y: (CGFloat(item.startsAt.epochSeconds) - startTime.timeIntervalSince1970) * heightPerSecond + + itemSize.height / 2 + itemSpacing.top + ) + return CGRect(origin: itemPosition, size: itemSize) + } } private let hourFormatter: DateFormatter = { From 57fe149c3941f5cbbd1b678f7f1702ede1192ddf Mon Sep 17 00:00:00 2001 From: woxtu Date: Mon, 18 Sep 2023 22:00:43 +0900 Subject: [PATCH 6/7] Switch the layout of the timetable --- .../list_view.imageset/Contents.json | 22 ++++++++++++ .../list_view.imageset/trailing-icon 3.pdf | Bin 0 -> 4453 bytes .../list_view.imageset/trailing-icon 4.pdf | Bin 0 -> 4453 bytes .../Sources/Timetable/TimetableView.swift | 33 +++++++++++++----- 4 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 app-ios/Modules/Sources/Assets/Resources/Icons.xcassets/list_view.imageset/Contents.json create mode 100644 app-ios/Modules/Sources/Assets/Resources/Icons.xcassets/list_view.imageset/trailing-icon 3.pdf create mode 100644 app-ios/Modules/Sources/Assets/Resources/Icons.xcassets/list_view.imageset/trailing-icon 4.pdf diff --git a/app-ios/Modules/Sources/Assets/Resources/Icons.xcassets/list_view.imageset/Contents.json b/app-ios/Modules/Sources/Assets/Resources/Icons.xcassets/list_view.imageset/Contents.json new file mode 100644 index 000000000..2cd81cba5 --- /dev/null +++ b/app-ios/Modules/Sources/Assets/Resources/Icons.xcassets/list_view.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "trailing-icon 3.pdf", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "trailing-icon 4.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/app-ios/Modules/Sources/Assets/Resources/Icons.xcassets/list_view.imageset/trailing-icon 3.pdf b/app-ios/Modules/Sources/Assets/Resources/Icons.xcassets/list_view.imageset/trailing-icon 3.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d8270501dc83f820873afda409f1e95c1f910235 GIT binary patch literal 4453 zcmd^C$!;4*5WV+T^hJPuFgZ)l1{eaY6+vQHA#*TbeZ|2?d0a->P@<+luC7?$J;MT>$h+9@|Ukqyp z=Len9z?FxtcjNO@G{OFMeRhtUxF&nMb~`<_yMEh!-RnO+^`_R(x3hJ6HSQigw(6(x zdDrz5yTHh^v++fL(#ayRpEOJzAZh(drfB9g@A~#pEid{%HeJ8EKGWyx_*XZn-&Go> z!}J@p(3cjAq%2KRYHm3O-J?ntS&=k#LTs|S%&LMLC4H5ix~(!{C>oDS*oMx5u&mDW z+-Que7e$uT4rvPN)b*lD$yrKcvbr)&qdS_{Bqk+iW?`x(Elb@5qlShv5kZ8v!l)uR zhNZ$ej{FtQabo>>R)uq15-ZQV42}^WkWO>}HmKYYtTeFP1yN~O&pFg0NeHpQGlzVU zupovoOD5NZxP%~@2no63d2SSxfhDL1f04#uMY(aA0CQyPu+gapRRxcb#4K?=bOP4icFtPX&S65tJ%|3()Qef)eIMXUx|G7qi_J2=i-&GHXIn5b8Gu*|rF? z5m(VxmST0#Y-|*SS{AvEEaqS#zIjCu3tpZP%N#5u8j1Eui)N!v$d1p|K-*QQV}MO4 z4&vw+0H@n-76gF~)jKO?G=V5tZ&<>^svrmzA|M14YtU7^MhOsh$dtr@WKru;xe4+Ls0z>1lONd1Ko`C;Y=3J((%uSV{%IO&py{i0s%08GrrkbBzD|y#k zzRcI_xt)94f0^2U>-X*Sn{Bx#8UNgSK*>96zqP#9yu|!VZNKl}*OH!S?}n#`_WP#8 zGwi?y1ODBJNdC^;>8T5wjD`Jx&Z9^v|JI~4%_;P+-fv6N?0!;9lJ;Uez8SGWpQRG6 zYk<5Jz1wcbdD5TwaG>cdgB zA+7f&(ji20{RL{o*1T&sL%&lj?++Iw?yG5h>|g6wo4eOe;^k@_Nne)F=4-j$eCt^Y V5_g*0-E7q{X_2XulgkfRe*)#kkJkVI literal 0 HcmV?d00001 diff --git a/app-ios/Modules/Sources/Assets/Resources/Icons.xcassets/list_view.imageset/trailing-icon 4.pdf b/app-ios/Modules/Sources/Assets/Resources/Icons.xcassets/list_view.imageset/trailing-icon 4.pdf new file mode 100644 index 0000000000000000000000000000000000000000..adb4eaa380fee43c5a986fd39f767cb7615dc5a8 GIT binary patch literal 4453 zcmd^C$!;7s5WVv&coAS9Jktw%0}KJyiXbtp%;aFe$f4D0OXIYrmFZR>`|DH1oa}6j(>HN`dy`A zI!wPo3w>#^NXpVArRJ7n&^@YTQJE&m5@J);b(R<0D3hu-dg`{ygrR6WDq$Ns2g0&C z&vTAeUK`!fye2VeSrKNcCM`?d1fzzAm-GoDycI?j z!7(fq&T-_gaE=q}&$B9==#sAKUC7oO8WA`|5)A&@(QQbuqB+7m%g!o28=`JCWnwx0fk;_zSi-}uAP5;EAOsU@&{e!f3n1*UQW68UXA~?j zP89rr7?dUpL;8}!z>-D7M}9>}>XIQ@6ixs%I=Z0HX@{3$z?-BOK!_QRd0r3+8)eu7 z3%Y^m4ubuZlHT1|@J^5kX#utb*6z+iNGUcB2na+u0S1E74k;I&f}p}7@&XbuoxOg~ zJF;`kHdqj&L&8J|AcPe!K74vTfDU9Ldy#g2xg@+JD*>oGk}E@;K@gNO2mt`JDjr#9 z43Ig4ctS6G`mDCoquali{F!q-;3^HnVBTz0T#{yf9Jhv{@?FS9CT>d*QQ@A zBmf%x+Qg3xEqi|IXz_!I%S4nlw9Z+lpby{B&f8G^@<&O3c{wK zLxh5y7&;_>wqW|0YA(4} zQrBF*%-8F=oqOAVnc9Er_wDqXZMl++f9@4fQfKYAme-oMn6K3K`wo6BsYH7>JUz7E zHyz5b0~-wZx)G85ow?If7d9CS=KwH+Mu;a|A0L7@v>NG&eoqKM@jHO6d&|nc@g1c$CP`+qoUa`~A5u zyZ*CEbebx6sPJE176sM4g!_*j@TciSvR_sfM4!J1s_BB*gL0D`LK*F^{ZUnRFseQr zRU6WJZz5enB-dY{Mr_Tyb~E%l#q$1eLE^re#>f7(ezm!K?Id2V#*y@8`RsZv*PCxW WYeC{pbGw_ZIwmbLb#ij~;p$K2`;XTE literal 0 HcmV?d00001 diff --git a/app-ios/Modules/Sources/Timetable/TimetableView.swift b/app-ios/Modules/Sources/Timetable/TimetableView.swift index 1b1e3074a..15d28aa36 100644 --- a/app-ios/Modules/Sources/Timetable/TimetableView.swift +++ b/app-ios/Modules/Sources/Timetable/TimetableView.swift @@ -14,6 +14,7 @@ enum TimetableRouting: Hashable { public struct TimetableView: View { @Environment(\.colorScheme) var colorScheme @StateObject var viewModel: TimetableViewModel = .init() + @State private var isListPresented: Bool = true private let sessionViewBuilder: ViewProvider let gradient = Gradient(stops: [ .init(color: AssetColors.Surface.surfaceGradientTOP.swiftUIColor, location: 0.0), @@ -78,13 +79,20 @@ public struct TimetableView: View { .frame(height: shouldCollapse ? 53 : 82) .animation(.easeInOut(duration: 0.08), value: shouldCollapse) ) { - TimetableListView( - timetableTimeGroupItems: state.timeGroupTimetableItems, - searchWord: "", - onToggleBookmark: { [weak viewModel] in - viewModel?.toggleBookmark($0) - } - ) + if isListPresented { + TimetableListView( + timetableTimeGroupItems: state.timeGroupTimetableItems, + searchWord: "", + onToggleBookmark: { [weak viewModel] in + viewModel?.toggleBookmark($0) + } + ) + } else { + TimetableGridView( + day: viewModel.state.selectedDay, + timetableRoomGroupItems: state.roomGroupTimetableItems + ) + } } } .background(AssetColors.Surface.surface.swiftUIColor) @@ -132,7 +140,16 @@ public struct TimetableView: View { .buttonStyle(.plain) } ToolbarItem { - Assets.Icons.gridView.swiftUIImage + Button { + isListPresented.toggle() + } label: { + if isListPresented { + Assets.Icons.gridView.swiftUIImage + } else { + Assets.Icons.listView.swiftUIImage + } + } + .buttonStyle(.plain) } } } From 86e9f76a19c31938ab3175c8822ab8107f45ed1f Mon Sep 17 00:00:00 2001 From: woxtu Date: Mon, 18 Sep 2023 22:20:51 +0900 Subject: [PATCH 7/7] Move to session details --- app-ios/Modules/Sources/Timetable/TimetableGridView.swift | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app-ios/Modules/Sources/Timetable/TimetableGridView.swift b/app-ios/Modules/Sources/Timetable/TimetableGridView.swift index 54fdf4941..12934adaf 100644 --- a/app-ios/Modules/Sources/Timetable/TimetableGridView.swift +++ b/app-ios/Modules/Sources/Timetable/TimetableGridView.swift @@ -78,9 +78,11 @@ struct TimetableGridView: View { gridSize: gridSize ) - TimetableGridItemView( - timetableItemWithFavorite: timetableItemWithFavorite - ) + NavigationLink(value: TimetableRouting.session(timetableItemWithFavorite.timetableItem)) { + TimetableGridItemView( + timetableItemWithFavorite: timetableItemWithFavorite + ) + } .frame(width: frame.width, height: frame.height) .position(x: frame.origin.x, y: frame.origin.y) }