Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Modules/SharedUI/Sources/SharedUI/Colors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,8 @@ public extension Color {
static var palletOrange: Color {
Color(.palletOrange)
}

static var lightGray: Color {
Color(.lightGray)
}
}
2 changes: 1 addition & 1 deletion Modules/SharedUI/Sources/SharedUI/Images.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import SwiftUI

public extension Image {
static var logoRounded: Image {
Image(.logoRounded)
Image("LogoRounded")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xD6",
"green" : "0xD1",
"red" : "0xD1"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import SwiftUI

struct ProducSearchTabBarHeader: View {
public struct TabBarHeader: View {
@Namespace var namespace
@Binding var currentTab: Int
var tabBarOptions: [String]

var body: some View {
public init(currentTab: Binding<Int>, tabBarOptions: [String]) {
_currentTab = currentTab
self.tabBarOptions = tabBarOptions
}

public var body: some View {
VStack(spacing: 0) {
ScrollView(.horizontal) {
HStack {
Expand Down Expand Up @@ -48,8 +53,11 @@ struct ProducSearchTabBarHeader: View {
}
}

@available(iOS 17.0, *)
#Preview {
ProducSearchTabBarHeader(
currentTab: .constant(4), tabBarOptions: ["All", "Food", "Drinks", "more", "One more"]
@Previewable @State var currentTab = 3
TabBarHeader(
currentTab: $currentTab,
tabBarOptions: ["All", "Food", "Drinks", "more", "One more"]
)
}
2 changes: 1 addition & 1 deletion Modules/WRCore/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ let package = Package(
],
dependencies: [
.package(path: "../SharedUI"),
.package(url: "https://github.com/DatepollSystems/WaiterRobot-Shared-Android.git", from: "1.6.1"),
.package(url: "https://github.com/DatepollSystems/WaiterRobot-Shared-Android.git", from: "1.7.3"),
],
targets: [
.target(
Expand Down
21 changes: 21 additions & 0 deletions Modules/WRCore/Sources/WRCore/Alert.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import shared
import SwiftUI

public extension Alert {
init(_ dialog: DialogState) {
if let secondaryButton = dialog.secondaryButton {
self.init(
title: Text(dialog.title.localized()),
message: Text(dialog.text.localized()),
primaryButton: .default(Text(dialog.primaryButton.text.localized()), action: dialog.primaryButton.action),
secondaryButton: .cancel(Text(secondaryButton.text.localized()), action: secondaryButton.action)
)
} else {
self.init(
title: Text(dialog.title.localized()),
message: Text(dialog.text.localized()),
dismissButton: .default(Text(dialog.primaryButton.text.localized()), action: dialog.primaryButton.action)
)
}
}
}
47 changes: 47 additions & 0 deletions Modules/WRCore/Sources/WRCore/ErrorBar.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import shared
import SharedUI
import SwiftUI

public struct ErrorBar: View {
let message: StringDesc
let initialLines: Int
let retryAction: (() -> Void)?

@State private var expanded = false

public init(message: StringDesc, initialLines: Int = 2, retryAction: (() -> Void)? = nil) {
self.message = message
self.initialLines = initialLines
self.retryAction = retryAction
}

public var body: some View {
HStack(alignment: .center) {
Text(message())
.lineLimit(expanded ? nil : initialLines)
.multilineTextAlignment(.leading)
.frame(maxWidth: .infinity, alignment: .leading)

if retryAction != nil {
Spacer().frame(width: 16)
Button(action: {
retryAction?()
}) {
Text(localize.exceptions_retry())
.bold()
.multilineTextAlignment(.center)
.lineLimit(expanded ? nil : initialLines)
}
}
}
.padding(.leading, 16)
.padding(.top, 8)
.padding(.trailing, retryAction == nil ? 16 : 8)
.padding(.bottom, 8)
.background(Color.red)
.onTapGesture {
expanded.toggle()
}
.animation(.default, value: expanded)
}
}
33 changes: 30 additions & 3 deletions Modules/WRCore/Sources/WRCore/Globals.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import SwiftUI
import UIKit

public var koin: IosKoinComponent { IosKoinComponent.shared }

public var localize: shared.L.Companion { shared.L.Companion.shared }
public var localize: shared.MR.strings { shared.MR.strings() }

public enum WRCore {
/// Setup of frameworks and all the other related stuff which is needed everywhere in the app
Expand All @@ -29,7 +28,6 @@ public enum WRCore {

let logger = koin.logger(tag: "AppDelegate")

KMMResourcesLocalizationKt.localizationBundle = Bundle(for: shared.L.self)
logger.d { "initialized localization bundle" }
print("finished app setup")
}
Expand All @@ -53,3 +51,32 @@ public extension EnvironmentValues {
#endif
}
}

public extension StringResource {
func callAsFunction() -> String {
desc().localized()
}

func callAsFunction(_ args: String...) -> String {
format(args: args).localized()
}
}

public extension StringDesc {
func callAsFunction() -> String {
localized()
}
}

public extension Skie.Shared.Resource.__Sealed {
var data: T? {
switch self {
case let .loading(resource):
resource.data
case let .error(resource):
resource.data
case let .success(resource):
resource.data
}
}
}
7 changes: 7 additions & 0 deletions Modules/WRCore/Sources/WRCore/KotlinArrayWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ import Foundation
import shared

public extension Array where Element: AnyObject {
init?(_ kotlinArray: KotlinArray<Element>?) {
guard let array = kotlinArray else {
return nil
}
self.init(array)
}

init(_ kotlinArray: KotlinArray<Element>) {
self.init()
let iterator = kotlinArray.iterator()
Expand Down
89 changes: 63 additions & 26 deletions Modules/WRCore/Sources/WRCore/Mock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,76 @@ import Foundation
import shared

public enum Mock {
public static func tableGroups() -> [TableGroup] {
[
tableGroup(with: 1, name: "Hof"),
tableGroup(with: 2, name: "Terasse"),
tableGroup(with: 3, name: "Zimmer A"),
]
public static func groupedTables(groups: Int = 1) -> [GroupedTables] {
let colors = ["ffaaee", "ffeeaa", "eeaaff", nil]
return (1 ... groups).map { groupId in
let tableCount = groupId % 3 == 0 ? 4 : 3
let groupName = "Table Group \(groupId)"

return GroupedTables(
id: Int64(groupId),
name: groupName,
eventId: 1,
color: colors[groupId % colors.count],
tables: (1 ... tableCount).map {
table(with: groupId * 10 + $0, hasOrders: $0 % 2 == 0, groupName: groupName)
}
)
}
}

public static func tableGroup(with id: Int64, name: String = "Hof") -> TableGroup {
TableGroup(
id: id,
name: name,
eventId: 1,
position: Int32(id),
color: "",
hidden: false,
tables: [
table(with: 1),
table(with: 2, hasOrders: true),
table(with: 3),
table(with: 4),
table(with: 5),
table(with: 6),
]
)
public static func tableGroups(groups: Int = 1) -> [TableGroup] {
groupedTables(groups: groups).map {
TableGroup(
id: $0.id,
name: $0.name,
color: $0.color,
hidden: false
)
}
}

public static func table(with id: Int64, hasOrders: Bool = false) -> shared.Table {
public static func table(with id: Int, hasOrders: Bool = false, groupName: String = "Hof") -> shared.Table {
shared.Table(
id: id,
id: Int64(id),
number: Int32(id),
groupName: "Hof",
groupName: groupName,
hasOrders: hasOrders
)
}

public static func product(with id: Int, soldOut: Bool = false, color: String? = nil, allergens: Set<Character> = []) -> Product {
Product(
id: Int64(id),
name: "Product \(id)",
price: Money(cents: Int32(id * 10)),
soldOut: soldOut,
color: color,
allergens: allergens.enumerated().map { index, shortName in
Allergen(id: Int64(index), name: shortName.description, shortName: shortName.description)
}.filter { $0.shortName.isEmpty == false },
position: Int32(id)
)
}

public static func productGroups(groups: Int = 1) -> [GroupedProducts] {
let colors = ["ffaaee", "ffeeaa", "eeaaff", nil].shuffled()
let allergenList = "ABCDEFG "
return (1 ... groups).map { groupId in
let productCount = groupId % 3 == 0 ? 4 : 3
let groupName = "Product Group \(groupId)"
return GroupedProducts(
id: Int64(groupId),
name: groupName,
position: Int32(groupId),
color: colors[groupId % colors.count],
products: (1 ... productCount).map {
let allergens = (0 ... ($0 % 3)).map { _ in
allergenList.randomElement()!
}
return product(with: groupId * 10 + $0, soldOut: $0 % 5 == 2, allergens: Set(allergens))
}
)
}
}
}
4 changes: 2 additions & 2 deletions Modules/WRCore/Sources/WRCore/Navigation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ extension UIPilot<Screen> {

public extension View {
func customBackNavigation(
title: String = localize.navigation.back(),
title: String = localize.navigation_back(),
icon: String? = "chevron.left",
action: @escaping () -> Void
) -> some View {
Expand Down Expand Up @@ -73,7 +73,7 @@ public extension View {
logger.d { "Got sideEffect: \(sideEffect)" }
switch onEnum(of: sideEffect as! NavOrViewModelEffect<SideEffect>) {
case let .navEffect(navEffect):
await navigator.navigate(navEffect.action)
navigator.navigate(navEffect.action)
case let .vMEffect(effect):
if handler?(effect.effect) != true {
logger.w { "Side effect \(effect.effect) was not handled." }
Expand Down
12 changes: 12 additions & 0 deletions Modules/WRCore/Sources/WRCore/ObservableViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ public class ObservableTableListViewModel: ObservableViewModel<TableListState, T
}
}

public class ObservableTableGroupFilterViewModel: ObservableViewModel<TableGroupFilterState, TableGroupFilterEffect, TableGroupFilterViewModel> {
public init() {
super.init(viewModel: koin.tableGroupFilterVM())
}
}

public class ObservableTableDetailViewModel: ObservableViewModel<TableDetailState, TableDetailEffect, TableDetailViewModel> {
public init(table: Table) {
super.init(viewModel: koin.tableDetailVM(table: table))
Expand All @@ -60,6 +66,12 @@ public class ObservableOrderViewModel: ObservableViewModel<OrderState, OrderEffe
}
}

public class ObservableProductListViewModel: ObservableViewModel<ProductListState, ProductListEffect, ProductListViewModel> {
public init() {
super.init(viewModel: koin.productListVM())
}
}

public class ObservableLoginScannerViewModel: ObservableViewModel<LoginScannerState, LoginScannerEffect, LoginScannerViewModel> {
public init() {
super.init(viewModel: koin.loginScannerVM())
Expand Down
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,14 @@ The KMM module is integrated as a Swift-Package (shared).

This project uses XcodeGen for generating the Xcode project.

1. Xcodegen
1. Gems

Run in your terminal:

```bash
swift run xcodegen
bundle install
```

> This command must also be run after switching branches and it's advisable to also run it after a `git pull`

2. Git pre-commit hook

To have unified formatting, we use SwiftFormat. The pre-commit hook can be installed if the code should be formatted automatically before every commit. Execute following command in your terminal:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "wr-round.svg",
"filename" : "wr-round-yellow.svg",
"idiom" : "universal"
}
],
Expand Down
Loading
Loading