Implement auto aspect ratio for LibraryIconViews
This commit is contained in:
parent
bd0b6ff491
commit
7aa602f19d
@ -12,7 +12,7 @@
|
|||||||
3D13F95A2B375A9E00E91913 /* Nuke in Frameworks */ = {isa = PBXBuildFile; productRef = 3D13F9592B375A9E00E91913 /* Nuke */; };
|
3D13F95A2B375A9E00E91913 /* Nuke in Frameworks */ = {isa = PBXBuildFile; productRef = 3D13F9592B375A9E00E91913 /* Nuke */; };
|
||||||
3D13F95C2B375A9E00E91913 /* NukeUI in Frameworks */ = {isa = PBXBuildFile; productRef = 3D13F95B2B375A9E00E91913 /* NukeUI */; };
|
3D13F95C2B375A9E00E91913 /* NukeUI in Frameworks */ = {isa = PBXBuildFile; productRef = 3D13F95B2B375A9E00E91913 /* NukeUI */; };
|
||||||
3D13F95F2B375DB800E91913 /* ItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D13F95E2B375DB800E91913 /* ItemView.swift */; };
|
3D13F95F2B375DB800E91913 /* ItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D13F95E2B375DB800E91913 /* ItemView.swift */; };
|
||||||
3D13F9612B37637500E91913 /* ItemMovieView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D13F9602B37637500E91913 /* ItemMovieView.swift */; };
|
3D13F9612B37637500E91913 /* ItemMediaView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D13F9602B37637500E91913 /* ItemMediaView.swift */; };
|
||||||
3D13F9652B37EC7A00E91913 /* ItemHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D13F9642B37EC7A00E91913 /* ItemHeaderView.swift */; };
|
3D13F9652B37EC7A00E91913 /* ItemHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D13F9642B37EC7A00E91913 /* ItemHeaderView.swift */; };
|
||||||
3D13F9692B389FA300E91913 /* ViewOffsetKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D13F9682B389FA300E91913 /* ViewOffsetKey.swift */; };
|
3D13F9692B389FA300E91913 /* ViewOffsetKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D13F9682B389FA300E91913 /* ViewOffsetKey.swift */; };
|
||||||
3D13F96F2B38A32500E91913 /* StickyHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D13F96E2B38A32500E91913 /* StickyHeaderView.swift */; };
|
3D13F96F2B38A32500E91913 /* StickyHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D13F96E2B38A32500E91913 /* StickyHeaderView.swift */; };
|
||||||
@ -37,6 +37,7 @@
|
|||||||
3DAFA8E82B38AFED00D71AD1 /* ItemInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DAFA8E72B38AFED00D71AD1 /* ItemInfoView.swift */; };
|
3DAFA8E82B38AFED00D71AD1 /* ItemInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DAFA8E72B38AFED00D71AD1 /* ItemInfoView.swift */; };
|
||||||
3DAFA8EA2B39039900D71AD1 /* JellyfinKitExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DAFA8E92B39039900D71AD1 /* JellyfinKitExtensions.swift */; };
|
3DAFA8EA2B39039900D71AD1 /* JellyfinKitExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DAFA8E92B39039900D71AD1 /* JellyfinKitExtensions.swift */; };
|
||||||
3DAFA8EC2B394F9F00D71AD1 /* ViewConditionalMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DAFA8EB2B394F9F00D71AD1 /* ViewConditionalMethod.swift */; };
|
3DAFA8EC2B394F9F00D71AD1 /* ViewConditionalMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DAFA8EB2B394F9F00D71AD1 /* ViewConditionalMethod.swift */; };
|
||||||
|
3DAFA8EF2B3B707B00D71AD1 /* ItemMovieView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DAFA8EE2B3B707B00D71AD1 /* ItemMovieView.swift */; };
|
||||||
3DC6BA2D2B2A422300416B9F /* SettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DC6BA2C2B2A422300416B9F /* SettingsController.swift */; };
|
3DC6BA2D2B2A422300416B9F /* SettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DC6BA2C2B2A422300416B9F /* SettingsController.swift */; };
|
||||||
3DDD67932B293BC40026781E /* DashboardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DDD67922B293BC40026781E /* DashboardView.swift */; };
|
3DDD67932B293BC40026781E /* DashboardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DDD67922B293BC40026781E /* DashboardView.swift */; };
|
||||||
3DDD67962B29E28B0026781E /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DDD67952B29E28B0026781E /* SettingsView.swift */; };
|
3DDD67962B29E28B0026781E /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DDD67952B29E28B0026781E /* SettingsView.swift */; };
|
||||||
@ -78,7 +79,7 @@
|
|||||||
3D1015D82B27F57400F5C29A /* AddServerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddServerView.swift; sourceTree = "<group>"; };
|
3D1015D82B27F57400F5C29A /* AddServerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddServerView.swift; sourceTree = "<group>"; };
|
||||||
3D1015E32B28000E00F5C29A /* AuthStateController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthStateController.swift; sourceTree = "<group>"; };
|
3D1015E32B28000E00F5C29A /* AuthStateController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthStateController.swift; sourceTree = "<group>"; };
|
||||||
3D13F95E2B375DB800E91913 /* ItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemView.swift; sourceTree = "<group>"; };
|
3D13F95E2B375DB800E91913 /* ItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemView.swift; sourceTree = "<group>"; };
|
||||||
3D13F9602B37637500E91913 /* ItemMovieView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemMovieView.swift; sourceTree = "<group>"; };
|
3D13F9602B37637500E91913 /* ItemMediaView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemMediaView.swift; sourceTree = "<group>"; };
|
||||||
3D13F9642B37EC7A00E91913 /* ItemHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemHeaderView.swift; sourceTree = "<group>"; };
|
3D13F9642B37EC7A00E91913 /* ItemHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemHeaderView.swift; sourceTree = "<group>"; };
|
||||||
3D13F9682B389FA300E91913 /* ViewOffsetKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewOffsetKey.swift; sourceTree = "<group>"; };
|
3D13F9682B389FA300E91913 /* ViewOffsetKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewOffsetKey.swift; sourceTree = "<group>"; };
|
||||||
3D13F96E2B38A32500E91913 /* StickyHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickyHeaderView.swift; sourceTree = "<group>"; };
|
3D13F96E2B38A32500E91913 /* StickyHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickyHeaderView.swift; sourceTree = "<group>"; };
|
||||||
@ -104,6 +105,7 @@
|
|||||||
3DAFA8E72B38AFED00D71AD1 /* ItemInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemInfoView.swift; sourceTree = "<group>"; };
|
3DAFA8E72B38AFED00D71AD1 /* ItemInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemInfoView.swift; sourceTree = "<group>"; };
|
||||||
3DAFA8E92B39039900D71AD1 /* JellyfinKitExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JellyfinKitExtensions.swift; sourceTree = "<group>"; };
|
3DAFA8E92B39039900D71AD1 /* JellyfinKitExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JellyfinKitExtensions.swift; sourceTree = "<group>"; };
|
||||||
3DAFA8EB2B394F9F00D71AD1 /* ViewConditionalMethod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewConditionalMethod.swift; sourceTree = "<group>"; };
|
3DAFA8EB2B394F9F00D71AD1 /* ViewConditionalMethod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewConditionalMethod.swift; sourceTree = "<group>"; };
|
||||||
|
3DAFA8EE2B3B707B00D71AD1 /* ItemMovieView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemMovieView.swift; sourceTree = "<group>"; };
|
||||||
3DC0E5802B2832B9001CCE96 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
3DC0E5802B2832B9001CCE96 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
3DC6BA2C2B2A422300416B9F /* SettingsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsController.swift; sourceTree = "<group>"; };
|
3DC6BA2C2B2A422300416B9F /* SettingsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsController.swift; sourceTree = "<group>"; };
|
||||||
3DDD67922B293BC40026781E /* DashboardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardView.swift; sourceTree = "<group>"; };
|
3DDD67922B293BC40026781E /* DashboardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardView.swift; sourceTree = "<group>"; };
|
||||||
@ -179,8 +181,9 @@
|
|||||||
3D13F95D2B375DAC00E91913 /* Item */ = {
|
3D13F95D2B375DAC00E91913 /* Item */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
3DAFA8ED2B3B707100D71AD1 /* Types */,
|
||||||
3D13F95E2B375DB800E91913 /* ItemView.swift */,
|
3D13F95E2B375DB800E91913 /* ItemView.swift */,
|
||||||
3D13F9602B37637500E91913 /* ItemMovieView.swift */,
|
3D13F9602B37637500E91913 /* ItemMediaView.swift */,
|
||||||
3DAFA8E72B38AFED00D71AD1 /* ItemInfoView.swift */,
|
3DAFA8E72B38AFED00D71AD1 /* ItemInfoView.swift */,
|
||||||
3D13F9642B37EC7A00E91913 /* ItemHeaderView.swift */,
|
3D13F9642B37EC7A00E91913 /* ItemHeaderView.swift */,
|
||||||
);
|
);
|
||||||
@ -276,6 +279,14 @@
|
|||||||
path = SignIn;
|
path = SignIn;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
3DAFA8ED2B3B707100D71AD1 /* Types */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
3DAFA8EE2B3B707B00D71AD1 /* ItemMovieView.swift */,
|
||||||
|
);
|
||||||
|
path = Types;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
3DDD67902B293B780026781E /* Dashboard */ = {
|
3DDD67902B293B780026781E /* Dashboard */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -447,9 +458,10 @@
|
|||||||
3D13F9692B389FA300E91913 /* ViewOffsetKey.swift in Sources */,
|
3D13F9692B389FA300E91913 /* ViewOffsetKey.swift in Sources */,
|
||||||
3D91FDCD2B2907E800919017 /* JellyfinDateFormatter.swift in Sources */,
|
3D91FDCD2B2907E800919017 /* JellyfinDateFormatter.swift in Sources */,
|
||||||
3D91FDC92B28C62800919017 /* SignInView.swift in Sources */,
|
3D91FDC92B28C62800919017 /* SignInView.swift in Sources */,
|
||||||
|
3DAFA8EF2B3B707B00D71AD1 /* ItemMovieView.swift in Sources */,
|
||||||
3D8AB2A82B366353005BD7D0 /* LibraryDetailView.swift in Sources */,
|
3D8AB2A82B366353005BD7D0 /* LibraryDetailView.swift in Sources */,
|
||||||
3DDD67932B293BC40026781E /* DashboardView.swift in Sources */,
|
3DDD67932B293BC40026781E /* DashboardView.swift in Sources */,
|
||||||
3D13F9612B37637500E91913 /* ItemMovieView.swift in Sources */,
|
3D13F9612B37637500E91913 /* ItemMediaView.swift in Sources */,
|
||||||
3D41D1FA2B2CAE0000E58234 /* LibraryIconView.swift in Sources */,
|
3D41D1FA2B2CAE0000E58234 /* LibraryIconView.swift in Sources */,
|
||||||
3D8AB2A52B36440D005BD7D0 /* BlurHashDecode.swift in Sources */,
|
3D8AB2A52B36440D005BD7D0 /* BlurHashDecode.swift in Sources */,
|
||||||
3DC6BA2D2B2A422300416B9F /* SettingsController.swift in Sources */,
|
3DC6BA2D2B2A422300416B9F /* SettingsController.swift in Sources */,
|
||||||
|
@ -29,6 +29,7 @@ struct DashboardLibraryView: View {
|
|||||||
LibraryDetailView(library: library)
|
LibraryDetailView(library: library)
|
||||||
} label: {
|
} label: {
|
||||||
LibraryIconView(library: library, height: 150)
|
LibraryIconView(library: library, height: 150)
|
||||||
|
.setAspectRatio(library.primaryImageAspectRatio)
|
||||||
.padding()
|
.padding()
|
||||||
}
|
}
|
||||||
.buttonStyle(PlainButtonStyle())
|
.buttonStyle(PlainButtonStyle())
|
||||||
|
@ -14,9 +14,9 @@ struct ItemInfoView: View {
|
|||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
HStack {
|
HStack {
|
||||||
Text(item.genres?.first ?? "---")
|
|
||||||
Text("•")
|
|
||||||
Text((item.productionYear != nil) ? String(item.productionYear!) : "---")
|
Text((item.productionYear != nil) ? String(item.productionYear!) : "---")
|
||||||
|
Text("•")
|
||||||
|
Text(item.genres?.first ?? "---")
|
||||||
}
|
}
|
||||||
Text(item.getRuntime() ?? "-:--")
|
Text(item.getRuntime() ?? "-:--")
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// ItemMovieView.swift
|
// ItemMediaView.swift
|
||||||
// Jel
|
// Jel
|
||||||
//
|
//
|
||||||
// Created by zerocool on 12/23/23.
|
// Created by zerocool on 12/23/23.
|
||||||
@ -8,7 +8,7 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
import JellyfinKit
|
import JellyfinKit
|
||||||
|
|
||||||
struct ItemMovieView: View {
|
struct ItemMediaView: View {
|
||||||
@EnvironmentObject var jellyfinClient: JellyfinClientController
|
@EnvironmentObject var jellyfinClient: JellyfinClientController
|
||||||
@StateObject var authState: AuthStateController = AuthStateController.shared
|
@StateObject var authState: AuthStateController = AuthStateController.shared
|
||||||
|
|
22
Jel/Views/Library/Item/Types/ItemMovieView.swift
Normal file
22
Jel/Views/Library/Item/Types/ItemMovieView.swift
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
//
|
||||||
|
// ItemMovieView.swift
|
||||||
|
// Jel
|
||||||
|
//
|
||||||
|
// Created by zerocool on 12/26/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
import JellyfinKit
|
||||||
|
|
||||||
|
struct ItemMovieView: View {
|
||||||
|
@State var item: BaseItemDto
|
||||||
|
var body: some View {
|
||||||
|
VStack {
|
||||||
|
ItemMediaView(item: item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//#Preview {
|
||||||
|
// ItemMovieView()
|
||||||
|
//}
|
@ -34,27 +34,18 @@ struct LibraryDetailView: View {
|
|||||||
}
|
}
|
||||||
ScrollView {
|
ScrollView {
|
||||||
LazyVGrid(columns: columns) {
|
LazyVGrid(columns: columns) {
|
||||||
if !searchText.isEmpty {
|
// uses searchResultItems only if searchText is not empty
|
||||||
ForEach(searchResultItems ?? []) {item in
|
ForEach(!searchText.isEmpty ? (searchResultItems ?? items) ?? [] : items ?? []) {item in
|
||||||
NavigationLink {
|
NavigationLink {
|
||||||
ItemView(item: item)
|
ItemView(item: item)
|
||||||
} label: {
|
} label: {
|
||||||
LibraryIconView(library: item, imageType: "Primary", width: 170)
|
LibraryIconView(library: item, imageType: "Primary", width: 170)
|
||||||
|
.setAspectRatio(item.primaryImageAspectRatio ?? 0.6)
|
||||||
.padding()
|
.padding()
|
||||||
|
|
||||||
}
|
}
|
||||||
.buttonStyle(PlainButtonStyle())
|
.buttonStyle(PlainButtonStyle())
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
ForEach(items ?? []) {item in
|
|
||||||
NavigationLink {
|
|
||||||
ItemView(item: item)
|
|
||||||
} label: {
|
|
||||||
LibraryIconView(library: item, imageType: "Primary", width: 170)
|
|
||||||
.padding()
|
|
||||||
}
|
|
||||||
.buttonStyle(PlainButtonStyle())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.if(!loading) {view in
|
.if(!loading) {view in
|
||||||
@ -82,7 +73,11 @@ struct LibraryDetailView: View {
|
|||||||
.navigationTitle(library.name ?? "Unknown")
|
.navigationTitle(library.name ?? "Unknown")
|
||||||
.onAppear {
|
.onAppear {
|
||||||
Task {
|
Task {
|
||||||
let params = Paths.GetItemsParameters(userID: authState.userId, parentID: library.id)
|
let params = Paths.GetItemsParameters(
|
||||||
|
userID: authState.userId,
|
||||||
|
parentID: library.id,
|
||||||
|
fields: [.primaryImageAspectRatio]
|
||||||
|
)
|
||||||
let request = Paths.getItems(parameters: params)
|
let request = Paths.getItems(parameters: params)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -32,21 +32,22 @@ struct LibraryIconView: View {
|
|||||||
if let image = state.image {
|
if let image = state.image {
|
||||||
image
|
image
|
||||||
.resizable()
|
.resizable()
|
||||||
|
.aspectRatio(contentMode: contentMode)
|
||||||
} else {
|
} else {
|
||||||
if let content = placeHolder {
|
if let content = placeHolder {
|
||||||
content
|
content
|
||||||
} else {
|
} else {
|
||||||
Image(uiImage: blurHashImage)
|
Image(uiImage: blurHashImage)
|
||||||
.resizable()
|
.resizable()
|
||||||
|
.aspectRatio(contentMode: .fill)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.aspectRatio(contentMode: contentMode)
|
|
||||||
.frame(width: width, height: height)
|
.frame(width: width, height: height)
|
||||||
.clipShape(RoundedRectangle(cornerRadius: imageCornerRadius))
|
.clipShape(RoundedRectangle(cornerRadius: imageCornerRadius))
|
||||||
.onAppear {
|
.onAppear {
|
||||||
let blurhash = library.imageBlurHashes?.primary?[library.imageTags?[imageType] ?? ""] ?? ""
|
let blurhash = library.imageBlurHashes?.primary?[library.imageTags?[imageType] ?? ""] ?? ""
|
||||||
blurHashImage = UIImage(blurHash: blurhash, size: CGSize(width: 16, height: 16)) ?? UIImage()
|
blurHashImage = UIImage(blurHash: blurhash, size: CGSize(width: 32, height: 32)) ?? UIImage()
|
||||||
|
|
||||||
let imageId = library.id ?? ""
|
let imageId = library.id ?? ""
|
||||||
let request = Paths.getItemImage(itemID: imageId, imageType: imageType)
|
let request = Paths.getItemImage(itemID: imageId, imageType: imageType)
|
||||||
@ -70,6 +71,22 @@ struct LibraryIconView: View {
|
|||||||
copy.imageCornerRadius = cornerRadius
|
copy.imageCornerRadius = cornerRadius
|
||||||
return copy
|
return copy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setAspectRatio(_ aspectRatio: Double?) -> Self {
|
||||||
|
var copy = self
|
||||||
|
if aspectRatio == nil {
|
||||||
|
return copy
|
||||||
|
}
|
||||||
|
|
||||||
|
if let newWidth = copy.width {
|
||||||
|
copy.height = newWidth / aspectRatio!
|
||||||
|
}
|
||||||
|
if let newHeight = copy.height {
|
||||||
|
copy.width = newHeight * aspectRatio!
|
||||||
|
}
|
||||||
|
|
||||||
|
return copy
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//#Preview {
|
//#Preview {
|
||||||
|
Loading…
Reference in New Issue
Block a user