Initial PoC of iPad grid
This commit is contained in:
parent
0ac6ad376f
commit
446fbd9b9e
|
@ -27,6 +27,7 @@
|
||||||
F8210DEA2966E4F9001D9973 /* AnimatePlaceholderModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8210DE92966E4F9001D9973 /* AnimatePlaceholderModifier.swift */; };
|
F8210DEA2966E4F9001D9973 /* AnimatePlaceholderModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8210DE92966E4F9001D9973 /* AnimatePlaceholderModifier.swift */; };
|
||||||
F825F0C929F7A562008BD204 /* UserProfilePrivateAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F825F0C829F7A562008BD204 /* UserProfilePrivateAccountView.swift */; };
|
F825F0C929F7A562008BD204 /* UserProfilePrivateAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F825F0C829F7A562008BD204 /* UserProfilePrivateAccountView.swift */; };
|
||||||
F825F0CB29F7CFC4008BD204 /* FollowRequestsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F825F0CA29F7CFC4008BD204 /* FollowRequestsView.swift */; };
|
F825F0CB29F7CFC4008BD204 /* FollowRequestsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F825F0CA29F7CFC4008BD204 /* FollowRequestsView.swift */; };
|
||||||
|
F830C3CD2A07A4020005FEF8 /* WaterfallGrid in Frameworks */ = {isa = PBXBuildFile; productRef = F830C3CC2A07A4020005FEF8 /* WaterfallGrid */; };
|
||||||
F835082329BEF9C400DE3247 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = F835082629BEF9C400DE3247 /* Localizable.strings */; };
|
F835082329BEF9C400DE3247 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = F835082629BEF9C400DE3247 /* Localizable.strings */; };
|
||||||
F835082429BEF9C400DE3247 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = F835082629BEF9C400DE3247 /* Localizable.strings */; };
|
F835082429BEF9C400DE3247 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = F835082629BEF9C400DE3247 /* Localizable.strings */; };
|
||||||
F83CBEFB298298A1002972C8 /* ImageCarouselPicture.swift in Sources */ = {isa = PBXBuildFile; fileRef = F83CBEFA298298A1002972C8 /* ImageCarouselPicture.swift */; };
|
F83CBEFB298298A1002972C8 /* ImageCarouselPicture.swift in Sources */ = {isa = PBXBuildFile; fileRef = F83CBEFA298298A1002972C8 /* ImageCarouselPicture.swift */; };
|
||||||
|
@ -449,6 +450,7 @@
|
||||||
F8210DD92966BB7E001D9973 /* NukeUI in Frameworks */,
|
F8210DD92966BB7E001D9973 /* NukeUI in Frameworks */,
|
||||||
F89B5CC029D019B600549F2F /* HTMLString in Frameworks */,
|
F89B5CC029D019B600549F2F /* HTMLString in Frameworks */,
|
||||||
F88BC52A29E046D700CE6141 /* WidgetsKit in Frameworks */,
|
F88BC52A29E046D700CE6141 /* WidgetsKit in Frameworks */,
|
||||||
|
F830C3CD2A07A4020005FEF8 /* WaterfallGrid in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -988,6 +990,7 @@
|
||||||
F88BC52629E0431D00CE6141 /* ServicesKit */,
|
F88BC52629E0431D00CE6141 /* ServicesKit */,
|
||||||
F88BC52929E046D700CE6141 /* WidgetsKit */,
|
F88BC52929E046D700CE6141 /* WidgetsKit */,
|
||||||
F88BC52C29E04BB600CE6141 /* EnvironmentKit */,
|
F88BC52C29E04BB600CE6141 /* EnvironmentKit */,
|
||||||
|
F830C3CC2A07A4020005FEF8 /* WaterfallGrid */,
|
||||||
);
|
);
|
||||||
productName = Vernissage;
|
productName = Vernissage;
|
||||||
productReference = F88C2468295C37B80006098B /* Vernissage.app */;
|
productReference = F88C2468295C37B80006098B /* Vernissage.app */;
|
||||||
|
@ -1031,6 +1034,7 @@
|
||||||
F88E4D4B297EA4290057491A /* XCRemoteSwiftPackageReference "EmojiText" */,
|
F88E4D4B297EA4290057491A /* XCRemoteSwiftPackageReference "EmojiText" */,
|
||||||
F89B5CBE29D019B600549F2F /* XCRemoteSwiftPackageReference "HTMLString" */,
|
F89B5CBE29D019B600549F2F /* XCRemoteSwiftPackageReference "HTMLString" */,
|
||||||
F84625F929FE393B002D3AF4 /* XCRemoteSwiftPackageReference "QRCode" */,
|
F84625F929FE393B002D3AF4 /* XCRemoteSwiftPackageReference "QRCode" */,
|
||||||
|
F830C3CB2A07A4020005FEF8 /* XCRemoteSwiftPackageReference "WaterfallGrid" */,
|
||||||
);
|
);
|
||||||
productRefGroup = F88C2469295C37B80006098B /* Products */;
|
productRefGroup = F88C2469295C37B80006098B /* Products */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
|
@ -1338,7 +1342,7 @@
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = 1;
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
|
@ -1366,7 +1370,7 @@
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = 1;
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
@ -1394,7 +1398,7 @@
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = 1;
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
|
@ -1421,7 +1425,7 @@
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = 1;
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
@ -1580,7 +1584,7 @@
|
||||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = 1;
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
|
@ -1621,7 +1625,7 @@
|
||||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = 1;
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
@ -1675,6 +1679,14 @@
|
||||||
minimumVersion = 12.0.0;
|
minimumVersion = 12.0.0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
F830C3CB2A07A4020005FEF8 /* XCRemoteSwiftPackageReference "WaterfallGrid" */ = {
|
||||||
|
isa = XCRemoteSwiftPackageReference;
|
||||||
|
repositoryURL = "https://github.com/paololeonardi/WaterfallGrid.git";
|
||||||
|
requirement = {
|
||||||
|
kind = upToNextMajorVersion;
|
||||||
|
minimumVersion = 1.0.0;
|
||||||
|
};
|
||||||
|
};
|
||||||
F84625F929FE393B002D3AF4 /* XCRemoteSwiftPackageReference "QRCode" */ = {
|
F84625F929FE393B002D3AF4 /* XCRemoteSwiftPackageReference "QRCode" */ = {
|
||||||
isa = XCRemoteSwiftPackageReference;
|
isa = XCRemoteSwiftPackageReference;
|
||||||
repositoryURL = "https://github.com/dmrschmidt/QRCode";
|
repositoryURL = "https://github.com/dmrschmidt/QRCode";
|
||||||
|
@ -1717,6 +1729,11 @@
|
||||||
package = F8210DD32966BB7E001D9973 /* XCRemoteSwiftPackageReference "Nuke" */;
|
package = F8210DD32966BB7E001D9973 /* XCRemoteSwiftPackageReference "Nuke" */;
|
||||||
productName = NukeUI;
|
productName = NukeUI;
|
||||||
};
|
};
|
||||||
|
F830C3CC2A07A4020005FEF8 /* WaterfallGrid */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = F830C3CB2A07A4020005FEF8 /* XCRemoteSwiftPackageReference "WaterfallGrid" */;
|
||||||
|
productName = WaterfallGrid;
|
||||||
|
};
|
||||||
F84625FA29FE393B002D3AF4 /* QRCode */ = {
|
F84625FA29FE393B002D3AF4 /* QRCode */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
package = F84625F929FE393B002D3AF4 /* XCRemoteSwiftPackageReference "QRCode" */;
|
package = F84625F929FE393B002D3AF4 /* XCRemoteSwiftPackageReference "QRCode" */;
|
||||||
|
|
|
@ -11,6 +11,7 @@ import ClientKit
|
||||||
import ServicesKit
|
import ServicesKit
|
||||||
import EnvironmentKit
|
import EnvironmentKit
|
||||||
import WidgetsKit
|
import WidgetsKit
|
||||||
|
import WaterfallGrid
|
||||||
|
|
||||||
struct StatusesView: View {
|
struct StatusesView: View {
|
||||||
public enum ListType: Hashable {
|
public enum ListType: Hashable {
|
||||||
|
@ -50,7 +51,7 @@ struct StatusesView: View {
|
||||||
@State private var state: ViewState = .loading
|
@State private var state: ViewState = .loading
|
||||||
@State private var lastStatusId: String?
|
@State private var lastStatusId: String?
|
||||||
|
|
||||||
private let defaultLimit = 20
|
private let defaultLimit = 40
|
||||||
private let imagePrefetcher = ImagePrefetcher(destination: .diskCache)
|
private let imagePrefetcher = ImagePrefetcher(destination: .diskCache)
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
|
@ -88,26 +89,35 @@ struct StatusesView: View {
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private func list() -> some View {
|
private func list() -> some View {
|
||||||
ScrollView {
|
ScrollView {
|
||||||
LazyVStack(alignment: .center) {
|
WaterfallGrid(self.statusViewModels, id: \.id) { item in
|
||||||
ForEach(self.statusViewModels, id: \.id) { item in
|
ImageRowAsync(statusViewModel: item,
|
||||||
ImageRowAsync(statusViewModel: item)
|
withAvatar: true,
|
||||||
}
|
imageScale: self.applicationState.showGridOnUserProfile ? .squareHalfWidth : .orginalFullWidth)
|
||||||
|
.padding(.top, -2)
|
||||||
if allItemsLoaded == false {
|
|
||||||
HStack {
|
|
||||||
Spacer()
|
|
||||||
LoadingIndicator()
|
|
||||||
.task {
|
|
||||||
do {
|
|
||||||
try await self.loadMoreStatuses()
|
|
||||||
} catch {
|
|
||||||
ErrorService.shared.handle(error, message: "statuses.error.loadingStatusesFailed", showToastr: !Task.isCancelled)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Spacer()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
.gridStyle(columns: 3, spacing: 4)
|
||||||
|
// .padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
|
||||||
|
|
||||||
|
// LazyVStack(alignment: .center) {
|
||||||
|
// ForEach(self.statusViewModels, id: \.id) { item in
|
||||||
|
// ImageRowAsync(statusViewModel: item)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if allItemsLoaded == false {
|
||||||
|
// HStack {
|
||||||
|
// Spacer()
|
||||||
|
// LoadingIndicator()
|
||||||
|
// .task {
|
||||||
|
// do {
|
||||||
|
// try await self.loadMoreStatuses()
|
||||||
|
// } catch {
|
||||||
|
// ErrorService.shared.handle(error, message: "statuses.error.loadingStatusesFailed", showToastr: !Task.isCancelled)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// Spacer()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
.refreshable {
|
.refreshable {
|
||||||
do {
|
do {
|
||||||
|
|
|
@ -11,6 +11,7 @@ import ClientKit
|
||||||
import ServicesKit
|
import ServicesKit
|
||||||
import EnvironmentKit
|
import EnvironmentKit
|
||||||
import WidgetsKit
|
import WidgetsKit
|
||||||
|
import WaterfallGrid
|
||||||
|
|
||||||
struct UserProfileStatusesView: View {
|
struct UserProfileStatusesView: View {
|
||||||
@EnvironmentObject private var applicationState: ApplicationState
|
@EnvironmentObject private var applicationState: ApplicationState
|
||||||
|
@ -22,7 +23,7 @@ struct UserProfileStatusesView: View {
|
||||||
@State private var firstLoadFinished = false
|
@State private var firstLoadFinished = false
|
||||||
@State private var statusViewModels: [StatusModel] = []
|
@State private var statusViewModels: [StatusModel] = []
|
||||||
|
|
||||||
private let defaultLimit = 20
|
private let defaultLimit = 40
|
||||||
private let imagePrefetcher = ImagePrefetcher(destination: .diskCache)
|
private let imagePrefetcher = ImagePrefetcher(destination: .diskCache)
|
||||||
private let singleGrids = [GridItem(.flexible(), spacing: 10)]
|
private let singleGrids = [GridItem(.flexible(), spacing: 10)]
|
||||||
private let dubleGrid = [GridItem(.flexible(), spacing: 10), GridItem(.flexible(), spacing: 0)]
|
private let dubleGrid = [GridItem(.flexible(), spacing: 10), GridItem(.flexible(), spacing: 0)]
|
||||||
|
@ -54,7 +55,19 @@ struct UserProfileStatusesView: View {
|
||||||
.padding(.bottom, 8)
|
.padding(.bottom, 8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WaterfallGrid(self.statusViewModels, id: \.id) { item in
|
||||||
|
ImageRowAsync(statusViewModel: item,
|
||||||
|
withAvatar: false,
|
||||||
|
imageScale: self.applicationState.showGridOnUserProfile ? .squareHalfWidth : .orginalFullWidth)
|
||||||
|
// .if(self.applicationState.showGridOnUserProfile) {
|
||||||
|
// $0.frame(width: UIScreen.main.bounds.width / 2, height: UIScreen.main.bounds.width / 2)
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
.gridStyle(columns: 3, spacing: 2)
|
||||||
|
.padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
|
||||||
|
|
||||||
|
/*
|
||||||
LazyVGrid(columns: self.applicationState.showGridOnUserProfile ? dubleGrid : singleGrids, spacing: 5) {
|
LazyVGrid(columns: self.applicationState.showGridOnUserProfile ? dubleGrid : singleGrids, spacing: 5) {
|
||||||
ForEach(self.statusViewModels, id: \.id) { item in
|
ForEach(self.statusViewModels, id: \.id) { item in
|
||||||
ImageRowAsync(statusViewModel: item,
|
ImageRowAsync(statusViewModel: item,
|
||||||
|
@ -80,6 +93,7 @@ struct UserProfileStatusesView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
} else {
|
} else {
|
||||||
LoadingIndicator()
|
LoadingIndicator()
|
||||||
.onFirstAppear {
|
.onFirstAppear {
|
||||||
|
|
|
@ -59,8 +59,8 @@ struct ImageRowAsync: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.if(self.imageScale == .orginalFullWidth) {
|
.if(self.imageScale == .squareHalfWidth) {
|
||||||
$0.frame(width: self.imageWidth, height: self.imageHeight)
|
$0.frame(width: self.imageWidth / 3, height: self.imageHeight / 3)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TabView(selection: $selected) {
|
TabView(selection: $selected) {
|
||||||
|
@ -98,8 +98,8 @@ struct ImageRowAsync: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.if(self.imageScale == .orginalFullWidth) {
|
.if(self.imageScale == .squareHalfWidth) {
|
||||||
$0.frame(width: self.imageWidth, height: self.imageHeight)
|
$0.frame(width: self.imageWidth / 3, height: self.imageHeight / 3)
|
||||||
}
|
}
|
||||||
.tabViewStyle(.page(indexDisplayMode: .never))
|
.tabViewStyle(.page(indexDisplayMode: .never))
|
||||||
.overlay(CustomPageTabViewStyleView(pages: self.statusViewModel.mediaAttachments, currentId: $selected))
|
.overlay(CustomPageTabViewStyleView(pages: self.statusViewModel.mediaAttachments, currentId: $selected))
|
||||||
|
|
|
@ -155,10 +155,11 @@ struct ImageRowItemAsync: View {
|
||||||
private func imageView(image: Image) -> some View {
|
private func imageView(image: Image) -> some View {
|
||||||
image
|
image
|
||||||
.resizable()
|
.resizable()
|
||||||
.scaledToFill()
|
//.aspectRatio(contentMode: .fill)
|
||||||
.if(self.imageScale == .squareHalfWidth) {
|
.aspectRatio(contentMode: .fit)
|
||||||
$0.frame(width: UIScreen.main.bounds.width / 2, height: UIScreen.main.bounds.width / 2).clipped()
|
// .if(self.imageScale == .squareHalfWidth) {
|
||||||
}
|
// $0.frame(width: UIScreen.main.bounds.width / 4, height: UIScreen.main.bounds.width / 4).clipped()
|
||||||
|
// }
|
||||||
.onTapGesture(count: 2) {
|
.onTapGesture(count: 2) {
|
||||||
Task {
|
Task {
|
||||||
// Update favourite in Pixelfed server.
|
// Update favourite in Pixelfed server.
|
||||||
|
|
|
@ -159,7 +159,7 @@ public struct BaseComposeView: View {
|
||||||
}
|
}
|
||||||
.photosPicker(isPresented: $photosPickerVisible,
|
.photosPicker(isPresented: $photosPickerVisible,
|
||||||
selection: $selectedItems,
|
selection: $selectedItems,
|
||||||
maxSelectionCount: 4,
|
maxSelectionCount: self.applicationState.statusMaxMediaAttachments,
|
||||||
matching: .images)
|
matching: .images)
|
||||||
.fileImporter(isPresented: $isFileImporterPresented,
|
.fileImporter(isPresented: $isFileImporterPresented,
|
||||||
allowedContentTypes: [.image],
|
allowedContentTypes: [.image],
|
||||||
|
|
Loading…
Reference in New Issue