-
Notifications
You must be signed in to change notification settings - Fork 200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/timetable feature grid2 #367
Changes from 11 commits
6be1dfa
ab2c5e5
3d84fe1
42a0f8f
a8ec52f
398d589
16190a5
3ec6e7f
7ce2c62
3458ce9
0c5fac1
404fec3
7ef8e12
01a633e
c75137c
1085d24
38eaa49
34c3e46
f201358
2a8d3eb
0900ab1
f48e5ba
2563d07
ab85531
bdf3b12
348203e
b39f2d6
16262aa
45d96ec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import Foundation | ||
import SwiftUI | ||
import Theme | ||
import class shared.TimetableItem | ||
|
||
public struct TimetableGridCard: View { | ||
let timetableItem: TimetableItem? | ||
let onTap: (TimetableItem) -> Void | ||
|
||
public init( | ||
timetableItem: TimetableItem?, | ||
onTap: @escaping (TimetableItem) -> Void | ||
) { | ||
self.timetableItem = timetableItem | ||
self.onTap = onTap | ||
} | ||
|
||
public var body: some View { | ||
if let timetableItem { | ||
Button { | ||
onTap(timetableItem) | ||
} label: { | ||
VStack(alignment: .leading, spacing: 8) { | ||
HStack(spacing: 4) { | ||
timetableItem.room.type.shape | ||
.foregroundColor(timetableItem.room.roomTheme.primaryColor) | ||
charles-b-stb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Text("\(timetableItem.startsTimeString) - \(timetableItem.endsTimeString)") | ||
.textStyle(.labelMedium) | ||
.foregroundColor(timetableItem.room.roomTheme.primaryColor) | ||
charles-b-stb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Spacer() | ||
} | ||
|
||
Text(timetableItem.title.currentLangTitle) | ||
.textStyle(.titleMedium) | ||
.foregroundColor(timetableItem.room.roomTheme.primaryColor) | ||
charles-b-stb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
.multilineTextAlignment(.leading) | ||
|
||
Spacer() | ||
|
||
ForEach(timetableItem.speakers, id: \.id) { speaker in | ||
HStack(spacing: 8) { | ||
Group { | ||
AsyncImage(url: URL(string: speaker.iconUrl)) { | ||
$0.resizable() | ||
} placeholder: { | ||
Color.gray | ||
} | ||
} | ||
.frame(width: 32, height: 32) | ||
.clipShape(Circle()) | ||
|
||
Text(speaker.name) | ||
.textStyle(.titleSmall) | ||
.foregroundStyle(AssetColors.Surface.onSurfaceVariant.swiftUIColor) | ||
.lineLimit(1) | ||
} | ||
} | ||
} | ||
.frame(maxWidth: .infinity) | ||
.padding(12) | ||
.frame(width: 192, height: 153) | ||
.background(timetableItem.room.roomTheme.containerColor, in: RoundedRectangle(cornerRadius: 4)) | ||
.overlay(RoundedRectangle(cornerRadius: 4).stroke(timetableItem.room.roomTheme.primaryColor, lineWidth: 1)) | ||
} | ||
} else { | ||
VStack { | ||
//Empty on purpose | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it possible to instead it to EmptyView() ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. will try it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Empty view collapses. We need something that will hold the space open. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about following? Color.clear
.frame(maxWidth: .infinity)
.padding(12)
.frame(width: 192, height: 153)
.clipShape(RoundedRectangle(cornerRadius: 4)) |
||
.frame(maxWidth: .infinity) | ||
.padding(12) | ||
.frame(width: 192, height: 153) | ||
.background(Color.clear, in: RoundedRectangle(cornerRadius: 4)) | ||
charles-b-stb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
} | ||
} | ||
|
||
#Preview { | ||
VStack { | ||
TimetableGridCard( | ||
timetableItem: TimetableItem.Session.companion.fake(), | ||
onTap: { _ in } | ||
) | ||
.padding(.horizontal, 16) | ||
} | ||
.frame(maxWidth: .infinity, maxHeight: .infinity) | ||
.background(Color.black) | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it correct my understanding that sample data no longer used? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The sample data is still used in previews. I can refactor this to break out data class items. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,8 +33,7 @@ | |
case TimetableMode.list: | ||
TimetableListView(store: store) | ||
case TimetableMode.grid: | ||
Text("Grid view placeholder") | ||
.foregroundStyle(AssetColors.Surface.onSurface.swiftUIColor) | ||
TimetableGridView(store: store) | ||
} | ||
Spacer() | ||
} | ||
|
@@ -107,6 +106,53 @@ | |
} | ||
} | ||
|
||
struct TimetableGridView: View { | ||
private let store: StoreOf<TimetableReducer> | ||
|
||
public init(store: StoreOf<TimetableReducer>) { | ||
self.store = store | ||
} | ||
|
||
var body: some View { | ||
let rooms = RoomType.allCases.filter {$0 != RoomType.roomIj} | ||
|
||
ScrollView([.horizontal, .vertical]) { | ||
Grid { | ||
GridRow { | ||
Color.clear | ||
.gridCellUnsizedAxes([.horizontal, .vertical]) | ||
|
||
ForEach(rooms, id: \.self) { column in | ||
|
||
let room = getTimetableRoom(type: column) | ||
|
||
Text(room.name.currentLangTitle).foregroundStyle(room.roomTheme.primaryColor) | ||
.frame(width: 192) | ||
} | ||
} | ||
ForEach(store.timetableItems, id: \.self) { timeBlock in | ||
GridRow { | ||
VStack { | ||
Text(timeBlock.startsTimeString).foregroundStyle(AssetColors.Surface.onSurface.swiftUIColor) | ||
Spacer() | ||
|
||
}.frame(height: 153) | ||
|
||
charles-b-stb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
ForEach(rooms, id: \.self) { room in | ||
|
||
timeBlock.getCellForRoom(room: room, onTap: { item in | ||
store.send(.view(.timetableItemTapped)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I need to backmerge for this to work, so I will fix that soon. |
||
}) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
} | ||
} | ||
|
||
struct TimeGroupMiniList: View { | ||
let contents: TimetableTimeGroupItems | ||
let onItemTap: (TimetableItemWithFavorite) -> Void | ||
|
@@ -136,38 +182,86 @@ | |
} | ||
} | ||
|
||
struct TagView: View { | ||
let tagText: String | ||
let highlight: Bool | ||
|
||
var body: some View { | ||
HStack { | ||
if highlight { | ||
Image(systemName: "diamond.fill").resizable().frame(width: 11,height: 11).foregroundStyle(AssetColors.Custom.flamingo.swiftUIColor) | ||
.padding(-3) | ||
} | ||
Text(tagText).foregroundStyle(highlight ? AssetColors.Custom.flamingo.swiftUIColor : AssetColors.Surface.onSurface.swiftUIColor) | ||
} | ||
.padding( | ||
EdgeInsets(top: 2,leading: 7, bottom: 2, trailing: 7)) | ||
.border(highlight ? AssetColors.Custom.flamingo.swiftUIColor : AssetColors.Surface.onSurface.swiftUIColor) | ||
.padding(-2) | ||
func getTimetableRoom(type: RoomType) -> TimetableRoom { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it would be more Swift-Like to implement this convert logic in extension. extension RoomType {
func toRoom() -> TimetableRoom {
...
}
}
let type: RoomType = .roomI
let room = type.toRoom() There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed |
||
switch (type) { | ||
charles-b-stb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
case .roomI: | ||
return TimetableRoom( | ||
id: 1, | ||
name: MultiLangText( | ||
jaTitle: "Iguana", | ||
enTitle: "Iguana" | ||
), | ||
type: .roomI, | ||
sort: 1 | ||
) | ||
case .roomG: | ||
return TimetableRoom( | ||
id: 2, | ||
name: MultiLangText( | ||
jaTitle: "Giraffe", | ||
enTitle: "Giraffe" | ||
), | ||
type: .roomG, | ||
sort: 2 | ||
) | ||
case .roomH: | ||
return TimetableRoom( | ||
id: 3, | ||
name: MultiLangText( | ||
jaTitle: "Hedgehog", | ||
enTitle: "Hedgehog" | ||
), | ||
type: .roomH, | ||
sort: 3 | ||
) | ||
case .roomF: | ||
return TimetableRoom( | ||
id: 4, | ||
name: MultiLangText( | ||
jaTitle: "Flamingo", | ||
enTitle: "Flamingo" | ||
), | ||
type: .roomF, | ||
sort: 4 | ||
) | ||
case .roomJ: | ||
return TimetableRoom( | ||
id: 5, | ||
name: MultiLangText( | ||
jaTitle: "Jellyfish", | ||
enTitle: "Jellyfish" | ||
), | ||
type: .roomJ, | ||
sort: 5 | ||
) | ||
case .roomIj: | ||
return TimetableRoom( | ||
id: 6, | ||
name: MultiLangText( | ||
jaTitle: "All", | ||
enTitle: "All" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there not an item for all rooms? From the UI it looked like some events fill the whole screen. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bigger question: Do we have any examples of Iguana and Jellyfish? It seems like a case we should test in grid mode. |
||
), | ||
type: .roomIj, | ||
sort: 6 | ||
) | ||
} | ||
} | ||
|
||
struct PhotoView: View { | ||
//TODO: Replace this with an actual photo render | ||
let photo: String | ||
let name: String | ||
|
||
var body: some View { | ||
HStack { | ||
Image(systemName:photo).resizable().frame(width: 32,height: 32).foregroundStyle(AssetColors.Custom.flamingo.swiftUIColor) | ||
Text(name) | ||
extension TimetableTimeGroupItems { | ||
func getCellForRoom(room: RoomType, onTap: @escaping (TimetableItem) -> Void) -> TimetableGridCard { | ||
return if let cell = getItemForRoom(forRoom: room) { | ||
TimetableGridCard(timetableItem: cell.timetableItem) { timetableItem in | ||
onTap(timetableItem) | ||
} | ||
} else { | ||
TimetableGridCard(timetableItem: nil) { _ in | ||
// Does nothing | ||
} | ||
} | ||
} | ||
} | ||
|
||
|
||
#Preview { | ||
TimetableView( | ||
store: .init(initialState: .init(timetableItems: SampleData.init().workdayResults), | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This view isn't common component I think.
you should move to Timetable package please🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved it, but it did require me to make one shared class between the card classes public (it was package before)