Recently used tags
This commit is contained in:
parent
3e968525ac
commit
f428118fa0
|
@ -136,6 +136,7 @@ extension View {
|
|||
Draft.self,
|
||||
LocalTimeline.self,
|
||||
TagGroup.self,
|
||||
RecentTag.self,
|
||||
])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import Foundation
|
||||
import SwiftData
|
||||
import SwiftUI
|
||||
|
||||
@Model public class RecentTag: Equatable {
|
||||
public var title: String = ""
|
||||
public var lastUse: Date = Date()
|
||||
|
||||
public init(title: String) {
|
||||
self.title = title
|
||||
self.lastUse = Date()
|
||||
}
|
||||
}
|
|
@ -38,7 +38,7 @@ struct StatusEditorAccessoryView: View {
|
|||
}
|
||||
.frame(height: 24)
|
||||
.padding(16)
|
||||
.background(.ultraThinMaterial)
|
||||
.background(.thinMaterial)
|
||||
.cornerRadius(8)
|
||||
#else
|
||||
Divider()
|
||||
|
@ -47,7 +47,7 @@ struct StatusEditorAccessoryView: View {
|
|||
}
|
||||
.frame(height: 20)
|
||||
.padding(.vertical, 12)
|
||||
.background(.ultraThinMaterial)
|
||||
.background(.thinMaterial)
|
||||
#endif
|
||||
}
|
||||
.onAppear {
|
||||
|
|
|
@ -2,26 +2,54 @@ import DesignSystem
|
|||
import EmojiText
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
import Models
|
||||
import SwiftData
|
||||
|
||||
@MainActor
|
||||
struct StatusEditorAutoCompleteView: View {
|
||||
@Environment(\.modelContext) private var context
|
||||
|
||||
@Environment(Theme.self) private var theme
|
||||
|
||||
var viewModel: StatusEditorViewModel
|
||||
|
||||
@State private var isTagSuggestionExpanded: Bool = false
|
||||
|
||||
@Query(sort: \RecentTag.lastUse, order: .reverse) var recentTags: [RecentTag]
|
||||
|
||||
var body: some View {
|
||||
if !viewModel.mentionsSuggestions.isEmpty || !viewModel.tagsSuggestions.isEmpty {
|
||||
ScrollView(.horizontal, showsIndicators: false) {
|
||||
LazyHStack {
|
||||
if !viewModel.mentionsSuggestions.isEmpty {
|
||||
suggestionsMentionsView
|
||||
} else {
|
||||
suggestionsTagView
|
||||
VStack {
|
||||
HStack {
|
||||
ScrollView(.horizontal, showsIndicators: false) {
|
||||
LazyHStack {
|
||||
if !viewModel.mentionsSuggestions.isEmpty {
|
||||
suggestionsMentionsView
|
||||
} else {
|
||||
suggestionsTagView
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, .layoutPadding)
|
||||
}
|
||||
.scrollContentBackground(.hidden)
|
||||
if !viewModel.tagsSuggestions.isEmpty {
|
||||
Spacer()
|
||||
Button {
|
||||
withAnimation {
|
||||
isTagSuggestionExpanded.toggle()
|
||||
}
|
||||
} label: {
|
||||
Image(systemName: isTagSuggestionExpanded ? "chevron.down.circle" : "chevron.up.circle")
|
||||
}
|
||||
.padding(.trailing, 8)
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, .layoutPadding)
|
||||
.frame(height: 40)
|
||||
if isTagSuggestionExpanded {
|
||||
expandedTagsSuggestionView
|
||||
}
|
||||
}
|
||||
.frame(height: 40)
|
||||
.background(.ultraThinMaterial)
|
||||
.background(.thinMaterial)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,10 +66,11 @@ struct StatusEditorAutoCompleteView: View {
|
|||
.emojiSize(Font.scaledFootnoteFont.emojiSize)
|
||||
.emojiBaselineOffset(Font.scaledFootnoteFont.emojiBaselineOffset)
|
||||
.font(.scaledFootnote)
|
||||
.fontWeight(.bold)
|
||||
.foregroundColor(theme.labelColor)
|
||||
Text("@\(account.acct)")
|
||||
.font(.scaledCaption)
|
||||
.foregroundColor(theme.tintColor)
|
||||
.font(.scaledFootnote)
|
||||
.foregroundStyle(theme.tintColor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,17 +80,53 @@ struct StatusEditorAutoCompleteView: View {
|
|||
private var suggestionsTagView: some View {
|
||||
ForEach(viewModel.tagsSuggestions) { tag in
|
||||
Button {
|
||||
viewModel.selectHashtagSuggestion(tag: tag)
|
||||
viewModel.selectHashtagSuggestion(tag: tag.name)
|
||||
if let index = recentTags.firstIndex(where: { $0.title.lowercased() == tag.name.lowercased() }) {
|
||||
recentTags[index].lastUse = Date()
|
||||
} else {
|
||||
context.insert(RecentTag(title: tag.name))
|
||||
}
|
||||
} label: {
|
||||
VStack(alignment: .leading) {
|
||||
Text("#\(tag.name)")
|
||||
.font(.scaledFootnote)
|
||||
.foregroundColor(theme.tintColor)
|
||||
.fontWeight(.bold)
|
||||
.foregroundColor(theme.labelColor)
|
||||
Text("tag.suggested.mentions-\(tag.totalUses)")
|
||||
.font(.scaledCaption)
|
||||
.foregroundStyle(.secondary)
|
||||
.font(.scaledFootnote)
|
||||
.foregroundStyle(theme.tintColor)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var expandedTagsSuggestionView: some View {
|
||||
ScrollView(.vertical) {
|
||||
LazyVStack(alignment: .leading, spacing: 12) {
|
||||
Text("status.editor.language-select.recently-used")
|
||||
.font(.scaledSubheadline)
|
||||
.foregroundStyle(theme.labelColor)
|
||||
.fontWeight(.bold)
|
||||
ForEach(recentTags) { tag in
|
||||
HStack {
|
||||
Button {
|
||||
tag.lastUse = Date()
|
||||
withAnimation {
|
||||
isTagSuggestionExpanded = false
|
||||
viewModel.selectHashtagSuggestion(tag: tag.title)
|
||||
}
|
||||
} label: {
|
||||
Text("#\(tag.title)")
|
||||
.font(.scaledFootnote)
|
||||
.fontWeight(.bold)
|
||||
.foregroundColor(theme.labelColor)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, .layoutPadding)
|
||||
}
|
||||
.frame(height: 250)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -564,9 +564,9 @@ import SwiftUI
|
|||
}
|
||||
}
|
||||
|
||||
func selectHashtagSuggestion(tag: Tag) {
|
||||
func selectHashtagSuggestion(tag: String) {
|
||||
if let range = currentSuggestionRange {
|
||||
replaceTextWith(text: "#\(tag.name) ", inRange: range)
|
||||
replaceTextWith(text: "#\(tag) ", inRange: range)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue