mirror of
https://github.com/samuelclay/NewsBlur.git
synced 2025-09-18 21:50:56 +00:00
#1720 (Grid view)
- Added support for the Grid layout on iPhone, with one or two columns. Works fairly well. - Bumped up the feed title & date/author font size again. - Now markes as read on scroll when the card is scrolled halfway off the top.
This commit is contained in:
parent
eb94e7bc7f
commit
f703d58b94
7 changed files with 87 additions and 46 deletions
|
@ -139,6 +139,11 @@ class DetailViewController: BaseViewController {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the device is an iPhone, otherwise `false`.
|
||||
@objc var isPhone: Bool {
|
||||
return UIDevice.current.userInterfaceIdiom == .phone
|
||||
}
|
||||
|
||||
/// Returns `true` if the window is in portrait orientation, otherwise `false`.
|
||||
@objc var isPortraitOrientation: Bool {
|
||||
return view.window?.windowScene?.interfaceOrientation.isPortrait ?? false
|
||||
|
@ -258,7 +263,7 @@ class DetailViewController: BaseViewController {
|
|||
|
||||
/// Moves the story pages controller to a Grid layout cell content (automatically removing it from the previous parent).
|
||||
func prepareStoriesForGridView() {
|
||||
guard let storyPagesViewController else {
|
||||
guard !isPhone, let storyPagesViewController else {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -338,7 +343,7 @@ class DetailViewController: BaseViewController {
|
|||
}
|
||||
|
||||
private func adjustTopConstraint() {
|
||||
if UIDevice.current.userInterfaceIdiom != .phone {
|
||||
if !isPhone {
|
||||
if view.window?.windowScene?.traitCollection.horizontalSizeClass == .compact {
|
||||
topContainerTopConstraint.constant = -50
|
||||
} else {
|
||||
|
@ -388,7 +393,7 @@ private extension DetailViewController {
|
|||
func checkViewControllers() {
|
||||
let isTop = layout == .top
|
||||
|
||||
if layout == .left {
|
||||
if layout == .left || isPhone {
|
||||
if feedDetailViewController != nil {
|
||||
remove(viewController: feedDetailViewController)
|
||||
|
||||
|
@ -459,7 +464,7 @@ private extension DetailViewController {
|
|||
|
||||
appDelegate.feedDetailViewController.changedLayout()
|
||||
|
||||
if layout != .grid {
|
||||
if layout != .grid || isPhone {
|
||||
moveStoriesToDetail()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -261,7 +261,7 @@ struct CardContentView: View {
|
|||
.padding(.leading, 24)
|
||||
|
||||
Text(story.feedName)
|
||||
.font(font(named: "WhitneySSm-Medium", size: 11))
|
||||
.font(font(named: "WhitneySSm-Medium", size: 12))
|
||||
.lineLimit(1)
|
||||
.foregroundColor(feedColor)
|
||||
}
|
||||
|
@ -315,7 +315,7 @@ struct CardContentView: View {
|
|||
Spacer()
|
||||
|
||||
Text(story.dateAndAuthor)
|
||||
.font(font(named: "WhitneySSm-Medium", size: 11))
|
||||
.font(font(named: "WhitneySSm-Medium", size: 12))
|
||||
.foregroundColor(dateAndAuthorColor)
|
||||
.padding(.top, 5)
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ struct FeedDetailGridView: View {
|
|||
}
|
||||
}
|
||||
|
||||
if cache.isGrid {
|
||||
if cache.isGrid && !cache.isPhone {
|
||||
EmptyView()
|
||||
.id(storyViewID)
|
||||
} else if let story = cache.selected {
|
||||
|
@ -134,7 +134,7 @@ struct FeedDetailGridView: View {
|
|||
.onPreferenceChange(CardKey.self) {
|
||||
print("pref change for '\(story.title)': \($0)")
|
||||
|
||||
if let value = $0.first, value.frame.minY < 0 {
|
||||
if let value = $0.first, value.frame.minY < -(value.frame.size.height / 2) {
|
||||
print("pref '\(story.title)': scrolled off the top")
|
||||
|
||||
feedDetailInteraction.read(story: story)
|
||||
|
@ -153,7 +153,7 @@ struct FeedDetailGridView: View {
|
|||
|
||||
@ViewBuilder
|
||||
func makeStoryView(cache: StoryCache) -> some View {
|
||||
if cache.isGrid, let story = cache.selected {
|
||||
if cache.isGrid, !cache.isPhone, let story = cache.selected {
|
||||
StoryView(cache: cache, story: loaded(story: story), interaction: feedDetailInteraction)
|
||||
// .frame(height: storyHeight)
|
||||
}
|
||||
|
|
|
@ -2390,40 +2390,52 @@ didEndSwipingSwipingWithState:(MCSwipeTableViewCellState)state
|
|||
}];
|
||||
}
|
||||
|
||||
if ([[UIDevice currentDevice] userInterfaceIdiom] != UIUserInterfaceIdiomPhone) {
|
||||
[appDelegate addSplitControlToMenuController:viewController];
|
||||
[appDelegate addSplitControlToMenuController:viewController];
|
||||
|
||||
NSString *preferenceKey = @"story_titles_position";
|
||||
NSArray *titles;
|
||||
NSArray *values;
|
||||
|
||||
if (appDelegate.detailViewController.isPhone) {
|
||||
titles = @[@"List", @"Grid"];
|
||||
values = @[@"titles_on_left", @"titles_in_grid"];
|
||||
} else {
|
||||
titles = @[@"Left", @"Top", @"Bottom", @"Grid"];
|
||||
values = @[@"titles_on_left", @"titles_on_top", @"titles_on_bottom", @"titles_in_grid"];
|
||||
}
|
||||
|
||||
[viewController addSegmentedControlWithTitles:titles values:values preferenceKey:preferenceKey selectionShouldDismiss:YES handler:^(NSUInteger selectedIndex) {
|
||||
[self.appDelegate.detailViewController updateLayoutWithReload:YES];
|
||||
}];
|
||||
|
||||
if (self.appDelegate.detailViewController.storyTitlesInGrid) {
|
||||
preferenceKey = @"grid_columns";
|
||||
|
||||
NSString *preferenceKey = @"story_titles_position";
|
||||
NSArray *titles = @[@"Left", @"Top", @"Bottom", @"Grid"];
|
||||
NSArray *values = @[@"titles_on_left", @"titles_on_top", @"titles_on_bottom", @"titles_in_grid"];
|
||||
if (appDelegate.detailViewController.isPhone) {
|
||||
titles = @[@"Auto Cols", @"1", @"2"];
|
||||
values = @[@"auto", @"1", @"2"];
|
||||
} else {
|
||||
titles = @[@"Auto Cols", @"1", @"2", @"3", @"4"];
|
||||
values = @[@"auto", @"1", @"2", @"3", @"4"];
|
||||
}
|
||||
|
||||
[viewController addSegmentedControlWithTitles:titles values:values preferenceKey:preferenceKey selectionShouldDismiss:YES handler:^(NSUInteger selectedIndex) {
|
||||
[viewController addSegmentedControlWithTitles:titles values:values defaultValue:@"auto" preferenceKey:preferenceKey selectionShouldDismiss:NO handler:^(NSUInteger selectedIndex) {
|
||||
[self.appDelegate.detailViewController updateLayoutWithReload:YES];
|
||||
}];
|
||||
|
||||
if (self.appDelegate.detailViewController.storyTitlesInGrid) {
|
||||
NSString *preferenceKey = @"grid_columns";
|
||||
NSArray *titles = @[@"Auto Cols", @"2", @"3", @"4"];
|
||||
NSArray *values = @[@"auto", @"2", @"3", @"4"];
|
||||
|
||||
[viewController addSegmentedControlWithTitles:titles values:values defaultValue:@"auto" preferenceKey:preferenceKey selectionShouldDismiss:NO handler:^(NSUInteger selectedIndex) {
|
||||
[self.appDelegate.detailViewController updateLayoutWithReload:YES];
|
||||
}];
|
||||
|
||||
preferenceKey = @"grid_height";
|
||||
titles = @[@"XS", @"Short", @"Medium", @"Tall", @"XL"];
|
||||
values = @[@"xs", @"short", @"medium", @"tall", @"xl"];
|
||||
|
||||
[viewController addSegmentedControlWithTitles:titles values:values defaultValue:@"medium" preferenceKey:preferenceKey selectionShouldDismiss:NO handler:^(NSUInteger selectedIndex) {
|
||||
[self.appDelegate.detailViewController updateLayoutWithReload:YES];
|
||||
}];
|
||||
}
|
||||
preferenceKey = @"grid_height";
|
||||
titles = @[@"XS", @"Short", @"Medium", @"Tall", @"XL"];
|
||||
values = @[@"xs", @"short", @"medium", @"tall", @"xl"];
|
||||
|
||||
[viewController addSegmentedControlWithTitles:titles values:values defaultValue:@"medium" preferenceKey:preferenceKey selectionShouldDismiss:NO handler:^(NSUInteger selectedIndex) {
|
||||
[self.appDelegate.detailViewController updateLayoutWithReload:YES];
|
||||
}];
|
||||
}
|
||||
|
||||
if (!self.appDelegate.detailViewController.storyTitlesInGrid) {
|
||||
NSString *preferenceKey = @"story_list_preview_text_size";
|
||||
NSArray *titles = @[@"Title", @"content_preview_small.png", @"content_preview_medium.png", @"content_preview_large.png"];
|
||||
NSArray *values = @[@"title", @"short", @"medium", @"long"];
|
||||
preferenceKey = @"story_list_preview_text_size";
|
||||
titles = @[@"Title", @"content_preview_small.png", @"content_preview_medium.png", @"content_preview_large.png"];
|
||||
values = @[@"title", @"short", @"medium", @"long"];
|
||||
|
||||
[viewController addSegmentedControlWithTitles:titles values:values preferenceKey:preferenceKey selectionShouldDismiss:NO handler:^(NSUInteger selectedIndex) {
|
||||
[self.appDelegate resizePreviewSize];
|
||||
|
@ -2447,9 +2459,9 @@ didEndSwipingSwipingWithState:(MCSwipeTableViewCellState)state
|
|||
}];
|
||||
}
|
||||
|
||||
NSString *preferenceKey = @"feed_list_font_size";
|
||||
NSArray *titles = @[@"XS", @"S", @"M", @"L", @"XL"];
|
||||
NSArray *values = @[@"xs", @"small", @"medium", @"large", @"xl"];
|
||||
preferenceKey = @"feed_list_font_size";
|
||||
titles = @[@"XS", @"S", @"M", @"L", @"XL"];
|
||||
values = @[@"xs", @"small", @"medium", @"large", @"xl"];
|
||||
|
||||
[viewController addSegmentedControlWithTitles:titles values:values preferenceKey:preferenceKey selectionShouldDismiss:NO handler:^(NSUInteger selectedIndex) {
|
||||
[self.appDelegate resizeFontSize];
|
||||
|
|
|
@ -141,6 +141,10 @@ class StoryCache: ObservableObject {
|
|||
return appDelegate.detailViewController.layout == .grid
|
||||
}
|
||||
|
||||
var isPhone: Bool {
|
||||
return appDelegate.detailViewController.isPhone
|
||||
}
|
||||
|
||||
@Published var before = [Story]()
|
||||
@Published var selected: Story?
|
||||
@Published var after = [Story]()
|
||||
|
@ -288,13 +292,13 @@ class StorySettings {
|
|||
// }
|
||||
|
||||
var gridColumns: Int {
|
||||
if NewsBlurAppDelegate.shared.isCompactWidth {
|
||||
return 1
|
||||
}
|
||||
|
||||
guard let pref = UserDefaults.standard.string(forKey: "grid_columns"), let columns = Int(pref) else {
|
||||
//TODO: 🚧 could have extra logic to determine the ideal number of columns
|
||||
return 4
|
||||
if NewsBlurAppDelegate.shared.isCompactWidth {
|
||||
return 1
|
||||
} else {
|
||||
return 4
|
||||
}
|
||||
}
|
||||
|
||||
return columns
|
||||
|
|
|
@ -287,7 +287,7 @@
|
|||
}
|
||||
|
||||
- (void)deferredEnableScrolling {
|
||||
self.webView.scrollView.scrollEnabled = !self.appDelegate.detailViewController.storyTitlesInGrid;
|
||||
self.webView.scrollView.scrollEnabled = self.appDelegate.detailViewController.isPhone || !self.appDelegate.detailViewController.storyTitlesInGrid;
|
||||
}
|
||||
|
||||
- (void)viewDidDisappear:(BOOL)animated {
|
||||
|
@ -1817,7 +1817,7 @@
|
|||
|
||||
[self.activityIndicator stopAnimating];
|
||||
|
||||
self.webView.scrollView.scrollEnabled = !self.appDelegate.detailViewController.storyTitlesInGrid;
|
||||
self.webView.scrollView.scrollEnabled = self.appDelegate.detailViewController.isPhone || !self.appDelegate.detailViewController.storyTitlesInGrid;
|
||||
|
||||
[self loadHTMLString:self.fullStoryHTML];
|
||||
self.fullStoryHTML = nil;
|
||||
|
@ -1837,7 +1837,7 @@
|
|||
self.webView.hidden = NO;
|
||||
[self.webView setNeedsDisplay];
|
||||
|
||||
if (self == self.appDelegate.storyPagesViewController.currentPage && self.appDelegate.detailViewController.storyTitlesInGrid) {
|
||||
if (self == self.appDelegate.storyPagesViewController.currentPage && !self.appDelegate.detailViewController.isPhone && self.appDelegate.detailViewController.storyTitlesInGrid) {
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
// [self.appDelegate.feedDetailViewController changedStoryHeight:self.webView.scrollView.contentSize.height];
|
||||
[self.appDelegate.feedDetailViewController reload];
|
||||
|
|
|
@ -202,6 +202,26 @@
|
|||
<key>Key</key>
|
||||
<string>override_scroll_read_filter</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Type</key>
|
||||
<string>PSMultiValueSpecifier</string>
|
||||
<key>Title</key>
|
||||
<string>Story titles layout</string>
|
||||
<key>Titles</key>
|
||||
<array>
|
||||
<string>Titles in list</string>
|
||||
<string>Titles in grid</string>
|
||||
</array>
|
||||
<key>DefaultValue</key>
|
||||
<string>titles_on_left</string>
|
||||
<key>Values</key>
|
||||
<array>
|
||||
<string>titles_on_left</string>
|
||||
<string>titles_in_grid</string>
|
||||
</array>
|
||||
<key>Key</key>
|
||||
<string>story_titles_position</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Type</key>
|
||||
<string>PSMultiValueSpecifier</string>
|
||||
|
|
Loading…
Add table
Reference in a new issue