diff --git a/seafile/QuickSettingsPanel.h b/seafile/QuickSettingsPanel.h new file mode 100644 index 00000000..16db9a10 --- /dev/null +++ b/seafile/QuickSettingsPanel.h @@ -0,0 +1,17 @@ +// +// SettingsBlock.h +// SettingsAnimation +// +// Created by Max on 30/09/2017. +// Copyright © 2017 34x. All rights reserved. +// + +#import + +FOUNDATION_EXPORT NSString* const QuickSettingsFontSizeIncrement; +FOUNDATION_EXPORT NSString* const QuickSettingsFontSizeDecrement; + +@interface QuickSettingsPanel : UIView +@property(nonatomic, copy) void(^actionHandler)(NSString* actionKey, NSDictionary* userInfo); +- (void)setOpen:(BOOL)isOpen animate:(BOOL)animate; +@end diff --git a/seafile/QuickSettingsPanel.m b/seafile/QuickSettingsPanel.m new file mode 100644 index 00000000..90ff1164 --- /dev/null +++ b/seafile/QuickSettingsPanel.m @@ -0,0 +1,214 @@ +// +// SettingsBlock.m +// SettingsAnimation +// +// Created by Max on 30/09/2017. +// Copyright © 2017 34x. All rights reserved. +// + +#import "QuickSettingsPanel.h" + +NSString* const QuickSettingsFontSizeIncrement = @"QuickSettingsFontSizeIncrement"; +NSString* const QuickSettingsFontSizeDecrement = @"QuickSettingsFontSizeDecrement";; + +@interface QuickSettingsPanel() +@property (nonatomic) UIView* settingsBlock; +@property (nonatomic) UIButton* settingsToggle; +@property (nonatomic) CGSize elementSize; +@property (nonatomic) CGSize panelSize; +@property (nonatomic) UIButton* fontSizeIncrementButton; +@property (nonatomic) UIButton* fontSizeDecrementButton; +@property (nonatomic, readonly) BOOL isOpen; +@end + +@implementation QuickSettingsPanel + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + self = [super initWithCoder:aDecoder]; + if (self) { + [self configureView]; + } + return self; +} + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + [self configureView]; + } + return self; +} + +- (void)layoutSubviews { + // Moving settings overlay to the right bottom corner + CGSize parentSize = self.superview.bounds.size; + CGFloat margin = self.elementSize.width * 0.25; + self.frame = CGRectMake(parentSize.width - self.panelSize.width - margin, + parentSize.height - self.panelSize.height - margin, + self.panelSize.width, self.panelSize.height); + + self.settingsBlock.center = CGPointMake(self.bounds.size.width, self.bounds.size.height); +} + +- (void)orientationChanged:(NSNotification*)notification { + [self layoutSubviews]; +} + +- (void)configureView { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil]; + + self.elementSize = CGSizeMake(52.0, 52.0); + self.panelSize = CGSizeMake(self.elementSize.width * 3, self.elementSize.height); + + UIView* settingsBlock = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.panelSize.width, self.panelSize.height)]; + settingsBlock.layer.anchorPoint = CGPointMake(1.0, 1.0); + + + settingsBlock.backgroundColor = [[UIColor orangeColor] colorWithAlphaComponent:0.9]; + settingsBlock.layer.cornerRadius = self.elementSize.height / 8.0; + + UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(toggle:)]; + [settingsBlock addGestureRecognizer:tap]; + + self.settingsBlock = settingsBlock; + + CGFloat x = settingsBlock.bounds.size.width; + + UIButton *settings = [[UIButton alloc] initWithFrame:CGRectMake(0.0, 0, self.elementSize.width, self.elementSize.height)]; + [settings setTitle:@"→" forState:UIControlStateNormal]; + settings.titleLabel.font = [UIFont systemFontOfSize: self.elementSize.height * 0.8]; + [settings addTarget:self action:@selector(toggle:) forControlEvents:UIControlEventTouchUpInside]; + settings.alpha = 0.8; + self.settingsToggle = settings; + [self.settingsBlock addSubview:settings]; + + UIView *separator = [[UIView alloc] initWithFrame:CGRectMake(self.elementSize.width, 0, 2.0, self.elementSize.height)]; + separator.backgroundColor = [[UIColor whiteColor]colorWithAlphaComponent:0.4]; + [self.settingsBlock addSubview:separator]; + + x = x - self.elementSize.width; + + self.fontSizeIncrementButton = [[UIButton alloc] initWithFrame:CGRectMake(x, 0, self.elementSize.width, self.elementSize.height)]; + + [self.fontSizeIncrementButton setTitle:@"A" forState:UIControlStateNormal]; + self.fontSizeIncrementButton.titleLabel.font = [UIFont systemFontOfSize: self.elementSize.height * 0.8]; + [self.fontSizeIncrementButton addTarget:self action:@selector(settingsDidChange:) forControlEvents:UIControlEventTouchUpInside]; + [self.settingsBlock addSubview:self.fontSizeIncrementButton]; + + x = x - self.elementSize.width; + + self.fontSizeDecrementButton = [[UIButton alloc] initWithFrame:CGRectMake(x, 0, self.elementSize.width, self.elementSize.height)]; + [self.fontSizeDecrementButton setTitle:@"A" forState:UIControlStateNormal]; + self.fontSizeDecrementButton.titleLabel.font = [UIFont systemFontOfSize:self.elementSize.height / 2.0]; + [self.fontSizeDecrementButton addTarget:self action:@selector(settingsDidChange:) forControlEvents:UIControlEventTouchUpInside]; + [self.settingsBlock addSubview:self.fontSizeDecrementButton]; + + [self addSubview:settingsBlock]; + + [self toggleAnimate:NO]; +} + +- (void)settingsDidChange:(id)element { + NSString* key; + + if (element == self.fontSizeIncrementButton) { + key = QuickSettingsFontSizeIncrement; + } else if (element == self.fontSizeDecrementButton) { + key = QuickSettingsFontSizeDecrement; + } + + if (key && self.actionHandler) { + self.actionHandler(key, nil); + } +} + +- (void)toggle:(id)button { + [self toggleAnimate:YES]; +} + +- (void)toggleAnimate:(BOOL)animate { + CGFloat targetWidth = 0; + CGFloat rotateFrom = 0.0; + CGFloat rotateTo = 0.0; + CGFloat scaleFrom = 1.0; + CGFloat scaleTo = 0.0; + CGFloat alphaFrom = 0.0; + CGFloat alphaTo = 0.0; + + // going to close + if (self.isOpen) { + targetWidth = self.elementSize.width; + rotateFrom = 0; + rotateTo = M_PI; + scaleTo = 0.5; + alphaFrom = 1.0; + alphaTo = 0.4; + // going to open + } else { + targetWidth = self.panelSize.width; + rotateFrom = M_PI; + rotateTo = 0; + scaleTo = 1.0; + scaleFrom = 0.5; + alphaFrom = 0.4; + alphaTo = 1.0; + } + + CGRect bounds = self.settingsBlock.bounds; + NSTimeInterval commonDuration = 0.4; + + CABasicAnimation* toggleRotate = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; + toggleRotate.fromValue = @(rotateFrom); + toggleRotate.toValue = @(rotateTo); + toggleRotate.fillMode = kCAFillModeBackwards; + toggleRotate.duration = commonDuration; + CGAffineTransform zero = CGAffineTransformMakeRotation(0); + + self.settingsToggle.transform = CGAffineTransformRotate(zero, rotateTo); + + CABasicAnimation* commonWidth = [CABasicAnimation animationWithKeyPath:@"bounds.size.width"]; + commonWidth.fromValue = @(bounds.size.width); + commonWidth.toValue = @(targetWidth); + commonWidth.duration = commonDuration; + + CABasicAnimation* commonScale = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; + commonScale.fromValue = @(scaleFrom); + commonScale.toValue = @(scaleTo); + commonScale.duration = commonDuration; + commonScale.fillMode = kCAFillModeBackwards; + + CABasicAnimation* commonAlpha = [CABasicAnimation animationWithKeyPath:@"opacity"]; + commonAlpha.fromValue = @(alphaFrom); + commonAlpha.toValue = @(alphaTo); + commonAlpha.duration = commonDuration; + + if (animate) { + [self.settingsToggle.layer addAnimation:toggleRotate forKey:nil]; + [self.settingsBlock.layer addAnimation:commonWidth forKey:nil]; + [self.settingsBlock.layer addAnimation:commonScale forKey:nil]; + [self.settingsBlock.layer addAnimation:commonAlpha forKey:nil]; + } + + self.settingsBlock.bounds = CGRectMake(0, 0, targetWidth, bounds.size.height); + CGAffineTransform zeroScale = CGAffineTransformMakeScale(1.0, 1.0); + self.settingsBlock.transform = CGAffineTransformScale(zeroScale, scaleTo, scaleTo); + self.settingsBlock.alpha = alphaTo; +} + +- (BOOL)isOpen { + return self.settingsBlock.bounds.size.width > self.elementSize.width; +} + +- (void)setOpen:(BOOL)isOpen animate:(BOOL)animate { + // if it's already the same do nothing + if (self.isOpen == isOpen) { + return; + } + + [self toggleAnimate:animate]; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} +@end diff --git a/seafile/SeafDetailViewController.m b/seafile/SeafDetailViewController.m index 508411be..ec04a873 100644 --- a/seafile/SeafDetailViewController.m +++ b/seafile/SeafDetailViewController.m @@ -21,7 +21,7 @@ #import "UIViewController+Extend.h" #import "ExtentedString.h" #import "Debug.h" - +#import "QuickSettingsPanel.h" enum SHARE_STATUS { @@ -29,6 +29,8 @@ SHARE_BY_LINK = 1 }; +NSString* const DetailPreviewFontSizeKey = @"DetailPreviewFontSizeKey"; + #define PADDING 10 #define ACTION_SHEET_OLD_ACTIONS 2000 @@ -58,6 +60,8 @@ @interface SeafDetailViewController () minimumFontSize && previewFontSize < maximumFontSize) { + [[self getUserDefaults] setObject:@(previewFontSize) forKey:DetailPreviewFontSizeKey]; + } +} + +- (void)applyPreviewFontSize { + if ([self canApplyPreviewFontSize]) { + NSString *newValue = [NSString stringWithFormat:@"%.0f%%", self.previewFontSize]; + NSString *jsCheck = [NSString stringWithFormat:@"document.body.style.fontSize;"]; + NSString *currentValue = [self.webView stringByEvaluatingJavaScriptFromString:jsCheck]; + NSString *js = [NSString stringWithFormat:@"document.body.style.fontSize = '%@';", newValue]; + if (![newValue isEqualToString:currentValue]) { + [self.webView stringByEvaluatingJavaScriptFromString:js]; + } + } +} + +- (BOOL)canApplyPreviewFontSize { + return [self.preViewItem.mime isEqualToString:@"text/plain"]; +} + +#pragma mark KVO +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { + if ([keyPath isEqualToString:DetailPreviewFontSizeKey]) { + [self applyPreviewFontSize]; + } +} + @end diff --git a/seafilePro.xcodeproj/project.pbxproj b/seafilePro.xcodeproj/project.pbxproj index 8642c7e4..e5e030de 100644 --- a/seafilePro.xcodeproj/project.pbxproj +++ b/seafilePro.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 10CC62C9699DE05CBA3647E4 /* libPods-seafile-appstore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E2A39A0EBB6C3379F30D1A83 /* libPods-seafile-appstore.a */; }; 11FAE5D19696AF534A19C252 /* libPods-SeafProvider.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 08E34A4BEBB32AD5D2CB9442 /* libPods-SeafProvider.a */; }; + 50098B991F802E8A0072941D /* QuickSettingsPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = 50098B971F802E8A0072941D /* QuickSettingsPanel.m */; }; 5704C6D31753A1380028F4FE /* IntelligentSplitViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5704C6D11753A1380028F4FE /* IntelligentSplitViewController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 5704C6F91756710F0028F4FE /* tab-account.png in Resources */ = {isa = PBXBuildFile; fileRef = 5704C6F51756710F0028F4FE /* tab-account.png */; }; 5704C6FB1756710F0028F4FE /* tab-modify.png in Resources */ = {isa = PBXBuildFile; fileRef = 5704C6F61756710F0028F4FE /* tab-modify.png */; }; @@ -256,6 +257,8 @@ 159E0D2A7419F67E532A240F /* libPods-SeafAction.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-SeafAction.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 2979DE872836DD67FEA29262 /* Pods-SeafProviderFileProvider.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SeafProviderFileProvider.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SeafProviderFileProvider/Pods-SeafProviderFileProvider.debug.xcconfig"; sourceTree = ""; }; 3DFD7A698B44546A8DDD2D26 /* libPods-SeafProviderFileProvider.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-SeafProviderFileProvider.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 50098B971F802E8A0072941D /* QuickSettingsPanel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QuickSettingsPanel.m; sourceTree = ""; }; + 50098B981F802E8A0072941D /* QuickSettingsPanel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QuickSettingsPanel.h; sourceTree = ""; }; 5704C6D01753A1380028F4FE /* IntelligentSplitViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntelligentSplitViewController.h; sourceTree = ""; }; 5704C6D11753A1380028F4FE /* IntelligentSplitViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IntelligentSplitViewController.m; sourceTree = ""; }; 5704C6F51756710F0028F4FE /* tab-account.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tab-account.png"; sourceTree = ""; }; @@ -555,6 +558,8 @@ 5704C6CF1753A07E0028F4FE /* thirdpart */ = { isa = PBXGroup; children = ( + 50098B981F802E8A0072941D /* QuickSettingsPanel.h */, + 50098B971F802E8A0072941D /* QuickSettingsPanel.m */, 5704C6D01753A1380028F4FE /* IntelligentSplitViewController.h */, 5704C6D11753A1380028F4FE /* IntelligentSplitViewController.m */, ); @@ -1444,6 +1449,7 @@ 5704C6D31753A1380028F4FE /* IntelligentSplitViewController.m in Sources */, 57F476EC1C00623300047395 /* SeafPhotoThumb.m in Sources */, 576C91C4177EB43F007B50BD /* SeafDirViewController.m in Sources */, + 50098B991F802E8A0072941D /* QuickSettingsPanel.m in Sources */, 58D40A7E1E9AF86D00A68BEF /* SeafData.m in Sources */, 58D40A691E9AF72200A68BEF /* SeafGlobal.m in Sources */, );