mirror of
https://github.com/samuelclay/NewsBlur.git
synced 2025-08-31 21:41:33 +00:00
Merge branch 'dejal' into catalyst
* dejal: Using discourse icon for support forum link on ios. #1578 #1575 (subscribe to site in share sheet) #1579 (focus changes) #1540 (comfortable/compact feeds) #1578 (support link)
This commit is contained in:
commit
4101aba7b6
10 changed files with 221 additions and 58 deletions
|
@ -95,6 +95,9 @@ typedef NS_ENUM(NSUInteger, MarkReadShowMenu)
|
||||||
|
|
||||||
self.storyTitlesTable.backgroundColor = UIColorFromRGB(0xf4f4f4);
|
self.storyTitlesTable.backgroundColor = UIColorFromRGB(0xf4f4f4);
|
||||||
self.storyTitlesTable.separatorColor = UIColorFromRGB(0xE9E8E4);
|
self.storyTitlesTable.separatorColor = UIColorFromRGB(0xE9E8E4);
|
||||||
|
if (@available(iOS 15.0, *)) {
|
||||||
|
self.storyTitlesTable.allowsFocus = NO;
|
||||||
|
}
|
||||||
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
|
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
|
||||||
self.storyTitlesTable.dragDelegate = self;
|
self.storyTitlesTable.dragDelegate = self;
|
||||||
self.storyTitlesTable.dragInteractionEnabled = YES;
|
self.storyTitlesTable.dragInteractionEnabled = YES;
|
||||||
|
|
|
@ -579,6 +579,7 @@ static NSArray<NSString *> *NewsBlurTopSectionNames;
|
||||||
[defaults setObject:[results objectForKey:@"share_ext_token"] forKey:@"share:token"];
|
[defaults setObject:[results objectForKey:@"share_ext_token"] forKey:@"share:token"];
|
||||||
[defaults setObject:self.appDelegate.url forKey:@"share:host"];
|
[defaults setObject:self.appDelegate.url forKey:@"share:host"];
|
||||||
[defaults setObject:appDelegate.dictSavedStoryTags forKey:@"share:tags"];
|
[defaults setObject:appDelegate.dictSavedStoryTags forKey:@"share:tags"];
|
||||||
|
[defaults setObject:appDelegate.dictFoldersArray forKey:@"share:folders"];
|
||||||
[self validateWidgetFeedsForGroupDefaults:defaults usingResults:results];
|
[self validateWidgetFeedsForGroupDefaults:defaults usingResults:results];
|
||||||
[defaults synchronize];
|
[defaults synchronize];
|
||||||
|
|
||||||
|
@ -1019,6 +1020,11 @@ static NSArray<NSString *> *NewsBlurTopSectionNames;
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[viewController addTitle:@"Support Forum" iconName:@"discourse.png" selectionShouldDismiss:YES handler:^{
|
||||||
|
NSURL *url = [NSURL URLWithString:@"https://forum.newsblur.com"];
|
||||||
|
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
|
||||||
|
}];
|
||||||
|
|
||||||
[viewController addTitle:@"Logout" iconName:@"menu_icn_fetch_subscribers.png" selectionShouldDismiss:YES handler:^{
|
[viewController addTitle:@"Logout" iconName:@"menu_icn_fetch_subscribers.png" selectionShouldDismiss:YES handler:^{
|
||||||
[self.appDelegate confirmLogout];
|
[self.appDelegate confirmLogout];
|
||||||
}];
|
}];
|
||||||
|
@ -1041,6 +1047,14 @@ static NSArray<NSString *> *NewsBlurTopSectionNames;
|
||||||
[self.appDelegate resizeFontSize];
|
[self.appDelegate resizeFontSize];
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
preferenceKey = @"feed_list_spacing";
|
||||||
|
titles = @[@"Compact", @"Comfortable"];
|
||||||
|
values = @[@"compact", @"comfortable"];
|
||||||
|
|
||||||
|
[viewController addSegmentedControlWithTitles:titles values:values defaultValue:@"comfortable" preferenceKey:preferenceKey selectionShouldDismiss:YES handler:^(NSUInteger selectedIndex) {
|
||||||
|
[self reloadFeedTitlesTable];
|
||||||
|
}];
|
||||||
|
|
||||||
[viewController addThemeSegmentedControl];
|
[viewController addThemeSegmentedControl];
|
||||||
|
|
||||||
UINavigationController *navController = self.navigationController;
|
UINavigationController *navController = self.navigationController;
|
||||||
|
@ -1582,7 +1596,10 @@ static NSArray<NSString *> *NewsBlurTopSectionNames;
|
||||||
|
|
||||||
UIFontDescriptor *fontDescriptor = [self fontDescriptorUsingPreferredSize:UIFontTextStyleCaption1];
|
UIFontDescriptor *fontDescriptor = [self fontDescriptorUsingPreferredSize:UIFontTextStyleCaption1];
|
||||||
UIFont *font = [UIFont fontWithName:@"WhitneySSm-Medium" size:fontDescriptor.pointSize];
|
UIFont *font = [UIFont fontWithName:@"WhitneySSm-Medium" size:fontDescriptor.pointSize];
|
||||||
return height + font.pointSize*2;
|
NSString *spacing = [[NSUserDefaults standardUserDefaults] objectForKey:@"feed_list_spacing"];
|
||||||
|
NSInteger offset = [spacing isEqualToString:@"compact"] ? 6 : 0;
|
||||||
|
|
||||||
|
return height + (font.pointSize * 2) - offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)resetRowHeights {
|
- (void)resetRowHeights {
|
||||||
|
|
|
@ -22,6 +22,7 @@ typedef void (^MenuItemSegmentedHandler)(NSUInteger selectedIndex);
|
||||||
- (void)addTitle:(NSString *)title iconTemplateName:(NSString *)iconTemplateName selectionShouldDismiss:(BOOL)selectionShouldDismiss handler:(MenuItemHandler)handler;
|
- (void)addTitle:(NSString *)title iconTemplateName:(NSString *)iconTemplateName selectionShouldDismiss:(BOOL)selectionShouldDismiss handler:(MenuItemHandler)handler;
|
||||||
- (void)addSegmentedControlWithTitles:(NSArray *)titles selectIndex:(NSUInteger)selectIndex selectionShouldDismiss:(BOOL)selectionShouldDismiss handler:(MenuItemSegmentedHandler)handler;
|
- (void)addSegmentedControlWithTitles:(NSArray *)titles selectIndex:(NSUInteger)selectIndex selectionShouldDismiss:(BOOL)selectionShouldDismiss handler:(MenuItemSegmentedHandler)handler;
|
||||||
- (void)addSegmentedControlWithTitles:(NSArray *)titles values:(NSArray *)values preferenceKey:(NSString *)preferenceKey selectionShouldDismiss:(BOOL)selectionShouldDismiss handler:(MenuItemSegmentedHandler)handler;
|
- (void)addSegmentedControlWithTitles:(NSArray *)titles values:(NSArray *)values preferenceKey:(NSString *)preferenceKey selectionShouldDismiss:(BOOL)selectionShouldDismiss handler:(MenuItemSegmentedHandler)handler;
|
||||||
|
- (void)addSegmentedControlWithTitles:(NSArray *)titles values:(NSArray *)values defaultValue:(NSString *)defaultValue preferenceKey:(NSString *)preferenceKey selectionShouldDismiss:(BOOL)selectionShouldDismiss handler:(MenuItemSegmentedHandler)handler;
|
||||||
- (void)addThemeSegmentedControl;
|
- (void)addThemeSegmentedControl;
|
||||||
|
|
||||||
- (void)showFromNavigationController:(UINavigationController *)navigationController barButtonItem:(UIBarButtonItem *)barButtonItem;
|
- (void)showFromNavigationController:(UINavigationController *)navigationController barButtonItem:(UIBarButtonItem *)barButtonItem;
|
||||||
|
|
|
@ -106,11 +106,19 @@ NSString * const MenuHandler = @"handler";
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)addSegmentedControlWithTitles:(NSArray *)titles values:(NSArray *)values preferenceKey:(NSString *)preferenceKey selectionShouldDismiss:(BOOL)selectionShouldDismiss handler:(MenuItemSegmentedHandler)handler {
|
- (void)addSegmentedControlWithTitles:(NSArray *)titles values:(NSArray *)values preferenceKey:(NSString *)preferenceKey selectionShouldDismiss:(BOOL)selectionShouldDismiss handler:(MenuItemSegmentedHandler)handler {
|
||||||
|
[self addSegmentedControlWithTitles:titles values:values defaultValue:nil preferenceKey:preferenceKey selectionShouldDismiss:selectionShouldDismiss handler:handler];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)addSegmentedControlWithTitles:(NSArray *)titles values:(NSArray *)values defaultValue:(NSString *)defaultValue preferenceKey:(NSString *)preferenceKey selectionShouldDismiss:(BOOL)selectionShouldDismiss handler:(MenuItemSegmentedHandler)handler {
|
||||||
NSUserDefaults *userPreferences = [NSUserDefaults standardUserDefaults];
|
NSUserDefaults *userPreferences = [NSUserDefaults standardUserDefaults];
|
||||||
id value = [userPreferences objectForKey:preferenceKey];
|
id value = [userPreferences objectForKey:preferenceKey];
|
||||||
NSUInteger valueIndex = [values indexOfObject:value];
|
NSUInteger valueIndex = [values indexOfObject:value];
|
||||||
|
|
||||||
if (valueIndex < 0) {
|
if (valueIndex == NSNotFound && defaultValue != nil) {
|
||||||
|
valueIndex = [values indexOfObject:defaultValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valueIndex == NSNotFound) {
|
||||||
valueIndex = 0;
|
valueIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -347,6 +347,8 @@
|
||||||
FF22FE7616E557D80046165A /* toolbar_tall_background.png in Resources */ = {isa = PBXBuildFile; fileRef = FF22FE7416E557D80046165A /* toolbar_tall_background.png */; };
|
FF22FE7616E557D80046165A /* toolbar_tall_background.png in Resources */ = {isa = PBXBuildFile; fileRef = FF22FE7416E557D80046165A /* toolbar_tall_background.png */; };
|
||||||
FF22FE7716E557D80046165A /* toolbar_tall_background@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FF22FE7516E557D80046165A /* toolbar_tall_background@2x.png */; };
|
FF22FE7716E557D80046165A /* toolbar_tall_background@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FF22FE7516E557D80046165A /* toolbar_tall_background@2x.png */; };
|
||||||
FF265F12187B6D4F0080C332 /* fitvid.js in Resources */ = {isa = PBXBuildFile; fileRef = FF265F10187B6B230080C332 /* fitvid.js */; };
|
FF265F12187B6D4F0080C332 /* fitvid.js in Resources */ = {isa = PBXBuildFile; fileRef = FF265F10187B6B230080C332 /* fitvid.js */; };
|
||||||
|
FF28C5B8278603750033D2A2 /* discourse.png in Resources */ = {isa = PBXBuildFile; fileRef = FF28C5B7278603750033D2A2 /* discourse.png */; };
|
||||||
|
FF28C5BA278604940033D2A2 /* discourse@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FF28C5B9278604940033D2A2 /* discourse@2x.png */; };
|
||||||
FF2924E51E932D2900FCFA63 /* PINCache.m in Sources */ = {isa = PBXBuildFile; fileRef = FF2924DF1E932D2900FCFA63 /* PINCache.m */; };
|
FF2924E51E932D2900FCFA63 /* PINCache.m in Sources */ = {isa = PBXBuildFile; fileRef = FF2924DF1E932D2900FCFA63 /* PINCache.m */; };
|
||||||
FF2924E61E932D2900FCFA63 /* PINDiskCache.m in Sources */ = {isa = PBXBuildFile; fileRef = FF2924E21E932D2900FCFA63 /* PINDiskCache.m */; };
|
FF2924E61E932D2900FCFA63 /* PINDiskCache.m in Sources */ = {isa = PBXBuildFile; fileRef = FF2924E21E932D2900FCFA63 /* PINDiskCache.m */; };
|
||||||
FF2924E71E932D2900FCFA63 /* PINMemoryCache.m in Sources */ = {isa = PBXBuildFile; fileRef = FF2924E41E932D2900FCFA63 /* PINMemoryCache.m */; };
|
FF2924E71E932D2900FCFA63 /* PINMemoryCache.m in Sources */ = {isa = PBXBuildFile; fileRef = FF2924E41E932D2900FCFA63 /* PINMemoryCache.m */; };
|
||||||
|
@ -1119,6 +1121,8 @@
|
||||||
FF22FE7516E557D80046165A /* toolbar_tall_background@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "toolbar_tall_background@2x.png"; sourceTree = "<group>"; };
|
FF22FE7516E557D80046165A /* toolbar_tall_background@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "toolbar_tall_background@2x.png"; sourceTree = "<group>"; };
|
||||||
FF26125318C00FEC0055FF4D /* AddressBook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBook.framework; path = System/Library/Frameworks/AddressBook.framework; sourceTree = SDKROOT; };
|
FF26125318C00FEC0055FF4D /* AddressBook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBook.framework; path = System/Library/Frameworks/AddressBook.framework; sourceTree = SDKROOT; };
|
||||||
FF265F10187B6B230080C332 /* fitvid.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = fitvid.js; path = static/fitvid.js; sourceTree = SOURCE_ROOT; };
|
FF265F10187B6B230080C332 /* fitvid.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = fitvid.js; path = static/fitvid.js; sourceTree = SOURCE_ROOT; };
|
||||||
|
FF28C5B7278603750033D2A2 /* discourse.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = discourse.png; sourceTree = "<group>"; };
|
||||||
|
FF28C5B9278604940033D2A2 /* discourse@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "discourse@2x.png"; sourceTree = "<group>"; };
|
||||||
FF2924DD1E932D2900FCFA63 /* Nullability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Nullability.h; sourceTree = "<group>"; };
|
FF2924DD1E932D2900FCFA63 /* Nullability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Nullability.h; sourceTree = "<group>"; };
|
||||||
FF2924DE1E932D2900FCFA63 /* PINCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PINCache.h; sourceTree = "<group>"; };
|
FF2924DE1E932D2900FCFA63 /* PINCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PINCache.h; sourceTree = "<group>"; };
|
||||||
FF2924DF1E932D2900FCFA63 /* PINCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PINCache.m; sourceTree = "<group>"; };
|
FF2924DF1E932D2900FCFA63 /* PINCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PINCache.m; sourceTree = "<group>"; };
|
||||||
|
@ -2308,6 +2312,8 @@
|
||||||
FF5F3A81162B82B5008DBE3E /* rainbow.png */,
|
FF5F3A81162B82B5008DBE3E /* rainbow.png */,
|
||||||
43A4C3F315B00A26008787B5 /* arrow.png */,
|
43A4C3F315B00A26008787B5 /* arrow.png */,
|
||||||
43A4C3F415B00A26008787B5 /* arrow@2x.png */,
|
43A4C3F415B00A26008787B5 /* arrow@2x.png */,
|
||||||
|
FF28C5B7278603750033D2A2 /* discourse.png */,
|
||||||
|
FF28C5B9278604940033D2A2 /* discourse@2x.png */,
|
||||||
43A4C3F715B00A26008787B5 /* Background.png */,
|
43A4C3F715B00A26008787B5 /* Background.png */,
|
||||||
43A4C3F815B00A26008787B5 /* Background@2X.png */,
|
43A4C3F815B00A26008787B5 /* Background@2X.png */,
|
||||||
43A4C41115B00A26008787B5 /* fleuron.png */,
|
43A4C41115B00A26008787B5 /* fleuron.png */,
|
||||||
|
@ -3423,6 +3429,7 @@
|
||||||
FFDD847F16E887D3000AA0A2 /* g_icn_folder@2x.png in Resources */,
|
FFDD847F16E887D3000AA0A2 /* g_icn_folder@2x.png in Resources */,
|
||||||
1740C6881C10FD75005EA453 /* theme_color_dark.png in Resources */,
|
1740C6881C10FD75005EA453 /* theme_color_dark.png in Resources */,
|
||||||
FFDD848016E887D3000AA0A2 /* g_icn_hidden.png in Resources */,
|
FFDD848016E887D3000AA0A2 /* g_icn_hidden.png in Resources */,
|
||||||
|
FF28C5B8278603750033D2A2 /* discourse.png in Resources */,
|
||||||
FF21B11C1C8228740053938A /* disclosure_border_medium.png in Resources */,
|
FF21B11C1C8228740053938A /* disclosure_border_medium.png in Resources */,
|
||||||
17C67DA02138B2D20027CCAE /* traverse_next_vert@2x.png in Resources */,
|
17C67DA02138B2D20027CCAE /* traverse_next_vert@2x.png in Resources */,
|
||||||
FFDD848116E887D3000AA0A2 /* g_icn_hidden@2x.png in Resources */,
|
FFDD848116E887D3000AA0A2 /* g_icn_hidden@2x.png in Resources */,
|
||||||
|
@ -3489,6 +3496,7 @@
|
||||||
17F39EB526478319004B46D1 /* image_preview_small_right@2x.png in Resources */,
|
17F39EB526478319004B46D1 /* image_preview_small_right@2x.png in Resources */,
|
||||||
FFCDD8F817F4BCB4000C6483 /* Default.png in Resources */,
|
FFCDD8F817F4BCB4000C6483 /* Default.png in Resources */,
|
||||||
FF5D4017179A00B900349659 /* traverse_send.png in Resources */,
|
FF5D4017179A00B900349659 /* traverse_send.png in Resources */,
|
||||||
|
FF28C5BA278604940033D2A2 /* discourse@2x.png in Resources */,
|
||||||
FFCDD8FA17F50C08000C6483 /* drag_icon.png in Resources */,
|
FFCDD8FA17F50C08000C6483 /* drag_icon.png in Resources */,
|
||||||
FF5D4018179A00B900349659 /* traverse_send@2x.png in Resources */,
|
FF5D4018179A00B900349659 /* traverse_send@2x.png in Resources */,
|
||||||
FF5D401B179A03E700349659 /* traverse_previous_off.png in Resources */,
|
FF5D401B179A03E700349659 /* traverse_previous_off.png in Resources */,
|
||||||
|
|
BIN
clients/ios/Resources/discourse.png
Normal file
BIN
clients/ios/Resources/discourse.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 495 B |
BIN
clients/ios/Resources/discourse@2x.png
Normal file
BIN
clients/ios/Resources/discourse@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 899 B |
|
@ -1,8 +1,9 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="Jka-P1-QHB">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19455" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="Jka-P1-QHB">
|
||||||
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
|
<deployment identifier="iOS"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19454"/>
|
||||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
@ -36,10 +37,11 @@
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="nek-0G-qOK">
|
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="nek-0G-qOK">
|
||||||
<rect key="frame" x="66" y="64" width="243" height="32"/>
|
<rect key="frame" x="5" y="64" width="365" height="32"/>
|
||||||
<segments>
|
<segments>
|
||||||
<segment title="Save This Story"/>
|
<segment title="Save This Story"/>
|
||||||
<segment title="Share This Story"/>
|
<segment title="Share This Story"/>
|
||||||
|
<segment title="Add This Site"/>
|
||||||
</segments>
|
</segments>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="changedMode:" destination="j1y-V4-xli" eventType="valueChanged" id="UPm-xD-bxX"/>
|
<action selector="changedMode:" destination="j1y-V4-xli" eventType="valueChanged" id="UPm-xD-bxX"/>
|
||||||
|
@ -52,7 +54,7 @@
|
||||||
<viewLayoutGuide key="frameLayoutGuide" id="PCs-SD-lDm"/>
|
<viewLayoutGuide key="frameLayoutGuide" id="PCs-SD-lDm"/>
|
||||||
<prototypes>
|
<prototypes>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="ShareSaveTagCell" id="QfW-wS-4rz" customClass="ShareSaveTagCell" customModule="Share_Extension" customModuleProvider="target">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="ShareSaveTagCell" id="QfW-wS-4rz" customClass="ShareSaveTagCell" customModule="Share_Extension" customModuleProvider="target">
|
||||||
<rect key="frame" x="0.0" y="24.5" width="375" height="43.5"/>
|
<rect key="frame" x="0.0" y="44.5" width="375" height="43.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="QfW-wS-4rz" id="FUw-X2-Tgd">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="QfW-wS-4rz" id="FUw-X2-Tgd">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
|
||||||
|
@ -76,14 +78,14 @@
|
||||||
</connections>
|
</connections>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="ShareSaveNewCell" id="efQ-d6-znU" customClass="ShareSaveNewCell" customModule="Share_Extension" customModuleProvider="target">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="ShareSaveNewCell" id="efQ-d6-znU" customClass="ShareSaveNewCell" customModule="Share_Extension" customModuleProvider="target">
|
||||||
<rect key="frame" x="0.0" y="68" width="375" height="43.5"/>
|
<rect key="frame" x="0.0" y="88" width="375" height="43.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="efQ-d6-znU" id="74T-Fj-bga">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="efQ-d6-znU" id="74T-Fj-bga">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="new tag" textAlignment="natural" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="qAx-nx-hOD">
|
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="new tag" textAlignment="natural" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="qAx-nx-hOD">
|
||||||
<rect key="frame" x="20" y="11" width="335" height="22"/>
|
<rect key="frame" x="20" y="11.5" width="335" height="21"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<textInputTraits key="textInputTraits" autocapitalizationType="words"/>
|
<textInputTraits key="textInputTraits" autocapitalizationType="words"/>
|
||||||
<connections>
|
<connections>
|
||||||
|
@ -105,7 +107,7 @@
|
||||||
</connections>
|
</connections>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="ShareCommentCell" rowHeight="252" id="Y1T-la-hCi" customClass="ShareCommentCell" customModule="Share_Extension" customModuleProvider="target">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="ShareCommentCell" rowHeight="252" id="Y1T-la-hCi" customClass="ShareCommentCell" customModule="Share_Extension" customModuleProvider="target">
|
||||||
<rect key="frame" x="0.0" y="111.5" width="375" height="252"/>
|
<rect key="frame" x="0.0" y="131.5" width="375" height="252"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Y1T-la-hCi" id="F3X-7c-ujj">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Y1T-la-hCi" id="F3X-7c-ujj">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="252"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="252"/>
|
||||||
|
|
|
@ -28,9 +28,12 @@ class ShareViewController: UIViewController {
|
||||||
|
|
||||||
/// Share publicly.
|
/// Share publicly.
|
||||||
case share
|
case share
|
||||||
|
|
||||||
|
/// Add site.
|
||||||
|
case add
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether we are saving the story privately or sharing publicly.
|
/// Whether we are saving the story privately, sharing publicly, or adding a site.
|
||||||
var mode: Mode = .save
|
var mode: Mode = .save
|
||||||
|
|
||||||
/// Dictionary representation of a tag.
|
/// Dictionary representation of a tag.
|
||||||
|
@ -60,6 +63,15 @@ class ShareViewController: UIViewController {
|
||||||
/// User-entered comments, only used when sharing.
|
/// User-entered comments, only used when sharing.
|
||||||
var comments = ""
|
var comments = ""
|
||||||
|
|
||||||
|
/// An array of folders, from the main app.
|
||||||
|
var folders = [String]()
|
||||||
|
|
||||||
|
/// New folder name, only used when adding.
|
||||||
|
var newFolder = ""
|
||||||
|
|
||||||
|
/// Index path of the selected folder.
|
||||||
|
var selectedFolderIndexPath = IndexPath(item: 0, section: 0)
|
||||||
|
|
||||||
/// Title of the item being shared.
|
/// Title of the item being shared.
|
||||||
var itemTitle: String? = nil
|
var itemTitle: String? = nil
|
||||||
|
|
||||||
|
@ -83,6 +95,12 @@ class ShareViewController: UIViewController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let foldersArray = prefs.object(forKey: "share:folders") as? [String] {
|
||||||
|
folders = foldersArray
|
||||||
|
|
||||||
|
folders.removeAll { ["river_global", "river_blurblogs", "infrequent", "read_stories", "saved_searches", "saved_stories"].contains($0) }
|
||||||
|
}
|
||||||
|
|
||||||
updateSaveButtonState()
|
updateSaveButtonState()
|
||||||
|
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidShow(notification:)), name: UIResponder.keyboardDidShowNotification, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidShow(notification:)), name: UIResponder.keyboardDidShowNotification, object: nil)
|
||||||
|
@ -90,13 +108,14 @@ class ShareViewController: UIViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateSaveButtonState() {
|
func updateSaveButtonState() {
|
||||||
if mode == .save {
|
switch mode {
|
||||||
|
case .save:
|
||||||
if let rows = tableView.indexPathsForSelectedRows {
|
if let rows = tableView.indexPathsForSelectedRows {
|
||||||
navigationItem.rightBarButtonItem?.isEnabled = !rows.isEmpty
|
navigationItem.rightBarButtonItem?.isEnabled = !rows.isEmpty
|
||||||
} else {
|
} else {
|
||||||
navigationItem.rightBarButtonItem?.isEnabled = false
|
navigationItem.rightBarButtonItem?.isEnabled = false
|
||||||
}
|
}
|
||||||
} else {
|
default:
|
||||||
navigationItem.rightBarButtonItem?.isEnabled = true
|
navigationItem.rightBarButtonItem?.isEnabled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,6 +131,7 @@ class ShareViewController: UIViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func newTagFieldChanged(_ sender: UITextField) {
|
@IBAction func newTagFieldChanged(_ sender: UITextField) {
|
||||||
|
if mode == .save {
|
||||||
newTag = sender.text ?? ""
|
newTag = sender.text ?? ""
|
||||||
|
|
||||||
if newTag.isEmpty {
|
if newTag.isEmpty {
|
||||||
|
@ -119,6 +139,9 @@ class ShareViewController: UIViewController {
|
||||||
} else {
|
} else {
|
||||||
tableView.selectRow(at: indexPathForNewTag, animated: false, scrollPosition: .none)
|
tableView.selectRow(at: indexPathForNewTag, animated: false, scrollPosition: .none)
|
||||||
}
|
}
|
||||||
|
} else if mode == .add {
|
||||||
|
newFolder = sender.text ?? ""
|
||||||
|
}
|
||||||
|
|
||||||
updateSaveButtonState()
|
updateSaveButtonState()
|
||||||
}
|
}
|
||||||
|
@ -154,9 +177,17 @@ class ShareViewController: UIViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func changedMode(_ sender: Any) {
|
@IBAction func changedMode(_ sender: Any) {
|
||||||
mode = modeSegmentedControl.selectedSegmentIndex == 0 ? .save : .share
|
switch modeSegmentedControl.selectedSegmentIndex {
|
||||||
|
case 1:
|
||||||
navigationItem.rightBarButtonItem?.title = mode == .save ? "Save" : "Share"
|
mode = .share
|
||||||
|
navigationItem.rightBarButtonItem?.title = "Share"
|
||||||
|
case 2:
|
||||||
|
mode = .add
|
||||||
|
navigationItem.rightBarButtonItem?.title = "Add"
|
||||||
|
default:
|
||||||
|
mode = .save
|
||||||
|
navigationItem.rightBarButtonItem?.title = "Save"
|
||||||
|
}
|
||||||
|
|
||||||
tableView.isEditing = mode == .save
|
tableView.isEditing = mode == .save
|
||||||
tableView.reloadData()
|
tableView.reloadData()
|
||||||
|
@ -231,20 +262,26 @@ private extension ShareViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
var requestPath: String {
|
var requestPath: String {
|
||||||
return mode == .save ? "api/save_story" : "api/share_story"
|
switch mode {
|
||||||
|
case .share:
|
||||||
|
return "api/share_story"
|
||||||
|
case .save:
|
||||||
|
return "api/save_story"
|
||||||
|
case .add:
|
||||||
|
return "reader/add_url"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func encoded(_ string: String?) -> String {
|
func encoded(_ string: String?) -> String {
|
||||||
return string?.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) ?? ""
|
return string?.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) ?? ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func postBody(url: URL?, text: String?) -> String {
|
func postSave(url: URL?, text: String?) -> String {
|
||||||
let title = itemTitle
|
let title = itemTitle
|
||||||
let encodedURL = encoded(url?.absoluteString)
|
let encodedURL = encoded(url?.absoluteString)
|
||||||
let encodedTitle = encoded(title)
|
let encodedTitle = encoded(title)
|
||||||
let encodedContent = encoded(text)
|
let encodedContent = encoded(text)
|
||||||
|
|
||||||
if mode == .save {
|
|
||||||
let indexPaths = tableView.indexPathsForSelectedRows ?? []
|
let indexPaths = tableView.indexPathsForSelectedRows ?? []
|
||||||
var selectedTagsArray = [String]()
|
var selectedTagsArray = [String]()
|
||||||
|
|
||||||
|
@ -260,7 +297,14 @@ private extension ShareViewController {
|
||||||
let postBody = "story_url=\(encodedURL)&title=\(encodedTitle)&content=\(encodedContent)&user_tags=\(selectedTags)&add_user_tag=\(encodedNewTag)"
|
let postBody = "story_url=\(encodedURL)&title=\(encodedTitle)&content=\(encodedContent)&user_tags=\(selectedTags)&add_user_tag=\(encodedNewTag)"
|
||||||
|
|
||||||
return postBody
|
return postBody
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
func postShare(url: URL?, text: String?) -> String {
|
||||||
|
let title = itemTitle
|
||||||
|
let encodedURL = encoded(url?.absoluteString)
|
||||||
|
let encodedTitle = encoded(title)
|
||||||
|
let encodedContent = encoded(text)
|
||||||
|
|
||||||
var comments = comments
|
var comments = comments
|
||||||
|
|
||||||
// Don't really need this stuff if I don't populate the comments from the title or text; leave for now just in case that is wanted.
|
// Don't really need this stuff if I don't populate the comments from the title or text; leave for now just in case that is wanted.
|
||||||
|
@ -278,6 +322,30 @@ private extension ShareViewController {
|
||||||
|
|
||||||
return postBody
|
return postBody
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func postAdd(url: URL?, text: String?) -> String {
|
||||||
|
let folder = folders[selectedFolderIndexPath.row]
|
||||||
|
let encodedFolder = encoded(folder)
|
||||||
|
let encodedURL = encoded(url?.absoluteString)
|
||||||
|
|
||||||
|
var postBody = "folder=\(encodedFolder)&url=\(encodedURL)"
|
||||||
|
|
||||||
|
if newFolder != "" {
|
||||||
|
postBody += "&new_folder=\(encoded(newFolder))"
|
||||||
|
}
|
||||||
|
|
||||||
|
return postBody
|
||||||
|
}
|
||||||
|
|
||||||
|
func postBody(url: URL?, text: String?) -> String {
|
||||||
|
switch mode {
|
||||||
|
case .save:
|
||||||
|
return postSave(url: url, text: text)
|
||||||
|
case .share:
|
||||||
|
return postShare(url: url, text: text)
|
||||||
|
case .add:
|
||||||
|
return postAdd(url: url, text: text)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,11 @@ class ShareViewDelegate: NSObject {
|
||||||
|
|
||||||
extension ShareViewDelegate: UITableViewDelegate {
|
extension ShareViewDelegate: UITableViewDelegate {
|
||||||
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||||
|
if viewController.mode == .add, indexPath.section == 0 {
|
||||||
|
viewController.selectedFolderIndexPath = indexPath
|
||||||
|
tableView.reloadData()
|
||||||
|
}
|
||||||
|
|
||||||
viewController.updateSaveButtonState()
|
viewController.updateSaveButtonState()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,14 +28,37 @@ extension ShareViewDelegate: UITableViewDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ShareViewDelegate: UITableViewDataSource {
|
extension ShareViewDelegate: UITableViewDataSource {
|
||||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
func numberOfSections(in tableView: UITableView) -> Int {
|
||||||
if viewController.mode == .save {
|
if viewController.mode == .add {
|
||||||
return viewController.tags.count + 1
|
return 2
|
||||||
} else {
|
} else {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
||||||
|
if viewController.mode == .add, section == 1 {
|
||||||
|
return "Add new sub-folder:"
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||||
|
switch viewController.mode {
|
||||||
|
case .save:
|
||||||
|
return viewController.tags.count + 1
|
||||||
|
case .share:
|
||||||
|
return 1
|
||||||
|
case .add:
|
||||||
|
if section == 0 {
|
||||||
|
return viewController.folders.count
|
||||||
|
} else {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||||
if viewController.mode == .save {
|
if viewController.mode == .save {
|
||||||
if indexPath.item < viewController.tags.count {
|
if indexPath.item < viewController.tags.count {
|
||||||
|
@ -47,6 +75,34 @@ extension ShareViewDelegate: UITableViewDataSource {
|
||||||
}
|
}
|
||||||
|
|
||||||
cell.tagField.text = ""
|
cell.tagField.text = ""
|
||||||
|
cell.tagField.placeholder = "new tag"
|
||||||
|
|
||||||
|
return cell
|
||||||
|
}
|
||||||
|
} else if viewController.mode == .add {
|
||||||
|
if indexPath.section == 0 {
|
||||||
|
guard let cell = tableView.dequeueReusableCell(withIdentifier: ShareSaveTagCell.reuseIdentifier, for: indexPath) as? ShareSaveTagCell else {
|
||||||
|
preconditionFailure("Expected to dequeue a ShareSaveTagCell")
|
||||||
|
}
|
||||||
|
|
||||||
|
let components = viewController.folders[indexPath.item].components(separatedBy: " ▸ ")
|
||||||
|
|
||||||
|
if components.first == "everything" {
|
||||||
|
cell.tagLabel.text = "🗃 Top Level"
|
||||||
|
} else {
|
||||||
|
cell.tagLabel.text = "\(String(repeating: " ", count: components.count))📁 \(components.last ?? "?")"
|
||||||
|
}
|
||||||
|
|
||||||
|
cell.accessoryType = indexPath == viewController.selectedFolderIndexPath ? .checkmark : .none
|
||||||
|
|
||||||
|
return cell
|
||||||
|
} else {
|
||||||
|
guard let cell = tableView.dequeueReusableCell(withIdentifier: ShareSaveNewCell.reuseIdentifier, for: indexPath) as? ShareSaveNewCell else {
|
||||||
|
preconditionFailure("Expected to dequeue a ShareSaveNewCell")
|
||||||
|
}
|
||||||
|
|
||||||
|
cell.tagField.text = viewController.newFolder
|
||||||
|
cell.tagField.placeholder = "new folder title"
|
||||||
|
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue