mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-12-01 20:51:25 +00:00
Merge branch 'main' into iOS-18
This commit is contained in:
commit
22a7b2a938
7 changed files with 261 additions and 38 deletions
|
@ -3,10 +3,10 @@
|
|||
{
|
||||
"identity" : "bodega",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/Dimillian/Bodega",
|
||||
"location" : "https://github.com/mergesort/Bodega",
|
||||
"state" : {
|
||||
"branch" : "main",
|
||||
"revision" : "a144ed8afdd760b65b6b9a136ba8bb75cd19387e"
|
||||
"revision" : "bfd8871e9c2590d31b200e54c75428a71483afdf",
|
||||
"version" : "2.1.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -23,8 +23,8 @@
|
|||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/divadretlaw/EmojiText",
|
||||
"state" : {
|
||||
"revision" : "415112e5f14619be0fdddd9dc6594bd76702927c",
|
||||
"version" : "4.0.3"
|
||||
"revision" : "174a7bc7bd75650ad1acb5679dbb754296093de0",
|
||||
"version" : "4.0.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -68,8 +68,8 @@
|
|||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/kean/Nuke",
|
||||
"state" : {
|
||||
"revision" : "2efd206503e99dd3a88a4dc433a76f98ce8cc198",
|
||||
"version" : "12.7.1"
|
||||
"revision" : "311016d972aa751ae8ab0cd5897422ebe7db0501",
|
||||
"version" : "12.7.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -129,10 +129,10 @@
|
|||
{
|
||||
"identity" : "swiftui-introspect",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/Dimillian/swiftui-introspect",
|
||||
"location" : "https://github.com/siteline/swiftui-introspect",
|
||||
"state" : {
|
||||
"branch" : "main",
|
||||
"revision" : "e5d36b00e6e437b552aa76ed6d1eca71d6fd8f8b"
|
||||
"revision" : "668a65735751432b640260c56dfa621cec568368",
|
||||
"version" : "1.2.0"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -332,6 +332,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "%@"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "%@"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -714,6 +720,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "%@ Mastodon'da yayınlandı"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "%@ 已在 Mastodon 发布"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -8935,6 +8947,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "Hesap"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Account"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -20503,6 +20521,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "Mastodon'a gönderim yapılırken bir hata oluştu, lütfen tekrar deneyin."
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "在向 Mastodon 发表嘟文时出错,请重试。"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -20651,6 +20675,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "Uygulama Hesabı"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "AppAccount"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -20713,6 +20743,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "Gönderi oluştur"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "撰写一篇嘟文"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -20741,6 +20777,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "Mastodon'a bir gönderi yazın"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "向 Mastodon 撰写一篇嘟文"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -20769,6 +20811,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "Mastodon'a gönderilecek gönderinin içeriği"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "发布到 Mastodon 的嘟文内容"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -22338,6 +22386,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "DeepL'e ulaşılamadı!\nAPI Anahtarı doğru mu?"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "无法连接 DeepL!\n你的 API 密钥是正确的吗?"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -31163,6 +31217,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "Yalnızca Takipçiler"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "仅关注者"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -31294,6 +31354,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "Örnek"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "服务器"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -32858,6 +32924,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "Ancak yine de örneğinizin çeviri hizmeti için bir yedek olarak kullanılabilir."
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "它仍可用作为你所处服务器的翻译服务的备用。"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -32881,6 +32953,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "Anahtar"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Key"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -35469,7 +35547,7 @@
|
|||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "needs_review",
|
||||
"state" : "translated",
|
||||
"value" : "设置 ..."
|
||||
}
|
||||
},
|
||||
|
@ -41022,6 +41100,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "Resim ile bir durum gönder"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "发布带图片的状态"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -41176,6 +41260,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "Gönderi görünürlüğü"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "嘟文可见度"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -41204,6 +41294,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "Özel"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "具体的人"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -41300,6 +41396,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "Herkese Açık"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "公开"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -41328,6 +41430,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "Oldukça Açık"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "悄悄公开"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -41864,6 +41972,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "Post gönder"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "发送嘟文"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -41892,6 +42006,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "Ice cubes ile Mastodon'a kısa mesaj gönder"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "使用 Ice Cubes 向 Mastodon 发布文本嘟文"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -41920,6 +42040,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "Gönderiyi Mastodon'a gönder"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "发送嘟文至 Mastodon"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -61537,7 +61663,7 @@
|
|||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "needs_review",
|
||||
"state" : "translated",
|
||||
"value" : "该功能需要 DeepL API 密钥"
|
||||
}
|
||||
},
|
||||
|
@ -69630,7 +69756,7 @@
|
|||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Your settings require alt text on all media before posting"
|
||||
"value" : "你的设置要求在发布前为所有媒体添加描述文本"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
|
@ -76981,8 +77107,8 @@
|
|||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "needs_review",
|
||||
"value" : "Profile (%@)"
|
||||
"state" : "translated",
|
||||
"value" : "个人主页 (%@)"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
|
@ -77845,6 +77971,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "DeepL API Anahtarı hala saklanıyor!"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "DeepL API 密钥已存储!"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -77874,6 +78006,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "Örneğinizin Çeviri Hizmetine ulaşılamadı!"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "无法连接你的服务器的翻译服务!"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -81771,6 +81909,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "Zaman Çizelgesi Filtresi"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "TimelineFilter"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -81800,6 +81944,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "Çeviri servisi"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "翻译服务"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -82255,6 +82405,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "Mastodon için bir gönderi oluşturmak için Ice Cubes kullanın"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "使用 Ice Cubes 向 Mastodon 发布嘟文"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -82283,6 +82439,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "Mastodon'da görsel içeren bir gönderi oluşturmak için Ice Cubes kullanın"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "使用 Ice Cubes 向 Mastodon 发布带有图片的嘟文"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -82369,6 +82531,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "Görünürlük"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "可见度"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -82397,6 +82565,12 @@
|
|||
"state" : "translated",
|
||||
"value" : "Gönderinizin görünürlüğü"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "嘟文可见度"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ public struct AccountDetailView: View {
|
|||
client: client,
|
||||
routerPath: routerPath)
|
||||
}
|
||||
.environment(\.defaultMinListRowHeight, 1)
|
||||
.environment(\.defaultMinListRowHeight, 0)
|
||||
.listStyle(.plain)
|
||||
#if !os(visionOS)
|
||||
.scrollContentBackground(.hidden)
|
||||
|
|
|
@ -51,17 +51,19 @@ import SwiftUI
|
|||
didSet {
|
||||
if let item = mediaPickers.first {
|
||||
Task {
|
||||
if let data = await getItemImageData(item: item) {
|
||||
if isChangingAvatar {
|
||||
_ = await uploadAvatar(data: data)
|
||||
if let data = await getItemImageData(item: item, for: .avatar) {
|
||||
_ = await uploadAvatar(data: data)
|
||||
}
|
||||
isChangingAvatar = false
|
||||
} else if isChangingHeader {
|
||||
_ = await uploadHeader(data: data)
|
||||
if let data = await getItemImageData(item: item, for: .header) {
|
||||
_ = await uploadHeader(data: data)
|
||||
}
|
||||
isChangingHeader = false
|
||||
}
|
||||
await fetchAccount()
|
||||
isChangingAvatar = false
|
||||
isChangingHeader = false
|
||||
mediaPickers = []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -140,16 +142,48 @@ import SwiftUI
|
|||
}
|
||||
}
|
||||
|
||||
private func getItemImageData(item: PhotosPickerItem) async -> Data? {
|
||||
private func getItemImageData(item: PhotosPickerItem, for type: ItemType) async -> Data? {
|
||||
guard let imageFile = try? await item.loadTransferable(type: StatusEditor.ImageFileTranseferable.self) else { return nil }
|
||||
|
||||
let compressor = StatusEditor.Compressor()
|
||||
|
||||
guard let compressedData = await compressor.compressImageFrom(url: imageFile.url),
|
||||
let image = UIImage(data: compressedData),
|
||||
let uploadData = try? await compressor.compressImageForUpload(image)
|
||||
else { return nil }
|
||||
let uploadData = try? await compressor.compressImageForUpload(
|
||||
image,
|
||||
maxSize: 2 * 1024 * 1024, // 2MB
|
||||
maxHeight: type.maxHeight,
|
||||
maxWidth: type.maxWidth
|
||||
)
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return uploadData
|
||||
}
|
||||
}
|
||||
|
||||
extension EditAccountViewModel {
|
||||
private enum ItemType {
|
||||
case avatar
|
||||
case header
|
||||
|
||||
var maxHeight: CGFloat {
|
||||
switch self {
|
||||
case .avatar:
|
||||
400
|
||||
case .header:
|
||||
500
|
||||
}
|
||||
}
|
||||
|
||||
var maxWidth: CGFloat {
|
||||
switch self {
|
||||
case .avatar:
|
||||
400
|
||||
case .header:
|
||||
1500
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,8 @@ let package = Package(
|
|||
dependencies: [
|
||||
.package(name: "Models", path: "../Models"),
|
||||
.package(name: "Env", path: "../Env"),
|
||||
.package(url: "https://github.com/kean/Nuke", from: "12.4.0"),
|
||||
.package(url: "https://github.com/divadretlaw/EmojiText", from: "4.0.0"),
|
||||
.package(url: "https://github.com/kean/Nuke", exact: "12.7.3"),
|
||||
.package(url: "https://github.com/divadretlaw/EmojiText", exact: "4.0.0"),
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
|
|
|
@ -57,30 +57,45 @@ public extension StatusEditor {
|
|||
}
|
||||
}
|
||||
|
||||
public func compressImageForUpload(_ image: UIImage) async throws -> Data {
|
||||
public func compressImageForUpload(
|
||||
_ image: UIImage,
|
||||
maxSize: Int = 10 * 1024 * 1024,
|
||||
maxHeight: Double = 5000,
|
||||
maxWidth: Double = 5000
|
||||
) async throws -> Data {
|
||||
var image = image
|
||||
if image.size.height > 5000 || image.size.width > 5000 {
|
||||
image = image.resized(to: .init(width: image.size.width / 4,
|
||||
height: image.size.height / 4))
|
||||
|
||||
if image.size.height > maxHeight || image.size.width > maxWidth {
|
||||
let heightFactor = image.size.height / maxHeight
|
||||
let widthFactor = image.size.width / maxWidth
|
||||
let maxFactor = max(heightFactor, widthFactor)
|
||||
|
||||
image = image.resized(to: .init(width: image.size.width / maxFactor,
|
||||
height: image.size.height / maxFactor))
|
||||
}
|
||||
|
||||
guard var imageData = image.jpegData(compressionQuality: 0.8) else {
|
||||
throw CompressorError.noData
|
||||
}
|
||||
|
||||
let maxSize = 10 * 1024 * 1024
|
||||
|
||||
var compressionQualityFactor: CGFloat = 0.8
|
||||
if imageData.count > maxSize {
|
||||
while imageData.count > maxSize {
|
||||
while imageData.count > maxSize && compressionQualityFactor >= 0 {
|
||||
guard let compressedImage = UIImage(data: imageData),
|
||||
let compressedData = compressedImage.jpegData(compressionQuality: 0.8)
|
||||
let compressedData = compressedImage.jpegData(compressionQuality: compressionQualityFactor)
|
||||
else {
|
||||
throw CompressorError.noData
|
||||
}
|
||||
|
||||
imageData = compressedData
|
||||
compressionQualityFactor -= 0.1
|
||||
}
|
||||
}
|
||||
|
||||
if imageData.count > maxSize && compressionQualityFactor <= 0 {
|
||||
throw CompressorError.noData
|
||||
}
|
||||
|
||||
return imageData
|
||||
}
|
||||
|
||||
|
|
|
@ -22,8 +22,8 @@ let package = Package(
|
|||
.package(name: "Env", path: "../Env"),
|
||||
.package(name: "StatusKit", path: "../StatusKit"),
|
||||
.package(name: "DesignSystem", path: "../DesignSystem"),
|
||||
.package(url: "https://github.com/Dimillian/swiftui-introspect", branch: "main"),
|
||||
.package(url: "https://github.com/Dimillian/Bodega", branch: "main"),
|
||||
.package(url: "https://github.com/siteline/swiftui-introspect", exact: "1.2.0"),
|
||||
.package(url: "https://github.com/mergesort/Bodega", exact: "2.1.3"),
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
|
|
Loading…
Reference in a new issue