update grid spacing

This commit is contained in:
Satindar Dhillon 2022-05-25 12:06:30 -07:00
parent d89b17800e
commit 508763b061
4 changed files with 109 additions and 93 deletions

View file

@ -54,6 +54,14 @@ struct GridCardNavigationLink: View {
@ObservedObject var viewModel: HomeFeedViewModel
func tapAction() {
scale = 0.95
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(150)) {
scale = 1.0
viewModel.selectedLinkItem = item.objectID
}
}
var body: some View {
let destination = LinkItemDetailView(
viewModel: LinkItemDetailViewModel(
@ -77,13 +85,7 @@ struct GridCardNavigationLink: View {
EmptyView()
}
GridCard(item: item, isContextMenuOpen: $isContextMenuOpen, actionHandler: actionHandler, tapAction: {
withAnimation {
scale = 0.95
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(150)) {
scale = 1.0
viewModel.selectedLinkItem = item.objectID
}
}
withAnimation { tapAction() }
})
.onAppear {
Task { await viewModel.itemAppeared(item: item, dataService: dataService) }
@ -91,5 +93,18 @@ struct GridCardNavigationLink: View {
}
.aspectRatio(1.8, contentMode: .fill)
.scaleEffect(scale)
.background(
Color.secondarySystemGroupedBackground
.onTapGesture {
if isContextMenuOpen {
isContextMenuOpen = false
} else {
withAnimation {
tapAction()
}
}
}
)
.cornerRadius(6)
}
}

View file

@ -338,7 +338,7 @@ import Views
var body: some View {
ScrollView {
LazyVGrid(columns: [GridItem(.adaptive(minimum: 325), spacing: 24)], spacing: 24) {
LazyVGrid(columns: [GridItem(.adaptive(minimum: 325), spacing: 16)], spacing: 16) {
ForEach(viewModel.items) { item in
GridCardNavigationLink(
item: item,

View file

@ -34,6 +34,10 @@ public extension LinkedItem {
var unwrappedSavedAt: Date { savedAt ?? Date() }
var unwrappedCreatedAt: Date { createdAt ?? Date() }
var hasLabels: Bool {
(labels?.count ?? 0) > 0
}
var isRead: Bool {
readingProgress >= 0.98
}

View file

@ -75,100 +75,97 @@ public struct GridCard: View {
}
.onTapGesture { tapHandler() }
// Title, Subtitle, Menu Button
VStack(alignment: .leading, spacing: 4) {
HStack {
Text(item.unwrappedTitle)
.font(.appHeadline)
VStack {
// Title, Subtitle, Menu Button
VStack(alignment: .leading, spacing: 4) {
HStack {
Text(item.unwrappedTitle)
.font(.appHeadline)
.foregroundColor(.appGrayTextContrast)
.lineLimit(1)
.onTapGesture { tapHandler() }
Spacer()
Menu(
content: { contextMenuView },
label: { Image(systemName: "ellipsis").padding() }
)
.frame(width: 16, height: 16, alignment: .center)
.onTapGesture { isContextMenuOpen = true }
}
HStack {
if let author = item.author {
Text("by \(author)")
.font(.appCaptionTwo)
.foregroundColor(.appGrayText)
.lineLimit(1)
}
if let publisherDisplayName = item.publisherDisplayName {
Text(publisherDisplayName)
.font(.appCaptionTwo)
.foregroundColor(.appGrayText)
.lineLimit(1)
}
Spacer()
}
.onTapGesture { tapHandler() }
}
.frame(height: 30)
.padding(.horizontal)
.padding(.bottom, 16)
// Link description and image
HStack(alignment: .top) {
Text(item.descriptionText ?? item.unwrappedTitle)
.font(.appSubheadline)
.foregroundColor(.appGrayTextContrast)
.lineLimit(1)
.onTapGesture { tapHandler() }
Spacer()
Menu(
content: { contextMenuView },
label: { Image(systemName: "ellipsis").padding() }
)
.frame(width: 16, height: 16, alignment: .center)
.onTapGesture { isContextMenuOpen = true }
}
HStack {
if let author = item.author {
Text("by \(author)")
.font(.appCaptionTwo)
.foregroundColor(.appGrayText)
.lineLimit(1)
}
if let publisherDisplayName = item.publisherDisplayName {
Text(publisherDisplayName)
.font(.appCaptionTwo)
.foregroundColor(.appGrayText)
.lineLimit(1)
}
.lineLimit(nil)
.multilineTextAlignment(.leading)
Spacer()
}
.onTapGesture { tapHandler() }
}
.frame(height: 30)
.padding(.horizontal)
.padding(.bottom, 12)
// Link description and image
HStack(alignment: .top) {
Text(item.descriptionText ?? item.unwrappedTitle)
.font(.appSubheadline)
.foregroundColor(.appGrayTextContrast)
.lineLimit(nil)
.multilineTextAlignment(.leading)
.frame(height: (geo.size.width * 2) / 9, alignment: .top)
Spacer()
if let imageURL = item.imageURL {
AsyncLoadingImage(url: imageURL) { imageStatus in
if case let AsyncImageStatus.loaded(image) = imageStatus {
image
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: geo.size.width / 3, height: (geo.size.width * 2) / 9)
.cornerRadius(3)
} else if case AsyncImageStatus.loading = imageStatus {
Color.appButtonBackground
.frame(width: geo.size.width / 3, height: (geo.size.width * 2) / 9)
.cornerRadius(3)
} else {
EmptyView()
if let imageURL = item.imageURL {
AsyncLoadingImage(url: imageURL) { imageStatus in
if case let AsyncImageStatus.loaded(image) = imageStatus {
image
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: geo.size.width / 3, height: (geo.size.width * 2) / 9)
.cornerRadius(3)
} else if case AsyncImageStatus.loading = imageStatus {
Color.appButtonBackground
.frame(width: geo.size.width / 3, height: (geo.size.width * 2) / 9)
.cornerRadius(3)
} else {
EmptyView()
}
}
}
}
}
.padding(.horizontal)
.onTapGesture { tapHandler() }
// Category Labels
ScrollView(.horizontal, showsIndicators: false) {
HStack {
ForEach(item.sortedLabels, id: \.self) {
TextChip(feedItemLabel: $0)
}
// Add an empty chip to the end so that we create a Spacer equivalent
// in the case where there are no labels set on the item
TextChip(text: "", color: Color.secondarySystemGroupedBackground)
Spacer()
}
.padding(.horizontal)
}
.frame(height: 40)
.onTapGesture { tapHandler() }
}
.background(
Color.secondarySystemGroupedBackground
.onTapGesture { tapHandler() }
)
.cornerRadius(6)
// Category Labels
if item.hasLabels {
ScrollView(.horizontal, showsIndicators: false) {
HStack {
ForEach(item.sortedLabels, id: \.self) {
TextChip(feedItemLabel: $0)
}
Spacer()
}
.padding(.horizontal)
}
.onTapGesture { tapHandler() }
}
}
.padding(.horizontal, 0)
.padding(.top, 0)
.padding(.bottom, 8)
}
.contextMenu { contextMenuView }
}
}