From 188d8e4ea870d1a6c8edd5a9b323742804badeba Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Sun, 28 Aug 2016 21:03:22 +0300 Subject: project cleanup --- Juick.xcodeproj/project.pbxproj | 126 ++++++++------ Juick/AppDelegate.m | 2 +- Juick/ColorScheme.h | 17 -- Juick/ColorScheme.m | 37 ----- Juick/Helpers/ColorScheme.h | 17 ++ Juick/Helpers/ColorScheme.m | 37 +++++ Juick/Helpers/NSURL+PathParameters.h | 37 +++++ Juick/Helpers/NSURL+PathParameters.m | 173 ++++++++++++++++++++ Juick/Helpers/UIImage+Utils.h | 19 +++ Juick/Helpers/UIImage+Utils.m | 69 ++++++++ Juick/Juick-Info.plist | 62 ------- Juick/Juick-Prefix.pch | 25 --- Juick/LoginViewController.h | 15 -- Juick/LoginViewController.m | 92 ----------- Juick/Message.h | 29 ---- Juick/Message.m | 52 ------ Juick/MessagesViewController.h | 15 -- Juick/MessagesViewController.m | 181 -------------------- Juick/Model/Message.h | 29 ++++ Juick/Model/Message.m | 52 ++++++ Juick/Model/User.h | 27 +++ Juick/Model/User.m | 49 ++++++ Juick/NSURL+PathParameters.h | 37 ----- Juick/NSURL+PathParameters.m | 173 -------------------- Juick/NewPostViewController.h | 13 -- Juick/NewPostViewController.m | 61 ------- Juick/RevealPanelViewController.h | 16 -- Juick/RevealPanelViewController.m | 182 --------------------- Juick/Supporting Files/Juick-Info.plist | 62 +++++++ Juick/Supporting Files/Juick-Prefix.pch | 25 +++ Juick/Supporting Files/en.lproj/InfoPlist.strings | 2 + Juick/Supporting Files/main.m | 18 ++ Juick/UIImage+Utils.h | 19 --- Juick/UIImage+Utils.m | 69 -------- Juick/User.h | 27 --- Juick/User.m | 49 ------ Juick/ViewControllers/LoginViewController.h | 15 ++ Juick/ViewControllers/LoginViewController.m | 92 +++++++++++ Juick/ViewControllers/MessagesViewController.h | 15 ++ Juick/ViewControllers/MessagesViewController.m | 181 ++++++++++++++++++++ Juick/ViewControllers/NewPostViewController.h | 13 ++ Juick/ViewControllers/NewPostViewController.m | 61 +++++++ Juick/ViewControllers/RevealPanelViewController.h | 16 ++ Juick/ViewControllers/RevealPanelViewController.m | 182 +++++++++++++++++++++ Juick/en.lproj/InfoPlist.strings | 2 - Juick/main.m | 18 -- JuickTests/JuickTests-Info.plist | 22 --- JuickTests/Supporting Files/JuickTests-Info.plist | 22 +++ .../Supporting Files/en.lproj/InfoPlist.strings | 2 + JuickTests/en.lproj/InfoPlist.strings | 2 - 50 files changed, 1292 insertions(+), 1266 deletions(-) delete mode 100644 Juick/ColorScheme.h delete mode 100644 Juick/ColorScheme.m create mode 100644 Juick/Helpers/ColorScheme.h create mode 100644 Juick/Helpers/ColorScheme.m create mode 100644 Juick/Helpers/NSURL+PathParameters.h create mode 100644 Juick/Helpers/NSURL+PathParameters.m create mode 100644 Juick/Helpers/UIImage+Utils.h create mode 100644 Juick/Helpers/UIImage+Utils.m delete mode 100644 Juick/Juick-Info.plist delete mode 100644 Juick/Juick-Prefix.pch delete mode 100644 Juick/LoginViewController.h delete mode 100644 Juick/LoginViewController.m delete mode 100644 Juick/Message.h delete mode 100644 Juick/Message.m delete mode 100644 Juick/MessagesViewController.h delete mode 100644 Juick/MessagesViewController.m create mode 100644 Juick/Model/Message.h create mode 100644 Juick/Model/Message.m create mode 100644 Juick/Model/User.h create mode 100644 Juick/Model/User.m delete mode 100644 Juick/NSURL+PathParameters.h delete mode 100644 Juick/NSURL+PathParameters.m delete mode 100644 Juick/NewPostViewController.h delete mode 100644 Juick/NewPostViewController.m delete mode 100644 Juick/RevealPanelViewController.h delete mode 100644 Juick/RevealPanelViewController.m create mode 100644 Juick/Supporting Files/Juick-Info.plist create mode 100644 Juick/Supporting Files/Juick-Prefix.pch create mode 100644 Juick/Supporting Files/en.lproj/InfoPlist.strings create mode 100644 Juick/Supporting Files/main.m delete mode 100644 Juick/UIImage+Utils.h delete mode 100644 Juick/UIImage+Utils.m delete mode 100644 Juick/User.h delete mode 100644 Juick/User.m create mode 100644 Juick/ViewControllers/LoginViewController.h create mode 100644 Juick/ViewControllers/LoginViewController.m create mode 100644 Juick/ViewControllers/MessagesViewController.h create mode 100644 Juick/ViewControllers/MessagesViewController.m create mode 100644 Juick/ViewControllers/NewPostViewController.h create mode 100644 Juick/ViewControllers/NewPostViewController.m create mode 100644 Juick/ViewControllers/RevealPanelViewController.h create mode 100644 Juick/ViewControllers/RevealPanelViewController.m delete mode 100644 Juick/en.lproj/InfoPlist.strings delete mode 100644 Juick/main.m delete mode 100644 JuickTests/JuickTests-Info.plist create mode 100644 JuickTests/Supporting Files/JuickTests-Info.plist create mode 100644 JuickTests/Supporting Files/en.lproj/InfoPlist.strings delete mode 100644 JuickTests/en.lproj/InfoPlist.strings diff --git a/Juick.xcodeproj/project.pbxproj b/Juick.xcodeproj/project.pbxproj index fff0dfb..b68ad14 100644 --- a/Juick.xcodeproj/project.pbxproj +++ b/Juick.xcodeproj/project.pbxproj @@ -111,12 +111,12 @@ 77E35A81189A5B5A00B2D216 /* LoginViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LoginViewController.m; sourceTree = ""; }; 77FCADDE1D6A50DA00CBA649 /* APIClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = APIClient.m; sourceTree = ""; }; 77FCADE01D6A50EC00CBA649 /* APIClient.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = APIClient.h; sourceTree = ""; }; - 77FFC0161D5FD186003BD81A /* MessageCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MessageCell.h; path = Views/MessageCell.h; sourceTree = ""; }; - 77FFC0171D5FD186003BD81A /* MessageCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MessageCell.m; path = Views/MessageCell.m; sourceTree = ""; }; - 77FFC0181D5FD186003BD81A /* MessageCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = MessageCell.xib; path = Views/MessageCell.xib; sourceTree = ""; }; - 77FFC01B1D5FE7CE003BD81A /* NavCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NavCell.h; path = Views/NavCell.h; sourceTree = ""; }; - 77FFC01C1D5FE7CE003BD81A /* NavCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NavCell.m; path = Views/NavCell.m; sourceTree = ""; }; - 77FFC01D1D5FE7CE003BD81A /* NavCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = NavCell.xib; path = Views/NavCell.xib; sourceTree = ""; }; + 77FFC0161D5FD186003BD81A /* MessageCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageCell.h; sourceTree = ""; }; + 77FFC0171D5FD186003BD81A /* MessageCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MessageCell.m; sourceTree = ""; }; + 77FFC0181D5FD186003BD81A /* MessageCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MessageCell.xib; sourceTree = ""; }; + 77FFC01B1D5FE7CE003BD81A /* NavCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NavCell.h; sourceTree = ""; }; + 77FFC01C1D5FE7CE003BD81A /* NavCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NavCell.m; sourceTree = ""; }; + 77FFC01D1D5FE7CE003BD81A /* NavCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NavCell.xib; sourceTree = ""; }; 8F93DB342C85111DFBC86143 /* Pods-Juick.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Juick.release.xcconfig"; path = "Pods/Target Support Files/Pods-Juick/Pods-Juick.release.xcconfig"; sourceTree = ""; }; D5F79ADD6611E9C3C0D56671 /* Pods-JuickTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JuickTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-JuickTests/Pods-JuickTests.debug.xcconfig"; sourceTree = ""; }; F3C23ADDEF1C47900AA28093 /* Pods-Juick.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Juick.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Juick/Pods-Juick.debug.xcconfig"; sourceTree = ""; }; @@ -166,12 +166,12 @@ 77317B9F181BBE8500D60005 = { isa = PBXGroup; children = ( - 7738FEC41D36CE6D008B5CD0 /* Launch Screen.storyboard */, + 77317BAA181BBE8500D60005 /* Frameworks */, 77317BB1181BBE8500D60005 /* Juick */, 77317BD3181BBE8500D60005 /* JuickTests */, - 77317BAA181BBE8500D60005 /* Frameworks */, - 77317BA9181BBE8500D60005 /* Products */, 478C26C1EEFED1F89B8F65E7 /* Pods */, + 77317BA9181BBE8500D60005 /* Products */, + 7738FEC41D36CE6D008B5CD0 /* Launch Screen.storyboard */, ); sourceTree = ""; }; @@ -204,38 +204,23 @@ 77317BB1181BBE8500D60005 /* Juick */ = { isa = PBXGroup; children = ( + 774DD4601D735E1D00C7F290 /* Helpers */, + 774DD45D1D735DDD00C7F290 /* Model */, + 77317BB2181BBE8500D60005 /* Supporting Files */, + 774DD45F1D735E0300C7F290 /* ViewControllers */, 77FFC0151D5FD13C003BD81A /* Views */, 77A5BDAF189AEB28000F8D9E /* 0.png */, - 77418CC0182FBABB004111B7 /* iTunesArtwork@2x */, + 77FCADE01D6A50EC00CBA649 /* APIClient.h */, + 77FCADDE1D6A50DA00CBA649 /* APIClient.m */, + 77317BBA181BBE8500D60005 /* AppDelegate.h */, + 77317BBB181BBE8500D60005 /* AppDelegate.m */, 77418CBA182F9A78004111B7 /* AttachPlaceholder@2x.png */, - 77418CBE182FBAB5004111B7 /* iTunesArtwork */, + 77317BC6181BBE8500D60005 /* Images.xcassets */, 77C67EE918283C8D00427098 /* buttons.png */, - 77C67EE31828342000427098 /* NSURL+PathParameters.h */, - 77C67EE41828342000427098 /* NSURL+PathParameters.m */, + 77418CBE182FBAB5004111B7 /* iTunesArtwork */, + 77418CC0182FBABB004111B7 /* iTunesArtwork@2x */, 77C67EDC182827DB00427098 /* reveal-icon.png */, 77C67EDD182827DB00427098 /* reveal-icon@2x.png */, - 77317BBA181BBE8500D60005 /* AppDelegate.h */, - 77317BBB181BBE8500D60005 /* AppDelegate.m */, - 77317BC0181BBE8500D60005 /* MessagesViewController.h */, - 77317BC1181BBE8500D60005 /* MessagesViewController.m */, - 77317BC6181BBE8500D60005 /* Images.xcassets */, - 77317BB2181BBE8500D60005 /* Supporting Files */, - 77A09548181F1F25002BDECD /* Message.h */, - 77A09549181F1F25002BDECD /* Message.m */, - 77C67EE01828288C00427098 /* RevealPanelViewController.h */, - 77C67EE11828288C00427098 /* RevealPanelViewController.m */, - 77C67EE61828379700427098 /* ColorScheme.h */, - 77C67EE71828379700427098 /* ColorScheme.m */, - 77975A1B182B6E9A00410C2B /* NewPostViewController.h */, - 77975A1C182B6E9A00410C2B /* NewPostViewController.m */, - 77E35A80189A5B5A00B2D216 /* LoginViewController.h */, - 77E35A81189A5B5A00B2D216 /* LoginViewController.m */, - 77B09992189D0B9900A84F59 /* UIImage+Utils.h */, - 77B09993189D0B9900A84F59 /* UIImage+Utils.m */, - 77B099A4189D57F000A84F59 /* User.h */, - 77B099A5189D57F000A84F59 /* User.m */, - 77FCADDE1D6A50DA00CBA649 /* APIClient.m */, - 77FCADE01D6A50EC00CBA649 /* APIClient.h */, ); path = Juick; sourceTree = ""; @@ -243,19 +228,19 @@ 77317BB2181BBE8500D60005 /* Supporting Files */ = { isa = PBXGroup; children = ( - 77317BB3181BBE8500D60005 /* Juick-Info.plist */, 77317BB4181BBE8500D60005 /* InfoPlist.strings */, - 77317BB7181BBE8500D60005 /* main.m */, + 77317BB3181BBE8500D60005 /* Juick-Info.plist */, 77317BB9181BBE8500D60005 /* Juick-Prefix.pch */, + 77317BB7181BBE8500D60005 /* main.m */, ); - name = "Supporting Files"; + path = "Supporting Files"; sourceTree = ""; }; 77317BD3181BBE8500D60005 /* JuickTests */ = { isa = PBXGroup; children = ( - 77317BD9181BBE8500D60005 /* JuickTests.m */, 77317BD4181BBE8500D60005 /* Supporting Files */, + 77317BD9181BBE8500D60005 /* JuickTests.m */, ); path = JuickTests; sourceTree = ""; @@ -263,10 +248,49 @@ 77317BD4181BBE8500D60005 /* Supporting Files */ = { isa = PBXGroup; children = ( - 77317BD5181BBE8500D60005 /* JuickTests-Info.plist */, 77317BD6181BBE8500D60005 /* InfoPlist.strings */, + 77317BD5181BBE8500D60005 /* JuickTests-Info.plist */, + ); + path = "Supporting Files"; + sourceTree = ""; + }; + 774DD45D1D735DDD00C7F290 /* Model */ = { + isa = PBXGroup; + children = ( + 77A09548181F1F25002BDECD /* Message.h */, + 77A09549181F1F25002BDECD /* Message.m */, + 77B099A4189D57F000A84F59 /* User.h */, + 77B099A5189D57F000A84F59 /* User.m */, + ); + path = Model; + sourceTree = ""; + }; + 774DD45F1D735E0300C7F290 /* ViewControllers */ = { + isa = PBXGroup; + children = ( + 77E35A80189A5B5A00B2D216 /* LoginViewController.h */, + 77E35A81189A5B5A00B2D216 /* LoginViewController.m */, + 77317BC0181BBE8500D60005 /* MessagesViewController.h */, + 77317BC1181BBE8500D60005 /* MessagesViewController.m */, + 77975A1B182B6E9A00410C2B /* NewPostViewController.h */, + 77975A1C182B6E9A00410C2B /* NewPostViewController.m */, + 77C67EE01828288C00427098 /* RevealPanelViewController.h */, + 77C67EE11828288C00427098 /* RevealPanelViewController.m */, + ); + path = ViewControllers; + sourceTree = ""; + }; + 774DD4601D735E1D00C7F290 /* Helpers */ = { + isa = PBXGroup; + children = ( + 77C67EE61828379700427098 /* ColorScheme.h */, + 77C67EE71828379700427098 /* ColorScheme.m */, + 77C67EE31828342000427098 /* NSURL+PathParameters.h */, + 77C67EE41828342000427098 /* NSURL+PathParameters.m */, + 77B09992189D0B9900A84F59 /* UIImage+Utils.h */, + 77B09993189D0B9900A84F59 /* UIImage+Utils.m */, ); - name = "Supporting Files"; + path = Helpers; sourceTree = ""; }; 77FFC0151D5FD13C003BD81A /* Views */ = { @@ -279,7 +303,7 @@ 77FFC01C1D5FE7CE003BD81A /* NavCell.m */, 77FFC01D1D5FE7CE003BD81A /* NavCell.xib */, ); - name = Views; + path = Views; sourceTree = ""; }; /* End PBXGroup section */ @@ -532,6 +556,7 @@ 77317BB5181BBE8500D60005 /* en */, ); name = InfoPlist.strings; + path = .; sourceTree = ""; }; 77317BD6181BBE8500D60005 /* InfoPlist.strings */ = { @@ -540,6 +565,7 @@ 77317BD7181BBE8500D60005 /* en */, ); name = InfoPlist.strings; + path = .; sourceTree = ""; }; /* End PBXVariantGroup section */ @@ -624,8 +650,8 @@ ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CODE_SIGN_IDENTITY = "iPhone Developer"; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "Juick/Juick-Prefix.pch"; - INFOPLIST_FILE = "Juick/Juick-Info.plist"; + GCC_PREFIX_HEADER = "Juick/Supporting Files/Juick-Prefix.pch"; + INFOPLIST_FILE = "Juick/Supporting Files/Juick-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 9.3; PRODUCT_BUNDLE_IDENTIFIER = "com.juick.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -642,8 +668,8 @@ ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CODE_SIGN_IDENTITY = "iPhone Developer"; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "Juick/Juick-Prefix.pch"; - INFOPLIST_FILE = "Juick/Juick-Info.plist"; + GCC_PREFIX_HEADER = "Juick/Supporting Files/Juick-Prefix.pch"; + INFOPLIST_FILE = "Juick/Supporting Files/Juick-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 9.3; PRODUCT_BUNDLE_IDENTIFIER = "com.juick.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -663,12 +689,12 @@ "$(DEVELOPER_FRAMEWORKS_DIR)", ); GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "Juick/Juick-Prefix.pch"; + GCC_PREFIX_HEADER = "Juick/Supporting Files/Juick-Prefix.pch"; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); - INFOPLIST_FILE = "JuickTests/JuickTests-Info.plist"; + INFOPLIST_FILE = "JuickTests/Supporting Files/JuickTests-Info.plist"; PRODUCT_BUNDLE_IDENTIFIER = "com.juick.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUNDLE_LOADER)"; @@ -687,8 +713,8 @@ "$(DEVELOPER_FRAMEWORKS_DIR)", ); GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "Juick/Juick-Prefix.pch"; - INFOPLIST_FILE = "JuickTests/JuickTests-Info.plist"; + GCC_PREFIX_HEADER = "Juick/Supporting Files/Juick-Prefix.pch"; + INFOPLIST_FILE = "JuickTests/Supporting Files/JuickTests-Info.plist"; PRODUCT_BUNDLE_IDENTIFIER = "com.juick.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUNDLE_LOADER)"; diff --git a/Juick/AppDelegate.m b/Juick/AppDelegate.m index 9dc5362..56b6ee9 100644 --- a/Juick/AppDelegate.m +++ b/Juick/AppDelegate.m @@ -37,7 +37,7 @@ self.viewController = reveal; [messages.navigationController.navigationBar addGestureRecognizer:reveal.panGestureRecognizer]; UIBarButtonItem *revealButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"reveal-icon.png"] - style:UIBarButtonItemStyleBordered target:reveal action:@selector(revealToggle:)]; + style:UIBarButtonItemStylePlain target:reveal action:@selector(revealToggle:)]; messages.navigationItem.leftBarButtonItem = revealButtonItem; UIBarButtonItem *compose = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCompose target:messages action:@selector(composePressed)]; diff --git a/Juick/ColorScheme.h b/Juick/ColorScheme.h deleted file mode 100644 index de69689..0000000 --- a/Juick/ColorScheme.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// Colors.h -// Juick -// -// Created by Vitaly Takmazov on 05.11.13. -// Copyright (c) 2013 com.juick. All rights reserved. -// - -#import - -@interface ColorScheme : NSObject - -+ (UIColor *)colorWithHex:(UInt32)col; - -+(UIColor *) mainBackground; -+(UIColor *) linkColor; -@end diff --git a/Juick/ColorScheme.m b/Juick/ColorScheme.m deleted file mode 100644 index 8417489..0000000 --- a/Juick/ColorScheme.m +++ /dev/null @@ -1,37 +0,0 @@ -// -// Colors.m -// Juick -// -// Created by Vitaly Takmazov on 05.11.13. -// Copyright (c) 2013 com.juick. All rights reserved. -// - -#import "ColorScheme.h" - -@implementation ColorScheme - -+ (void) initialize -{ - [super initialize]; -} - -// takes 0x123456 -+ (UIColor *)colorWithHex:(UInt32)col { - unsigned char r, g, b; - b = col & 0xFF; - g = (col >> 8) & 0xFF; - r = (col >> 16) & 0xFF; - return [UIColor colorWithRed:(float)r/255.0f green:(float)g/255.0f blue:(float)b/255.0f alpha:1]; -} - - -+ (UIColor *) mainBackground { - return [UIColor colorWithRed:238/255.0f green:238/255.0f blue:229/255.0f alpha:1.0f]; -} - -+ (UIColor *) linkColor { - return [self colorWithHex:0x006699]; -} - - -@end diff --git a/Juick/Helpers/ColorScheme.h b/Juick/Helpers/ColorScheme.h new file mode 100644 index 0000000..de69689 --- /dev/null +++ b/Juick/Helpers/ColorScheme.h @@ -0,0 +1,17 @@ +// +// Colors.h +// Juick +// +// Created by Vitaly Takmazov on 05.11.13. +// Copyright (c) 2013 com.juick. All rights reserved. +// + +#import + +@interface ColorScheme : NSObject + ++ (UIColor *)colorWithHex:(UInt32)col; + ++(UIColor *) mainBackground; ++(UIColor *) linkColor; +@end diff --git a/Juick/Helpers/ColorScheme.m b/Juick/Helpers/ColorScheme.m new file mode 100644 index 0000000..8417489 --- /dev/null +++ b/Juick/Helpers/ColorScheme.m @@ -0,0 +1,37 @@ +// +// Colors.m +// Juick +// +// Created by Vitaly Takmazov on 05.11.13. +// Copyright (c) 2013 com.juick. All rights reserved. +// + +#import "ColorScheme.h" + +@implementation ColorScheme + ++ (void) initialize +{ + [super initialize]; +} + +// takes 0x123456 ++ (UIColor *)colorWithHex:(UInt32)col { + unsigned char r, g, b; + b = col & 0xFF; + g = (col >> 8) & 0xFF; + r = (col >> 16) & 0xFF; + return [UIColor colorWithRed:(float)r/255.0f green:(float)g/255.0f blue:(float)b/255.0f alpha:1]; +} + + ++ (UIColor *) mainBackground { + return [UIColor colorWithRed:238/255.0f green:238/255.0f blue:229/255.0f alpha:1.0f]; +} + ++ (UIColor *) linkColor { + return [self colorWithHex:0x006699]; +} + + +@end diff --git a/Juick/Helpers/NSURL+PathParameters.h b/Juick/Helpers/NSURL+PathParameters.h new file mode 100644 index 0000000..73fc004 --- /dev/null +++ b/Juick/Helpers/NSURL+PathParameters.h @@ -0,0 +1,37 @@ +// +// NSURL+PathParameters.h +// +// Created by Johan Kool on 27/9/2011. +// Copyright 2011 Koolistov Pte. Ltd. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// * Neither the name of KOOLISTOV PTE. LTD. nor the names of its contributors may be used to +// endorse or promote products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + + +#import + +@interface NSURL (PathParameters) + +- (NSURL *)URLByReplacingPathWithPath:(NSString *)path; +- (NSURL *)URLByAppendingPathWithRelativePath:(NSString *)path; +- (NSURL *)URLByAppendingParameters:(NSDictionary *)parameters; +- (NSURL *)URLByAppendingParameterName:(NSString *)parameter value:(id)value; + +@end diff --git a/Juick/Helpers/NSURL+PathParameters.m b/Juick/Helpers/NSURL+PathParameters.m new file mode 100644 index 0000000..83a55bb --- /dev/null +++ b/Juick/Helpers/NSURL+PathParameters.m @@ -0,0 +1,173 @@ +// +// NSURL+PathParameters.m +// +// Created by Johan Kool on 27/9/2011. +// Copyright 2011 Koolistov Pte. Ltd. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// * Neither the name of KOOLISTOV PTE. LTD. nor the names of its contributors may be used to +// endorse or promote products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + +#import "NSURL+PathParameters.h" + +@interface NSString (URLParameters) + +- (NSString *)stringByEscapingForURLArgument; + +@end + +@implementation NSString (URLParameters) + +- (NSString *)stringByEscapingForURLArgument { + // Encode all the reserved characters, per RFC 3986 () + NSString *escapedString = (__bridge NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, + (CFStringRef)self, + NULL, + (CFStringRef)@"!*'\"();:@&=+$,/?%#[] ", + kCFStringEncodingUTF8); + return [escapedString copy]; +} + +@end + +@implementation NSURL (PathParameters) + +- (NSURL *)URLByReplacingPathWithPath:(NSString *)path { + // scheme://username:password@domain:port/path?query_string#fragment_id + + // Chop off path, query and fragment from absoluteString, then add new path and put back query and fragment + + NSString *absoluteString = [self absoluteString]; + NSUInteger endIndex = [absoluteString length]; + + NSString *fragment = [self fragment]; + if (fragment) { + endIndex -= [fragment length]; + endIndex--; // The # character + } + + NSString *query = [self query]; + if (query) { + endIndex -= [query length]; + endIndex--; // The ? character + } + + // Check if the last character of the path is a slash (range must be valid as endIndex must be smaller or equal to length) + BOOL trailingSlashOnPath = [[absoluteString substringWithRange:NSMakeRange(endIndex - 1, 1)] isEqualToString:@"/"]; + + NSString *originalPath = [self path]; // This method strips any trailing slash "/" + if (originalPath) { + endIndex -= [originalPath length]; + if (trailingSlashOnPath && [originalPath length] > 1) { // Don't get confused with the starting slash + endIndex--; + } + } + + absoluteString = [absoluteString substringToIndex:endIndex]; + absoluteString = [absoluteString stringByAppendingString:path]; + if (query) { + absoluteString = [absoluteString stringByAppendingString:@"?"]; + absoluteString = [absoluteString stringByAppendingString:query]; + } + if (fragment) { + absoluteString = [absoluteString stringByAppendingString:@"#"]; + absoluteString = [absoluteString stringByAppendingString:fragment]; + } + + return [NSURL URLWithString:absoluteString]; +} + +- (NSURL *)URLByAppendingPathWithRelativePath:(NSString *)path { + NSString *originalPath = [self path]; + NSString *combinedPath = [[originalPath stringByAppendingPathComponent:path] stringByStandardizingPath]; + // Don't standardize away a trailing slash + if ([path length] > 1 && [path hasSuffix:@"/"]) { + combinedPath = [combinedPath stringByAppendingString:@"/"]; + } + return [self URLByReplacingPathWithPath:combinedPath]; +} + +- (NSURL *)URLByAppendingParameters:(NSDictionary *)parameters { + NSMutableString *query = [[self query] mutableCopy]; + + if (!query) { + query = [NSMutableString stringWithString:@""]; + } + + // Sort parameters to be appended so that our solution is stable (and testable) + NSArray *parameterNames = [parameters allKeys]; + parameterNames = [parameterNames sortedArrayUsingSelector:@selector(compare:)]; + + for (NSString *parameterName in parameterNames) { + id value = [parameters objectForKey:parameterName]; + NSAssert3([parameterName isKindOfClass:[NSString class]], @"Got '%@' of type %@ as key for parameter with value '%@'. Expected an NSString.", parameterName, NSStringFromClass([parameterName class]), value); + + // The value needs to be an NSString, or be able to give us an NSString + if (![value isKindOfClass:[NSString class]]) { + if ([value respondsToSelector:@selector(stringValue)]) { + value = [value stringValue]; + } else { + // Fallback to simply giving the description + value = [value description]; + } + } + + if ([query length] == 0) { + [query appendFormat:@"%@=%@", [parameterName stringByEscapingForURLArgument], [value stringByEscapingForURLArgument]]; + } else { + [query appendFormat:@"&%@=%@", [parameterName stringByEscapingForURLArgument], [value stringByEscapingForURLArgument]]; + } + } + + // scheme://username:password@domain:port/path?query_string#fragment_id + + // Chop off query and fragment from absoluteString, then add new query and put back fragment + + NSString *absoluteString = [self absoluteString]; + NSUInteger endIndex = [absoluteString length]; + + NSString *fragment = [self fragment]; + if (fragment) { + endIndex -= [fragment length]; + endIndex--; // The # character + } + + NSString *originalQuery = [self query]; + if (originalQuery) { + endIndex -= [originalQuery length]; + endIndex--; // The ? character + } + + absoluteString = [absoluteString substringToIndex:endIndex]; + absoluteString = [absoluteString stringByAppendingString:@"?"]; + absoluteString = [absoluteString stringByAppendingString:query]; + if (fragment) { + absoluteString = [absoluteString stringByAppendingString:@"#"]; + absoluteString = [absoluteString stringByAppendingString:fragment]; + } + + return [NSURL URLWithString:absoluteString]; +} + +- (NSURL *)URLByAppendingParameterName:(NSString *)parameter value:(id)value { + return [self URLByAppendingParameters:[NSDictionary dictionaryWithObjectsAndKeys:value, parameter, nil]]; +} + + +@end diff --git a/Juick/Helpers/UIImage+Utils.h b/Juick/Helpers/UIImage+Utils.h new file mode 100644 index 0000000..8de91bf --- /dev/null +++ b/Juick/Helpers/UIImage+Utils.h @@ -0,0 +1,19 @@ +// +// UIImage+Utils.h +// Juick +// +// Created by Vitaly on 01.02.14. +// Copyright (c) 2014 com.juick. All rights reserved. +// + +#import + +@interface UIImage (Utils) + ++ (UIImage*)imageWithImage:(UIImage *)image convertToWidth:(float)width covertToHeight:(float)height; ++ (UIImage*)imageWithImage:(UIImage *)image convertToHeight:(float)height; ++ (UIImage*)imageWithImage:(UIImage *)image convertToWidth:(float)width; ++ (UIImage*)imageWithImage:(UIImage *)image fitInsideWidth:(float)width fitInsideHeight:(float)height; ++ (UIImage*)imageWithImage:(UIImage *)image fitOutsideWidth:(float)width fitOutsideHeight:(float)height; ++ (UIImage*)imageWithImage:(UIImage *)image cropToWidth:(float)width cropToHeight:(float)height; +@end diff --git a/Juick/Helpers/UIImage+Utils.m b/Juick/Helpers/UIImage+Utils.m new file mode 100644 index 0000000..4617c65 --- /dev/null +++ b/Juick/Helpers/UIImage+Utils.m @@ -0,0 +1,69 @@ +// +// UIImage+Utils.m +// Juick +// +// Created by Vitaly on 01.02.14. +// Copyright (c) 2014 com.juick. All rights reserved. +// + +#import "UIImage+Utils.h" + +@implementation UIImage (Utils) + ++ (UIImage*)imageWithImage:(UIImage *)image convertToWidth:(float)width covertToHeight:(float)height { + CGSize size = CGSizeMake(width, height); + UIGraphicsBeginImageContext(size); + [image drawInRect:CGRectMake(0, 0, size.width, size.height)]; + UIImage * newimage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + return newimage; +} + ++ (UIImage*)imageWithImage:(UIImage *)image convertToHeight:(float)height { + float ratio = image.size.height / height; + float width = image.size.width / ratio; + CGSize size = CGSizeMake(width, height); + UIGraphicsBeginImageContext(size); + [image drawInRect:CGRectMake(0, 0, size.width, size.height)]; + UIImage * newimage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + return newimage; +} + ++ (UIImage*)imageWithImage:(UIImage *)image convertToWidth:(float)width { + float ratio = image.size.width / width; + float height = image.size.height / ratio; + CGSize size = CGSizeMake(width, height); + UIGraphicsBeginImageContext(size); + [image drawInRect:CGRectMake(0, 0, size.width, size.height)]; + UIImage * newimage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + return newimage; +} + ++ (UIImage*)imageWithImage:(UIImage *)image fitInsideWidth:(float)width fitInsideHeight:(float)height { + if (image.size.height >= image.size.width) { + return [UIImage imageWithImage:image convertToWidth:width]; + } else { + return [UIImage imageWithImage:image convertToHeight:height]; + } +} + ++ (UIImage*)imageWithImage:(UIImage *)image fitOutsideWidth:(float)width fitOutsideHeight:(float)height { + if (image.size.height >= image.size.width) { + return [UIImage imageWithImage:image convertToHeight:height]; + } else { + return [UIImage imageWithImage:image convertToWidth:width]; + } +} + ++ (UIImage*)imageWithImage:(UIImage *)image cropToWidth:(float)width cropToHeight:(float)height { + CGSize size = [image size]; + CGRect rect = CGRectMake(((size.width-width) / 2.0f), ((size.height-height) / 2.0f), width, height); + CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], rect); + UIImage * img = [UIImage imageWithCGImage:imageRef]; + CGImageRelease(imageRef); + return img; +} + +@end diff --git a/Juick/Juick-Info.plist b/Juick/Juick-Info.plist deleted file mode 100644 index 0df6f2a..0000000 --- a/Juick/Juick-Info.plist +++ /dev/null @@ -1,62 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleDisplayName - ${PRODUCT_NAME} - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - ${PRODUCT_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0.10 - CFBundleSignature - ???? - CFBundleVersion - 1.0.10 - LSApplicationCategoryType - public.app-category.social-networking - LSRequiresIPhoneOS - - NSHumanReadableCopyright - - UIAppFonts - - FontAwesome.ttf - - UILaunchStoryboardName - Launch Screen - UIPrerenderedIcon - - UIRequiredDeviceCapabilities - - armv7 - - UIStatusBarTintParameters - - UINavigationBar - - Style - UIBarStyleDefault - Translucent - - - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - - - diff --git a/Juick/Juick-Prefix.pch b/Juick/Juick-Prefix.pch deleted file mode 100644 index c80380f..0000000 --- a/Juick/Juick-Prefix.pch +++ /dev/null @@ -1,25 +0,0 @@ -// -// Prefix header -// -// The contents of this file are implicitly included at the beginning of every source file. -// - -#import - -#ifndef __IPHONE_5_0 -#warning "This project uses features only available in iOS SDK 5.0 and later." -#endif - -#ifdef __OBJC__ - #import - #import - #import - #import - #import - #import "NSString+HTML.h" - #import "UIImage+Utils.h" - #import "NSDate+TimeAgo.h" - #import "TTTAttributedLabel.h" - #import - #import -#endif diff --git a/Juick/LoginViewController.h b/Juick/LoginViewController.h deleted file mode 100644 index bf980fa..0000000 --- a/Juick/LoginViewController.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// LoginViewController.h -// Juick -// -// Created by Vitaly on 30.01.14. -// Copyright (c) 2014 com.juick. All rights reserved. -// - -#import -#import "XLForm.h" -#import "PDKeychainbindingsController.h" - -@interface LoginViewController : XLFormViewController - -@end diff --git a/Juick/LoginViewController.m b/Juick/LoginViewController.m deleted file mode 100644 index eedc6d3..0000000 --- a/Juick/LoginViewController.m +++ /dev/null @@ -1,92 +0,0 @@ -// -// LoginViewController.m -// Juick -// -// Created by Vitaly on 30.01.14. -// Copyright (c) 2014 com.juick. All rights reserved. -// - -#import "LoginViewController.h" -#import "User.h" -#import "ColorScheme.h" - -@implementation LoginViewController - -- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; - if (self){ - [self initializeForm]; - } - return self; -} - -- (id)initWithCoder:(NSCoder *)aDecoder { - self = [super initWithCoder:aDecoder]; - if (self){ - [self initializeForm]; - } - return self; -} - -- (void)initializeForm { - self.title = @"Sign in"; - [self.view setBackgroundColor:[ColorScheme mainBackground]]; - - self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel - target:self action:@selector(cancelSignIn)]; - self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave - target:self action:@selector(doneSignIn)]; - XLFormDescriptor *form = [XLFormDescriptor formDescriptorWithTitle:@"Sign in"]; - form.rowNavigationOptions = XLFormRowNavigationOptionEnabled; - XLFormSectionDescriptor *section = [XLFormSectionDescriptor formSection]; - [form addFormSection:section]; - XLFormRowDescriptor * usernameRow = [XLFormRowDescriptor - formRowDescriptorWithTag:@"com.juick.username" - rowType:XLFormRowDescriptorTypeText title:@"Username"]; - usernameRow.value = [[PDKeychainBindings sharedKeychainBindings] stringForKey:@"com.juick.username"]; - [section addFormRow:usernameRow]; - XLFormRowDescriptor * passwordRow = [XLFormRowDescriptor - formRowDescriptorWithTag:@"com.juick.password" - rowType:XLFormRowDescriptorTypePassword title:@"Password"]; - passwordRow.value = [[PDKeychainBindings sharedKeychainBindings] stringForKey:@"com.juick.password"]; - [section addFormRow:passwordRow]; - - self.form = form; -} - - -- (void) cancelSignIn { - CATransition* transition = [CATransition animation]; - transition.duration = 0.3; - transition.type = kCATransitionFade; - transition.subtype = kCATransitionFromTop; - - [self.navigationController.view.layer addAnimation:transition forKey:kCATransition]; - [self.navigationController popViewControllerAnimated:NO]; -} - -- (void) doneSignIn { - [User checkIsValid:^(BOOL success) { - if (success) { - CATransition* transition = [CATransition animation]; - transition.duration = 0.3; - transition.type = kCATransitionFade; - transition.subtype = kCATransitionFromTop; - - [self.navigationController.view.layer addAnimation:transition forKey:kCATransition]; - [self.navigationController popToRootViewControllerAnimated:NO]; - } else { - [User throwUnableToLogin]; - } - }]; - -} - --(void) formRowDescriptorValueHasChanged:(XLFormRowDescriptor *)formRow oldValue:(id)oldValue newValue:(id)newValue { - [super formRowDescriptorValueHasChanged:formRow oldValue:oldValue newValue:newValue]; - if ([newValue isKindOfClass:[NSString class]]) { - [[PDKeychainBindings sharedKeychainBindings] setObject:newValue forKey:formRow.tag]; - } -} - -@end diff --git a/Juick/Message.h b/Juick/Message.h deleted file mode 100644 index 39d3c38..0000000 --- a/Juick/Message.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// Message.h -// Juick -// -// Created by Vitaly Takmazov on 29.10.13. -// Copyright (c) 2013 com.juick. All rights reserved. -// - -#import -#import "User.h" - -@interface Message : NSObject - -@property NSNumber *MID; -@property NSNumber *RID; -@property User *user; -@property NSString *text; -@property NSArray *tags; -@property NSString *timestamp; -@property NSString *attach; -@property NSString *repliesBy; -@property NSNumber *repliesCount; - -+(void) pullNextFromPath:(NSString *)path params:(NSDictionary *)params callback:(void(^)(NSArray *))callback; -+(NSString *) messagesUrl; -+(NSString *) threadUrl; -+(NSString *) feedUrl; - -@end diff --git a/Juick/Message.m b/Juick/Message.m deleted file mode 100644 index de08e98..0000000 --- a/Juick/Message.m +++ /dev/null @@ -1,52 +0,0 @@ -// -// Message.m -// Juick -// -// Created by Vitaly Takmazov on 29.10.13. -// Copyright (c) 2013 com.juick. All rights reserved. -// - -#import "Message.h" -#import "PDKeychainBindings.h" - -@implementation Message - -+ (NSDictionary *)modelCustomPropertyMapper { - return @{@"text" : @"body", - @"MID" : @"mid", - @"RID" : @"rid", - @"attach" : @"photo.small", - @"repliesCount": @"replies", - @"repliesBy": @"repliesby"}; -} - - -+(void) pullNextFromPath:(NSString *)path params:(NSDictionary *) params callback:(void(^)(NSArray *))callback { - AFHTTPSessionManager *manager = [APIClient sharedClient].manager; - if ([[PDKeychainBindings sharedKeychainBindings] stringForKey:@"com.juick.username"] != nil) { - [manager.requestSerializer setAuthorizationHeaderFieldWithUsername:[[PDKeychainBindings sharedKeychainBindings] stringForKey:@"com.juick.username"] password:[[PDKeychainBindings sharedKeychainBindings] stringForKey:@"com.juick.password"]]; - } - [manager GET:path parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { - NSMutableArray *messages = [NSMutableArray new]; - [((NSArray *)responseObject) enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { - [messages addObject:[Message yy_modelWithJSON:obj]]; - }]; - callback(messages); - } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { - NSLog(@"REST Error: %@", error); - }]; -} - -+(NSString *) messagesUrl { - return @"https://api.juick.com/messages"; -} - -+(NSString *) threadUrl { - return @"https://api.juick.com/thread"; -} - -+(NSString *) feedUrl { - return @"https://api.juick.com/home"; -} - -@end diff --git a/Juick/MessagesViewController.h b/Juick/MessagesViewController.h deleted file mode 100644 index 38123bd..0000000 --- a/Juick/MessagesViewController.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// MasterViewController.h -// Juick -// -// Created by Vitaly Takmazov on 26.10.13. -// Copyright (c) 2013 com.juick. All rights reserved. -// - -#import - -@interface MessagesViewController : UITableViewController -- (void)loadFromPath:(NSString *)messagesPath withParams:(NSDictionary *)params withTitle:(NSString *)title; -- (void) refreshData; -- (void) composePressed; -@end diff --git a/Juick/MessagesViewController.m b/Juick/MessagesViewController.m deleted file mode 100644 index 28e7613..0000000 --- a/Juick/MessagesViewController.m +++ /dev/null @@ -1,181 +0,0 @@ -// -// MasterViewController.m -// Juick -// -// Created by Vitaly Takmazov on 26.10.13. -// Copyright (c) 2013 com.juick. All rights reserved. -// - -#import "MessagesViewController.h" -#import "MessageCell.h" - -#import "Message.h" -#import "ColorScheme.h" - -#import "NewPostViewController.h" - - -#import "NSURL+PathParameters.h" - -static NSString *CellIdentifier = @"MessageCell"; - - -@interface MessagesViewController (); - -@property(nonatomic, strong) NSMutableArray *messages; -@property(nonatomic, assign) Boolean dataLoading; -@property(nonatomic, strong) NSString *path; -@property(nonatomic, strong) NSMutableDictionary *params; - -@end - -@implementation MessagesViewController - -- (void)loadFromPath:(NSString *)messagesPath withParams:(NSDictionary *)params withTitle:(NSString *)title -{ - [self setPath:messagesPath]; - [self setParams:[[NSMutableDictionary alloc] initWithDictionary:params]]; - self.title = title; - __weak MessagesViewController * weakSelf = self; - [self.messages removeAllObjects]; - [weakSelf refreshData]; -} - -- (void) refreshData { - if ([self.path isEqualToString:[Message threadUrl]]) { - [self.messages removeAllObjects]; - } - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - self.dataLoading = YES; - [Message pullNextFromPath:self.path params:self.params callback:^(NSArray *next) { - dispatch_async(dispatch_get_main_queue(), ^{ - [self.messages addObjectsFromArray:next]; - [self.tableView reloadData]; - [self.refreshControl endRefreshing]; - self.dataLoading = NO; - }); - }]; - }); -} - -- (UIStatusBarStyle)preferredStatusBarStyle -{ - return UIStatusBarStyleLightContent; -} - -- (void)viewDidLoad -{ - [super viewDidLoad]; - self.dataLoading = NO; - [self.view setBackgroundColor:[ColorScheme mainBackground]]; - self.messages = [NSMutableArray array]; - - SWRevealViewController *revealController = [self revealViewController]; - if (revealController) { - // TODO: add to thread view too - [self.view addGestureRecognizer:[revealController panGestureRecognizer]]; - } - - [self.tableView registerNib:[UINib nibWithNibName:@"MessageCell" bundle:nil] forCellReuseIdentifier:CellIdentifier]; - self.tableView.rowHeight = UITableViewAutomaticDimension; - self.tableView.estimatedRowHeight = 500.0f; - self.refreshControl = [UIRefreshControl new]; - [self.refreshControl addTarget:self action:@selector(refreshData) forControlEvents:UIControlEventValueChanged];} - -- (void) composePressed { - CATransition* transition = [CATransition animation]; - transition.duration = 0.3; - transition.type = kCATransitionFade; - transition.subtype = kCATransitionFromTop; - - [self.navigationController.view.layer addAnimation:transition forKey:kCATransition]; - [self.navigationController pushViewController:[[NewPostViewController alloc] init] animated:NO]; -} - -- (void)viewDidAppear:(BOOL)animated -{ - [super viewDidAppear:animated]; - if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) { - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(contentSizeCategoryChanged:) - name:UIContentSizeCategoryDidChangeNotification - object:nil]; - } -} - -- (void)viewDidDisappear:(BOOL)animated -{ - [super viewDidDisappear:animated]; - if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) { - [[NSNotificationCenter defaultCenter] removeObserver:self - name:UIContentSizeCategoryDidChangeNotification - object:nil]; - } -} - -- (void)contentSizeCategoryChanged:(NSNotification *)notification -{ - [self.tableView reloadData]; -} - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - return 1; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return _messages.count; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - MessageCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; - Message *msg = [_messages objectAtIndex:indexPath.row]; - [cell setMessage:msg]; - if ([msg.attach length] > 0) { - __weak MessagesViewController * weakSelf = self; - [cell.attach yy_setImageWithURL:[NSURL URLWithString:msg.attach] placeholder:[UIImage imageNamed:@"AttachPlaceholder"] options:YYWebImageOptionProgressiveBlur | YYWebImageOptionSetImageWithFadeAnimation completion:^(UIImage * _Nullable image, NSURL * _Nonnull url, YYWebImageFromType from, YYWebImageStage stage, NSError * _Nullable error) { - dispatch_async(dispatch_get_main_queue(), ^{ - [cell setNeedsUpdateConstraints]; - [cell updateConstraintsIfNeeded]; - [cell setNeedsLayout]; - [cell layoutIfNeeded]; - }); - }]; - - } else { - cell.attach.image = nil; - } - - return cell; -} - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - if ([self.path isEqualToString:[Message threadUrl]]) - return; - Message *msg = [_messages objectAtIndex:indexPath.row]; - MessagesViewController *threadViewController = [[MessagesViewController alloc] init]; - [threadViewController loadFromPath:[Message threadUrl] withParams:[NSDictionary dictionaryWithObjectsAndKeys:msg.MID, @"mid", nil] withTitle:@"Thread"]; - [self.navigationController pushViewController:threadViewController animated:NO]; -} - --(void)splitViewController:(UISplitViewController *)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem { - self.navigationItem.leftBarButtonItem = nil; -} - --(void)splitViewController:(UISplitViewController *)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)pc { - self.navigationItem.leftBarButtonItem = barButtonItem; -} - --(void)scrollViewDidScroll:(UIScrollView *)scrollView_ { - CGFloat actualPosition = scrollView_.contentOffset.y; - CGFloat contentHeight = scrollView_.contentSize.height - scrollView_.contentSize.height / 2; - if (actualPosition >= contentHeight && !self.dataLoading) { - NSNumber *lastMid = ((Message *)[self.messages lastObject]).MID; - if (![self.path isEqualToString:[Message threadUrl]]) { - [self.params setValue:lastMid forKey:@"before_mid"]; - } - [self refreshData]; - } -} - - -@end diff --git a/Juick/Model/Message.h b/Juick/Model/Message.h new file mode 100644 index 0000000..b100e7d --- /dev/null +++ b/Juick/Model/Message.h @@ -0,0 +1,29 @@ +// +// Message.h +// Juick +// +// Created by Vitaly Takmazov on 29.10.13. +// Copyright (c) 2013 com.juick. All rights reserved. +// + +#import +#import "User.h" + +@interface Message : NSObject + +@property NSNumber *MID; +@property NSNumber *RID; +@property User *user; +@property NSString *text; +@property NSArray *tags; +@property NSString *timestamp; +@property NSString *attach; +@property NSString *repliesBy; +@property NSNumber *repliesCount; + ++(void) pullNextFromPath:(NSString *)path params:(NSDictionary *)params callback:(void(^)(NSArray *))callback; ++(NSString *) messagesUrl; ++(NSString *) threadUrl; ++(NSString *) feedUrl; + +@end diff --git a/Juick/Model/Message.m b/Juick/Model/Message.m new file mode 100644 index 0000000..de08e98 --- /dev/null +++ b/Juick/Model/Message.m @@ -0,0 +1,52 @@ +// +// Message.m +// Juick +// +// Created by Vitaly Takmazov on 29.10.13. +// Copyright (c) 2013 com.juick. All rights reserved. +// + +#import "Message.h" +#import "PDKeychainBindings.h" + +@implementation Message + ++ (NSDictionary *)modelCustomPropertyMapper { + return @{@"text" : @"body", + @"MID" : @"mid", + @"RID" : @"rid", + @"attach" : @"photo.small", + @"repliesCount": @"replies", + @"repliesBy": @"repliesby"}; +} + + ++(void) pullNextFromPath:(NSString *)path params:(NSDictionary *) params callback:(void(^)(NSArray *))callback { + AFHTTPSessionManager *manager = [APIClient sharedClient].manager; + if ([[PDKeychainBindings sharedKeychainBindings] stringForKey:@"com.juick.username"] != nil) { + [manager.requestSerializer setAuthorizationHeaderFieldWithUsername:[[PDKeychainBindings sharedKeychainBindings] stringForKey:@"com.juick.username"] password:[[PDKeychainBindings sharedKeychainBindings] stringForKey:@"com.juick.password"]]; + } + [manager GET:path parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { + NSMutableArray *messages = [NSMutableArray new]; + [((NSArray *)responseObject) enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + [messages addObject:[Message yy_modelWithJSON:obj]]; + }]; + callback(messages); + } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { + NSLog(@"REST Error: %@", error); + }]; +} + ++(NSString *) messagesUrl { + return @"https://api.juick.com/messages"; +} + ++(NSString *) threadUrl { + return @"https://api.juick.com/thread"; +} + ++(NSString *) feedUrl { + return @"https://api.juick.com/home"; +} + +@end diff --git a/Juick/Model/User.h b/Juick/Model/User.h new file mode 100644 index 0000000..84300f3 --- /dev/null +++ b/Juick/Model/User.h @@ -0,0 +1,27 @@ +// +// User.h +// Juick +// +// Created by Vitaly on 01.02.14. +// Copyright (c) 2014 com.juick. All rights reserved. +// + +#import +#import "PDKeychainBindings.h" +#import "SIAlertView.h" +#import "APIClient.h" +#import "YYModel.h" + +@interface User : NSObject +@property (nonatomic, strong) NSString *uname; +@property (nonatomic, strong) NSString *uid; + ++ (void) get:(NSString *)name callback:(void(^)(User *))callback; + ++ (BOOL) isAuthenticated; + ++ (void) checkIsValid:(void(^)(BOOL))callback; + ++ (void) throwUnableToLogin; + +@end diff --git a/Juick/Model/User.m b/Juick/Model/User.m new file mode 100644 index 0000000..f4b1e00 --- /dev/null +++ b/Juick/Model/User.m @@ -0,0 +1,49 @@ +// +// User.m +// Juick +// +// Created by Vitaly on 01.02.14. +// Copyright (c) 2014 com.juick. All rights reserved. +// + +#import "User.h" + + +@implementation User + ++(BOOL) isAuthenticated { + return [[PDKeychainBindings sharedKeychainBindings] stringForKey:@"com.juick.username"] != nil; +} + ++(void) throwUnableToLogin { + SIAlertView *alert = [[SIAlertView alloc] initWithTitle:@"Error" andMessage:@"Unable to login, check username/password, or network connectivity"]; + [alert addButtonWithTitle:@"OK" type:SIAlertViewButtonTypeCancel handler:^(SIAlertView *alertView) { + // <#code#> + }]; + [alert show]; +} + ++(void) checkIsValid:(void (^)(BOOL))callback { + AFHTTPSessionManager *manager = [APIClient sharedClient].manager; + [manager.requestSerializer setAuthorizationHeaderFieldWithUsername:[[PDKeychainBindings sharedKeychainBindings] stringForKey:@"com.juick.username"] password:[[PDKeychainBindings sharedKeychainBindings] stringForKey:@"com.juick.password"]]; + [manager POST:@"/post" parameters:nil progress:nil success:nil failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { + NSInteger statusCode = ((NSHTTPURLResponse *)task.response).statusCode; + if (statusCode == 400) { + callback(YES); + } else { + [manager.requestSerializer setAuthorizationHeaderFieldWithUsername:nil password:nil]; + callback(NO); + } + }];} + ++(void) get:(NSString *) name callback:(void(^)(User *))callback { + AFHTTPSessionManager *manager = [APIClient sharedClient].manager; + NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:name, @"uname", nil]; + [manager GET:@"/users" parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { + callback([User yy_modelWithJSON:[(NSArray *)responseObject firstObject]]); + } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { + callback(nil); + }]; +} + +@end diff --git a/Juick/NSURL+PathParameters.h b/Juick/NSURL+PathParameters.h deleted file mode 100644 index 73fc004..0000000 --- a/Juick/NSURL+PathParameters.h +++ /dev/null @@ -1,37 +0,0 @@ -// -// NSURL+PathParameters.h -// -// Created by Johan Kool on 27/9/2011. -// Copyright 2011 Koolistov Pte. Ltd. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// * Neither the name of KOOLISTOV PTE. LTD. nor the names of its contributors may be used to -// endorse or promote products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - - -#import - -@interface NSURL (PathParameters) - -- (NSURL *)URLByReplacingPathWithPath:(NSString *)path; -- (NSURL *)URLByAppendingPathWithRelativePath:(NSString *)path; -- (NSURL *)URLByAppendingParameters:(NSDictionary *)parameters; -- (NSURL *)URLByAppendingParameterName:(NSString *)parameter value:(id)value; - -@end diff --git a/Juick/NSURL+PathParameters.m b/Juick/NSURL+PathParameters.m deleted file mode 100644 index 83a55bb..0000000 --- a/Juick/NSURL+PathParameters.m +++ /dev/null @@ -1,173 +0,0 @@ -// -// NSURL+PathParameters.m -// -// Created by Johan Kool on 27/9/2011. -// Copyright 2011 Koolistov Pte. Ltd. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// * Neither the name of KOOLISTOV PTE. LTD. nor the names of its contributors may be used to -// endorse or promote products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -#import "NSURL+PathParameters.h" - -@interface NSString (URLParameters) - -- (NSString *)stringByEscapingForURLArgument; - -@end - -@implementation NSString (URLParameters) - -- (NSString *)stringByEscapingForURLArgument { - // Encode all the reserved characters, per RFC 3986 () - NSString *escapedString = (__bridge NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, - (CFStringRef)self, - NULL, - (CFStringRef)@"!*'\"();:@&=+$,/?%#[] ", - kCFStringEncodingUTF8); - return [escapedString copy]; -} - -@end - -@implementation NSURL (PathParameters) - -- (NSURL *)URLByReplacingPathWithPath:(NSString *)path { - // scheme://username:password@domain:port/path?query_string#fragment_id - - // Chop off path, query and fragment from absoluteString, then add new path and put back query and fragment - - NSString *absoluteString = [self absoluteString]; - NSUInteger endIndex = [absoluteString length]; - - NSString *fragment = [self fragment]; - if (fragment) { - endIndex -= [fragment length]; - endIndex--; // The # character - } - - NSString *query = [self query]; - if (query) { - endIndex -= [query length]; - endIndex--; // The ? character - } - - // Check if the last character of the path is a slash (range must be valid as endIndex must be smaller or equal to length) - BOOL trailingSlashOnPath = [[absoluteString substringWithRange:NSMakeRange(endIndex - 1, 1)] isEqualToString:@"/"]; - - NSString *originalPath = [self path]; // This method strips any trailing slash "/" - if (originalPath) { - endIndex -= [originalPath length]; - if (trailingSlashOnPath && [originalPath length] > 1) { // Don't get confused with the starting slash - endIndex--; - } - } - - absoluteString = [absoluteString substringToIndex:endIndex]; - absoluteString = [absoluteString stringByAppendingString:path]; - if (query) { - absoluteString = [absoluteString stringByAppendingString:@"?"]; - absoluteString = [absoluteString stringByAppendingString:query]; - } - if (fragment) { - absoluteString = [absoluteString stringByAppendingString:@"#"]; - absoluteString = [absoluteString stringByAppendingString:fragment]; - } - - return [NSURL URLWithString:absoluteString]; -} - -- (NSURL *)URLByAppendingPathWithRelativePath:(NSString *)path { - NSString *originalPath = [self path]; - NSString *combinedPath = [[originalPath stringByAppendingPathComponent:path] stringByStandardizingPath]; - // Don't standardize away a trailing slash - if ([path length] > 1 && [path hasSuffix:@"/"]) { - combinedPath = [combinedPath stringByAppendingString:@"/"]; - } - return [self URLByReplacingPathWithPath:combinedPath]; -} - -- (NSURL *)URLByAppendingParameters:(NSDictionary *)parameters { - NSMutableString *query = [[self query] mutableCopy]; - - if (!query) { - query = [NSMutableString stringWithString:@""]; - } - - // Sort parameters to be appended so that our solution is stable (and testable) - NSArray *parameterNames = [parameters allKeys]; - parameterNames = [parameterNames sortedArrayUsingSelector:@selector(compare:)]; - - for (NSString *parameterName in parameterNames) { - id value = [parameters objectForKey:parameterName]; - NSAssert3([parameterName isKindOfClass:[NSString class]], @"Got '%@' of type %@ as key for parameter with value '%@'. Expected an NSString.", parameterName, NSStringFromClass([parameterName class]), value); - - // The value needs to be an NSString, or be able to give us an NSString - if (![value isKindOfClass:[NSString class]]) { - if ([value respondsToSelector:@selector(stringValue)]) { - value = [value stringValue]; - } else { - // Fallback to simply giving the description - value = [value description]; - } - } - - if ([query length] == 0) { - [query appendFormat:@"%@=%@", [parameterName stringByEscapingForURLArgument], [value stringByEscapingForURLArgument]]; - } else { - [query appendFormat:@"&%@=%@", [parameterName stringByEscapingForURLArgument], [value stringByEscapingForURLArgument]]; - } - } - - // scheme://username:password@domain:port/path?query_string#fragment_id - - // Chop off query and fragment from absoluteString, then add new query and put back fragment - - NSString *absoluteString = [self absoluteString]; - NSUInteger endIndex = [absoluteString length]; - - NSString *fragment = [self fragment]; - if (fragment) { - endIndex -= [fragment length]; - endIndex--; // The # character - } - - NSString *originalQuery = [self query]; - if (originalQuery) { - endIndex -= [originalQuery length]; - endIndex--; // The ? character - } - - absoluteString = [absoluteString substringToIndex:endIndex]; - absoluteString = [absoluteString stringByAppendingString:@"?"]; - absoluteString = [absoluteString stringByAppendingString:query]; - if (fragment) { - absoluteString = [absoluteString stringByAppendingString:@"#"]; - absoluteString = [absoluteString stringByAppendingString:fragment]; - } - - return [NSURL URLWithString:absoluteString]; -} - -- (NSURL *)URLByAppendingParameterName:(NSString *)parameter value:(id)value { - return [self URLByAppendingParameters:[NSDictionary dictionaryWithObjectsAndKeys:value, parameter, nil]]; -} - - -@end diff --git a/Juick/NewPostViewController.h b/Juick/NewPostViewController.h deleted file mode 100644 index ceaca49..0000000 --- a/Juick/NewPostViewController.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// NewPostViewController.h -// Juick -// -// Created by Vitaly Takmazov on 07.11.13. -// Copyright (c) 2013 com.juick. All rights reserved. -// - -#import - -@interface NewPostViewController : UIViewController - -@end diff --git a/Juick/NewPostViewController.m b/Juick/NewPostViewController.m deleted file mode 100644 index 8c8fbf0..0000000 --- a/Juick/NewPostViewController.m +++ /dev/null @@ -1,61 +0,0 @@ -// -// NewPostViewController.m -// Juick -// -// Created by Vitaly Takmazov on 07.11.13. -// Copyright (c) 2013 com.juick. All rights reserved. -// - -#import "NewPostViewController.h" - -@interface NewPostViewController () - -@end - -@implementation NewPostViewController - -- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil -{ - self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; - if (self) { - // Custom initialization - } - return self; -} - -- (void)viewDidLoad -{ - [super viewDidLoad]; - self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel - target:self action:@selector(cancelCompose)]; - self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone - target:self action:@selector(doneCompose)]; -} - -- (void) cancelCompose { - CATransition* transition = [CATransition animation]; - transition.duration = 0.3; - transition.type = kCATransitionFade; - transition.subtype = kCATransitionFromTop; - - [self.navigationController.view.layer addAnimation:transition forKey:kCATransition]; - [self.navigationController popViewControllerAnimated:NO]; -} - -- (void) doneCompose { - CATransition* transition = [CATransition animation]; - transition.duration = 0.3; - transition.type = kCATransitionFade; - transition.subtype = kCATransitionFromTop; - - [self.navigationController.view.layer addAnimation:transition forKey:kCATransition]; - [self.navigationController popToRootViewControllerAnimated:NO]; -} - -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. -} - -@end diff --git a/Juick/RevealPanelViewController.h b/Juick/RevealPanelViewController.h deleted file mode 100644 index ff5006c..0000000 --- a/Juick/RevealPanelViewController.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// RevealPanelViewController.h -// Juick -// -// Created by Vitaly Takmazov on 04.11.13. -// Copyright (c) 2013 com.juick. All rights reserved. -// - -#import -#import -#import "LoginViewController.h" - -@interface RevealPanelViewController : UIViewController -@property (nonatomic, strong) IBOutlet UITableView *tableView; -@property (nonatomic, strong) IBOutlet UIButton *signButton; -@end diff --git a/Juick/RevealPanelViewController.m b/Juick/RevealPanelViewController.m deleted file mode 100644 index d890f97..0000000 --- a/Juick/RevealPanelViewController.m +++ /dev/null @@ -1,182 +0,0 @@ -// -// RevealPanelViewController.m -// Juick -// -// Created by Vitaly Takmazov on 04.11.13. -// Copyright (c) 2013 com.juick. All rights reserved. -// - -#import "SWRevealViewController.h" - -#import "RevealPanelViewController.h" -#import "MessagesViewController.h" - -#import "ColorScheme.h" -#import "NSURL+PathParameters.h" -#import "NavCell.h" -#import "Message.h" -#import "User.h" - - -static NSString *CellIdentifier = @"NavCell"; - -@interface RevealPanelViewController () - -@end - -@implementation RevealPanelViewController - -- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil -{ - self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; - if (self) { - // Custom initialization - } - return self; -} - -- (void)viewDidLoad -{ - [super viewDidLoad]; - [self.view setBackgroundColor:[ColorScheme mainBackground]]; - self.tableView = [[UITableView alloc] init]; - [self.tableView setBackgroundColor:[ColorScheme mainBackground]]; - self.tableView.delegate = self; - self.tableView.dataSource = self; - [self.tableView setSeparatorInset:UIEdgeInsetsZero]; - self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; - self.tableView.separatorColor =[UIColor darkGrayColor]; - [self.tableView registerNib:[UINib nibWithNibName:@"NavCell" bundle:nil] forCellReuseIdentifier:CellIdentifier]; - [self.view addSubview:self.tableView]; - self.signButton = [[UIButton alloc] init]; - [self.signButton addTarget:self action:@selector(signInOut) forControlEvents:UIControlEventTouchUpInside]; - [self.view addSubview:self.signButton]; - [self refreshInfo]; -} - --(void) refreshInfo { - NSString *text; - UIColor *color; - - if ([User isAuthenticated]) { - text = @"Sign Out"; - color = [UIColor redColor]; - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ - [User get:[[PDKeychainBindings sharedKeychainBindings] stringForKey:@"com.juick.username"] callback:^(User *user) { - if (user != nil) { - /*[self.titleView.image setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://i.juick.com/as/%@.png", user.uid]]]; - [self.titleView.title setText:user.uname];*/ - } - }]; - }); - } else { - text = @"Sign In"; - color = [UIColor greenColor]; - } - [self.signButton setTitle:text forState:UIControlStateNormal]; - [self.signButton setBackgroundColor:color]; -} - --(void) signInOut { - [self refreshInfo]; - [self pushLoginForm]; -} - --(void) viewWillLayoutSubviews { - [super viewWillLayoutSubviews]; - self.tableView.frame = CGRectMake(0, 0, self.view.bounds.size.width, 400); - self.signButton.frame = CGRectMake(0, self.view.bounds.size.height - 40, self.view.bounds.size.width, 40); -} - -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. -} - - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - return 1; -} - -- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return 4; -} - -- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { - return 32 + 10*2; // icon size + insets -} - -- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - NavCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; - NSInteger row = indexPath.row; - [cell.contentView setBackgroundColor:[UIColor whiteColor]]; - cell.icon.font = [UIFont fontWithName:kFontAwesomeFamilyName size:32.f]; - cell.icon.textColor = [ColorScheme linkColor]; - cell.descriptionText.textColor = [ColorScheme linkColor]; - if (row == 0) { - cell.descriptionText.text = @"My feed"; - cell.icon.text = [NSString fontAwesomeIconStringForEnum:FAIconHome]; - - } else if (row == 1) { - cell.descriptionText.text = @"Popular"; - cell.icon.text = [NSString fontAwesomeIconStringForEnum:FAIconComments]; - } else if (row == 2) { - cell.descriptionText.text = @"Discover"; - cell.icon.text = [NSString fontAwesomeIconStringForEnum:FAIconSearch]; - } else if (row == 3) { - cell.descriptionText.text = @"Images"; - cell.icon.text = [NSString fontAwesomeIconStringForEnum:FAIconPicture]; - } - UIView *bgColorView = [[UIView alloc] init]; - bgColorView.backgroundColor = [UIColor blackColor]; - bgColorView.layer.masksToBounds = YES; - [cell setSelectedBackgroundView:bgColorView]; - [cell.contentView setNeedsLayout]; - [cell.contentView layoutIfNeeded]; - return cell; -} - -- (void) pushLoginForm { - [self.revealViewController revealToggle:self]; - UIViewController *loginView = [[LoginViewController alloc] init]; - UINavigationController *messages = (UINavigationController *)self.revealViewController.frontViewController; - [messages pushViewController:loginView animated:YES]; -} - -- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - NSInteger row = indexPath.row; - NSString *targetPath; - NSDictionary *targetParams; - NSString *targetTitle; - if (row == 0) { - if ([[PDKeychainBindings sharedKeychainBindings] stringForKey:@"com.juick.username"] == nil) { - [self pushLoginForm]; - return; - } else { - targetTitle = @"My feed"; - targetPath = [Message feedUrl]; - } - - } - if (row == 1) { - targetTitle = @"Popular"; - targetPath = [Message messagesUrl]; - targetParams = [NSDictionary dictionaryWithObjectsAndKeys:@"1", @"popular", nil]; - } else if (row == 2) { - targetTitle = @"Discover"; - targetPath = [Message messagesUrl]; - } - if (row == 3) { - targetTitle = @"Images"; - targetPath = [Message messagesUrl]; - targetParams = [NSDictionary dictionaryWithObjectsAndKeys:@"photo", @"media", nil]; - } - SWRevealViewController *reveal = self.revealViewController; - UINavigationController *front = (UINavigationController *)reveal.frontViewController; - MessagesViewController *messages = (MessagesViewController *)[front.viewControllers objectAtIndex:0]; - [messages loadFromPath:targetPath withParams:targetParams withTitle:targetTitle]; - [reveal revealToggle:self]; -} - -@end diff --git a/Juick/Supporting Files/Juick-Info.plist b/Juick/Supporting Files/Juick-Info.plist new file mode 100644 index 0000000..0df6f2a --- /dev/null +++ b/Juick/Supporting Files/Juick-Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0.10 + CFBundleSignature + ???? + CFBundleVersion + 1.0.10 + LSApplicationCategoryType + public.app-category.social-networking + LSRequiresIPhoneOS + + NSHumanReadableCopyright + + UIAppFonts + + FontAwesome.ttf + + UILaunchStoryboardName + Launch Screen + UIPrerenderedIcon + + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarTintParameters + + UINavigationBar + + Style + UIBarStyleDefault + Translucent + + + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/Juick/Supporting Files/Juick-Prefix.pch b/Juick/Supporting Files/Juick-Prefix.pch new file mode 100644 index 0000000..c80380f --- /dev/null +++ b/Juick/Supporting Files/Juick-Prefix.pch @@ -0,0 +1,25 @@ +// +// Prefix header +// +// The contents of this file are implicitly included at the beginning of every source file. +// + +#import + +#ifndef __IPHONE_5_0 +#warning "This project uses features only available in iOS SDK 5.0 and later." +#endif + +#ifdef __OBJC__ + #import + #import + #import + #import + #import + #import "NSString+HTML.h" + #import "UIImage+Utils.h" + #import "NSDate+TimeAgo.h" + #import "TTTAttributedLabel.h" + #import + #import +#endif diff --git a/Juick/Supporting Files/en.lproj/InfoPlist.strings b/Juick/Supporting Files/en.lproj/InfoPlist.strings new file mode 100644 index 0000000..477b28f --- /dev/null +++ b/Juick/Supporting Files/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/Juick/Supporting Files/main.m b/Juick/Supporting Files/main.m new file mode 100644 index 0000000..67b222f --- /dev/null +++ b/Juick/Supporting Files/main.m @@ -0,0 +1,18 @@ +// +// main.m +// Juick +// +// Created by Vitaly Takmazov on 26.10.13. +// Copyright (c) 2013 com.juick. All rights reserved. +// + +#import + +#import "AppDelegate.h" + +int main(int argc, char * argv[]) +{ + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/Juick/UIImage+Utils.h b/Juick/UIImage+Utils.h deleted file mode 100644 index 8de91bf..0000000 --- a/Juick/UIImage+Utils.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// UIImage+Utils.h -// Juick -// -// Created by Vitaly on 01.02.14. -// Copyright (c) 2014 com.juick. All rights reserved. -// - -#import - -@interface UIImage (Utils) - -+ (UIImage*)imageWithImage:(UIImage *)image convertToWidth:(float)width covertToHeight:(float)height; -+ (UIImage*)imageWithImage:(UIImage *)image convertToHeight:(float)height; -+ (UIImage*)imageWithImage:(UIImage *)image convertToWidth:(float)width; -+ (UIImage*)imageWithImage:(UIImage *)image fitInsideWidth:(float)width fitInsideHeight:(float)height; -+ (UIImage*)imageWithImage:(UIImage *)image fitOutsideWidth:(float)width fitOutsideHeight:(float)height; -+ (UIImage*)imageWithImage:(UIImage *)image cropToWidth:(float)width cropToHeight:(float)height; -@end diff --git a/Juick/UIImage+Utils.m b/Juick/UIImage+Utils.m deleted file mode 100644 index 4617c65..0000000 --- a/Juick/UIImage+Utils.m +++ /dev/null @@ -1,69 +0,0 @@ -// -// UIImage+Utils.m -// Juick -// -// Created by Vitaly on 01.02.14. -// Copyright (c) 2014 com.juick. All rights reserved. -// - -#import "UIImage+Utils.h" - -@implementation UIImage (Utils) - -+ (UIImage*)imageWithImage:(UIImage *)image convertToWidth:(float)width covertToHeight:(float)height { - CGSize size = CGSizeMake(width, height); - UIGraphicsBeginImageContext(size); - [image drawInRect:CGRectMake(0, 0, size.width, size.height)]; - UIImage * newimage = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - return newimage; -} - -+ (UIImage*)imageWithImage:(UIImage *)image convertToHeight:(float)height { - float ratio = image.size.height / height; - float width = image.size.width / ratio; - CGSize size = CGSizeMake(width, height); - UIGraphicsBeginImageContext(size); - [image drawInRect:CGRectMake(0, 0, size.width, size.height)]; - UIImage * newimage = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - return newimage; -} - -+ (UIImage*)imageWithImage:(UIImage *)image convertToWidth:(float)width { - float ratio = image.size.width / width; - float height = image.size.height / ratio; - CGSize size = CGSizeMake(width, height); - UIGraphicsBeginImageContext(size); - [image drawInRect:CGRectMake(0, 0, size.width, size.height)]; - UIImage * newimage = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - return newimage; -} - -+ (UIImage*)imageWithImage:(UIImage *)image fitInsideWidth:(float)width fitInsideHeight:(float)height { - if (image.size.height >= image.size.width) { - return [UIImage imageWithImage:image convertToWidth:width]; - } else { - return [UIImage imageWithImage:image convertToHeight:height]; - } -} - -+ (UIImage*)imageWithImage:(UIImage *)image fitOutsideWidth:(float)width fitOutsideHeight:(float)height { - if (image.size.height >= image.size.width) { - return [UIImage imageWithImage:image convertToHeight:height]; - } else { - return [UIImage imageWithImage:image convertToWidth:width]; - } -} - -+ (UIImage*)imageWithImage:(UIImage *)image cropToWidth:(float)width cropToHeight:(float)height { - CGSize size = [image size]; - CGRect rect = CGRectMake(((size.width-width) / 2.0f), ((size.height-height) / 2.0f), width, height); - CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], rect); - UIImage * img = [UIImage imageWithCGImage:imageRef]; - CGImageRelease(imageRef); - return img; -} - -@end diff --git a/Juick/User.h b/Juick/User.h deleted file mode 100644 index 84300f3..0000000 --- a/Juick/User.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// User.h -// Juick -// -// Created by Vitaly on 01.02.14. -// Copyright (c) 2014 com.juick. All rights reserved. -// - -#import -#import "PDKeychainBindings.h" -#import "SIAlertView.h" -#import "APIClient.h" -#import "YYModel.h" - -@interface User : NSObject -@property (nonatomic, strong) NSString *uname; -@property (nonatomic, strong) NSString *uid; - -+ (void) get:(NSString *)name callback:(void(^)(User *))callback; - -+ (BOOL) isAuthenticated; - -+ (void) checkIsValid:(void(^)(BOOL))callback; - -+ (void) throwUnableToLogin; - -@end diff --git a/Juick/User.m b/Juick/User.m deleted file mode 100644 index f4b1e00..0000000 --- a/Juick/User.m +++ /dev/null @@ -1,49 +0,0 @@ -// -// User.m -// Juick -// -// Created by Vitaly on 01.02.14. -// Copyright (c) 2014 com.juick. All rights reserved. -// - -#import "User.h" - - -@implementation User - -+(BOOL) isAuthenticated { - return [[PDKeychainBindings sharedKeychainBindings] stringForKey:@"com.juick.username"] != nil; -} - -+(void) throwUnableToLogin { - SIAlertView *alert = [[SIAlertView alloc] initWithTitle:@"Error" andMessage:@"Unable to login, check username/password, or network connectivity"]; - [alert addButtonWithTitle:@"OK" type:SIAlertViewButtonTypeCancel handler:^(SIAlertView *alertView) { - // <#code#> - }]; - [alert show]; -} - -+(void) checkIsValid:(void (^)(BOOL))callback { - AFHTTPSessionManager *manager = [APIClient sharedClient].manager; - [manager.requestSerializer setAuthorizationHeaderFieldWithUsername:[[PDKeychainBindings sharedKeychainBindings] stringForKey:@"com.juick.username"] password:[[PDKeychainBindings sharedKeychainBindings] stringForKey:@"com.juick.password"]]; - [manager POST:@"/post" parameters:nil progress:nil success:nil failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { - NSInteger statusCode = ((NSHTTPURLResponse *)task.response).statusCode; - if (statusCode == 400) { - callback(YES); - } else { - [manager.requestSerializer setAuthorizationHeaderFieldWithUsername:nil password:nil]; - callback(NO); - } - }];} - -+(void) get:(NSString *) name callback:(void(^)(User *))callback { - AFHTTPSessionManager *manager = [APIClient sharedClient].manager; - NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:name, @"uname", nil]; - [manager GET:@"/users" parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { - callback([User yy_modelWithJSON:[(NSArray *)responseObject firstObject]]); - } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { - callback(nil); - }]; -} - -@end diff --git a/Juick/ViewControllers/LoginViewController.h b/Juick/ViewControllers/LoginViewController.h new file mode 100644 index 0000000..bf980fa --- /dev/null +++ b/Juick/ViewControllers/LoginViewController.h @@ -0,0 +1,15 @@ +// +// LoginViewController.h +// Juick +// +// Created by Vitaly on 30.01.14. +// Copyright (c) 2014 com.juick. All rights reserved. +// + +#import +#import "XLForm.h" +#import "PDKeychainbindingsController.h" + +@interface LoginViewController : XLFormViewController + +@end diff --git a/Juick/ViewControllers/LoginViewController.m b/Juick/ViewControllers/LoginViewController.m new file mode 100644 index 0000000..eedc6d3 --- /dev/null +++ b/Juick/ViewControllers/LoginViewController.m @@ -0,0 +1,92 @@ +// +// LoginViewController.m +// Juick +// +// Created by Vitaly on 30.01.14. +// Copyright (c) 2014 com.juick. All rights reserved. +// + +#import "LoginViewController.h" +#import "User.h" +#import "ColorScheme.h" + +@implementation LoginViewController + +- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self){ + [self initializeForm]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)aDecoder { + self = [super initWithCoder:aDecoder]; + if (self){ + [self initializeForm]; + } + return self; +} + +- (void)initializeForm { + self.title = @"Sign in"; + [self.view setBackgroundColor:[ColorScheme mainBackground]]; + + self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel + target:self action:@selector(cancelSignIn)]; + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave + target:self action:@selector(doneSignIn)]; + XLFormDescriptor *form = [XLFormDescriptor formDescriptorWithTitle:@"Sign in"]; + form.rowNavigationOptions = XLFormRowNavigationOptionEnabled; + XLFormSectionDescriptor *section = [XLFormSectionDescriptor formSection]; + [form addFormSection:section]; + XLFormRowDescriptor * usernameRow = [XLFormRowDescriptor + formRowDescriptorWithTag:@"com.juick.username" + rowType:XLFormRowDescriptorTypeText title:@"Username"]; + usernameRow.value = [[PDKeychainBindings sharedKeychainBindings] stringForKey:@"com.juick.username"]; + [section addFormRow:usernameRow]; + XLFormRowDescriptor * passwordRow = [XLFormRowDescriptor + formRowDescriptorWithTag:@"com.juick.password" + rowType:XLFormRowDescriptorTypePassword title:@"Password"]; + passwordRow.value = [[PDKeychainBindings sharedKeychainBindings] stringForKey:@"com.juick.password"]; + [section addFormRow:passwordRow]; + + self.form = form; +} + + +- (void) cancelSignIn { + CATransition* transition = [CATransition animation]; + transition.duration = 0.3; + transition.type = kCATransitionFade; + transition.subtype = kCATransitionFromTop; + + [self.navigationController.view.layer addAnimation:transition forKey:kCATransition]; + [self.navigationController popViewControllerAnimated:NO]; +} + +- (void) doneSignIn { + [User checkIsValid:^(BOOL success) { + if (success) { + CATransition* transition = [CATransition animation]; + transition.duration = 0.3; + transition.type = kCATransitionFade; + transition.subtype = kCATransitionFromTop; + + [self.navigationController.view.layer addAnimation:transition forKey:kCATransition]; + [self.navigationController popToRootViewControllerAnimated:NO]; + } else { + [User throwUnableToLogin]; + } + }]; + +} + +-(void) formRowDescriptorValueHasChanged:(XLFormRowDescriptor *)formRow oldValue:(id)oldValue newValue:(id)newValue { + [super formRowDescriptorValueHasChanged:formRow oldValue:oldValue newValue:newValue]; + if ([newValue isKindOfClass:[NSString class]]) { + [[PDKeychainBindings sharedKeychainBindings] setObject:newValue forKey:formRow.tag]; + } +} + +@end diff --git a/Juick/ViewControllers/MessagesViewController.h b/Juick/ViewControllers/MessagesViewController.h new file mode 100644 index 0000000..38123bd --- /dev/null +++ b/Juick/ViewControllers/MessagesViewController.h @@ -0,0 +1,15 @@ +// +// MasterViewController.h +// Juick +// +// Created by Vitaly Takmazov on 26.10.13. +// Copyright (c) 2013 com.juick. All rights reserved. +// + +#import + +@interface MessagesViewController : UITableViewController +- (void)loadFromPath:(NSString *)messagesPath withParams:(NSDictionary *)params withTitle:(NSString *)title; +- (void) refreshData; +- (void) composePressed; +@end diff --git a/Juick/ViewControllers/MessagesViewController.m b/Juick/ViewControllers/MessagesViewController.m new file mode 100644 index 0000000..28e7613 --- /dev/null +++ b/Juick/ViewControllers/MessagesViewController.m @@ -0,0 +1,181 @@ +// +// MasterViewController.m +// Juick +// +// Created by Vitaly Takmazov on 26.10.13. +// Copyright (c) 2013 com.juick. All rights reserved. +// + +#import "MessagesViewController.h" +#import "MessageCell.h" + +#import "Message.h" +#import "ColorScheme.h" + +#import "NewPostViewController.h" + + +#import "NSURL+PathParameters.h" + +static NSString *CellIdentifier = @"MessageCell"; + + +@interface MessagesViewController (); + +@property(nonatomic, strong) NSMutableArray *messages; +@property(nonatomic, assign) Boolean dataLoading; +@property(nonatomic, strong) NSString *path; +@property(nonatomic, strong) NSMutableDictionary *params; + +@end + +@implementation MessagesViewController + +- (void)loadFromPath:(NSString *)messagesPath withParams:(NSDictionary *)params withTitle:(NSString *)title +{ + [self setPath:messagesPath]; + [self setParams:[[NSMutableDictionary alloc] initWithDictionary:params]]; + self.title = title; + __weak MessagesViewController * weakSelf = self; + [self.messages removeAllObjects]; + [weakSelf refreshData]; +} + +- (void) refreshData { + if ([self.path isEqualToString:[Message threadUrl]]) { + [self.messages removeAllObjects]; + } + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + self.dataLoading = YES; + [Message pullNextFromPath:self.path params:self.params callback:^(NSArray *next) { + dispatch_async(dispatch_get_main_queue(), ^{ + [self.messages addObjectsFromArray:next]; + [self.tableView reloadData]; + [self.refreshControl endRefreshing]; + self.dataLoading = NO; + }); + }]; + }); +} + +- (UIStatusBarStyle)preferredStatusBarStyle +{ + return UIStatusBarStyleLightContent; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + self.dataLoading = NO; + [self.view setBackgroundColor:[ColorScheme mainBackground]]; + self.messages = [NSMutableArray array]; + + SWRevealViewController *revealController = [self revealViewController]; + if (revealController) { + // TODO: add to thread view too + [self.view addGestureRecognizer:[revealController panGestureRecognizer]]; + } + + [self.tableView registerNib:[UINib nibWithNibName:@"MessageCell" bundle:nil] forCellReuseIdentifier:CellIdentifier]; + self.tableView.rowHeight = UITableViewAutomaticDimension; + self.tableView.estimatedRowHeight = 500.0f; + self.refreshControl = [UIRefreshControl new]; + [self.refreshControl addTarget:self action:@selector(refreshData) forControlEvents:UIControlEventValueChanged];} + +- (void) composePressed { + CATransition* transition = [CATransition animation]; + transition.duration = 0.3; + transition.type = kCATransitionFade; + transition.subtype = kCATransitionFromTop; + + [self.navigationController.view.layer addAnimation:transition forKey:kCATransition]; + [self.navigationController pushViewController:[[NewPostViewController alloc] init] animated:NO]; +} + +- (void)viewDidAppear:(BOOL)animated +{ + [super viewDidAppear:animated]; + if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) { + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(contentSizeCategoryChanged:) + name:UIContentSizeCategoryDidChangeNotification + object:nil]; + } +} + +- (void)viewDidDisappear:(BOOL)animated +{ + [super viewDidDisappear:animated]; + if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) { + [[NSNotificationCenter defaultCenter] removeObserver:self + name:UIContentSizeCategoryDidChangeNotification + object:nil]; + } +} + +- (void)contentSizeCategoryChanged:(NSNotification *)notification +{ + [self.tableView reloadData]; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return _messages.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + MessageCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; + Message *msg = [_messages objectAtIndex:indexPath.row]; + [cell setMessage:msg]; + if ([msg.attach length] > 0) { + __weak MessagesViewController * weakSelf = self; + [cell.attach yy_setImageWithURL:[NSURL URLWithString:msg.attach] placeholder:[UIImage imageNamed:@"AttachPlaceholder"] options:YYWebImageOptionProgressiveBlur | YYWebImageOptionSetImageWithFadeAnimation completion:^(UIImage * _Nullable image, NSURL * _Nonnull url, YYWebImageFromType from, YYWebImageStage stage, NSError * _Nullable error) { + dispatch_async(dispatch_get_main_queue(), ^{ + [cell setNeedsUpdateConstraints]; + [cell updateConstraintsIfNeeded]; + [cell setNeedsLayout]; + [cell layoutIfNeeded]; + }); + }]; + + } else { + cell.attach.image = nil; + } + + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + if ([self.path isEqualToString:[Message threadUrl]]) + return; + Message *msg = [_messages objectAtIndex:indexPath.row]; + MessagesViewController *threadViewController = [[MessagesViewController alloc] init]; + [threadViewController loadFromPath:[Message threadUrl] withParams:[NSDictionary dictionaryWithObjectsAndKeys:msg.MID, @"mid", nil] withTitle:@"Thread"]; + [self.navigationController pushViewController:threadViewController animated:NO]; +} + +-(void)splitViewController:(UISplitViewController *)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem { + self.navigationItem.leftBarButtonItem = nil; +} + +-(void)splitViewController:(UISplitViewController *)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)pc { + self.navigationItem.leftBarButtonItem = barButtonItem; +} + +-(void)scrollViewDidScroll:(UIScrollView *)scrollView_ { + CGFloat actualPosition = scrollView_.contentOffset.y; + CGFloat contentHeight = scrollView_.contentSize.height - scrollView_.contentSize.height / 2; + if (actualPosition >= contentHeight && !self.dataLoading) { + NSNumber *lastMid = ((Message *)[self.messages lastObject]).MID; + if (![self.path isEqualToString:[Message threadUrl]]) { + [self.params setValue:lastMid forKey:@"before_mid"]; + } + [self refreshData]; + } +} + + +@end diff --git a/Juick/ViewControllers/NewPostViewController.h b/Juick/ViewControllers/NewPostViewController.h new file mode 100644 index 0000000..ceaca49 --- /dev/null +++ b/Juick/ViewControllers/NewPostViewController.h @@ -0,0 +1,13 @@ +// +// NewPostViewController.h +// Juick +// +// Created by Vitaly Takmazov on 07.11.13. +// Copyright (c) 2013 com.juick. All rights reserved. +// + +#import + +@interface NewPostViewController : UIViewController + +@end diff --git a/Juick/ViewControllers/NewPostViewController.m b/Juick/ViewControllers/NewPostViewController.m new file mode 100644 index 0000000..8c8fbf0 --- /dev/null +++ b/Juick/ViewControllers/NewPostViewController.m @@ -0,0 +1,61 @@ +// +// NewPostViewController.m +// Juick +// +// Created by Vitaly Takmazov on 07.11.13. +// Copyright (c) 2013 com.juick. All rights reserved. +// + +#import "NewPostViewController.h" + +@interface NewPostViewController () + +@end + +@implementation NewPostViewController + +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil +{ + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { + // Custom initialization + } + return self; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel + target:self action:@selector(cancelCompose)]; + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone + target:self action:@selector(doneCompose)]; +} + +- (void) cancelCompose { + CATransition* transition = [CATransition animation]; + transition.duration = 0.3; + transition.type = kCATransitionFade; + transition.subtype = kCATransitionFromTop; + + [self.navigationController.view.layer addAnimation:transition forKey:kCATransition]; + [self.navigationController popViewControllerAnimated:NO]; +} + +- (void) doneCompose { + CATransition* transition = [CATransition animation]; + transition.duration = 0.3; + transition.type = kCATransitionFade; + transition.subtype = kCATransitionFromTop; + + [self.navigationController.view.layer addAnimation:transition forKey:kCATransition]; + [self.navigationController popToRootViewControllerAnimated:NO]; +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +@end diff --git a/Juick/ViewControllers/RevealPanelViewController.h b/Juick/ViewControllers/RevealPanelViewController.h new file mode 100644 index 0000000..ff5006c --- /dev/null +++ b/Juick/ViewControllers/RevealPanelViewController.h @@ -0,0 +1,16 @@ +// +// RevealPanelViewController.h +// Juick +// +// Created by Vitaly Takmazov on 04.11.13. +// Copyright (c) 2013 com.juick. All rights reserved. +// + +#import +#import +#import "LoginViewController.h" + +@interface RevealPanelViewController : UIViewController +@property (nonatomic, strong) IBOutlet UITableView *tableView; +@property (nonatomic, strong) IBOutlet UIButton *signButton; +@end diff --git a/Juick/ViewControllers/RevealPanelViewController.m b/Juick/ViewControllers/RevealPanelViewController.m new file mode 100644 index 0000000..d890f97 --- /dev/null +++ b/Juick/ViewControllers/RevealPanelViewController.m @@ -0,0 +1,182 @@ +// +// RevealPanelViewController.m +// Juick +// +// Created by Vitaly Takmazov on 04.11.13. +// Copyright (c) 2013 com.juick. All rights reserved. +// + +#import "SWRevealViewController.h" + +#import "RevealPanelViewController.h" +#import "MessagesViewController.h" + +#import "ColorScheme.h" +#import "NSURL+PathParameters.h" +#import "NavCell.h" +#import "Message.h" +#import "User.h" + + +static NSString *CellIdentifier = @"NavCell"; + +@interface RevealPanelViewController () + +@end + +@implementation RevealPanelViewController + +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil +{ + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { + // Custom initialization + } + return self; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + [self.view setBackgroundColor:[ColorScheme mainBackground]]; + self.tableView = [[UITableView alloc] init]; + [self.tableView setBackgroundColor:[ColorScheme mainBackground]]; + self.tableView.delegate = self; + self.tableView.dataSource = self; + [self.tableView setSeparatorInset:UIEdgeInsetsZero]; + self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; + self.tableView.separatorColor =[UIColor darkGrayColor]; + [self.tableView registerNib:[UINib nibWithNibName:@"NavCell" bundle:nil] forCellReuseIdentifier:CellIdentifier]; + [self.view addSubview:self.tableView]; + self.signButton = [[UIButton alloc] init]; + [self.signButton addTarget:self action:@selector(signInOut) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:self.signButton]; + [self refreshInfo]; +} + +-(void) refreshInfo { + NSString *text; + UIColor *color; + + if ([User isAuthenticated]) { + text = @"Sign Out"; + color = [UIColor redColor]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ + [User get:[[PDKeychainBindings sharedKeychainBindings] stringForKey:@"com.juick.username"] callback:^(User *user) { + if (user != nil) { + /*[self.titleView.image setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://i.juick.com/as/%@.png", user.uid]]]; + [self.titleView.title setText:user.uname];*/ + } + }]; + }); + } else { + text = @"Sign In"; + color = [UIColor greenColor]; + } + [self.signButton setTitle:text forState:UIControlStateNormal]; + [self.signButton setBackgroundColor:color]; +} + +-(void) signInOut { + [self refreshInfo]; + [self pushLoginForm]; +} + +-(void) viewWillLayoutSubviews { + [super viewWillLayoutSubviews]; + self.tableView.frame = CGRectMake(0, 0, self.view.bounds.size.width, 400); + self.signButton.frame = CGRectMake(0, self.view.bounds.size.height - 40, self.view.bounds.size.width, 40); +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + +- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return 4; +} + +- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { + return 32 + 10*2; // icon size + insets +} + +- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + NavCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; + NSInteger row = indexPath.row; + [cell.contentView setBackgroundColor:[UIColor whiteColor]]; + cell.icon.font = [UIFont fontWithName:kFontAwesomeFamilyName size:32.f]; + cell.icon.textColor = [ColorScheme linkColor]; + cell.descriptionText.textColor = [ColorScheme linkColor]; + if (row == 0) { + cell.descriptionText.text = @"My feed"; + cell.icon.text = [NSString fontAwesomeIconStringForEnum:FAIconHome]; + + } else if (row == 1) { + cell.descriptionText.text = @"Popular"; + cell.icon.text = [NSString fontAwesomeIconStringForEnum:FAIconComments]; + } else if (row == 2) { + cell.descriptionText.text = @"Discover"; + cell.icon.text = [NSString fontAwesomeIconStringForEnum:FAIconSearch]; + } else if (row == 3) { + cell.descriptionText.text = @"Images"; + cell.icon.text = [NSString fontAwesomeIconStringForEnum:FAIconPicture]; + } + UIView *bgColorView = [[UIView alloc] init]; + bgColorView.backgroundColor = [UIColor blackColor]; + bgColorView.layer.masksToBounds = YES; + [cell setSelectedBackgroundView:bgColorView]; + [cell.contentView setNeedsLayout]; + [cell.contentView layoutIfNeeded]; + return cell; +} + +- (void) pushLoginForm { + [self.revealViewController revealToggle:self]; + UIViewController *loginView = [[LoginViewController alloc] init]; + UINavigationController *messages = (UINavigationController *)self.revealViewController.frontViewController; + [messages pushViewController:loginView animated:YES]; +} + +- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + NSInteger row = indexPath.row; + NSString *targetPath; + NSDictionary *targetParams; + NSString *targetTitle; + if (row == 0) { + if ([[PDKeychainBindings sharedKeychainBindings] stringForKey:@"com.juick.username"] == nil) { + [self pushLoginForm]; + return; + } else { + targetTitle = @"My feed"; + targetPath = [Message feedUrl]; + } + + } + if (row == 1) { + targetTitle = @"Popular"; + targetPath = [Message messagesUrl]; + targetParams = [NSDictionary dictionaryWithObjectsAndKeys:@"1", @"popular", nil]; + } else if (row == 2) { + targetTitle = @"Discover"; + targetPath = [Message messagesUrl]; + } + if (row == 3) { + targetTitle = @"Images"; + targetPath = [Message messagesUrl]; + targetParams = [NSDictionary dictionaryWithObjectsAndKeys:@"photo", @"media", nil]; + } + SWRevealViewController *reveal = self.revealViewController; + UINavigationController *front = (UINavigationController *)reveal.frontViewController; + MessagesViewController *messages = (MessagesViewController *)[front.viewControllers objectAtIndex:0]; + [messages loadFromPath:targetPath withParams:targetParams withTitle:targetTitle]; + [reveal revealToggle:self]; +} + +@end diff --git a/Juick/en.lproj/InfoPlist.strings b/Juick/en.lproj/InfoPlist.strings deleted file mode 100644 index 477b28f..0000000 --- a/Juick/en.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/Juick/main.m b/Juick/main.m deleted file mode 100644 index 67b222f..0000000 --- a/Juick/main.m +++ /dev/null @@ -1,18 +0,0 @@ -// -// main.m -// Juick -// -// Created by Vitaly Takmazov on 26.10.13. -// Copyright (c) 2013 com.juick. All rights reserved. -// - -#import - -#import "AppDelegate.h" - -int main(int argc, char * argv[]) -{ - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/JuickTests/JuickTests-Info.plist b/JuickTests/JuickTests-Info.plist deleted file mode 100644 index 169b6f7..0000000 --- a/JuickTests/JuickTests-Info.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - - diff --git a/JuickTests/Supporting Files/JuickTests-Info.plist b/JuickTests/Supporting Files/JuickTests-Info.plist new file mode 100644 index 0000000..169b6f7 --- /dev/null +++ b/JuickTests/Supporting Files/JuickTests-Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/JuickTests/Supporting Files/en.lproj/InfoPlist.strings b/JuickTests/Supporting Files/en.lproj/InfoPlist.strings new file mode 100644 index 0000000..477b28f --- /dev/null +++ b/JuickTests/Supporting Files/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/JuickTests/en.lproj/InfoPlist.strings b/JuickTests/en.lproj/InfoPlist.strings deleted file mode 100644 index 477b28f..0000000 --- a/JuickTests/en.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - -- cgit v1.2.3