Skip to content
Draft
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
2 changes: 1 addition & 1 deletion DanXiUI/Forum/Presentation/FloorPresentation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func parseFloorImageURLs(content: String) -> [URL] {
var imageURLs: [URL] = []
for run in attributed.runs {
if let imageURL = run.imageURL,
Sticker(rawValue: imageURL.absoluteString) == nil {
imageURL.absoluteString.starts(with: "http") {
imageURLs.append(imageURL)
}
}
Expand Down
57 changes: 0 additions & 57 deletions DanXiUI/Forum/Presentation/Sticker.swift

This file was deleted.

84 changes: 84 additions & 0 deletions DanXiUI/Forum/Store/StickerStore.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import Utils
import SwiftUI
import Disk

class StickerStore: ObservableObject {
static let shared = StickerStore()

var stickers: [Sticker]
var stickerSet: Set<String>
var stickerImage: [String: LoadedImage]

init() {
stickers = []
stickerImage = [:]
stickerSet = []
}

func initialize() async throws {
if ConfigurationCenter.configuration.stickers.isEmpty {
try await ConfigurationCenter.refresh()
}

self.stickers = ConfigurationCenter.configuration.stickers
self.stickerSet = Set(stickers.map(\.id))

for sticker in stickers {
do {
let loadedImage = try await retrieveImage(sticker: sticker)
stickerImage[sticker.id] = loadedImage
} catch _ as URLError {
continue // ignore network error, sticker loading failed should not be fatal
}
}

Task {
try clearUnunsed(stickers: stickers)
}
}

private func retrieveImage(sticker: Sticker) async throws -> LoadedImage {
let filename = "stickers/\(sticker.sha256).jpg"

let fileURL = try Disk.url(for: filename, in: .caches)

// retrieved from disk
if let uiImage = try? Disk.retrieve(filename, from: .caches, as: UIImage.self) {
let image = Image(uiImage: uiImage)
return LoadedImage(image: image, uiImage: uiImage, fileURL: fileURL)
}

// download image from internet
let (data, _) = try await URLSession.shared.data(from: sticker.url)
guard let uiImage = UIImage(data: data) else {
throw LocatableError()
}
try Disk.save(uiImage, to: .caches, as: filename)
let image = Image(uiImage: uiImage)

return LoadedImage(image: image, uiImage: uiImage, fileURL: fileURL)
}

private func clearUnunsed(stickers: [Sticker]) throws {
let fileManager = FileManager.default
let paths = fileManager.urls(for: .cachesDirectory, in: .userDomainMask)
guard var path = paths.first else { return }
path.append(path: "stickers")

let items = try fileManager.contentsOfDirectory(at: path, includingPropertiesForKeys: nil)
for item in items {
let filename = item.lastPathComponent
for sticker in stickers {
if filename.starts(with: sticker.sha256) {
try? fileManager.removeItem(at: item)
}
}
}
}
}

struct LoadedImage {
let image: Image
let uiImage: UIImage
let fileURL: URL
}
13 changes: 9 additions & 4 deletions DanXiUI/Forum/Views/ForumEditor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import DanXiKit

public struct ForumEditor: View {
@EnvironmentObject.Optional private var holeModel: HoleModel?
@ObservedObject private var stickerStore = StickerStore.shared
@StateObject private var model: ForumEditorModel
@Binding var content: String
@State private var textHeight: CGFloat = .zero
Expand Down Expand Up @@ -118,7 +119,7 @@ public struct ForumEditor: View {
.useSafariController()
}
}

private var stickerPicker: some View {
NavigationStack {
Form {
Expand All @@ -127,12 +128,16 @@ public struct ForumEditor: View {
GridItem(.flexible()),
GridItem(.flexible()),
GridItem(.flexible())]) {
ForEach(Sticker.allCases, id: \.self.rawValue) { sticker in
ForEach(StickerStore.shared.stickers) { sticker in
Button {
model.insertTextAtCursor("![](\(sticker.rawValue))")
model.insertTextAtCursor("![](\(sticker.id))")
showStickers = false
} label: {
sticker.image
if let loadedImage = stickerStore.stickerImage[sticker.id] {
loadedImage.image
} else {
Image(systemName: "photo.badge.exclamationmark")
}
}
}
}
Expand Down
6 changes: 0 additions & 6 deletions DanXiUI/Resouces/Assets.xcassets/Stickers/Contents.json

This file was deleted.

This file was deleted.

Binary file not shown.
Binary file not shown.
Binary file not shown.

This file was deleted.

Binary file not shown.
Binary file not shown.
Binary file not shown.

This file was deleted.

Binary file not shown.
Binary file not shown.
Binary file not shown.

This file was deleted.

Binary file not shown.
Binary file not shown.
Binary file not shown.

This file was deleted.

Binary file not shown.
Binary file not shown.
Binary file not shown.

This file was deleted.

Binary file not shown.
Binary file not shown.
Binary file not shown.

This file was deleted.

Binary file not shown.
Binary file not shown.
Binary file not shown.

This file was deleted.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading