mirror of
https://github.com/ichmagmaus111/ghostgram.git
synced 2026-09-22 20:30:41 +02:00
Update Ghostgram features
This commit is contained in:
@@ -0,0 +1,209 @@
|
||||
import SwiftUI
|
||||
import Foundation
|
||||
|
||||
|
||||
// MARK: Swiftgram
|
||||
public struct ChatToolbarView: View {
|
||||
var onQuote: () -> Void
|
||||
var onSpoiler: () -> Void
|
||||
var onBold: () -> Void
|
||||
var onItalic: () -> Void
|
||||
var onMonospace: () -> Void
|
||||
var onLink: () -> Void
|
||||
var onStrikethrough: () -> Void
|
||||
var onUnderline: () -> Void
|
||||
var onCode: () -> Void
|
||||
|
||||
var onNewLine: () -> Void
|
||||
@Binding private var showNewLine: Bool
|
||||
|
||||
var onClearFormatting: () -> Void
|
||||
|
||||
public init(
|
||||
onQuote: @escaping () -> Void,
|
||||
onSpoiler: @escaping () -> Void,
|
||||
onBold: @escaping () -> Void,
|
||||
onItalic: @escaping () -> Void,
|
||||
onMonospace: @escaping () -> Void,
|
||||
onLink: @escaping () -> Void,
|
||||
onStrikethrough: @escaping () -> Void,
|
||||
onUnderline: @escaping () -> Void,
|
||||
onCode: @escaping () -> Void,
|
||||
onNewLine: @escaping () -> Void,
|
||||
showNewLine: Binding<Bool>,
|
||||
onClearFormatting: @escaping () -> Void
|
||||
) {
|
||||
self.onQuote = onQuote
|
||||
self.onSpoiler = onSpoiler
|
||||
self.onBold = onBold
|
||||
self.onItalic = onItalic
|
||||
self.onMonospace = onMonospace
|
||||
self.onLink = onLink
|
||||
self.onStrikethrough = onStrikethrough
|
||||
self.onUnderline = onUnderline
|
||||
self.onCode = onCode
|
||||
self.onNewLine = onNewLine
|
||||
self._showNewLine = showNewLine
|
||||
self.onClearFormatting = onClearFormatting
|
||||
}
|
||||
|
||||
public func setShowNewLine(_ value: Bool) {
|
||||
self.showNewLine = value
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
ScrollView(.horizontal, showsIndicators: false) {
|
||||
HStack(spacing: 12) {
|
||||
if showNewLine {
|
||||
Button(action: onNewLine) {
|
||||
Image(systemName: "return")
|
||||
}
|
||||
.buttonStyle(ToolbarButtonStyle())
|
||||
}
|
||||
Button(action: onClearFormatting) {
|
||||
Image(systemName: "pencil.slash")
|
||||
}
|
||||
.buttonStyle(ToolbarButtonStyle())
|
||||
Spacer()
|
||||
// Quote Button
|
||||
Button(action: onQuote) {
|
||||
Image(systemName: "text.quote")
|
||||
}
|
||||
.buttonStyle(ToolbarButtonStyle())
|
||||
|
||||
// Spoiler Button
|
||||
Button(action: onSpoiler) {
|
||||
Image(systemName: "eye.slash")
|
||||
}
|
||||
.buttonStyle(ToolbarButtonStyle())
|
||||
|
||||
// Bold Button
|
||||
Button(action: onBold) {
|
||||
Image(systemName: "bold")
|
||||
}
|
||||
.buttonStyle(ToolbarButtonStyle())
|
||||
|
||||
// Italic Button
|
||||
Button(action: onItalic) {
|
||||
Image(systemName: "italic")
|
||||
}
|
||||
.buttonStyle(ToolbarButtonStyle())
|
||||
|
||||
// Monospace Button
|
||||
Button(action: onMonospace) {
|
||||
if #available(iOS 16.4, *) {
|
||||
Text("M").monospaced()
|
||||
} else {
|
||||
Text("M")
|
||||
}
|
||||
}
|
||||
.buttonStyle(ToolbarButtonStyle())
|
||||
|
||||
// Link Button
|
||||
Button(action: onLink) {
|
||||
Image(systemName: "link")
|
||||
}
|
||||
.buttonStyle(ToolbarButtonStyle())
|
||||
|
||||
// Underline Button
|
||||
Button(action: onUnderline) {
|
||||
Image(systemName: "underline")
|
||||
}
|
||||
.buttonStyle(ToolbarButtonStyle())
|
||||
|
||||
|
||||
// Strikethrough Button
|
||||
Button(action: onStrikethrough) {
|
||||
Image(systemName: "strikethrough")
|
||||
}
|
||||
.buttonStyle(ToolbarButtonStyle())
|
||||
|
||||
|
||||
// Code Button
|
||||
Button(action: onCode) {
|
||||
Image(systemName: "chevron.left.forwardslash.chevron.right")
|
||||
}
|
||||
.buttonStyle(ToolbarButtonStyle())
|
||||
}
|
||||
.padding(.horizontal, 8)
|
||||
.padding(.vertical, 8)
|
||||
}
|
||||
.background(Color(UIColor.clear))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// iOS 13–14 blur fallback
|
||||
@available(iOS 13.0, *)
|
||||
struct BlurView: UIViewRepresentable {
|
||||
let style: UIBlurEffect.Style
|
||||
func makeUIView(context: Context) -> UIVisualEffectView {
|
||||
UIVisualEffectView(effect: UIBlurEffect(style: style))
|
||||
}
|
||||
func updateUIView(_ uiView: UIVisualEffectView, context: Context) {
|
||||
uiView.effect = UIBlurEffect(style: style)
|
||||
}
|
||||
}
|
||||
|
||||
// Simple glass background (now supports round + adaptive brightness)
|
||||
@available(iOS 13.0, *)
|
||||
struct Glass: View {
|
||||
var cornerRadius: CGFloat?
|
||||
@Environment(\.colorScheme) private var colorScheme
|
||||
|
||||
var body: some View {
|
||||
let isDark = colorScheme == .dark
|
||||
|
||||
Group {
|
||||
if #available(iOS 15.0, *) {
|
||||
Circle()
|
||||
.fill(.ultraThinMaterial)
|
||||
.overlay(
|
||||
Circle()
|
||||
.fill(
|
||||
Color.white.opacity(isDark ? 0.05 : 0.25)
|
||||
)
|
||||
)
|
||||
} else {
|
||||
Circle()
|
||||
.fill(Color.clear)
|
||||
.background(
|
||||
BlurView(style: .systemThinMaterial)
|
||||
.clipShape(Circle())
|
||||
)
|
||||
.overlay(
|
||||
Circle()
|
||||
.fill(
|
||||
Color.white.opacity(isDark ? 0.05 : 0.25)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
.overlay(
|
||||
Circle()
|
||||
.stroke(Color.white.opacity(0.25), lineWidth: 1)
|
||||
)
|
||||
.shadow(color: Color.black.opacity(0.12), radius: 6, x: 0, y: 3)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Button style
|
||||
@available(iOS 13.0, *)
|
||||
struct ToolbarButtonStyle: ButtonStyle {
|
||||
var size: CGFloat = 39
|
||||
|
||||
func makeBody(configuration: Configuration) -> some View {
|
||||
configuration.label
|
||||
.frame(width: size, height: size)
|
||||
.contentShape(Circle())
|
||||
.background(Glass())
|
||||
.overlay(
|
||||
Circle()
|
||||
.fill(Color.black.opacity(configuration.isPressed ? 0.08 : 0))
|
||||
)
|
||||
.scaleEffect(configuration.isPressed ? 0.95 : 1)
|
||||
.animation(nil, value: configuration.isPressed)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user