Files
omnivore/apple/OmnivoreKit/Sources/Views/TextChip.swift
Jackson Harper 3062e16e63 Pass tap events from web reader into native instead of setting up gestures in native
This allows us to handle tap events based on state better, most
importantly it means we wont raise the bottom buttons if the
there is a tap to dismiss an active menu.
2023-02-08 18:52:17 +08:00

189 lines
4.9 KiB
Swift

import Models
import SwiftUI
import Utils
public struct TextChip: View {
@Environment(\.colorScheme) var colorScheme
let checked: Bool
let padded: Bool
var onTap: ((TextChip) -> Void)?
public init(text: String, color: Color, negated: Bool = false) {
self.text = text
self.color = color
self.negated = negated
self.checked = false
self.padded = false
}
public init?(feedItemLabel: LinkedItemLabel, negated: Bool = false) {
guard let color = Color(hex: feedItemLabel.color ?? "") else { return nil }
self.text = feedItemLabel.name ?? ""
self.color = color
self.negated = negated
self.checked = false
self.padded = false
}
public init?(feedItemLabel: LinkedItemLabel, negated: Bool = false, checked: Bool = false, padded: Bool = false, onTap: ((TextChip) -> Void)?) {
guard let color = Color(hex: feedItemLabel.color ?? "") else {
return nil
}
self.text = feedItemLabel.name ?? ""
self.color = color
self.negated = negated
self.onTap = onTap
self.checked = checked
self.padded = padded
}
public let text: String
let color: Color
let negated: Bool
var textColor: Color {
guard let luminance = color.luminance else {
return .white
}
print(" Luminance: ", luminance, "for color", color.hex)
return luminance > 0.35 ? .black : .white
}
var backgroundColor: Color {
color.opacity(0.9)
}
var checkedBorderColor: Color {
colorScheme == .dark ? Color.white : Color.black
}
var borderColor: Color {
checked ? checkedBorderColor : Color.clear
}
public var body: some View {
ZStack(alignment: .topTrailing) {
Text(text)
.strikethrough(color: negated ? textColor : .clear)
.padding(.horizontal, padded ? 10 : 8)
.padding(.vertical, padded ? 8 : 5)
.font(.appCaptionMedium)
.foregroundColor(textColor)
.lineLimit(1)
.background(
RoundedRectangle(cornerRadius: 4)
.fill(backgroundColor)
)
.overlay(
RoundedRectangle(cornerRadius: 4)
.stroke(borderColor, lineWidth: 2)
)
.padding(1)
}.onTapGesture {
if let onTap = onTap {
onTap(self)
}
}
}
}
public struct TextChipButton: View {
public static func makeAddLabelButton(onTap: @escaping () -> Void) -> TextChipButton {
TextChipButton(title: LocalText.labelsGeneric, color: .systemGray6, actionType: .show, negated: false, onTap: onTap)
}
public static func makeMenuButton(title: String) -> TextChipButton {
TextChipButton(title: title, color: .systemGray6, actionType: .show, negated: false, onTap: {})
}
public static func makeSearchFilterButton(title: String, onTap: @escaping () -> Void) -> TextChipButton {
TextChipButton(title: title, color: .appCtaYellow, actionType: .filter, negated: false, onTap: onTap)
}
public static func makeShowOptionsButton(title: String, onTap: @escaping () -> Void) -> TextChipButton {
TextChipButton(title: title, color: .appButtonBackground, actionType: .add, negated: false, onTap: onTap)
}
public static func makeRemovableLabelButton(
feedItemLabel: LinkedItemLabel,
negated: Bool,
onTap: @escaping () -> Void
) -> TextChipButton {
TextChipButton(
title: feedItemLabel.name ?? "",
color: Color(hex: feedItemLabel.color ?? "") ?? .appButtonBackground,
actionType: .remove,
negated: negated,
onTap: onTap
)
}
public enum ActionType {
case remove
case add
case show
case filter
var systemIconName: String {
switch self {
case .filter, .remove:
return "xmark"
case .add:
return "plus"
case .show:
return "chevron.down"
}
}
}
public init(title: String, color: Color, actionType: ActionType, negated: Bool, onTap: @escaping () -> Void) {
self.text = title
self.color = color
self.onTap = onTap
self.actionType = actionType
self.foregroundColor = {
if actionType == .show {
return .appGrayText
}
return color.isDark ? .white : .black
}()
self.negated = negated
}
let text: String
let negated: Bool
let color: Color
let onTap: () -> Void
let actionType: ActionType
let foregroundColor: Color
public var body: some View {
VStack(spacing: 0) {
HStack {
if actionType == .filter {
Image(systemName: "line.3.horizontal.decrease")
}
Text(text)
.strikethrough(color: negated ? foregroundColor : .clear)
.padding(.leading, 3)
Image(systemName: actionType.systemIconName)
}
.padding(.horizontal, 10)
.padding(.vertical, 8)
.font(.appFootnote)
.foregroundColor(foregroundColor)
.lineLimit(1)
.background(Rectangle().fill(color))
.cornerRadius(8)
}
.padding(.vertical, 0)
.contentShape(Rectangle())
.onTapGesture { onTap() }
}
}