Add show more to alternative text on status details view
This commit is contained in:
parent
6111f0d615
commit
1c933b7cb6
|
@ -6,6 +6,8 @@
|
|||
"global.title.success" = "Success";
|
||||
"global.title.photoSaved" = "Photo has been saved.";
|
||||
"global.title.ok" = "OK";
|
||||
"global.title.showMore" = "Show more";
|
||||
"global.title.showLess" = "Show less";
|
||||
|
||||
// MARK: Global errors.
|
||||
"global.error.unexpected" = "Unexpected error.";
|
||||
|
@ -198,7 +200,7 @@
|
|||
"settings.title.alwaysShowSensitiveTitle" = "Always show NSFW";
|
||||
"settings.title.alwaysShowSensitiveDescription" = "Force show all NFSW (sensitive) media without warnings";
|
||||
"settings.title.alwaysShowAltTitle" = "Show alternative text";
|
||||
"settings.title.alwaysShowAltDescription" = "Show alternative text if present on status details screen";
|
||||
"settings.title.alwaysShowAltDescription" = "Alternative icon will be displayed on timelines";
|
||||
"settings.title.general" = "General";
|
||||
"settings.title.applicationIcon" = "Application icon";
|
||||
"settings.title.followVernissage" = "Follow Vernissage";
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
"global.title.success" = "Success";
|
||||
"global.title.photoSaved" = "Photo has been saved.";
|
||||
"global.title.ok" = "OK";
|
||||
"global.title.showMore" = "Show more";
|
||||
"global.title.showLess" = "Show less";
|
||||
|
||||
// MARK: Global errors.
|
||||
"global.error.unexpected" = "Espero ez zen errorea.";
|
||||
|
@ -198,7 +200,7 @@
|
|||
"settings.title.alwaysShowSensitiveTitle" = "Erakutsi beti NSFW edukia";
|
||||
"settings.title.alwaysShowSensitiveDescription" = "Erakutsi NSFW (Lanerako Egokia Izan Ez Daitekeen Edukia) gisa markatutako multimedia edukia ohartarazpenik gabe";
|
||||
"settings.title.alwaysShowAltTitle" = "Erakutsi testu alternatiboa";
|
||||
"settings.title.alwaysShowAltDescription" = "Erakutsi testu alternatiboa xehetasunen pantailan, baldin badago";
|
||||
"settings.title.alwaysShowAltDescription" = "Alternative icon will be displayed on timelines";
|
||||
"settings.title.general" = "Orokorra";
|
||||
"settings.title.applicationIcon" = "Aplikazioaren ikonoa";
|
||||
"settings.title.followVernissage" = "Jarraitu Vernissage-ri";
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
"global.title.success" = "Sukces";
|
||||
"global.title.photoSaved" = "Zdjęcie zostało zapisane.";
|
||||
"global.title.ok" = "OK";
|
||||
"global.title.showMore" = "Pokaż więcej";
|
||||
"global.title.showLess" = "Pokaż mniej";
|
||||
|
||||
// MARK: Global errors.
|
||||
"global.error.unexpected" = "Wystąpił nieoczekiwany błąd.";
|
||||
|
@ -198,7 +200,7 @@
|
|||
"settings.title.alwaysShowSensitiveTitle" = "Zawsze pokazuj statusy NSFW";
|
||||
"settings.title.alwaysShowSensitiveDescription" = "Wymuś pokazywanie statusów NFSW (czułych) bez ostrzeżeń";
|
||||
"settings.title.alwaysShowAltTitle" = "Pokaż tekst alternatywny";
|
||||
"settings.title.alwaysShowAltDescription" = "Pokaż alternatywny tekst, jeśli jest obecny na szczegółach statusu";
|
||||
"settings.title.alwaysShowAltDescription" = "Ikony alternatywnego tekstu będą widoczne na osiach zdjęć";
|
||||
"settings.title.general" = "Ogólne";
|
||||
"settings.title.applicationIcon" = "Ikona aplikacji";
|
||||
"settings.title.followVernissage" = "Obserwuj Vernissage";
|
||||
|
|
|
@ -128,10 +128,7 @@ struct StatusView: View {
|
|||
LabelIcon(iconName: "camera.aperture", value: self.exifLens)
|
||||
LabelIcon(iconName: "timelapse", value: self.exifExposure)
|
||||
LabelIcon(iconName: "calendar", value: self.exifCreatedDate?.toDate(.isoDateTimeSec)?.formatted())
|
||||
|
||||
if self.applicationState.showPhotoDescription {
|
||||
LabelIcon(iconName: "eye.trianglebadge.exclamationmark", value: self.description)
|
||||
}
|
||||
LabelIcon(iconName: "eye.trianglebadge.exclamationmark", value: self.description, isExpandable: true)
|
||||
}
|
||||
.padding(.bottom, 2)
|
||||
.foregroundColor(.lightGrayColor)
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
//
|
||||
// https://mczachurski.dev
|
||||
// Copyright © 2023 Marcin Czachurski and the repository contributors.
|
||||
// Licensed under the MIT License.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
struct ExpandableText: View {
|
||||
let text: String
|
||||
let lineLimit: Int
|
||||
|
||||
@State private var isExpanded = false
|
||||
@State private var isTruncated: Bool?
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading) {
|
||||
Text(text)
|
||||
.lineLimit(isExpanded ? nil : lineLimit)
|
||||
.background(calculateTruncation(text: text))
|
||||
|
||||
if isTruncated == true {
|
||||
button
|
||||
}
|
||||
}
|
||||
// Re-calculate isTruncated for the new text
|
||||
.onChange(of: text, perform: { _ in isTruncated = nil })
|
||||
}
|
||||
|
||||
func calculateTruncation(text: String) -> some View {
|
||||
// Select the view that fits in the background of the line-limited text.
|
||||
ViewThatFits(in: .vertical) {
|
||||
Text(text)
|
||||
.hidden()
|
||||
.onAppear {
|
||||
// If the whole text fits, then isTruncated is set to false and no button is shown.
|
||||
guard isTruncated == nil else { return }
|
||||
isTruncated = false
|
||||
}
|
||||
Color.clear
|
||||
.hidden()
|
||||
.onAppear {
|
||||
// If the whole text does not fit, Color.clear is selected,
|
||||
// isTruncated is set to true and button is shown.
|
||||
guard isTruncated == nil else { return }
|
||||
isTruncated = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var button: some View {
|
||||
HStack {
|
||||
Spacer()
|
||||
Button {
|
||||
withAnimation {
|
||||
isExpanded.toggle()
|
||||
}
|
||||
} label: {
|
||||
Text(isExpanded ? "global.title.showLess" : "global.title.showMore", comment: "Show less/more")
|
||||
.foregroundColor(.accentColor)
|
||||
.textCase(.uppercase)
|
||||
}
|
||||
.padding(.horizontal, 8)
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
}
|
||||
}
|
|
@ -9,10 +9,12 @@ import SwiftUI
|
|||
public struct LabelIcon: View {
|
||||
let iconName: String
|
||||
let value: String?
|
||||
let isExpandable: Bool
|
||||
|
||||
public init(iconName: String, value: String?) {
|
||||
public init(iconName: String, value: String?, isExpandable: Bool = false) {
|
||||
self.iconName = iconName
|
||||
self.value = value
|
||||
self.isExpandable = isExpandable
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
|
@ -20,9 +22,15 @@ public struct LabelIcon: View {
|
|||
HStack(alignment: .center) {
|
||||
Image(systemName: iconName)
|
||||
.frame(width: 24, alignment: .center)
|
||||
|
||||
if self.isExpandable {
|
||||
ExpandableText(text: value, lineLimit: 3)
|
||||
.font(.footnote)
|
||||
} else {
|
||||
Text(value)
|
||||
.font(.footnote)
|
||||
}
|
||||
}
|
||||
.padding(.vertical, 2)
|
||||
} else {
|
||||
EmptyView()
|
||||
|
|
Loading…
Reference in New Issue