diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..e6903ec75 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +Coding_iOS/Resources/* linguist-vendored diff --git a/.gitignore b/.gitignore index 2df519258..1ef09afad 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ DerivedData *.xcuserstate Coding_iOS/Coding_iOS-Prefix.pch +Coding_iOS/Coding_Enterprise_iOS-Prefix.pch .DS_Store # CocoaPods # @@ -25,6 +26,7 @@ Coding_iOS/Coding_iOS-Prefix.pch # you should judge for yourself, the pros and cons are mentioned at: # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control # +Carthage/ Pods/ .idea/ *.xcbkptlist diff --git a/.gitmodules b/.gitmodules index 67b2b3e9a..e69de29bb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +0,0 @@ -[submodule "Coding_iOS/Resources/webview"] - path = Coding_iOS/Resources/webview - url = git://git.coding.net/coding/CodingAppWebviewTemplate.git diff --git a/Cartfile b/Cartfile new file mode 100644 index 000000000..2101d38ab --- /dev/null +++ b/Cartfile @@ -0,0 +1,2 @@ + +github "libgit2/objective-git" diff --git a/Cartfile.resolved b/Cartfile.resolved new file mode 100644 index 000000000..efc011b20 --- /dev/null +++ b/Cartfile.resolved @@ -0,0 +1 @@ +github "libgit2/objective-git" "0.14.1" diff --git a/Coding_iOS.xcodeproj/project.pbxproj b/Coding_iOS.xcodeproj/project.pbxproj index 7ff3f7983..2670133d7 100644 --- a/Coding_iOS.xcodeproj/project.pbxproj +++ b/Coding_iOS.xcodeproj/project.pbxproj @@ -7,6 +7,17 @@ objects = { /* Begin PBXBuildFile section */ + 09A058801E0AA97000C1CA3F /* ActivenessModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A0587F1E0AA97000C1CA3F /* ActivenessModel.m */; }; + 09A058891E0AA9AE00C1CA3F /* ActivityMonScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A058821E0AA9AE00C1CA3F /* ActivityMonScrollView.m */; }; + 09A0588A1E0AA9AE00C1CA3F /* ActivityView.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A058841E0AA9AE00C1CA3F /* ActivityView.m */; }; + 09A0588C1E0AA9AE00C1CA3F /* UserActiveStatusView.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A058881E0AA9AE00C1CA3F /* UserActiveStatusView.m */; }; + 09A0588F1E0AA9D600C1CA3F /* UserActiveGraphCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A0588E1E0AA9D600C1CA3F /* UserActiveGraphCell.m */; }; + 09A058921E0AA9FC00C1CA3F /* EaseUserInfoCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A058911E0AA9FB00C1CA3F /* EaseUserInfoCell.m */; }; + 09A058951E0AAA2F00C1CA3F /* TaskSelectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A058941E0AAA2F00C1CA3F /* TaskSelectionView.m */; }; + 09A058981E0AAA5300C1CA3F /* ScreenView.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A058971E0AAA5300C1CA3F /* ScreenView.m */; }; + 09A0589B1E0AAA7200C1CA3F /* ScreenCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A0589A1E0AAA7200C1CA3F /* ScreenCell.m */; }; + 09A0589E1E0AAA8800C1CA3F /* TaskSelectionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A0589D1E0AAA8800C1CA3F /* TaskSelectionCell.m */; }; + 09A058A11E0AAACA00C1CA3F /* TagsScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A058A01E0AAACA00C1CA3F /* TagsScrollView.m */; }; 0A03E6D31ABD0F690034BB8E /* LocationHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A03E6D21ABD0F690034BB8E /* LocationHelper.m */; }; 0A0519E21ABA918100551B61 /* TweetSendDetailLoctionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A0519E01ABA918100551B61 /* TweetSendDetailLoctionCell.m */; }; 0A0519E31ABA918100551B61 /* TweetSendDetailLoctionCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0A0519E11ABA918100551B61 /* TweetSendDetailLoctionCell.xib */; }; @@ -58,9 +69,6 @@ 13FB5D3B1CA17A6400EE127C /* PR_push@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D1A1CA17A6400EE127C /* PR_push@3x.png */; }; 13FB5D3C1CA17A6400EE127C /* PR_update_content@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D1B1CA17A6400EE127C /* PR_update_content@2x.png */; }; 13FB5D3D1CA17A6400EE127C /* PR_update_content@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D1C1CA17A6400EE127C /* PR_update_content@3x.png */; }; - 13FB5D3E1CA17A6400EE127C /* EPointLikeHead@1x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D1D1CA17A6400EE127C /* EPointLikeHead@1x.png */; }; - 13FB5D3F1CA17A6400EE127C /* EPointLikeHead@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D1E1CA17A6400EE127C /* EPointLikeHead@2x.png */; }; - 13FB5D401CA17A6400EE127C /* EPointLikeHead@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D1F1CA17A6400EE127C /* EPointLikeHead@3x.png */; }; 13FB5D411CA17A6400EE127C /* PR_refuse@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D201CA17A6400EE127C /* PR_refuse@2x.png */; }; 13FB5D421CA17A6400EE127C /* PR_refuse@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D211CA17A6400EE127C /* PR_refuse@3x.png */; }; 13FB5D431CA17A6400EE127C /* PR_grant_undo@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D221CA17A6400EE127C /* PR_grant_undo@2x.png */; }; @@ -69,12 +77,10 @@ 13FB5D461CA17A6400EE127C /* merge-request coding@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D251CA17A6400EE127C /* merge-request coding@3x.png */; }; 13FB5D471CA17A6400EE127C /* PR_mergeChanges@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D261CA17A6400EE127C /* PR_mergeChanges@2x.png */; }; 13FB5D481CA17A6400EE127C /* PR_mergeChanges@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D271CA17A6400EE127C /* PR_mergeChanges@3x.png */; }; - 13FB5D491CA17A6400EE127C /* PointLikeHead@1x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D281CA17A6400EE127C /* PointLikeHead@1x.png */; }; 13FB5D4A1CA17A6400EE127C /* PointLikeHead@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D291CA17A6400EE127C /* PointLikeHead@2x.png */; }; 13FB5D4B1CA17A6400EE127C /* PointLikeHead@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D2A1CA17A6400EE127C /* PointLikeHead@3x.png */; }; 13FB5D4C1CA17A6400EE127C /* PR_review@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D2B1CA17A6400EE127C /* PR_review@2x.png */; }; 13FB5D4D1CA17A6400EE127C /* PR_review@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D2C1CA17A6400EE127C /* PR_review@3x.png */; }; - 13FB5D4E1CA17A6400EE127C /* PRReviewer@1x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D2D1CA17A6400EE127C /* PRReviewer@1x.png */; }; 13FB5D4F1CA17A6400EE127C /* PRReviewer@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D2E1CA17A6400EE127C /* PRReviewer@2x.png */; }; 13FB5D501CA17A6400EE127C /* PRReviewer@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D2F1CA17A6400EE127C /* PRReviewer@3x.png */; }; 13FB5D511CA17A6400EE127C /* PR_review_undo@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D301CA17A6400EE127C /* PR_review_undo@2x.png */; }; @@ -90,7 +96,6 @@ 3A3878491AE36ED70078D5DE /* TopicListButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A3878481AE36ED70078D5DE /* TopicListButton.m */; }; 3A38784C1AE36EF00078D5DE /* TopicListView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A38784B1AE36EF00078D5DE /* TopicListView.m */; }; 3A38784F1AE557700078D5DE /* TopicPreviewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A38784E1AE557700078D5DE /* TopicPreviewCell.m */; }; - 404ED88BE5253A2BE89DDC30 /* libPods-Coding_iOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C664C272FECA8523C17A4109 /* libPods-Coding_iOS.a */; }; 4E0022831B72095E005308DE /* PointRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0022821B72095E005308DE /* PointRecord.m */; }; 4E0022861B720966005308DE /* PointRecords.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0022851B720966005308DE /* PointRecords.m */; }; 4E0022891B721516005308DE /* PointRecordsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0022881B721516005308DE /* PointRecordsViewController.m */; }; @@ -101,39 +106,24 @@ 4E00229C1B735075005308DE /* EAIntroPage.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0022991B735075005308DE /* EAIntroPage.m */; }; 4E00229D1B735075005308DE /* EAIntroView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E00229B1B735075005308DE /* EAIntroView.m */; }; 4E0022A01B7360B1005308DE /* FunctionIntroManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E00229F1B7360B1005308DE /* FunctionIntroManager.m */; }; - 4E0022A61B7362EF005308DE /* intro_page0_ip4@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E0022A21B7362EF005308DE /* intro_page0_ip4@2x.png */; }; - 4E0022A71B7362EF005308DE /* intro_page0_ip5@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E0022A31B7362EF005308DE /* intro_page0_ip5@2x.png */; }; - 4E0022A81B7362EF005308DE /* intro_page0_ip6+@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E0022A41B7362EF005308DE /* intro_page0_ip6+@3x.png */; }; - 4E0022A91B7362EF005308DE /* intro_page0_ip6@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E0022A51B7362EF005308DE /* intro_page0_ip6@2x.png */; }; 4E03AC9A1A5BDDF9002B000B /* STARTIMAGE.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 4E03AC991A5BDDF9002B000B /* STARTIMAGE.jpg */; }; 4E03ACA61A5D2060002B000B /* UIVerticalAlignmentLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E03ACA51A5D2060002B000B /* UIVerticalAlignmentLabel.m */; }; 4E07D3081A4A96EA009EDDF2 /* FileListUploadCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E07D3071A4A96EA009EDDF2 /* FileListUploadCell.m */; }; 4E07D30D1A4A9F45009EDDF2 /* btn_file_cancel@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E07D30B1A4A9F45009EDDF2 /* btn_file_cancel@2x.png */; }; 4E07D30E1A4A9F45009EDDF2 /* btn_file_reDo@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E07D30C1A4A9F45009EDDF2 /* btn_file_reDo@2x.png */; }; 4E07D3111A4D1484009EDDF2 /* EaseStartView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E07D3101A4D1484009EDDF2 /* EaseStartView.m */; }; - 4E07D3151A4D3CA6009EDDF2 /* icon_user_monkey@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E07D3121A4D3CA6009EDDF2 /* icon_user_monkey@2x.png */; }; - 4E07D3161A4D3CA6009EDDF2 /* logo_coding@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E07D3131A4D3CA6009EDDF2 /* logo_coding@2x.png */; }; 4E0849801A918A7F00BD27F6 /* coding_emoji_38@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E08497A1A918A7F00BD27F6 /* coding_emoji_38@2x.png */; }; 4E0849811A918A7F00BD27F6 /* coding_emoji_39@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E08497B1A918A7F00BD27F6 /* coding_emoji_39@2x.png */; }; 4E0849821A918A7F00BD27F6 /* coding_emoji_40@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E08497C1A918A7F00BD27F6 /* coding_emoji_40@2x.png */; }; 4E0849831A918A7F00BD27F6 /* coding_emoji_41@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E08497D1A918A7F00BD27F6 /* coding_emoji_41@2x.png */; }; 4E0849841A918A7F00BD27F6 /* coding_emoji_42@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E08497E1A918A7F00BD27F6 /* coding_emoji_42@2x.png */; }; 4E0849851A918A7F00BD27F6 /* coding_emoji_43@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E08497F1A918A7F00BD27F6 /* coding_emoji_43@2x.png */; }; - 4E095A151D9534CB00E63D9E /* intro_page_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E095A111D9534CB00E63D9E /* intro_page_selected@2x.png */; }; - 4E095A161D9534CB00E63D9E /* intro_page_selected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E095A121D9534CB00E63D9E /* intro_page_selected@3x.png */; }; - 4E095A171D9534CB00E63D9E /* intro_page_unselected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E095A131D9534CB00E63D9E /* intro_page_unselected@2x.png */; }; - 4E095A181D9534CB00E63D9E /* intro_page_unselected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E095A141D9534CB00E63D9E /* intro_page_unselected@3x.png */; }; 4E095A591B690494008DC439 /* CodingBanner.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E095A581B690494008DC439 /* CodingBanner.m */; }; 4E095A5C1B6907AA008DC439 /* CodingBannersView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E095A5B1B6907AA008DC439 /* CodingBannersView.m */; }; 4E095A661B6909F9008DC439 /* AutoSlideScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E095A5F1B6909F9008DC439 /* AutoSlideScrollView.m */; }; 4E095A681B6909F9008DC439 /* NSTimer+Addition.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E095A631B6909F9008DC439 /* NSTimer+Addition.m */; }; 4E095A6D1B69F920008DC439 /* banner__page_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E095A6B1B69F920008DC439 /* banner__page_selected@2x.png */; }; 4E095A6E1B69F920008DC439 /* banner__page_unselected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E095A6C1B69F920008DC439 /* banner__page_unselected@2x.png */; }; - 4E095A7B1B6B1E40008DC439 /* calendar_0x95B763@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E095A761B6B1E40008DC439 /* calendar_0x95B763@2x.png */; }; - 4E095A7C1B6B1E40008DC439 /* calendar_0x9AAFC2@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E095A771B6B1E40008DC439 /* calendar_0x9AAFC2@2x.png */; }; - 4E095A7D1B6B1E40008DC439 /* calendar_0xB5B5B5@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E095A781B6B1E40008DC439 /* calendar_0xB5B5B5@2x.png */; }; - 4E095A7E1B6B1E40008DC439 /* calendar_0xF24B4B@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E095A791B6B1E40008DC439 /* calendar_0xF24B4B@2x.png */; }; - 4E095A7F1B6B1E40008DC439 /* calendar_0xF5A523@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E095A7A1B6B1E40008DC439 /* calendar_0xF5A523@2x.png */; }; 4E095A831B6B24DE008DC439 /* task_description_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E095A801B6B24DE008DC439 /* task_description_icon@2x.png */; }; 4E095A841B6B24DE008DC439 /* time_clock_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E095A811B6B24DE008DC439 /* time_clock_icon@2x.png */; }; 4E095A851B6B24DE008DC439 /* topic_comment_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E095A821B6B24DE008DC439 /* topic_comment_icon@2x.png */; }; @@ -164,15 +154,12 @@ 4E0EF6EC1BF42E4B00F2FCC8 /* task_activity_icon_update_label@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E0EF6EB1BF42E4B00F2FCC8 /* task_activity_icon_update_label@2x.png */; }; 4E15C7D01A26D2F000FB8DAD /* FolderToMoveViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E15C7CF1A26D2F000FB8DAD /* FolderToMoveViewController.m */; }; 4E15C7D61A271A6300FB8DAD /* EaseToolBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E15C7D51A271A6300FB8DAD /* EaseToolBar.m */; }; - 4E19E7071BCE03CD00C66DC6 /* UIActionSheet+Front.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E19E7061BCE03CD00C66DC6 /* UIActionSheet+Front.m */; }; 4E1A22821AB1729700CFC14F /* ProjectInfoCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E1A22811AB1729700CFC14F /* ProjectInfoCell.m */; }; 4E1A22851AB172C400CFC14F /* ProjectItemsCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E1A22841AB172C400CFC14F /* ProjectItemsCell.m */; }; 4E1A22881AB1731600CFC14F /* ProjectDescriptionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E1A22871AB1731600CFC14F /* ProjectDescriptionCell.m */; }; 4E1A228B1AB1844F00CFC14F /* EaseGitButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E1A228A1AB1844F00CFC14F /* EaseGitButton.m */; }; 4E1D99161DCAE67D00BAE585 /* icon_file_folder_out@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E1D99121DCAE67D00BAE585 /* icon_file_folder_out@2x.png */; }; - 4E1D99171DCAE67D00BAE585 /* icon_file_folder_out@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E1D99131DCAE67D00BAE585 /* icon_file_folder_out@3x.png */; }; 4E1D99181DCAE67D00BAE585 /* icon_file_folder_share@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E1D99141DCAE67D00BAE585 /* icon_file_folder_share@2x.png */; }; - 4E1D99191DCAE67D00BAE585 /* icon_file_folder_share@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E1D99151DCAE67D00BAE585 /* icon_file_folder_share@3x.png */; }; 4E1D991C1DCAE69600BAE585 /* icon_file_share_logo@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E1D991A1DCAE69600BAE585 /* icon_file_share_logo@2x.png */; }; 4E1D991D1DCAE69600BAE585 /* icon_file_share_logo@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E1D991B1DCAE69600BAE585 /* icon_file_share_logo@3x.png */; }; 4E217F0C1A70EDC700F6DF88 /* SVModalWebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E217EF91A70EDC700F6DF88 /* SVModalWebViewController.m */; }; @@ -221,10 +208,19 @@ 4E2F6A6F1C43CA4B00A25502 /* member_type_75@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2F6A691C43CA4B00A25502 /* member_type_75@3x.png */; }; 4E2F6A701C43CA4B00A25502 /* member_type_90@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2F6A6A1C43CA4B00A25502 /* member_type_90@2x.png */; }; 4E2F6A711C43CA4B00A25502 /* member_type_90@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2F6A6B1C43CA4B00A25502 /* member_type_90@3x.png */; }; + 4E30683D1E0B781A00AEE0CE /* EADeviceToServerLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E3068281E0B781A00AEE0CE /* EADeviceToServerLog.m */; }; + 4E30683E1E0B781A00AEE0CE /* EANetTraceRoute.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E30682A1E0B781A00AEE0CE /* EANetTraceRoute.m */; }; + 4E30683F1E0B781A00AEE0CE /* LDNetConnect.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E30682D1E0B781A00AEE0CE /* LDNetConnect.m */; }; + 4E3068401E0B781A00AEE0CE /* LDNetDiagnoService.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E30682F1E0B781A00AEE0CE /* LDNetDiagnoService.m */; }; + 4E3068411E0B781A00AEE0CE /* LDNetGetAddress.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E3068311E0B781A00AEE0CE /* LDNetGetAddress.m */; }; + 4E3068421E0B781A00AEE0CE /* LDNetPing.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E3068331E0B781A00AEE0CE /* LDNetPing.m */; }; + 4E3068431E0B781A00AEE0CE /* LDNetTimer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E3068351E0B781A00AEE0CE /* LDNetTimer.m */; }; + 4E3068441E0B781A00AEE0CE /* LDNetTraceRoute.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E3068371E0B781A00AEE0CE /* LDNetTraceRoute.m */; }; + 4E3068451E0B781A00AEE0CE /* LDSimplePing.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E3068391E0B781A00AEE0CE /* LDSimplePing.m */; }; + 4E3068461E0B781A00AEE0CE /* NSData+gzip.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E30683C1E0B781A00AEE0CE /* NSData+gzip.m */; }; 4E35A99F1A3EC47E00CE35F1 /* FileViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E35A99E1A3EC47E00CE35F1 /* FileViewController.m */; }; 4E38CF5F1A7A28AF005536C0 /* CodeBranchTagButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E38CF5E1A7A28AF005536C0 /* CodeBranchTagButton.m */; }; 4E38CF621A7B7C99005536C0 /* CodeBranchOrTag.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E38CF611A7B7C99005536C0 /* CodeBranchOrTag.m */; }; - 4E38CF641A7B8DD4005536C0 /* icon_triangle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E38CF631A7B8DD4005536C0 /* icon_triangle@2x.png */; }; 4E3DB53C1BFDD0F40062BA52 /* task_activity_icon_add_watcher@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E3DB53A1BFDD0F40062BA52 /* task_activity_icon_add_watcher@2x.png */; }; 4E3DB53D1BFDD0F40062BA52 /* task_activity_icon_MergeRequestBean@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E3DB53B1BFDD0F40062BA52 /* task_activity_icon_MergeRequestBean@2x.png */; }; 4E44DCFA1D81486600E7F9AF /* HelpViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E44DCF91D81486600E7F9AF /* HelpViewController.m */; }; @@ -264,8 +260,6 @@ 4E4D6AAC1B1EED6A00FD2E49 /* AddCommentCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6AAB1B1EED6A00FD2E49 /* AddCommentCell.m */; }; 4E4D6AAF1B2047DE00FD2E49 /* CommitCommentCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6AAE1B2047DE00FD2E49 /* CommitCommentCell.m */; }; 4E4D6AB21B21A96100FD2E49 /* Commits.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6AB11B21A96100FD2E49 /* Commits.m */; }; - 4E4D6AC11B252CD400FD2E49 /* icon_code_file@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E4D6ABF1B252CD400FD2E49 /* icon_code_file@2x.png */; }; - 4E4D6AC21B252CD400FD2E49 /* icon_code_tree@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E4D6AC01B252CD400FD2E49 /* icon_code_tree@2x.png */; }; 4E4D6AC81B252F4800FD2E49 /* icon_add_comment@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E4D6AC71B252F4800FD2E49 /* icon_add_comment@2x.png */; }; 4E4D6ACB1B2571B100FD2E49 /* git_icon_stared@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E4D6AC91B2571B100FD2E49 /* git_icon_stared@2x.png */; }; 4E4D6ACC1B2571B100FD2E49 /* git_icon_watched@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E4D6ACA1B2571B100FD2E49 /* git_icon_watched@2x.png */; }; @@ -304,7 +298,6 @@ 4E5F39051ACA958C0010515D /* TopicCommentCCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E5F39041ACA958C0010515D /* TopicCommentCCell.m */; }; 4E5F39071ACBFDCD0010515D /* keyboard_photo@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E5F39061ACBFDCD0010515D /* keyboard_photo@2x.png */; }; 4E62410B1B74D65400E1533C /* search_tweet_like@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E62410A1B74D65400E1533C /* search_tweet_like@2x.png */; }; - 4E63189C1BDA198000EFED97 /* MRListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E63189B1BDA198000EFED97 /* MRListViewController.m */; }; 4E6318A21BDA261100EFED97 /* MRListView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6318A11BDA261100EFED97 /* MRListView.m */; }; 4E6383A61B3262D300D98648 /* taskPriority0@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E63839B1B3262D300D98648 /* taskPriority0@2x.png */; }; 4E6383A71B3262D300D98648 /* taskPriority0_small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E63839C1B3262D300D98648 /* taskPriority0_small@2x.png */; }; @@ -321,7 +314,6 @@ 4E6383BB1B32640900D98648 /* messageSystem@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383B51B32640900D98648 /* messageSystem@2x.png */; }; 4E6383BC1B32640900D98648 /* private_message_send_fail@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383B61B32640900D98648 /* private_message_send_fail@2x.png */; }; 4E6383C31B3265DC00D98648 /* mrpr_icon_accepted@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383BE1B3265DC00D98648 /* mrpr_icon_accepted@2x.png */; }; - 4E6383C41B3265DC00D98648 /* mrpr_icon_arrow@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383BF1B3265DC00D98648 /* mrpr_icon_arrow@2x.png */; }; 4E6383C71B3265DC00D98648 /* mrpr_icon_refaused@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383C21B3265DC00D98648 /* mrpr_icon_refaused@2x.png */; }; 4E6383D11B32665700D98648 /* project_item_activity@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383C91B32665700D98648 /* project_item_activity@2x.png */; }; 4E6383D21B32665700D98648 /* project_item_code@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383CA1B32665700D98648 /* project_item_code@2x.png */; }; @@ -354,10 +346,6 @@ 4E66EE281A28226000DA1B3E /* button_file_denete_unable@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E66EE231A28226000DA1B3E /* button_file_denete_unable@2x.png */; }; 4E66EE291A28226000DA1B3E /* button_file_move_enable@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E66EE241A28226000DA1B3E /* button_file_move_enable@2x.png */; }; 4E66EE2A1A28226000DA1B3E /* button_file_upload_enable@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E66EE251A28226000DA1B3E /* button_file_upload_enable@2x.png */; }; - 4E6B07111BA3D9B5007D6027 /* intro_page1_ip4@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6B070D1BA3D9B5007D6027 /* intro_page1_ip4@2x.png */; }; - 4E6B07121BA3D9B5007D6027 /* intro_page1_ip5@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6B070E1BA3D9B5007D6027 /* intro_page1_ip5@2x.png */; }; - 4E6B07131BA3D9B5007D6027 /* intro_page1_ip6@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6B070F1BA3D9B5007D6027 /* intro_page1_ip6@2x.png */; }; - 4E6B07141BA3D9B5007D6027 /* intro_page1_ip6+@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6B07101BA3D9B5007D6027 /* intro_page1_ip6+@3x.png */; }; 4E6B07161BA4045E007D6027 /* MIDAUTUMNIMAGE.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 4E6B07151BA4045E007D6027 /* MIDAUTUMNIMAGE.jpg */; }; 4E6BA2D71A1EE6AF005FD721 /* AFHTTPRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6BA2AE1A1EE6AF005FD721 /* AFHTTPRequestOperation.m */; }; 4E6BA2D81A1EE6AF005FD721 /* AFHTTPRequestOperationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6BA2B01A1EE6AF005FD721 /* AFHTTPRequestOperationManager.m */; }; @@ -396,12 +384,37 @@ 4E72F82D1B144778001B6CE6 /* NSMutableString+Common.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E72F82C1B144778001B6CE6 /* NSMutableString+Common.m */; }; 4E72F8331B15B811001B6CE6 /* gif_mark@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E72F8321B15B811001B6CE6 /* gif_mark@2x.png */; }; 4E743E6D1A88A3CC00DADDE5 /* EaseMarkdownTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E743E6C1A88A3CC00DADDE5 /* EaseMarkdownTextView.m */; }; - 4E743E6F1A88ABF700DADDE5 /* blankpage_image_Hi@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E743E6E1A88ABF700DADDE5 /* blankpage_image_Hi@2x.png */; }; 4E74EC011C311B6300EC0E1B /* SettingPhoneViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E74EC001C311B6300EC0E1B /* SettingPhoneViewController.m */; }; 4E753D441B8AFDEC003A00B9 /* FileEditViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E753D431B8AFDEC003A00B9 /* FileEditViewController.m */; }; 4E76D4DE1A5A7B4A0094A35E /* text_clear_btn@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E76D4DD1A5A7B4A0094A35E /* text_clear_btn@2x.png */; }; 4E787DE21B0329B300F06E83 /* ProjectLineNote.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E787DE11B0329B300F06E83 /* ProjectLineNote.m */; }; 4E787DE51B03342000F06E83 /* ProjectActivity.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E787DE41B03342000F06E83 /* ProjectActivity.m */; }; + 4E80E92D1DFFF06E00DE1BC6 /* shortcut_2FA@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9271DFFF06E00DE1BC6 /* shortcut_2FA@2x.png */; }; + 4E80E92E1DFFF06E00DE1BC6 /* shortcut_2FA@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9281DFFF06E00DE1BC6 /* shortcut_2FA@3x.png */; }; + 4E80E92F1DFFF06E00DE1BC6 /* shortcut_task@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9291DFFF06E00DE1BC6 /* shortcut_task@2x.png */; }; + 4E80E9301DFFF06E00DE1BC6 /* shortcut_task@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E92A1DFFF06E00DE1BC6 /* shortcut_task@3x.png */; }; + 4E80E9311DFFF06E00DE1BC6 /* shortcut_tweet@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E92B1DFFF06E00DE1BC6 /* shortcut_tweet@2x.png */; }; + 4E80E9321DFFF06E00DE1BC6 /* shortcut_tweet@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E92C1DFFF06E00DE1BC6 /* shortcut_tweet@3x.png */; }; + 4E80E9351E011D6000DE1BC6 /* RewardTipManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E80E9341E011D6000DE1BC6 /* RewardTipManager.m */; }; + 4E80E9381E01218300DE1BC6 /* reward_tip_logo@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9361E01218300DE1BC6 /* reward_tip_logo@2x.png */; }; + 4E80E9391E01218300DE1BC6 /* reward_tip_logo@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9371E01218300DE1BC6 /* reward_tip_logo@3x.png */; }; + 4E80E93C1E02353900DE1BC6 /* CodingSearchDisplayView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E80E93B1E02353900DE1BC6 /* CodingSearchDisplayView.m */; }; + 4E80E94E1E02911E00DE1BC6 /* search_icon_tweet@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E93E1E02911E00DE1BC6 /* search_icon_tweet@2x.png */; }; + 4E80E94F1E02911E00DE1BC6 /* search_icon_tweet@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E93F1E02911E00DE1BC6 /* search_icon_tweet@3x.png */; }; + 4E80E9501E02911E00DE1BC6 /* search_icon_topic@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9401E02911E00DE1BC6 /* search_icon_topic@2x.png */; }; + 4E80E9511E02911E00DE1BC6 /* search_icon_topic@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9411E02911E00DE1BC6 /* search_icon_topic@3x.png */; }; + 4E80E9521E02911E00DE1BC6 /* search_icon_file@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9421E02911E00DE1BC6 /* search_icon_file@2x.png */; }; + 4E80E9531E02911E00DE1BC6 /* search_icon_file@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9431E02911E00DE1BC6 /* search_icon_file@3x.png */; }; + 4E80E9541E02911E00DE1BC6 /* search_icon_mr@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9441E02911E00DE1BC6 /* search_icon_mr@2x.png */; }; + 4E80E9551E02911E00DE1BC6 /* search_icon_mr@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9451E02911E00DE1BC6 /* search_icon_mr@3x.png */; }; + 4E80E9561E02911E00DE1BC6 /* search_icon_user@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9461E02911E00DE1BC6 /* search_icon_user@2x.png */; }; + 4E80E9571E02911E00DE1BC6 /* search_icon_user@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9471E02911E00DE1BC6 /* search_icon_user@3x.png */; }; + 4E80E9581E02911E00DE1BC6 /* search_icon_pr@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9481E02911E00DE1BC6 /* search_icon_pr@2x.png */; }; + 4E80E9591E02911E00DE1BC6 /* search_icon_pr@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9491E02911E00DE1BC6 /* search_icon_pr@3x.png */; }; + 4E80E95A1E02911E00DE1BC6 /* search_icon_project@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E94A1E02911E00DE1BC6 /* search_icon_project@2x.png */; }; + 4E80E95B1E02911E00DE1BC6 /* search_icon_project@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E94B1E02911E00DE1BC6 /* search_icon_project@3x.png */; }; + 4E80E95C1E02911E00DE1BC6 /* search_icon_task@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E94C1E02911E00DE1BC6 /* search_icon_task@2x.png */; }; + 4E80E95D1E02911E00DE1BC6 /* search_icon_task@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E94D1E02911E00DE1BC6 /* search_icon_task@3x.png */; }; 4E83AE7B1CF30F1A006BA3BB /* SettingEmailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E83AE7A1CF30F1A006BA3BB /* SettingEmailViewController.m */; }; 4E86FEE51BB556D6005E53F3 /* tipIcon_ProjectFileComment@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E86FEE41BB556D6005E53F3 /* tipIcon_ProjectFileComment@2x.png */; }; 4E8765651A22E5B40090CFB9 /* NSMutableArray+SWUtilityButtons.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E87655A1A22E5B40090CFB9 /* NSMutableArray+SWUtilityButtons.m */; }; @@ -427,18 +440,8 @@ 4E8D5D6E1B45400100B70936 /* ZXScanCodeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E8D5D6D1B45400100B70936 /* ZXScanCodeViewController.m */; }; 4E8D5D731B454D5000B70936 /* OTPAuthClock.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E8D5D721B454D5000B70936 /* OTPAuthClock.m */; }; 4E8D5D7D1B462ADB00B70936 /* OTPTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E8D5D7C1B462ADB00B70936 /* OTPTableViewCell.m */; }; - 4E8F92DE1B67BE3C00033D8F /* icon_user_monkey_i6@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E8F92DB1B67BE3C00033D8F /* icon_user_monkey_i6@2x.png */; }; - 4E8F92DF1B67BE3C00033D8F /* icon_user_monkey_i6p@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E8F92DC1B67BE3C00033D8F /* icon_user_monkey_i6p@3x.png */; }; - 4E90F89B1AF709C100B44F03 /* bubble.html in Resources */ = {isa = PBXBuildFile; fileRef = 4E90F8971AF709C100B44F03 /* bubble.html */; }; - 4E90F89C1AF709C100B44F03 /* code.html in Resources */ = {isa = PBXBuildFile; fileRef = 4E90F8981AF709C100B44F03 /* code.html */; }; - 4E90F89D1AF709C100B44F03 /* markdown.html in Resources */ = {isa = PBXBuildFile; fileRef = 4E90F8991AF709C100B44F03 /* markdown.html */; }; - 4E90F89E1AF709C100B44F03 /* topic-ios.html in Resources */ = {isa = PBXBuildFile; fileRef = 4E90F89A1AF709C100B44F03 /* topic-ios.html */; }; 4E9113A21A1C426000AC9431 /* ASPopUpView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E91139F1A1C426000AC9431 /* ASPopUpView.m */; }; 4E9113A31A1C426000AC9431 /* ASProgressPopUpView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E9113A11A1C426000AC9431 /* ASProgressPopUpView.m */; }; - 4E9113A91A1CB19900AC9431 /* icon_file_state_download@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9113A51A1CB19900AC9431 /* icon_file_state_download@2x.png */; }; - 4E9113AA1A1CB19900AC9431 /* icon_file_state_goon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9113A61A1CB19900AC9431 /* icon_file_state_goon@2x.png */; }; - 4E9113AB1A1CB19900AC9431 /* icon_file_state_look@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9113A71A1CB19900AC9431 /* icon_file_state_look@2x.png */; }; - 4E9113AC1A1CB19900AC9431 /* icon_file_state_pause@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9113A81A1CB19900AC9431 /* icon_file_state_pause@2x.png */; }; 4E93F2331B84243D00017916 /* KxMenu.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E93F2321B84243D00017916 /* KxMenu.m */; }; 4E93F23A1B84356500017916 /* file_menu_icon_delete@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E93F2351B84356500017916 /* file_menu_icon_delete@2x.png */; }; 4E93F23B1B84356500017916 /* file_menu_icon_edit@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E93F2361B84356500017916 /* file_menu_icon_edit@2x.png */; }; @@ -447,6 +450,34 @@ 4E93F23E1B84356500017916 /* file_menu_icon_share@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E93F2391B84356500017916 /* file_menu_icon_share@2x.png */; }; 4E93F2441B85C4C300017916 /* FileInfoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E93F2421B85C4C300017916 /* FileInfoViewController.m */; }; 4E93F2451B85C4C300017916 /* FileInfoViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4E93F2431B85C4C300017916 /* FileInfoViewController.xib */; }; + 4E9423DA1E69401B0095F1CD /* blankpage_image_Activity@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423BE1E69401B0095F1CD /* blankpage_image_Activity@2x.png */; }; + 4E9423DB1E69401B0095F1CD /* blankpage_image_Activity@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423BF1E69401B0095F1CD /* blankpage_image_Activity@3x.png */; }; + 4E9423DC1E69401B0095F1CD /* blankpage_image_Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423C01E69401B0095F1CD /* blankpage_image_Default@2x.png */; }; + 4E9423DD1E69401B0095F1CD /* blankpage_image_Default@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423C11E69401B0095F1CD /* blankpage_image_Default@3x.png */; }; + 4E9423DE1E69401B0095F1CD /* blankpage_image_File@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423C21E69401B0095F1CD /* blankpage_image_File@2x.png */; }; + 4E9423DF1E69401B0095F1CD /* blankpage_image_File@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423C31E69401B0095F1CD /* blankpage_image_File@3x.png */; }; + 4E9423E01E69401B0095F1CD /* blankpage_image_LoadFail@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423C41E69401B0095F1CD /* blankpage_image_LoadFail@2x.png */; }; + 4E9423E11E69401B0095F1CD /* blankpage_image_LoadFail@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423C51E69401B0095F1CD /* blankpage_image_LoadFail@3x.png */; }; + 4E9423E21E69401B0095F1CD /* blankpage_image_MessageList@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423C61E69401B0095F1CD /* blankpage_image_MessageList@2x.png */; }; + 4E9423E31E69401B0095F1CD /* blankpage_image_MessageList@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423C71E69401B0095F1CD /* blankpage_image_MessageList@3x.png */; }; + 4E9423E41E69401B0095F1CD /* blankpage_image_Notice@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423C81E69401B0095F1CD /* blankpage_image_Notice@2x.png */; }; + 4E9423E51E69401B0095F1CD /* blankpage_image_Notice@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423C91E69401B0095F1CD /* blankpage_image_Notice@3x.png */; }; + 4E9423E61E69401B0095F1CD /* blankpage_image_Project@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423CA1E69401B0095F1CD /* blankpage_image_Project@2x.png */; }; + 4E9423E71E69401B0095F1CD /* blankpage_image_Project@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423CB1E69401B0095F1CD /* blankpage_image_Project@3x.png */; }; + 4E9423E81E69401B0095F1CD /* blankpage_image_ShopOrder@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423CC1E69401B0095F1CD /* blankpage_image_ShopOrder@2x.png */; }; + 4E9423E91E69401B0095F1CD /* blankpage_image_ShopOrder@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423CD1E69401B0095F1CD /* blankpage_image_ShopOrder@3x.png */; }; + 4E9423EA1E69401B0095F1CD /* blankpage_image_Task@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423CE1E69401B0095F1CD /* blankpage_image_Task@2x.png */; }; + 4E9423EB1E69401B0095F1CD /* blankpage_image_Task@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423CF1E69401B0095F1CD /* blankpage_image_Task@3x.png */; }; + 4E9423EC1E69401B0095F1CD /* blankpage_image_Team@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423D01E69401B0095F1CD /* blankpage_image_Team@2x.png */; }; + 4E9423ED1E69401B0095F1CD /* blankpage_image_Team@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423D11E69401B0095F1CD /* blankpage_image_Team@3x.png */; }; + 4E9423EE1E69401B0095F1CD /* blankpage_image_Tip@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423D21E69401B0095F1CD /* blankpage_image_Tip@2x.png */; }; + 4E9423EF1E69401B0095F1CD /* blankpage_image_Tip@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423D31E69401B0095F1CD /* blankpage_image_Tip@3x.png */; }; + 4E9423F01E69401B0095F1CD /* blankpage_image_Topic@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423D41E69401B0095F1CD /* blankpage_image_Topic@2x.png */; }; + 4E9423F11E69401B0095F1CD /* blankpage_image_Topic@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423D51E69401B0095F1CD /* blankpage_image_Topic@3x.png */; }; + 4E9423F21E69401B0095F1CD /* blankpage_image_Tweet@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423D61E69401B0095F1CD /* blankpage_image_Tweet@2x.png */; }; + 4E9423F31E69401B0095F1CD /* blankpage_image_Tweet@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423D71E69401B0095F1CD /* blankpage_image_Tweet@3x.png */; }; + 4E9423F41E69401B0095F1CD /* blankpage_image_Wiki@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423D81E69401B0095F1CD /* blankpage_image_Wiki@2x.png */; }; + 4E9423F51E69401B0095F1CD /* blankpage_image_Wiki@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423D91E69401B0095F1CD /* blankpage_image_Wiki@3x.png */; }; 4E94C4E71B4A6AC700EB668A /* ScanBGView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E94C4E61B4A6AC700EB668A /* ScanBGView.m */; }; 4E94C4ED1B4A867A00EB668A /* scan_bg@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E94C4EC1B4A867A00EB668A /* scan_bg@2x.png */; }; 4E94C4EF1B4B73BB00EB668A /* scan_line@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E94C4EE1B4B73BB00EB668A /* scan_line@2x.png */; }; @@ -493,6 +524,7 @@ 4E996C051ABBF56A00C704F1 /* n_sex_man_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E996BFD1ABBF56A00C704F1 /* n_sex_man_icon@2x.png */; }; 4E996C061ABBF56A00C704F1 /* n_sex_woman_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E996BFE1ABBF56A00C704F1 /* n_sex_woman_icon@2x.png */; }; 4E996C071ABBF56A00C704F1 /* user_info_detail@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E996BFF1ABBF56A00C704F1 /* user_info_detail@2x.png */; }; + 4E9DEEC61E30CA3C001B8D1B /* keyboard_emotion_emoji_code@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9DEEC51E30CA3C001B8D1B /* keyboard_emotion_emoji_code@2x.png */; }; 4E9E3B751DCC2DB10005FD79 /* HtmlMediaViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E9E3B741DCC2DB10005FD79 /* HtmlMediaViewController.m */; }; 4E9F5D201C03051D007CCDCC /* tipIcon_tweetReward@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9F5D1F1C03051D007CCDCC /* tipIcon_tweetReward@2x.png */; }; 4EA6790A1A1461C3001A0324 /* ProjectFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA679091A1461C3001A0324 /* ProjectFile.m */; }; @@ -502,7 +534,6 @@ 4EA679191A14BFA0001A0324 /* icon_file_folder_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EA679171A14BFA0001A0324 /* icon_file_folder_default@2x.png */; }; 4EA6791A1A14BFA0001A0324 /* icon_file_folder_normal@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EA679181A14BFA0001A0324 /* icon_file_folder_normal@2x.png */; }; 4EA6791D1A15A943001A0324 /* FileListFolderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA6791C1A15A943001A0324 /* FileListFolderCell.m */; }; - 4EA679201A15AB9F001A0324 /* FileListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA6791F1A15AB9F001A0324 /* FileListViewController.m */; }; 4EA7F1591A6D192B00A046BD /* NSData+ImageContentType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA7F13A1A6D192B00A046BD /* NSData+ImageContentType.m */; }; 4EA7F15A1A6D192B00A046BD /* SDImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA7F13C1A6D192B00A046BD /* SDImageCache.m */; }; 4EA7F15B1A6D192B00A046BD /* SDWebImageCompat.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA7F13E1A6D192B00A046BD /* SDWebImageCompat.m */; }; @@ -518,6 +549,35 @@ 4EA7F1651A6D192B00A046BD /* UIImageView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA7F1531A6D192B00A046BD /* UIImageView+WebCache.m */; }; 4EA7F1661A6D192B00A046BD /* UIView+WebCacheOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA7F1551A6D192B00A046BD /* UIView+WebCacheOperation.m */; }; 4EA7F1671A6D192B00A046BD /* ODRefreshControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA7F1581A6D192B00A046BD /* ODRefreshControl.m */; }; + 4EAAD0141E5306F3008AA957 /* MRPRListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EAAD0131E5306F3008AA957 /* MRPRListViewController.m */; }; + 4EAAD0171E53EFF2008AA957 /* EAFliterMenu.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EAAD0161E53EFF2008AA957 /* EAFliterMenu.m */; }; + 4EAAD0211E540551008AA957 /* mrpr_icon_status_accepted@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD0191E540551008AA957 /* mrpr_icon_status_accepted@2x.png */; }; + 4EAAD0221E540551008AA957 /* mrpr_icon_status_accepted@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD01A1E540551008AA957 /* mrpr_icon_status_accepted@3x.png */; }; + 4EAAD0231E540551008AA957 /* mrpr_icon_status_canmerge@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD01B1E540551008AA957 /* mrpr_icon_status_canmerge@2x.png */; }; + 4EAAD0241E540551008AA957 /* mrpr_icon_status_canmerge@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD01C1E540551008AA957 /* mrpr_icon_status_canmerge@3x.png */; }; + 4EAAD0251E540551008AA957 /* mrpr_icon_status_cannotmerge@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD01D1E540551008AA957 /* mrpr_icon_status_cannotmerge@2x.png */; }; + 4EAAD0261E540551008AA957 /* mrpr_icon_status_cannotmerge@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD01E1E540551008AA957 /* mrpr_icon_status_cannotmerge@3x.png */; }; + 4EAAD0271E540551008AA957 /* mrpr_icon_status_refused@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD01F1E540551008AA957 /* mrpr_icon_status_refused@2x.png */; }; + 4EAAD0281E540551008AA957 /* mrpr_icon_status_refused@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD0201E540551008AA957 /* mrpr_icon_status_refused@3x.png */; }; + 4EAAD02B1E5405B4008AA957 /* mrpr_icon_status_cancel@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD0291E5405B4008AA957 /* mrpr_icon_status_cancel@2x.png */; }; + 4EAAD02C1E5405B4008AA957 /* mrpr_icon_status_cancel@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD02A1E5405B4008AA957 /* mrpr_icon_status_cancel@3x.png */; }; + 4EAAD0511E542B2D008AA957 /* icon_code_executable@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD0491E542B2D008AA957 /* icon_code_executable@2x.png */; }; + 4EAAD0521E542B2D008AA957 /* icon_code_executable@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD04A1E542B2D008AA957 /* icon_code_executable@3x.png */; }; + 4EAAD0531E542B2D008AA957 /* icon_code_tree@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD04B1E542B2D008AA957 /* icon_code_tree@2x.png */; }; + 4EAAD0541E542B2D008AA957 /* icon_code_tree@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD04C1E542B2D008AA957 /* icon_code_tree@3x.png */; }; + 4EAAD0551E542B2D008AA957 /* icon_code_file@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD04D1E542B2D008AA957 /* icon_code_file@2x.png */; }; + 4EAAD0561E542B2D008AA957 /* icon_code_file@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD04E1E542B2D008AA957 /* icon_code_file@3x.png */; }; + 4EAAD0571E542B2D008AA957 /* icon_code_git_link@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD04F1E542B2D008AA957 /* icon_code_git_link@2x.png */; }; + 4EAAD0581E542B2D008AA957 /* icon_code_git_link@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD0501E542B2D008AA957 /* icon_code_git_link@3x.png */; }; + 4EAAD05B1E544006008AA957 /* icon_triangle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD0591E544006008AA957 /* icon_triangle@2x.png */; }; + 4EAAD05C1E544006008AA957 /* icon_triangle@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD05A1E544006008AA957 /* icon_triangle@3x.png */; }; + 4EAAD05F1E545516008AA957 /* ProjectCodeListSearchCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EAAD05E1E545516008AA957 /* ProjectCodeListSearchCell.m */; }; + 4EAAD0821E55AC6E008AA957 /* icon_code_image@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD0801E55AC6E008AA957 /* icon_code_image@2x.png */; }; + 4EAAD0831E55AC6E008AA957 /* icon_code_image@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD0811E55AC6E008AA957 /* icon_code_image@3x.png */; }; + 4EAAD09D1E5D8558008AA957 /* mrpr_icon_arrow@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD09B1E5D8558008AA957 /* mrpr_icon_arrow@2x.png */; }; + 4EAAD09E1E5D8558008AA957 /* mrpr_icon_arrow@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD09C1E5D8558008AA957 /* mrpr_icon_arrow@3x.png */; }; + 4EAAD0A51E5D8D90008AA957 /* PR_plus@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD0A31E5D8D90008AA957 /* PR_plus@2x.png */; }; + 4EAAD0A61E5D8D90008AA957 /* PR_plus@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD0A41E5D8D90008AA957 /* PR_plus@3x.png */; }; 4EABD2541AD3CA7E005E515F /* UIMessageInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EABD2531AD3CA7E005E515F /* UIMessageInputView.m */; }; 4EABD2571AD3CAAC005E515F /* UIMessageInputView_Add.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EABD2561AD3CAAC005E515F /* UIMessageInputView_Add.m */; }; 4EABD25A1AD3CB4A005E515F /* UIMessageInputView_CCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EABD2591AD3CB4A005E515F /* UIMessageInputView_CCell.m */; }; @@ -542,7 +602,6 @@ 4EAE06C11B7B51AF00179F4B /* file_activity_icon_move_file@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAE06BD1B7B51AF00179F4B /* file_activity_icon_move_file@2x.png */; }; 4EAE06C21B7B51AF00179F4B /* file_activity_icon_update_file@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAE06BE1B7B51AF00179F4B /* file_activity_icon_update_file@2x.png */; }; 4EAE06C31B7B51AF00179F4B /* file_activity_icon_upload_file@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAE06BF1B7B51AF00179F4B /* file_activity_icon_upload_file@2x.png */; }; - 4EAE06C51B7B587200179F4B /* button_file_comment@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAE06C41B7B587200179F4B /* button_file_comment@2x.png */; }; 4EAE06C81B7C9EFF00179F4B /* FileVersionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EAE06C71B7C9EFF00179F4B /* FileVersionCell.m */; }; 4EAECBC21C44CB860096CA74 /* member_cell_edit_alias@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAECBBC1C44CB860096CA74 /* member_cell_edit_alias@2x.png */; }; 4EAECBC31C44CB860096CA74 /* member_cell_edit_alias@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAECBBD1C44CB860096CA74 /* member_cell_edit_alias@3x.png */; }; @@ -551,10 +610,6 @@ 4EAECBC61C44CB860096CA74 /* member_cell_edit_type@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAECBC01C44CB860096CA74 /* member_cell_edit_type@2x.png */; }; 4EAECBC71C44CB860096CA74 /* member_cell_edit_type@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAECBC11C44CB860096CA74 /* member_cell_edit_type@3x.png */; }; 4EB0C2001A807ED00042FC4F /* NSURL+Common.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EB0C1FF1A807ED00042FC4F /* NSURL+Common.m */; }; - 4EB119F81D953AE200A36341 /* intro_page2_ip4@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB119F41D953AE200A36341 /* intro_page2_ip4@2x.png */; }; - 4EB119F91D953AE200A36341 /* intro_page2_ip5@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB119F51D953AE200A36341 /* intro_page2_ip5@2x.png */; }; - 4EB119FA1D953AE200A36341 /* intro_page2_ip6@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB119F61D953AE200A36341 /* intro_page2_ip6@2x.png */; }; - 4EB119FB1D953AE200A36341 /* intro_page2_ip6+@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB119F71D953AE200A36341 /* intro_page2_ip6+@3x.png */; }; 4EB52F0F1C74691B00B5EBEA /* password_look@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F0B1C74691B00B5EBEA /* password_look@2x.png */; }; 4EB52F101C74691B00B5EBEA /* password_look@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F0C1C74691B00B5EBEA /* password_look@3x.png */; }; 4EB52F111C74691B00B5EBEA /* password_unlook@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F0D1C74691B00B5EBEA /* password_unlook@2x.png */; }; @@ -570,7 +625,6 @@ 4EB52F281C76ED4A00B5EBEA /* TagColorEditCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EB52F271C76ED4A00B5EBEA /* TagColorEditCell.m */; }; 4EB52F2B1C76ED7000B5EBEA /* TagColorDisplayCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EB52F2A1C76ED7000B5EBEA /* TagColorDisplayCell.m */; }; 4EB52F2E1C77138A00B5EBEA /* button_scan@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F2C1C77138A00B5EBEA /* button_scan@2x.png */; }; - 4EB52F2F1C77138A00B5EBEA /* button_scan@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F2D1C77138A00B5EBEA /* button_scan@3x.png */; }; 4EB52F381C7C38F600B5EBEA /* ResourceReference.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EB52F371C7C38F600B5EBEA /* ResourceReference.m */; }; 4EB52F3B1C7C45E700B5EBEA /* taskResourceReference@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F391C7C45E700B5EBEA /* taskResourceReference@2x.png */; }; 4EB52F3C1C7C45E700B5EBEA /* taskResourceReference@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F3A1C7C45E700B5EBEA /* taskResourceReference@3x.png */; }; @@ -584,9 +638,6 @@ 4EB52F611C7C5C4F00B5EBEA /* task_resource_reference_ProjectTopic@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F591C7C5C4F00B5EBEA /* task_resource_reference_ProjectTopic@3x.png */; }; 4EB52F621C7C5C4F00B5EBEA /* task_resource_reference_Task@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F5A1C7C5C4F00B5EBEA /* task_resource_reference_Task@2x.png */; }; 4EB52F631C7C5C4F00B5EBEA /* task_resource_reference_Task@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F5B1C7C5C4F00B5EBEA /* task_resource_reference_Task@3x.png */; }; - 4EB5A9421BF1DB4600C23AC3 /* libSocialSinaSSO.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EB5A9341BF1DB4600C23AC3 /* libSocialSinaSSO.a */; }; - 4EB5A9431BF1DB4600C23AC3 /* libWeiboSDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EB5A9351BF1DB4600C23AC3 /* libWeiboSDK.a */; }; - 4EB5A9441BF1DB4600C23AC3 /* WeiboSDK.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 4EB5A93F1BF1DB4600C23AC3 /* WeiboSDK.bundle */; }; 4EB862AD1CABB21E008074D1 /* tipIcon_TeamMember@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB862AC1CABB21E008074D1 /* tipIcon_TeamMember@2x.png */; }; 4EBB624C1A6F526C0045DAEF /* NJKWebViewProgress.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EBB62491A6F526C0045DAEF /* NJKWebViewProgress.m */; }; 4EBB624D1A6F526C0045DAEF /* NJKWebViewProgressView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EBB624B1A6F526C0045DAEF /* NJKWebViewProgressView.m */; }; @@ -594,7 +645,6 @@ 4EBD7FAF1CE4827A00B3AF49 /* CountryCodeListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EBD7FAE1CE4827A00B3AF49 /* CountryCodeListViewController.m */; }; 4EBD7FB11CE482A400B3AF49 /* country_code.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4EBD7FB01CE482A400B3AF49 /* country_code.plist */; }; 4EBD7FB41CE4833D00B3AF49 /* CountryCodeCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EBD7FB31CE4833D00B3AF49 /* CountryCodeCell.m */; }; - 4EBDA87C1A6640340035ED96 /* UIActionSheet+Common.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EBDA87B1A6640340035ED96 /* UIActionSheet+Common.m */; }; 4EBDC27B1BC501C00037EB66 /* tipIcon_ProjectPayment@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EBDC27A1BC501C00037EB66 /* tipIcon_ProjectPayment@2x.png */; }; 4EBFBD181AA85B8500E4B10E /* add_user_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EBFBD171AA85B8500E4B10E /* add_user_icon@2x.png */; }; 4EC461AD1B39084100D08970 /* FunctionTipsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EC461AC1B39084100D08970 /* FunctionTipsManager.m */; }; @@ -646,7 +696,6 @@ 4ECEFA031D1D0B4B002A27D3 /* tip_bg@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ECEFA011D1D0B4B002A27D3 /* tip_bg@3x.png */; }; 4ECF702C1B1704C5000280FF /* NProjectItemCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECF702B1B1704C5000280FF /* NProjectItemCell.m */; }; 4ECF70401B180740000280FF /* EaseGitButtonsView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECF703F1B180740000280FF /* EaseGitButtonsView.m */; }; - 4ECF70431B18514F000280FF /* PRListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECF70421B18514F000280FF /* PRListViewController.m */; }; 4ECF70461B18557E000280FF /* MRPRS.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECF70451B18557E000280FF /* MRPRS.m */; }; 4ECF70491B185BCC000280FF /* MRPR.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECF70481B185BCC000280FF /* MRPR.m */; }; 4ECF704C1B1876CB000280FF /* MRPRListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECF704B1B1876CB000280FF /* MRPRListCell.m */; }; @@ -703,7 +752,6 @@ 4EE1A22B1B5D02CA004284F1 /* ProjectActivitiesView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EE1A21A1B5D02CA004284F1 /* ProjectActivitiesView.m */; }; 4EE1A22C1B5D02CA004284F1 /* ProjectActivityListView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EE1A21C1B5D02CA004284F1 /* ProjectActivityListView.m */; }; 4EE1A22D1B5D02CA004284F1 /* ProjectCodeListView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EE1A21E1B5D02CA004284F1 /* ProjectCodeListView.m */; }; - 4EE1A22E1B5D02CA004284F1 /* ProjectFolderListView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EE1A2201B5D02CA004284F1 /* ProjectFolderListView.m */; }; 4EE1A22F1B5D02CA004284F1 /* ProjectListView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EE1A2221B5D02CA004284F1 /* ProjectListView.m */; }; 4EE1A2301B5D02CA004284F1 /* ProjectTaskListView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EE1A2241B5D02CA004284F1 /* ProjectTaskListView.m */; }; 4EE1A2311B5D02CA004284F1 /* ProjectTasksView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EE1A2261B5D02CA004284F1 /* ProjectTasksView.m */; }; @@ -720,36 +768,6 @@ 4EED9DCD1B539366000E5827 /* taskProject@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EED9DCB1B539366000E5827 /* taskProject@2x.png */; }; 4EED9DD11B53BBCF000E5827 /* twoFABtn_Nav@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EED9DD01B53BBCF000E5827 /* twoFABtn_Nav@2x.png */; }; 4EF17E5F1B3AB10F003CDD2D /* IntroductionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EF17E5E1B3AB10F003CDD2D /* IntroductionViewController.m */; }; - 4EF17ECB1B3C3112003CDD2D /* intro_dot_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EAD1B3C3112003CDD2D /* intro_dot_selected@2x.png */; }; - 4EF17ECC1B3C3112003CDD2D /* intro_dot_selected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EAE1B3C3112003CDD2D /* intro_dot_selected@3x.png */; }; - 4EF17ECD1B3C3112003CDD2D /* intro_dot_unselected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EAF1B3C3112003CDD2D /* intro_dot_unselected@2x.png */; }; - 4EF17ECE1B3C3112003CDD2D /* intro_dot_unselected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EB01B3C3112003CDD2D /* intro_dot_unselected@3x.png */; }; - 4EF17ECF1B3C3112003CDD2D /* intro_icon_0@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EB11B3C3112003CDD2D /* intro_icon_0@2x.png */; }; - 4EF17ED01B3C3112003CDD2D /* intro_icon_0@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EB21B3C3112003CDD2D /* intro_icon_0@3x.png */; }; - 4EF17ED11B3C3112003CDD2D /* intro_icon_1@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EB31B3C3112003CDD2D /* intro_icon_1@2x.png */; }; - 4EF17ED21B3C3112003CDD2D /* intro_icon_1@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EB41B3C3112003CDD2D /* intro_icon_1@3x.png */; }; - 4EF17ED31B3C3112003CDD2D /* intro_icon_2@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EB51B3C3112003CDD2D /* intro_icon_2@2x.png */; }; - 4EF17ED41B3C3112003CDD2D /* intro_icon_2@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EB61B3C3112003CDD2D /* intro_icon_2@3x.png */; }; - 4EF17ED51B3C3112003CDD2D /* intro_icon_3@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EB71B3C3112003CDD2D /* intro_icon_3@2x.png */; }; - 4EF17ED61B3C3112003CDD2D /* intro_icon_3@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EB81B3C3112003CDD2D /* intro_icon_3@3x.png */; }; - 4EF17ED71B3C3112003CDD2D /* intro_icon_4@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EB91B3C3112003CDD2D /* intro_icon_4@2x.png */; }; - 4EF17ED81B3C3112003CDD2D /* intro_icon_4@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EBA1B3C3112003CDD2D /* intro_icon_4@3x.png */; }; - 4EF17ED91B3C3112003CDD2D /* intro_icon_5@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EBB1B3C3112003CDD2D /* intro_icon_5@2x.png */; }; - 4EF17EDA1B3C3112003CDD2D /* intro_icon_5@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EBC1B3C3112003CDD2D /* intro_icon_5@3x.png */; }; - 4EF17EDB1B3C3112003CDD2D /* intro_icon_6@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EBD1B3C3112003CDD2D /* intro_icon_6@3x.png */; }; - 4EF17EDC1B3C3112003CDD2D /* intro_tip_0@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EBE1B3C3112003CDD2D /* intro_tip_0@2x.png */; }; - 4EF17EDD1B3C3112003CDD2D /* intro_tip_0@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EBF1B3C3112003CDD2D /* intro_tip_0@3x.png */; }; - 4EF17EDE1B3C3112003CDD2D /* intro_tip_1@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EC01B3C3112003CDD2D /* intro_tip_1@2x.png */; }; - 4EF17EDF1B3C3112003CDD2D /* intro_tip_1@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EC11B3C3112003CDD2D /* intro_tip_1@3x.png */; }; - 4EF17EE01B3C3112003CDD2D /* intro_tip_2@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EC21B3C3112003CDD2D /* intro_tip_2@2x.png */; }; - 4EF17EE11B3C3112003CDD2D /* intro_tip_2@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EC31B3C3112003CDD2D /* intro_tip_2@3x.png */; }; - 4EF17EE21B3C3112003CDD2D /* intro_tip_3@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EC41B3C3112003CDD2D /* intro_tip_3@2x.png */; }; - 4EF17EE31B3C3112003CDD2D /* intro_tip_3@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EC51B3C3112003CDD2D /* intro_tip_3@3x.png */; }; - 4EF17EE41B3C3112003CDD2D /* intro_tip_4@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EC61B3C3112003CDD2D /* intro_tip_4@2x.png */; }; - 4EF17EE51B3C3112003CDD2D /* intro_tip_4@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EC71B3C3112003CDD2D /* intro_tip_4@3x.png */; }; - 4EF17EE61B3C3112003CDD2D /* intro_tip_5@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EC81B3C3112003CDD2D /* intro_tip_5@2x.png */; }; - 4EF17EE71B3C3112003CDD2D /* intro_tip_5@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17EC91B3C3112003CDD2D /* intro_tip_5@3x.png */; }; - 4EF17EE81B3C3112003CDD2D /* intro_icon_6@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF17ECA1B3C3112003CDD2D /* intro_icon_6@2x.png */; }; 4EF374161BB1254700DDA662 /* LocalFoldersViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EF374151BB1254700DDA662 /* LocalFoldersViewController.m */; }; 4EF374191BB1255E00DDA662 /* LocalFilesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EF374181BB1255E00DDA662 /* LocalFilesViewController.m */; }; 4EF3741C1BB1258600DDA662 /* LocalFileViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EF3741B1BB1258600DDA662 /* LocalFileViewController.m */; }; @@ -764,6 +782,8 @@ 4EFE8DAD1B394A0D004B7559 /* file_changeType_RENAME@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EFE8DAB1B394A0D004B7559 /* file_changeType_RENAME@2x.png */; }; 4EFE8DAF1B3960E6004B7559 /* logo_coding_top@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EFE8DAE1B3960E6004B7559 /* logo_coding_top@2x.png */; }; 4EFE8DB91B3A5727004B7559 /* Launch Screen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4EFE8DB81B3A5727004B7559 /* Launch Screen.xib */; }; + 4EFF5A771E0AE54800683D03 /* libresolv.9.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFF5A761E0AE54800683D03 /* libresolv.9.tbd */; }; + 74BCC5B7B071C6418DBC18C7 /* libPods-Coding_iOS-Coding_Enterprise_iOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 627CA7E44F0D5A025A49E2F0 /* libPods-Coding_iOS-Coding_Enterprise_iOS.a */; }; 7E335D9D1B6F5E94003D0F3D /* keyboard_arrow_down@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E335D9A1B6F5E94003D0F3D /* keyboard_arrow_down@2x.png */; }; 7E335D9E1B6F5E94003D0F3D /* keyboard_voice_record@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E335D9B1B6F5E94003D0F3D /* keyboard_voice_record@2x.png */; }; 7E335D9F1B6F5E94003D0F3D /* keyboard_voice@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E335D9C1B6F5E94003D0F3D /* keyboard_voice@2x.png */; }; @@ -786,6 +806,7 @@ 7EB02FF31B6D111300D2166C /* AudioRecordView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7EB02FF01B6D111300D2166C /* AudioRecordView.m */; }; 7EB02FF61B6DAF3800D2166C /* AudioVolumeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7EB02FF51B6DAF3800D2166C /* AudioVolumeView.m */; }; 7EB02FFC1B6E001300D2166C /* VoiceMedia.m in Sources */ = {isa = PBXBuildFile; fileRef = 7EB02FFB1B6E001300D2166C /* VoiceMedia.m */; }; + 7FD0104CFC28ED5705E0D5E8 /* libPods-Coding_iOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 645969FE6A8616A74543C249 /* libPods-Coding_iOS.a */; }; 8B35164F1B6CE9460049BC45 /* icon_arrow_searchHistory@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8B35164A1B6CE9460049BC45 /* icon_arrow_searchHistory@2x.png */; }; 8B3516501B6CE9460049BC45 /* icon_topic_hotTop@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8B35164B1B6CE9460049BC45 /* icon_topic_hotTop@2x.png */; }; 8B3516511B6CE9460049BC45 /* search_tweet_colck@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8B35164C1B6CE9460049BC45 /* search_tweet_colck@2x.png */; }; @@ -812,9 +833,6 @@ 8E477016198770E700997D05 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E477015198770E700997D05 /* CoreGraphics.framework */; }; 8E477018198770E700997D05 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E477017198770E700997D05 /* UIKit.framework */; }; 8E47701A198770E700997D05 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E477019198770E700997D05 /* CoreData.framework */; }; - 8E525C8919F7E3F800496B34 /* blankpage_button_reload@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E525C8219F7E3F800496B34 /* blankpage_button_reload@2x.png */; }; - 8E525C8A19F7E3F800496B34 /* blankpage_image_loadFail@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E525C8319F7E3F800496B34 /* blankpage_image_loadFail@2x.png */; }; - 8E525C8D19F7E3F800496B34 /* blankpage_image_Sleep@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E525C8619F7E3F800496B34 /* blankpage_image_Sleep@2x.png */; }; 8E59F0E21A0098BA009A905F /* UIScrollView+SVInfiniteScrolling.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E59F0DF1A0098BA009A905F /* UIScrollView+SVInfiniteScrolling.m */; }; 8E59F0E31A0098BA009A905F /* UIScrollView+SVPullToRefresh.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E59F0E11A0098BA009A905F /* UIScrollView+SVPullToRefresh.m */; }; 8E59F0F41A00F3B9009A905F /* ProjectCodeListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E59F0F31A00F3B9009A905F /* ProjectCodeListCell.m */; }; @@ -826,17 +844,6 @@ 8E59F10D1A02188D009A905F /* CodeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E59F10C1A02188D009A905F /* CodeViewController.m */; }; 8E61D27B19C028CC00C00414 /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E61D27A19C028CC00C00414 /* AssetsLibrary.framework */; }; 8E62ADDA19E28DA800963870 /* tipIcon_User@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E62ADD919E28DA800963870 /* tipIcon_User@2x.png */; }; - 8E64ED7B19ED0CE3006E99DA /* QBAssetsCollectionCheckmarkView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E64ED6719ED0CE3006E99DA /* QBAssetsCollectionCheckmarkView.m */; }; - 8E64ED7C19ED0CE3006E99DA /* QBAssetsCollectionFooterView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E64ED6919ED0CE3006E99DA /* QBAssetsCollectionFooterView.m */; }; - 8E64ED7D19ED0CE3006E99DA /* QBAssetsCollectionOverlayView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E64ED6B19ED0CE3006E99DA /* QBAssetsCollectionOverlayView.m */; }; - 8E64ED7E19ED0CE3006E99DA /* QBAssetsCollectionVideoIndicatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E64ED6D19ED0CE3006E99DA /* QBAssetsCollectionVideoIndicatorView.m */; }; - 8E64ED7F19ED0CE3006E99DA /* QBAssetsCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E64ED6F19ED0CE3006E99DA /* QBAssetsCollectionViewCell.m */; }; - 8E64ED8019ED0CE3006E99DA /* QBAssetsCollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E64ED7119ED0CE3006E99DA /* QBAssetsCollectionViewController.m */; }; - 8E64ED8119ED0CE3006E99DA /* QBAssetsCollectionViewLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E64ED7319ED0CE3006E99DA /* QBAssetsCollectionViewLayout.m */; }; - 8E64ED8219ED0CE3006E99DA /* QBImagePickerController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E64ED7519ED0CE3006E99DA /* QBImagePickerController.m */; }; - 8E64ED8319ED0CE3006E99DA /* QBImagePickerController.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8E64ED7619ED0CE3006E99DA /* QBImagePickerController.strings */; }; - 8E64ED8419ED0CE3006E99DA /* QBImagePickerGroupCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E64ED7819ED0CE3006E99DA /* QBImagePickerGroupCell.m */; }; - 8E64ED8519ED0CE3006E99DA /* QBImagePickerThumbnailView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E64ED7A19ED0CE3006E99DA /* QBImagePickerThumbnailView.m */; }; 8E64ED8A19EE484A006E99DA /* NSDate+Helper.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E64ED8819EE484A006E99DA /* NSDate+Helper.m */; }; 8E64ED8B19EE484A006E99DA /* README.textile in Resources */ = {isa = PBXBuildFile; fileRef = 8E64ED8919EE484A006E99DA /* README.textile */; }; 8E6F1C951A03BD6000BF79C8 /* ProjectMemberActivityListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E6F1C941A03BD6000BF79C8 /* ProjectMemberActivityListViewController.m */; }; @@ -845,10 +852,8 @@ 8E8F7B2C19EF6306006BA8BD /* btn_followed_both@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E8F7B2219EF6306006BA8BD /* btn_followed_both@2x.png */; }; 8E8F7B2D19EF6306006BA8BD /* btn_followed_not@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E8F7B2319EF6306006BA8BD /* btn_followed_not@2x.png */; }; 8E8F7B2E19EF6306006BA8BD /* btn_followed_yes@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E8F7B2419EF6306006BA8BD /* btn_followed_yes@2x.png */; }; - 8E8F7B2F19EF6306006BA8BD /* btn_privateMsg_black@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E8F7B2519EF6306006BA8BD /* btn_privateMsg_black@2x.png */; }; 8E8F7B3019EF6306006BA8BD /* btn_privateMsg_friend@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E8F7B2619EF6306006BA8BD /* btn_privateMsg_friend@2x.png */; }; 8E8F7B3119EF6306006BA8BD /* btn_privateMsg_stranger@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E8F7B2719EF6306006BA8BD /* btn_privateMsg_stranger@2x.png */; }; - 8E8F7B3219EF6306006BA8BD /* btn_privateMsg_white@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E8F7B2819EF6306006BA8BD /* btn_privateMsg_white@2x.png */; }; 8E8F7B3319EF6306006BA8BD /* btn_project_add@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E8F7B2919EF6306006BA8BD /* btn_project_add@2x.png */; }; 8E8F7B3419EF6306006BA8BD /* btn_project_added@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E8F7B2A19EF6306006BA8BD /* btn_project_added@2x.png */; }; 8E8F7B3519EF6306006BA8BD /* btn_project_quit@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E8F7B2B19EF6306006BA8BD /* btn_project_quit@2x.png */; }; @@ -977,7 +982,6 @@ 8EA6D1A119E240C40076D59C /* tipIcon_UserFollow@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CFBC19E240C40076D59C /* tipIcon_UserFollow@2x.png */; }; 8EA6D1A319E240C40076D59C /* tweet_comment_btn@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CFBE19E240C40076D59C /* tweet_comment_btn@2x.png */; }; 8EA6D1A819E240C40076D59C /* xtsegment_bordor_left@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CFC319E240C40076D59C /* xtsegment_bordor_left@2x.png */; }; - 8EA6D1AA19E240C40076D59C /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CFC519E240C40076D59C /* Images.xcassets */; }; 8EA6D1AB19E240C40076D59C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CFC619E240C40076D59C /* main.m */; }; 8EA6D1AE19E240C40076D59C /* CodingTip.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CFCD19E240C40076D59C /* CodingTip.m */; }; 8EA6D1AF19E240C40076D59C /* CodingTips.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CFCF19E240C40076D59C /* CodingTips.m */; }; @@ -1095,13 +1099,2031 @@ 927AFF511BFF6DAD00AAE593 /* shop_exchange_icon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 927AFF491BFF6DAD00AAE593 /* shop_exchange_icon@3x.png */; }; 927AFF521BFF6DAD00AAE593 /* shop_nar_history_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 927AFF4A1BFF6DAD00AAE593 /* shop_nar_history_icon@2x.png */; }; 927AFF531BFF6DAD00AAE593 /* shop_nar_history_icon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 927AFF4B1BFF6DAD00AAE593 /* shop_nar_history_icon@3x.png */; }; - 927AFF541BFF6DAD00AAE593 /* shop_unexchange_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 927AFF4C1BFF6DAD00AAE593 /* shop_unexchange_icon@2x.png */; }; - 927AFF551BFF6DAD00AAE593 /* shop_unexchange_icon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 927AFF4D1BFF6DAD00AAE593 /* shop_unexchange_icon@3x.png */; }; 927AFF581BFF755200AAE593 /* ExchangeGoodsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 927AFF571BFF755200AAE593 /* ExchangeGoodsViewController.m */; }; 927AFF5B1BFF772A00AAE593 /* ShopOrderTextFieldCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 927AFF5A1BFF772A00AAE593 /* ShopOrderTextFieldCell.m */; }; + B10341292024633900853447 /* logo_coding@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B10341272024633800853447 /* logo_coding@2x.png */; }; + B103412A2024633900853447 /* logo_coding@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B10341282024633900853447 /* logo_coding@3x.png */; }; + B11DC7C020245728004E76A9 /* button_terminal@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B11DC7BE20245727004E76A9 /* button_terminal@2x.png */; }; + B11DC7C120245728004E76A9 /* button_terminal@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B11DC7BF20245728004E76A9 /* button_terminal@3x.png */; }; + B1280CED200EFDC600DEDF78 /* file_changeType_RENAME@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CE8200EFDC600DEDF78 /* file_changeType_RENAME@3x.png */; }; + B1280CEE200EFDC600DEDF78 /* file_changeType_ADD@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CE9200EFDC600DEDF78 /* file_changeType_ADD@3x.png */; }; + B1280CEF200EFDC600DEDF78 /* file_changeType_COPY@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CEA200EFDC600DEDF78 /* file_changeType_COPY@3x.png */; }; + B1280CF0200EFDC600DEDF78 /* file_changeType_DELETE@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CEB200EFDC600DEDF78 /* file_changeType_DELETE@3x.png */; }; + B1280CF1200EFDC600DEDF78 /* file_changeType_MODIFY@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CEC200EFDC600DEDF78 /* file_changeType_MODIFY@3x.png */; }; + B1280CFF200EFEA400DEDF78 /* PR_add_label@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CF3200EFEA400DEDF78 /* PR_add_label@3x.png */; }; + B1280D00200EFEA400DEDF78 /* PR_add_watcher@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CF4200EFEA400DEDF78 /* PR_add_watcher@2x.png */; }; + B1280D01200EFEA400DEDF78 /* PR_del_label@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CF5200EFEA400DEDF78 /* PR_del_label@3x.png */; }; + B1280D02200EFEA400DEDF78 /* PR_del_watcher@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CF6200EFEA400DEDF78 /* PR_del_watcher@2x.png */; }; + B1280D03200EFEA400DEDF78 /* PR_add_reviewer@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CF7200EFEA400DEDF78 /* PR_add_reviewer@3x.png */; }; + B1280D04200EFEA400DEDF78 /* PR_add_reviewer@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CF8200EFEA400DEDF78 /* PR_add_reviewer@2x.png */; }; + B1280D05200EFEA400DEDF78 /* PR_del_watcher@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CF9200EFEA400DEDF78 /* PR_del_watcher@3x.png */; }; + B1280D06200EFEA400DEDF78 /* PR_del_label@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CFA200EFEA400DEDF78 /* PR_del_label@2x.png */; }; + B1280D07200EFEA400DEDF78 /* PR_add_watcher@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CFB200EFEA400DEDF78 /* PR_add_watcher@3x.png */; }; + B1280D08200EFEA400DEDF78 /* PR_add_label@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CFC200EFEA400DEDF78 /* PR_add_label@2x.png */; }; + B1280D09200EFEA400DEDF78 /* PR_del_reviewer@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CFD200EFEA400DEDF78 /* PR_del_reviewer@2x.png */; }; + B1280D0A200EFEA400DEDF78 /* PR_del_reviewer@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CFE200EFEA400DEDF78 /* PR_del_reviewer@3x.png */; }; + B12B63F61FE8A77200ACFDCC /* WeiboSDK.bundle in Resources */ = {isa = PBXBuildFile; fileRef = B12B63F51FE8A77200ACFDCC /* WeiboSDK.bundle */; }; + B12B63F91FE8FF0400ACFDCC /* MartFunctionTipView.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B63F81FE8FF0300ACFDCC /* MartFunctionTipView.m */; }; + B12B64061FE900D400ACFDCC /* AMPopTip+Animation.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B63FB1FE900D400ACFDCC /* AMPopTip+Animation.m */; }; + B12B64071FE900D400ACFDCC /* AMPopTip.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B63FD1FE900D400ACFDCC /* AMPopTip.m */; }; + B12B64081FE900D400ACFDCC /* AMPopTip+Entrance.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B64021FE900D400ACFDCC /* AMPopTip+Entrance.m */; }; + B12B64091FE900D400ACFDCC /* AMPopTip+Draw.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B64031FE900D400ACFDCC /* AMPopTip+Draw.m */; }; + B12B640A1FE900D400ACFDCC /* AMPopTip+Exit.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B64051FE900D400ACFDCC /* AMPopTip+Exit.m */; }; + B12B640E1FECB59000ACFDCC /* login_wechat@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B12B640C1FECB58F00ACFDCC /* login_wechat@3x.png */; }; + B12B640F1FECB59000ACFDCC /* login_wechat@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B12B640D1FECB58F00ACFDCC /* login_wechat@2x.png */; }; + B12B64121FF0D54800ACFDCC /* SettingSkillsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B64111FF0D54800ACFDCC /* SettingSkillsViewController.m */; }; + B12B64151FF0DE4800ACFDCC /* SkillCCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B64141FF0DE4800ACFDCC /* SkillCCell.m */; }; + B12B64181FF0E4CB00ACFDCC /* skill_delete@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B12B64161FF0E4CA00ACFDCC /* skill_delete@2x.png */; }; + B12B64191FF0E4CB00ACFDCC /* skill_delete@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B12B64171FF0E4CA00ACFDCC /* skill_delete@3x.png */; }; + B12B641C1FF0F5E400ACFDCC /* JDStatusBarLayoutMarginHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B641B1FF0F5E300ACFDCC /* JDStatusBarLayoutMarginHelper.m */; }; + B12B641F1FF2835800ACFDCC /* CodingVipTipManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B641E1FF2835800ACFDCC /* CodingVipTipManager.m */; }; + B12B64261FF33E0100ACFDCC /* button_red_close@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B12B64201FF33DFE00ACFDCC /* button_red_close@3x.png */; }; + B12B64271FF33E0100ACFDCC /* button_red_close@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B12B64211FF33DFF00ACFDCC /* button_red_close@2x.png */; }; + B12B64281FF33E0100ACFDCC /* button_tip_close@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B12B64221FF33DFF00ACFDCC /* button_tip_close@3x.png */; }; + B12B64291FF33E0100ACFDCC /* upgrade_success@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B12B64231FF33DFF00ACFDCC /* upgrade_success@2x.png */; }; + B12B642A1FF33E0100ACFDCC /* upgrade_success@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B12B64241FF33E0000ACFDCC /* upgrade_success@3x.png */; }; + B12B642B1FF33E0100ACFDCC /* button_tip_close@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B12B64251FF33E0000ACFDCC /* button_tip_close@2x.png */; }; + B12B64731FFB61AD00ACFDCC /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = B12B64571FFB61AD00ACFDCC /* LICENSE */; }; + B12B64741FFB61AD00ACFDCC /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = B12B64581FFB61AD00ACFDCC /* README.md */; }; + B12B64751FFB61AD00ACFDCC /* QBImagePicker.strings in Resources */ = {isa = PBXBuildFile; fileRef = B12B645A1FFB61AD00ACFDCC /* QBImagePicker.strings */; }; + B12B64761FFB61AD00ACFDCC /* QBVideoIconView.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B64611FFB61AD00ACFDCC /* QBVideoIconView.m */; }; + B12B64771FFB61AD00ACFDCC /* QBVideoIndicatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B64621FFB61AD00ACFDCC /* QBVideoIndicatorView.m */; }; + B12B64781FFB61AD00ACFDCC /* QBAlbumCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B64681FFB61AD00ACFDCC /* QBAlbumCell.m */; }; + B12B64791FFB61AD00ACFDCC /* QBImagePicker.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B12B64691FFB61AD00ACFDCC /* QBImagePicker.storyboard */; }; + B12B647A1FFB61AD00ACFDCC /* QBAlbumsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B646B1FFB61AD00ACFDCC /* QBAlbumsViewController.m */; }; + B12B647B1FFB61AD00ACFDCC /* QBAssetsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B646D1FFB61AD00ACFDCC /* QBAssetsViewController.m */; }; + B12B647C1FFB61AD00ACFDCC /* QBImagePickerController.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B646E1FFB61AD00ACFDCC /* QBImagePickerController.m */; }; + B12B647D1FFB61AD00ACFDCC /* QBCheckmarkView.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B646F1FFB61AD00ACFDCC /* QBCheckmarkView.m */; }; + B12B647E1FFB61AD00ACFDCC /* QBSlomoIconView.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B64711FFB61AD00ACFDCC /* QBSlomoIconView.m */; }; + B12B647F1FFB61AD00ACFDCC /* QBAssetCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B64721FFB61AD00ACFDCC /* QBAssetCell.m */; }; + B12B64821FFC73A900ACFDCC /* PHAsset+Common.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B64811FFC73A900ACFDCC /* PHAsset+Common.m */; }; + B131E2112074D2EE00D84FAA /* project_item_reading@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B131E20F2074D2ED00D84FAA /* project_item_reading@3x.png */; }; + B131E2122074D2EE00D84FAA /* project_item_reading@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B131E2102074D2EE00D84FAA /* project_item_reading@2x.png */; }; + B14689B41EE100B200B01371 /* vip_3_30@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689A41EE100B200B01371 /* vip_3_30@2x.png */; }; + B14689B51EE100B200B01371 /* vip_3_30@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689A51EE100B200B01371 /* vip_3_30@3x.png */; }; + B14689B61EE100B200B01371 /* vip_3_40@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689A61EE100B200B01371 /* vip_3_40@2x.png */; }; + B14689B71EE100B200B01371 /* vip_3_40@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689A71EE100B200B01371 /* vip_3_40@3x.png */; }; + B14689B81EE100B200B01371 /* vip_3_45@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689A81EE100B200B01371 /* vip_3_45@2x.png */; }; + B14689B91EE100B200B01371 /* vip_3_45@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689A91EE100B200B01371 /* vip_3_45@3x.png */; }; + B14689BA1EE100B200B01371 /* vip_3_75@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689AA1EE100B200B01371 /* vip_3_75@2x.png */; }; + B14689BB1EE100B200B01371 /* vip_3_75@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689AB1EE100B200B01371 /* vip_3_75@3x.png */; }; + B14689BC1EE100B200B01371 /* vip_4_30@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689AC1EE100B200B01371 /* vip_4_30@2x.png */; }; + B14689BD1EE100B200B01371 /* vip_4_30@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689AD1EE100B200B01371 /* vip_4_30@3x.png */; }; + B14689BE1EE100B200B01371 /* vip_4_40@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689AE1EE100B200B01371 /* vip_4_40@2x.png */; }; + B14689BF1EE100B200B01371 /* vip_4_40@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689AF1EE100B200B01371 /* vip_4_40@3x.png */; }; + B14689C01EE100B200B01371 /* vip_4_45@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689B01EE100B200B01371 /* vip_4_45@2x.png */; }; + B14689C11EE100B200B01371 /* vip_4_45@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689B11EE100B200B01371 /* vip_4_45@3x.png */; }; + B14689C21EE100B200B01371 /* vip_4_75@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689B21EE100B200B01371 /* vip_4_75@2x.png */; }; + B14689C31EE100B200B01371 /* vip_4_75@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689B31EE100B200B01371 /* vip_4_75@3x.png */; }; + B14DE6DE20C914E70072ECEA /* AnimatedGIFImageSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = B14DE6DD20C914E60072ECEA /* AnimatedGIFImageSerialization.m */; }; + B14DE6DF20C914E70072ECEA /* AnimatedGIFImageSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = B14DE6DD20C914E60072ECEA /* AnimatedGIFImageSerialization.m */; }; + B152ED4E2090B223004A6E8A /* ProjectSettingEntranceController.m in Sources */ = {isa = PBXBuildFile; fileRef = B152ED4D2090B223004A6E8A /* ProjectSettingEntranceController.m */; }; + B152ED542091B7CB004A6E8A /* ProjectArchiveViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B152ED532091B7CB004A6E8A /* ProjectArchiveViewController.m */; }; + B152ED5A2092BF46004A6E8A /* EABoardTaskList.m in Sources */ = {isa = PBXBuildFile; fileRef = B152ED592092BF46004A6E8A /* EABoardTaskList.m */; }; + B152ED5D2092D51E004A6E8A /* EATaskBoardListTaskCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B152ED5C2092D51E004A6E8A /* EATaskBoardListTaskCell.m */; }; + B152ED602093018A004A6E8A /* EABoardTaskListView.m in Sources */ = {isa = PBXBuildFile; fileRef = B152ED5F2093018A004A6E8A /* EABoardTaskListView.m */; }; + B152ED6320935524004A6E8A /* EABoardTaskListBlankView.m in Sources */ = {isa = PBXBuildFile; fileRef = B152ED6220935524004A6E8A /* EABoardTaskListBlankView.m */; }; + B152ED6520935594004A6E8A /* EABoardTaskListBlankView.xib in Resources */ = {isa = PBXBuildFile; fileRef = B152ED6420935594004A6E8A /* EABoardTaskListBlankView.xib */; }; + B152ED68209420CD004A6E8A /* RATaskBoardListListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B152ED67209420CD004A6E8A /* RATaskBoardListListViewController.m */; }; + B152ED7C20945378004A6E8A /* project_item_taskboard@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED7A20945377004A6E8A /* project_item_taskboard@2x.png */; }; + B152ED7D20945378004A6E8A /* project_item_taskboard@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED7B20945377004A6E8A /* project_item_taskboard@3x.png */; }; + B152ED82209453E8004A6E8A /* taskBoardList@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED7E209453E6004A6E8A /* taskBoardList@3x.png */; }; + B152ED83209453E8004A6E8A /* taskboard_blankpage@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED7F209453E7004A6E8A /* taskboard_blankpage@2x.png */; }; + B152ED84209453E8004A6E8A /* taskBoardList@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED80209453E7004A6E8A /* taskBoardList@2x.png */; }; + B152ED85209453E8004A6E8A /* taskboard_blankpage@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED81209453E8004A6E8A /* taskboard_blankpage@3x.png */; }; + B152ED8F209453F3004A6E8A /* taskboard_normal_page_selected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED87209453F2004A6E8A /* taskboard_normal_page_selected@3x.png */; }; + B152ED90209453F3004A6E8A /* taskboard_normal_page_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED88209453F2004A6E8A /* taskboard_normal_page_selected@2x.png */; }; + B152ED91209453F3004A6E8A /* taskboard_add_page_unselected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED89209453F2004A6E8A /* taskboard_add_page_unselected@2x.png */; }; + B152ED92209453F3004A6E8A /* taskboard_add_page_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED8A209453F2004A6E8A /* taskboard_add_page_selected@2x.png */; }; + B152ED93209453F3004A6E8A /* taskboard_add_page_selected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED8B209453F2004A6E8A /* taskboard_add_page_selected@3x.png */; }; + B152ED94209453F3004A6E8A /* taskboard_add_page_unselected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED8C209453F2004A6E8A /* taskboard_add_page_unselected@3x.png */; }; + B152ED95209453F3004A6E8A /* taskboard_normal_page_unselected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED8D209453F2004A6E8A /* taskboard_normal_page_unselected@3x.png */; }; + B152ED96209453F3004A6E8A /* taskboard_normal_page_unselected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED8E209453F2004A6E8A /* taskboard_normal_page_unselected@2x.png */; }; + B15C98AD20D39C4B00DDA425 /* NewProject.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B94C1B6A1AC945FB0000C271 /* NewProject.storyboard */; }; + B15C98B020D39CA200DDA425 /* project_icon_edit@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B15C98AE20D39CA100DDA425 /* project_icon_edit@2x.png */; }; + B15C98B120D39CA200DDA425 /* project_icon_edit@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B15C98AE20D39CA100DDA425 /* project_icon_edit@2x.png */; }; + B15C98B220D39CA200DDA425 /* project_icon_edit@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B15C98AF20D39CA200DDA425 /* project_icon_edit@3x.png */; }; + B15C98B320D39CA200DDA425 /* project_icon_edit@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B15C98AF20D39CA200DDA425 /* project_icon_edit@3x.png */; }; + B16E6CA020C0FDB50076026D /* logo_coding_top@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6C9F20C0FDB50076026D /* logo_coding_top@3x.png */; }; + B16E6CA120C0FDB50076026D /* logo_coding_top@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6C9F20C0FDB50076026D /* logo_coding_top@3x.png */; }; + B16E6CA320C102B60076026D /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CFC519E240C40076D59C /* Images.xcassets */; }; + B16E6CA620C13BA20076026D /* btn_dismiss@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CA420C13BA10076026D /* btn_dismiss@3x.png */; }; + B16E6CA720C13BA20076026D /* btn_dismiss@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CA420C13BA10076026D /* btn_dismiss@3x.png */; }; + B16E6CA820C13BA20076026D /* btn_dismiss@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CA520C13BA10076026D /* btn_dismiss@2x.png */; }; + B16E6CA920C13BA20076026D /* btn_dismiss@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CA520C13BA10076026D /* btn_dismiss@2x.png */; }; + B16E6CAF20C13BF50076026D /* btn_next_unable@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CAB20C13BF40076026D /* btn_next_unable@2x.png */; }; + B16E6CB020C13BF50076026D /* btn_next_unable@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CAB20C13BF40076026D /* btn_next_unable@2x.png */; }; + B16E6CB120C13BF50076026D /* btn_next_unable@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CAC20C13BF40076026D /* btn_next_unable@3x.png */; }; + B16E6CB220C13BF50076026D /* btn_next_unable@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CAC20C13BF40076026D /* btn_next_unable@3x.png */; }; + B16E6CB320C13BF50076026D /* btn_next_enable@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CAD20C13BF40076026D /* btn_next_enable@2x.png */; }; + B16E6CB420C13BF50076026D /* btn_next_enable@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CAD20C13BF40076026D /* btn_next_enable@2x.png */; }; + B16E6CB520C13BF50076026D /* btn_next_enable@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CAE20C13BF40076026D /* btn_next_enable@3x.png */; }; + B16E6CB620C13BF50076026D /* btn_next_enable@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CAE20C13BF40076026D /* btn_next_enable@3x.png */; }; + B16E6CBE20C13F5F0076026D /* btn_project_add@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CB820C13F5E0076026D /* btn_project_add@3x.png */; }; + B16E6CBF20C13F5F0076026D /* btn_project_add@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CB820C13F5E0076026D /* btn_project_add@3x.png */; }; + B16E6CC020C13F5F0076026D /* btn_project_added@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CB920C13F5E0076026D /* btn_project_added@3x.png */; }; + B16E6CC120C13F5F0076026D /* btn_project_added@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CB920C13F5E0076026D /* btn_project_added@3x.png */; }; + B16E6CC220C13F5F0076026D /* btn_project_quit@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CBA20C13F5E0076026D /* btn_project_quit@3x.png */; }; + B16E6CC320C13F5F0076026D /* btn_project_quit@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CBA20C13F5E0076026D /* btn_project_quit@3x.png */; }; + B16E6CC420C13F5F0076026D /* btn_privateMsg_stranger@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CBB20C13F5E0076026D /* btn_privateMsg_stranger@3x.png */; }; + B16E6CC520C13F5F0076026D /* btn_privateMsg_stranger@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CBB20C13F5E0076026D /* btn_privateMsg_stranger@3x.png */; }; + B16E6CCA20C144930076026D /* done_Nav@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CC620C144910076026D /* done_Nav@2x.png */; }; + B16E6CCB20C144930076026D /* done_Nav@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CC620C144910076026D /* done_Nav@2x.png */; }; + B16E6CCC20C144930076026D /* done_Nav@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CC720C144920076026D /* done_Nav@3x.png */; }; + B16E6CCD20C144930076026D /* done_Nav@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CC720C144920076026D /* done_Nav@3x.png */; }; + B16E6CCE20C144930076026D /* done_un_Nav@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CC820C144920076026D /* done_un_Nav@2x.png */; }; + B16E6CCF20C144930076026D /* done_un_Nav@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CC820C144920076026D /* done_un_Nav@2x.png */; }; + B16E6CD020C144930076026D /* done_un_Nav@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CC920C144920076026D /* done_un_Nav@3x.png */; }; + B16E6CD120C144930076026D /* done_un_Nav@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CC920C144920076026D /* done_un_Nav@3x.png */; }; + B16E6CDB20C145BF0076026D /* quick_menu_icon_message@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CD320C145BE0076026D /* quick_menu_icon_message@2x.png */; }; + B16E6CDC20C145BF0076026D /* quick_menu_icon_message@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CD320C145BE0076026D /* quick_menu_icon_message@2x.png */; }; + B16E6CDD20C145BF0076026D /* quick_menu_icon_message@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CD420C145BE0076026D /* quick_menu_icon_message@3x.png */; }; + B16E6CDE20C145BF0076026D /* quick_menu_icon_message@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CD420C145BE0076026D /* quick_menu_icon_message@3x.png */; }; + B16E6CDF20C145BF0076026D /* quick_menu_icon_task@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CD520C145BE0076026D /* quick_menu_icon_task@3x.png */; }; + B16E6CE020C145BF0076026D /* quick_menu_icon_task@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CD520C145BE0076026D /* quick_menu_icon_task@3x.png */; }; + B16E6CE120C145BF0076026D /* quick_menu_icon_task@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CD620C145BE0076026D /* quick_menu_icon_task@2x.png */; }; + B16E6CE220C145BF0076026D /* quick_menu_icon_task@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CD620C145BE0076026D /* quick_menu_icon_task@2x.png */; }; + B16E6CE320C145BF0076026D /* quick_menu_icon_project@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CD720C145BE0076026D /* quick_menu_icon_project@3x.png */; }; + B16E6CE420C145BF0076026D /* quick_menu_icon_project@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CD720C145BE0076026D /* quick_menu_icon_project@3x.png */; }; + B16E6CE520C145BF0076026D /* quick_menu_icon_2fa@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CD820C145BE0076026D /* quick_menu_icon_2fa@3x.png */; }; + B16E6CE620C145BF0076026D /* quick_menu_icon_2fa@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CD820C145BE0076026D /* quick_menu_icon_2fa@3x.png */; }; + B16E6CE720C145BF0076026D /* quick_menu_icon_2fa@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CD920C145BE0076026D /* quick_menu_icon_2fa@2x.png */; }; + B16E6CE820C145BF0076026D /* quick_menu_icon_2fa@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CD920C145BE0076026D /* quick_menu_icon_2fa@2x.png */; }; + B16E6CE920C145BF0076026D /* quick_menu_icon_project@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CDA20C145BE0076026D /* quick_menu_icon_project@2x.png */; }; + B16E6CEA20C145BF0076026D /* quick_menu_icon_project@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CDA20C145BE0076026D /* quick_menu_icon_project@2x.png */; }; + B16E6CED20C147490076026D /* team_bg@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CEB20C147480076026D /* team_bg@3x.png */; }; + B16E6CEE20C147490076026D /* team_bg@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CEB20C147480076026D /* team_bg@3x.png */; }; + B16E6CEF20C147490076026D /* team_bg@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CEC20C147490076026D /* team_bg@2x.png */; }; + B16E6CF020C147490076026D /* team_bg@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CEC20C147490076026D /* team_bg@2x.png */; }; + B16E6D0120C147770076026D /* team_info_pro@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CF220C147760076026D /* team_info_pro@3x.png */; }; + B16E6D0220C147770076026D /* team_info_pro@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CF220C147760076026D /* team_info_pro@3x.png */; }; + B16E6D0320C147770076026D /* team_info_pro@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CF320C147760076026D /* team_info_pro@2x.png */; }; + B16E6D0420C147770076026D /* team_info_pro@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CF320C147760076026D /* team_info_pro@2x.png */; }; + B16E6D0520C147770076026D /* team_info_order@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CF420C147760076026D /* team_info_order@2x.png */; }; + B16E6D0620C147770076026D /* team_info_order@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CF420C147760076026D /* team_info_order@2x.png */; }; + B16E6D0720C147770076026D /* team_info_order@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CF520C147760076026D /* team_info_order@3x.png */; }; + B16E6D0820C147770076026D /* team_info_order@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CF520C147760076026D /* team_info_order@3x.png */; }; + B16E6D0920C147770076026D /* team_info_sup@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CF620C147760076026D /* team_info_sup@2x.png */; }; + B16E6D0A20C147770076026D /* team_info_sup@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CF620C147760076026D /* team_info_sup@2x.png */; }; + B16E6D0B20C147770076026D /* team_info_mem@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CF720C147760076026D /* team_info_mem@3x.png */; }; + B16E6D0C20C147770076026D /* team_info_mem@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CF720C147760076026D /* team_info_mem@3x.png */; }; + B16E6D0D20C147770076026D /* team_info_mem@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CF820C147760076026D /* team_info_mem@2x.png */; }; + B16E6D0E20C147770076026D /* team_info_mem@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CF820C147760076026D /* team_info_mem@2x.png */; }; + B16E6D0F20C147770076026D /* team_info_sup@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CF920C147760076026D /* team_info_sup@3x.png */; }; + B16E6D1020C147770076026D /* team_info_sup@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CF920C147760076026D /* team_info_sup@3x.png */; }; + B16E6D1120C147770076026D /* team_cell_edit_team@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CFB20C147760076026D /* team_cell_edit_team@3x.png */; }; + B16E6D1220C147770076026D /* team_cell_edit_team@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CFB20C147760076026D /* team_cell_edit_team@3x.png */; }; + B16E6D1320C147770076026D /* team_cell_edit_team@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CFC20C147760076026D /* team_cell_edit_team@2x.png */; }; + B16E6D1420C147770076026D /* team_cell_edit_team@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CFC20C147760076026D /* team_cell_edit_team@2x.png */; }; + B16E6D1520C147770076026D /* team_cell_edit_delete@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CFD20C147760076026D /* team_cell_edit_delete@3x.png */; }; + B16E6D1620C147770076026D /* team_cell_edit_delete@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CFD20C147760076026D /* team_cell_edit_delete@3x.png */; }; + B16E6D1720C147770076026D /* team_cell_edit_delete@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CFE20C147760076026D /* team_cell_edit_delete@2x.png */; }; + B16E6D1820C147770076026D /* team_cell_edit_delete@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CFE20C147760076026D /* team_cell_edit_delete@2x.png */; }; + B16E6D1920C147770076026D /* team_cell_edit_pro@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CFF20C147760076026D /* team_cell_edit_pro@3x.png */; }; + B16E6D1A20C147770076026D /* team_cell_edit_pro@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6CFF20C147760076026D /* team_cell_edit_pro@3x.png */; }; + B16E6D1B20C147770076026D /* team_cell_edit_pro@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D0020C147760076026D /* team_cell_edit_pro@2x.png */; }; + B16E6D1C20C147770076026D /* team_cell_edit_pro@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D0020C147760076026D /* team_cell_edit_pro@2x.png */; }; + B16E6D7420C148E50076026D /* intro_icon_4@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D2020C148E50076026D /* intro_icon_4@3x.png */; }; + B16E6D7520C148E50076026D /* intro_tip_2@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D2120C148E50076026D /* intro_tip_2@3x.png */; }; + B16E6D7620C148E50076026D /* intro_icon_6@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D2220C148E50076026D /* intro_icon_6@2x.png */; }; + B16E6D7720C148E50076026D /* intro_tip_0@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D2320C148E50076026D /* intro_tip_0@2x.png */; }; + B16E6D7820C148E50076026D /* intro_tip_0@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D2420C148E50076026D /* intro_tip_0@3x.png */; }; + B16E6D7920C148E50076026D /* intro_icon_6@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D2520C148E50076026D /* intro_icon_6@3x.png */; }; + B16E6D7A20C148E50076026D /* intro_tip_2@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D2620C148E50076026D /* intro_tip_2@2x.png */; }; + B16E6D7B20C148E50076026D /* intro_icon_4@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D2720C148E50076026D /* intro_icon_4@2x.png */; }; + B16E6D7C20C148E50076026D /* intro_icon_0@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D2820C148E50076026D /* intro_icon_0@2x.png */; }; + B16E6D7D20C148E50076026D /* intro_icon_2@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D2920C148E50076026D /* intro_icon_2@3x.png */; }; + B16E6D7E20C148E50076026D /* intro_tip_4@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D2A20C148E50076026D /* intro_tip_4@3x.png */; }; + B16E6D7F20C148E50076026D /* intro_tip_4@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D2B20C148E50076026D /* intro_tip_4@2x.png */; }; + B16E6D8020C148E50076026D /* intro_icon_2@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D2C20C148E50076026D /* intro_icon_2@2x.png */; }; + B16E6D8120C148E50076026D /* intro_icon_0@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D2D20C148E50076026D /* intro_icon_0@3x.png */; }; + B16E6D8220C148E50076026D /* intro_tip_1@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D2E20C148E50076026D /* intro_tip_1@2x.png */; }; + B16E6D8320C148E50076026D /* intro_icon_5@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D2F20C148E50076026D /* intro_icon_5@3x.png */; }; + B16E6D8420C148E50076026D /* intro_dot_unselected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D3020C148E50076026D /* intro_dot_unselected@2x.png */; }; + B16E6D8520C148E50076026D /* intro_tip_3@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D3120C148E50076026D /* intro_tip_3@3x.png */; }; + B16E6D8620C148E50076026D /* intro_tip_3@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D3220C148E50076026D /* intro_tip_3@2x.png */; }; + B16E6D8720C148E50076026D /* intro_icon_5@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D3320C148E50076026D /* intro_icon_5@2x.png */; }; + B16E6D8820C148E50076026D /* intro_dot_unselected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D3420C148E50076026D /* intro_dot_unselected@3x.png */; }; + B16E6D8920C148E50076026D /* intro_tip_1@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D3520C148E50076026D /* intro_tip_1@3x.png */; }; + B16E6D8A20C148E50076026D /* intro_icon_3@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D3620C148E50076026D /* intro_icon_3@3x.png */; }; + B16E6D8B20C148E50076026D /* intro_tip_5@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D3720C148E50076026D /* intro_tip_5@3x.png */; }; + B16E6D8C20C148E50076026D /* intro_icon_1@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D3820C148E50076026D /* intro_icon_1@2x.png */; }; + B16E6D8D20C148E50076026D /* intro_dot_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D3920C148E50076026D /* intro_dot_selected@2x.png */; }; + B16E6D8E20C148E50076026D /* intro_dot_selected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D3A20C148E50076026D /* intro_dot_selected@3x.png */; }; + B16E6D8F20C148E50076026D /* intro_icon_1@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D3B20C148E50076026D /* intro_icon_1@3x.png */; }; + B16E6D9020C148E50076026D /* intro_tip_5@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D3C20C148E50076026D /* intro_tip_5@2x.png */; }; + B16E6D9120C148E50076026D /* intro_icon_3@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D3D20C148E50076026D /* intro_icon_3@2x.png */; }; + B16E6D9220C148E50076026D /* intro_page0_ip5@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D3F20C148E50076026D /* intro_page0_ip5@2x.png */; }; + B16E6D9320C148E50076026D /* intro_page_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D4020C148E50076026D /* intro_page_selected@2x.png */; }; + B16E6D9420C148E50076026D /* intro_page_unselected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D4120C148E50076026D /* intro_page_unselected@2x.png */; }; + B16E6D9520C148E50076026D /* intro_page0_ip4@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D4220C148E50076026D /* intro_page0_ip4@2x.png */; }; + B16E6D9620C148E50076026D /* intro_page_unselected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D4320C148E50076026D /* intro_page_unselected@3x.png */; }; + B16E6D9720C148E50076026D /* intro_page_selected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D4420C148E50076026D /* intro_page_selected@3x.png */; }; + B16E6D9820C148E50076026D /* intro_page0_ip6@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D4520C148E50076026D /* intro_page0_ip6@2x.png */; }; + B16E6D9920C148E50076026D /* intro_page0_ip6+@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D4620C148E50076026D /* intro_page0_ip6+@3x.png */; }; + B16E6D9A20C148E50076026D /* intro_page0_ipX@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D4720C148E50076026D /* intro_page0_ipX@3x.png */; }; + B16E6D9B20C148E50076026D /* icon_user_monkey_i6p@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D4920C148E50076026D /* icon_user_monkey_i6p@3x.png */; }; + B16E6D9C20C148E50076026D /* icon_user_monkey_i6@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D4A20C148E50076026D /* icon_user_monkey_i6@2x.png */; }; + B16E6D9D20C148E50076026D /* icon_user_monkey@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D4B20C148E50076026D /* icon_user_monkey@2x.png */; }; + B16E6DC020C1492F0076026D /* intro_dot_dark_unselected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D5520C148E50076026D /* intro_dot_dark_unselected@3x.png */; }; + B16E6DC120C1492F0076026D /* intro_dot_dark_selected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D5620C148E50076026D /* intro_dot_dark_selected@3x.png */; }; + B16E6DC220C1492F0076026D /* intro_dot_dark_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D5720C148E50076026D /* intro_dot_dark_selected@2x.png */; }; + B16E6DC320C1492F0076026D /* intro_dot_dark_unselected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D5820C148E50076026D /* intro_dot_dark_unselected@2x.png */; }; + B16E6DC420C149350076026D /* intro_dot_light_unselected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D4F20C148E50076026D /* intro_dot_light_unselected@2x.png */; }; + B16E6DC520C149350076026D /* intro_dot_light_unselected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D5020C148E50076026D /* intro_dot_light_unselected@3x.png */; }; + B16E6DC620C149350076026D /* intro_dot_light_selected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D5120C148E50076026D /* intro_dot_light_selected@3x.png */; }; + B16E6DC720C149350076026D /* intro_dot_light_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D5220C148E50076026D /* intro_dot_light_selected@2x.png */; }; + B16E6DC820C1493A0076026D /* intro_icon_wiki_down.gif in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D5320C148E50076026D /* intro_icon_wiki_down.gif */; }; + B16E6DC920C1493A0076026D /* intro_icon_wiki_up.gif in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D5920C148E50076026D /* intro_icon_wiki_up.gif */; }; + B16E6DCA20C1493A0076026D /* intro_icon_file_up.gif in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D5A20C148E50076026D /* intro_icon_file_up.gif */; }; + B16E6DCB20C1493A0076026D /* intro_icon_code_up.gif in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D5B20C148E50076026D /* intro_icon_code_up.gif */; }; + B16E6DCC20C1493A0076026D /* intro_icon_task_up.gif in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D5C20C148E50076026D /* intro_icon_task_up.gif */; }; + B16E6DCD20C1493A0076026D /* intro_icon_file_down.gif in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D5D20C148E50076026D /* intro_icon_file_down.gif */; }; + B16E6DCE20C1493A0076026D /* intro_icon_task_down.gif in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D5E20C148E50076026D /* intro_icon_task_down.gif */; }; + B16E6DCF20C1493A0076026D /* intro_icon_code_down.gif in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D5F20C148E50076026D /* intro_icon_code_down.gif */; }; + B16E6DD020C149440076026D /* intro_page0_ip5@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D6120C148E50076026D /* intro_page0_ip5@2x.png */; }; + B16E6DD120C149440076026D /* intro_page2_ip6+@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D6220C148E50076026D /* intro_page2_ip6+@3x.png */; }; + B16E6DD220C149440076026D /* intro_page1_ip6@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D6320C148E50076026D /* intro_page1_ip6@2x.png */; }; + B16E6DD320C149440076026D /* intro_page1_ip4@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D6420C148E50076026D /* intro_page1_ip4@2x.png */; }; + B16E6DD420C149440076026D /* intro_page2_ip5@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D6520C148E50076026D /* intro_page2_ip5@2x.png */; }; + B16E6DD520C149440076026D /* intro_page1_ip6+@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D6620C148E50076026D /* intro_page1_ip6+@3x.png */; }; + B16E6DD620C149440076026D /* intro_page_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D6720C148E50076026D /* intro_page_selected@2x.png */; }; + B16E6DD720C149440076026D /* intro_page_unselected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D6820C148E50076026D /* intro_page_unselected@2x.png */; }; + B16E6DD820C149440076026D /* intro_page0_ip4@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D6920C148E50076026D /* intro_page0_ip4@2x.png */; }; + B16E6DD920C149440076026D /* intro_page1_ip5@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D6A20C148E50076026D /* intro_page1_ip5@2x.png */; }; + B16E6DDA20C149440076026D /* intro_page_unselected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D6B20C148E50076026D /* intro_page_unselected@3x.png */; }; + B16E6DDB20C149440076026D /* intro_page_selected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D6C20C148E50076026D /* intro_page_selected@3x.png */; }; + B16E6DDC20C149440076026D /* intro_page0_ip6@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D6D20C148E50076026D /* intro_page0_ip6@2x.png */; }; + B16E6DDD20C149440076026D /* intro_page2_ip4@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D6E20C148E50076026D /* intro_page2_ip4@2x.png */; }; + B16E6DDE20C149440076026D /* intro_page0_ip6+@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D6F20C148E50076026D /* intro_page0_ip6+@3x.png */; }; + B16E6DDF20C149440076026D /* intro_page2_ip6@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D7020C148E50076026D /* intro_page2_ip6@2x.png */; }; + B16E6DE020C1494B0076026D /* icon_user_monkey@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D7220C148E50076026D /* icon_user_monkey@2x.png */; }; + B16E6DE120C1494B0076026D /* icon_user_monkey@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16E6D7320C148E50076026D /* icon_user_monkey@3x.png */; }; + B16EEF08208DDBB6005ABFD5 /* timeline_icon_read@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16EEF06208DDBB5005ABFD5 /* timeline_icon_read@3x.png */; }; + B16EEF09208DDBB6005ABFD5 /* timeline_icon_unread@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16EEF07208DDBB6005ABFD5 /* timeline_icon_unread@3x.png */; }; + B16EEF13209080D7005ABFD5 /* TaskBoardsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B16EEF12209080D7005ABFD5 /* TaskBoardsViewController.m */; }; + B177F5C52060E6B1006709C2 /* wiki.html in Resources */ = {isa = PBXBuildFile; fileRef = B177F5C02060E6B1006709C2 /* wiki.html */; }; + B177F5C62060E6B1006709C2 /* bubble.html in Resources */ = {isa = PBXBuildFile; fileRef = B177F5C12060E6B1006709C2 /* bubble.html */; }; + B177F5C72060E6B1006709C2 /* markdown.html in Resources */ = {isa = PBXBuildFile; fileRef = B177F5C22060E6B1006709C2 /* markdown.html */; }; + B177F5C82060E6B1006709C2 /* topic-ios.html in Resources */ = {isa = PBXBuildFile; fileRef = B177F5C32060E6B1006709C2 /* topic-ios.html */; }; + B177F5C92060E6B1006709C2 /* code.html in Resources */ = {isa = PBXBuildFile; fileRef = B177F5C42060E6B1006709C2 /* code.html */; }; + B17CC31420731E950077C956 /* icon_release_tag_blue@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC31220731E900077C956 /* icon_release_tag_blue@3x.png */; }; + B17CC31520731E950077C956 /* icon_release_tag_blue@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC31320731E910077C956 /* icon_release_tag_blue@2x.png */; }; + B17CC31D20731FF10077C956 /* code_release_resource_Zip@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC31720731FF10077C956 /* code_release_resource_Zip@2x.png */; }; + B17CC31E20731FF10077C956 /* code_release_resource_Zip@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC31820731FF10077C956 /* code_release_resource_Zip@3x.png */; }; + B17CC31F20731FF10077C956 /* code_release_resource_Default@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC31920731FF10077C956 /* code_release_resource_Default@3x.png */; }; + B17CC32020731FF10077C956 /* code_release_resource__Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC31A20731FF10077C956 /* code_release_resource__Default@2x.png */; }; + B17CC32120731FF10077C956 /* code_release_resource_Task@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC31B20731FF10077C956 /* code_release_resource_Task@2x.png */; }; + B17CC32220731FF10077C956 /* code_release_resource_Task@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC31C20731FF10077C956 /* code_release_resource_Task@3x.png */; }; + B17CC3292073212E0077C956 /* code_release_resource_ProjectFile@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC3232073212D0077C956 /* code_release_resource_ProjectFile@3x.png */; }; + B17CC32A2073212E0077C956 /* code_release_resource_MergeRequestBean@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC3242073212D0077C956 /* code_release_resource_MergeRequestBean@3x.png */; }; + B17CC32B2073212E0077C956 /* code_release_resource_ProjectFile@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC3252073212D0077C956 /* code_release_resource_ProjectFile@2x.png */; }; + B17CC32C2073212E0077C956 /* code_release_resource_ProjectTopic@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC3262073212D0077C956 /* code_release_resource_ProjectTopic@3x.png */; }; + B17CC32D2073212E0077C956 /* code_release_resource_MergeRequestBean@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC3272073212E0077C956 /* code_release_resource_MergeRequestBean@2x.png */; }; + B17CC32E2073212E0077C956 /* code_release_resource_ProjectTopic@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC3282073212E0077C956 /* code_release_resource_ProjectTopic@2x.png */; }; + B1816063202063440022B4C6 /* EATerminalViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1816062202063440022B4C6 /* EATerminalViewController.m */; }; + B1817EB62063899400E9BAD1 /* EACodeBranchListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1817EB52063899400E9BAD1 /* EACodeBranchListViewController.m */; }; + B1817EB9206389F500E9BAD1 /* EACodeReleaseListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1817EB8206389F500E9BAD1 /* EACodeReleaseListViewController.m */; }; + B1817EBC2063936100E9BAD1 /* EACodeBranches.m in Sources */ = {isa = PBXBuildFile; fileRef = B1817EBB2063936100E9BAD1 /* EACodeBranches.m */; }; + B1817EBF2063951000E9BAD1 /* EABasePageModel.m in Sources */ = {isa = PBXBuildFile; fileRef = B1817EBE2063951000E9BAD1 /* EABasePageModel.m */; }; + B1817EC4206397E000E9BAD1 /* EACodeRelease.m in Sources */ = {isa = PBXBuildFile; fileRef = B1817EC3206397E000E9BAD1 /* EACodeRelease.m */; }; + B1817EC7206397F500E9BAD1 /* EACodeReleases.m in Sources */ = {isa = PBXBuildFile; fileRef = B1817EC6206397F500E9BAD1 /* EACodeReleases.m */; }; + B1817ECA20639E9500E9BAD1 /* EACodeReleaseListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B1817EC920639E9500E9BAD1 /* EACodeReleaseListCell.m */; }; + B1817ECD20639F0A00E9BAD1 /* EACodeBranchListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B1817ECC20639F0A00E9BAD1 /* EACodeBranchListCell.m */; }; + B1817EE42064F92C00E9BAD1 /* EACodeReleaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1817EE32064F92C00E9BAD1 /* EACodeReleaseViewController.m */; }; + B1817EE72064FC6100E9BAD1 /* EACodeReleaseTopCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B1817EE62064FC6100E9BAD1 /* EACodeReleaseTopCell.m */; }; + B1817EEA2064FC7300E9BAD1 /* EACodeReleaseBodyCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B1817EE92064FC7300E9BAD1 /* EACodeReleaseBodyCell.m */; }; + B1817EED2064FD9400E9BAD1 /* EACodeReleaseAttachmentsOrReferencesCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B1817EEC2064FD9400E9BAD1 /* EACodeReleaseAttachmentsOrReferencesCell.m */; }; + B1817EEF2068C7A100E9BAD1 /* EACodeBranchListCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B1817EEE2068C7A100E9BAD1 /* EACodeBranchListCell.xib */; }; + B1817EF12068F4B400E9BAD1 /* EACodeReleaseListCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B1817EF02068F4B400E9BAD1 /* EACodeReleaseListCell.xib */; }; + B1817EF62069186E00E9BAD1 /* project_item_tag@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1817EF22069186C00E9BAD1 /* project_item_tag@2x.png */; }; + B1817EF72069186E00E9BAD1 /* project_item_branch@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1817EF32069186C00E9BAD1 /* project_item_branch@2x.png */; }; + B1817EF82069186E00E9BAD1 /* project_item_branch@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1817EF42069186D00E9BAD1 /* project_item_branch@3x.png */; }; + B1817EF92069186E00E9BAD1 /* project_item_tag@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1817EF52069186E00E9BAD1 /* project_item_tag@3x.png */; }; + B1817EFC206918D200E9BAD1 /* icon_branch_protected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1817EFA206918D100E9BAD1 /* icon_branch_protected@3x.png */; }; + B1817EFD206918D200E9BAD1 /* icon_branch_protected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1817EFB206918D200E9BAD1 /* icon_branch_protected@2x.png */; }; + B1817F002069197D00E9BAD1 /* icon_release_tag@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1817EFE2069197C00E9BAD1 /* icon_release_tag@3x.png */; }; + B1817F012069197D00E9BAD1 /* icon_release_tag@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1817EFF2069197C00E9BAD1 /* icon_release_tag@2x.png */; }; + B1817F0320691B2700E9BAD1 /* EACodeReleaseTopCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B1817F0220691B2700E9BAD1 /* EACodeReleaseTopCell.xib */; }; + B1817F062069F67700E9BAD1 /* EAEditCodeReleaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1817F052069F67700E9BAD1 /* EAEditCodeReleaseViewController.m */; }; + B184166920513CA100207666 /* topic_add_watcher_btn@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B184166720513CA000207666 /* topic_add_watcher_btn@3x.png */; }; + B184166A20513CA100207666 /* tweet_comment_btn@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B184166820513CA000207666 /* tweet_comment_btn@3x.png */; }; + B186AEB020F462F600A6AF35 /* UIAlertController+Common.m in Sources */ = {isa = PBXBuildFile; fileRef = B186AEAF20F462F600A6AF35 /* UIAlertController+Common.m */; }; + B186AEB120F462F600A6AF35 /* UIAlertController+Common.m in Sources */ = {isa = PBXBuildFile; fileRef = B186AEAF20F462F600A6AF35 /* UIAlertController+Common.m */; }; + B1890C292015D82600F52ABA /* wiki_menu_0@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1890C1E2015D82600F52ABA /* wiki_menu_0@2x.png */; }; + B1890C2A2015D82600F52ABA /* wiki_menu_2@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1890C1F2015D82600F52ABA /* wiki_menu_2@3x.png */; }; + B1890C2B2015D82600F52ABA /* wiki_menu_2@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1890C202015D82600F52ABA /* wiki_menu_2@2x.png */; }; + B1890C2C2015D82600F52ABA /* wiki_menu_0@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1890C212015D82600F52ABA /* wiki_menu_0@3x.png */; }; + B1890C2D2015D82600F52ABA /* wiki_revert@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1890C222015D82600F52ABA /* wiki_revert@3x.png */; }; + B1890C2E2015D82600F52ABA /* wiki_revert@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1890C232015D82600F52ABA /* wiki_revert@2x.png */; }; + B1890C2F2015D82600F52ABA /* wiki_menu_1@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1890C242015D82600F52ABA /* wiki_menu_1@2x.png */; }; + B1890C302015D82600F52ABA /* wiki_menu_1@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1890C252015D82600F52ABA /* wiki_menu_1@3x.png */; }; + B1890C312015D82600F52ABA /* wiki_menu_icon_share@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1890C272015D82600F52ABA /* wiki_menu_icon_share@2x.png */; }; + B1890C322015D82600F52ABA /* wiki_menu_icon_delete@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1890C282015D82600F52ABA /* wiki_menu_icon_delete@2x.png */; }; + B1890C352015D87900F52ABA /* EAWiki.m in Sources */ = {isa = PBXBuildFile; fileRef = B1890C342015D87800F52ABA /* EAWiki.m */; }; + B1890C382015D89A00F52ABA /* WikiMenuListView.m in Sources */ = {isa = PBXBuildFile; fileRef = B1890C362015D89A00F52ABA /* WikiMenuListView.m */; }; + B1890C3D2015D8C900F52ABA /* WikiMenuListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B1890C3A2015D8C800F52ABA /* WikiMenuListCell.m */; }; + B1890C3E2015D8C900F52ABA /* WikiHistoryCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B1890C3B2015D8C800F52ABA /* WikiHistoryCell.m */; }; + B1890C412015D8F700F52ABA /* WikiHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = B1890C402015D8F700F52ABA /* WikiHeaderView.m */; }; + B1890C482015D92600F52ABA /* WikiEditViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1890C432015D92500F52ABA /* WikiEditViewController.m */; }; + B1890C492015D92600F52ABA /* WikiHistoryListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1890C442015D92500F52ABA /* WikiHistoryListViewController.m */; }; + B1890C4A2015D92600F52ABA /* WikiViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1890C472015D92600F52ABA /* WikiViewController.m */; }; + B1890C4D2019B29900F52ABA /* UINavigationBar+Common.m in Sources */ = {isa = PBXBuildFile; fileRef = B1890C4B2019B29800F52ABA /* UINavigationBar+Common.m */; }; + B1944144206BB87F00147158 /* EALocalCodeListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1944143206BB87F00147158 /* EALocalCodeListViewController.m */; }; + B1944147206BB89100147158 /* EALocalCodeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1944146206BB89100147158 /* EALocalCodeViewController.m */; }; + B194414A206BB8BB00147158 /* EALocalCodeListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B1944149206BB8BB00147158 /* EALocalCodeListCell.m */; }; + B1944154206CBE8C00147158 /* code_lang.plist in Resources */ = {isa = PBXBuildFile; fileRef = B1944153206CBE8C00147158 /* code_lang.plist */; }; + B19D4EE11F690F5E00C598F3 /* file_activity_icon_rename@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B19D4EDF1F690F5E00C598F3 /* file_activity_icon_rename@2x.png */; }; + B19D4EE21F690F5E00C598F3 /* file_activity_icon_rename@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B19D4EE01F690F5E00C598F3 /* file_activity_icon_rename@3x.png */; }; + B19D4EEA1F6FAA6000C598F3 /* AboutPointViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B19D4EE81F6FAA6000C598F3 /* AboutPointViewController.m */; }; + B19D4EEB1F6FAA6000C598F3 /* AboutPointViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = B19D4EE91F6FAA6000C598F3 /* AboutPointViewController.xib */; }; + B19D4EEE1F6FCEAC00C598F3 /* CodingSkill.m in Sources */ = {isa = PBXBuildFile; fileRef = B19D4EED1F6FCEAC00C598F3 /* CodingSkill.m */; }; + B19D4EF21F710EF900C598F3 /* ShopSwitchCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B19D4EF01F710EF900C598F3 /* ShopSwitchCell.m */; }; + B19D4EF31F710EF900C598F3 /* ShopSwitchCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B19D4EF11F710EF900C598F3 /* ShopSwitchCell.xib */; }; + B19D4EF61F7210C300C598F3 /* user_info_shop@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B19D4EF41F7210C300C598F3 /* user_info_shop@2x.png */; }; + B19D4EF71F7210C300C598F3 /* user_info_shop@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B19D4EF51F7210C300C598F3 /* user_info_shop@3x.png */; }; + B19D4EFB1F7247BA00C598F3 /* AlipaySDK.bundle in Resources */ = {isa = PBXBuildFile; fileRef = B19D4EF91F7247BA00C598F3 /* AlipaySDK.bundle */; }; + B19D4EFC1F7247BA00C598F3 /* AlipaySDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B19D4EFA1F7247BA00C598F3 /* AlipaySDK.framework */; }; + B19D4EFE1F724CDC00C598F3 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B19D4EFD1F724CDC00C598F3 /* CoreMotion.framework */; }; + B1AB5C9A202953E50075A669 /* terminal_tail@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5C90202953E40075A669 /* terminal_tail@2x.png */; }; + B1AB5C9B202953E50075A669 /* terminal_box_unselected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5C91202953E40075A669 /* terminal_box_unselected@2x.png */; }; + B1AB5C9C202953E50075A669 /* terminal_box_unselected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5C92202953E40075A669 /* terminal_box_unselected@3x.png */; }; + B1AB5C9D202953E50075A669 /* terminal_tail@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5C93202953E40075A669 /* terminal_tail@3x.png */; }; + B1AB5C9E202953E50075A669 /* terminal_more@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5C94202953E40075A669 /* terminal_more@3x.png */; }; + B1AB5C9F202953E50075A669 /* terminal_more@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5C95202953E40075A669 /* terminal_more@2x.png */; }; + B1AB5CA0202953E50075A669 /* terminal_triangle@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5C96202953E40075A669 /* terminal_triangle@3x.png */; }; + B1AB5CA1202953E50075A669 /* terminal_box_selected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5C97202953E40075A669 /* terminal_box_selected@3x.png */; }; + B1AB5CA2202953E50075A669 /* terminal_triangle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5C98202953E40075A669 /* terminal_triangle@2x.png */; }; + B1AB5CA3202953E50075A669 /* terminal_box_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5C99202953E40075A669 /* terminal_box_selected@2x.png */; }; + B1AB5CB1202D7D500075A669 /* button_file_createFolder_enable@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5CA6202D7D4D0075A669 /* button_file_createFolder_enable@3x.png */; }; + B1AB5CB2202D7D500075A669 /* button_file_denete_enable@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5CA7202D7D4E0075A669 /* button_file_denete_enable@3x.png */; }; + B1AB5CB3202D7D500075A669 /* button_file_download_enable@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5CA8202D7D4E0075A669 /* button_file_download_enable@3x.png */; }; + B1AB5CB4202D7D500075A669 /* button_file_upload_enable@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5CA9202D7D4E0075A669 /* button_file_upload_enable@3x.png */; }; + B1AB5CB5202D7D500075A669 /* button_file_history@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5CAA202D7D4E0075A669 /* button_file_history@3x.png */; }; + B1AB5CB6202D7D500075A669 /* button_file_activity@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5CAB202D7D4F0075A669 /* button_file_activity@3x.png */; }; + B1AB5CB7202D7D500075A669 /* button_file_denete_unable@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5CAC202D7D4F0075A669 /* button_file_denete_unable@3x.png */; }; + B1AB5CB8202D7D500075A669 /* button_file_download_unable@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5CAD202D7D4F0075A669 /* button_file_download_unable@3x.png */; }; + B1AB5CB9202D7D500075A669 /* button_file_move_enable@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5CAE202D7D4F0075A669 /* button_file_move_enable@3x.png */; }; + B1AB5CBA202D7D500075A669 /* button_file_move_unable@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5CAF202D7D4F0075A669 /* button_file_move_unable@3x.png */; }; + B1AB5CBB202D7D500075A669 /* button_file_createFolder_unable@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5CB0202D7D500075A669 /* button_file_createFolder_unable@3x.png */; }; + B1ACFE0D20A975E2000BC41E /* EAMilestone.m in Sources */ = {isa = PBXBuildFile; fileRef = B1ACFE0C20A975E2000BC41E /* EAMilestone.m */; }; + B1BCB87D1FCD006C0098B87B /* icon_file_doc_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8701FCD006A0098B87B /* icon_file_doc_big@2x.png */; }; + B1BCB87E1FCD006C0098B87B /* icon_file_zip_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8711FCD006B0098B87B /* icon_file_zip_big@2x.png */; }; + B1BCB87F1FCD006C0098B87B /* icon_file_pdf_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8721FCD006B0098B87B /* icon_file_pdf_big@2x.png */; }; + B1BCB8801FCD006C0098B87B /* icon_file_psd_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8731FCD006B0098B87B /* icon_file_psd_big@2x.png */; }; + B1BCB8811FCD006C0098B87B /* icon_file_unknown_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8741FCD006B0098B87B /* icon_file_unknown_big@2x.png */; }; + B1BCB8821FCD006C0098B87B /* icon_file_movie_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8751FCD006B0098B87B /* icon_file_movie_big@2x.png */; }; + B1BCB8831FCD006C0098B87B /* icon_file_md_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8761FCD006B0098B87B /* icon_file_md_big@2x.png */; }; + B1BCB8841FCD006C0098B87B /* icon_file_apk_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8771FCD006B0098B87B /* icon_file_apk_big@2x.png */; }; + B1BCB8851FCD006C0098B87B /* icon_file_code_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8781FCD006C0098B87B /* icon_file_code_big@2x.png */; }; + B1BCB8861FCD006C0098B87B /* icon_file_txt_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8791FCD006C0098B87B /* icon_file_txt_big@2x.png */; }; + B1BCB8871FCD006C0098B87B /* icon_file_music_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB87A1FCD006C0098B87B /* icon_file_music_big@2x.png */; }; + B1BCB8881FCD006C0098B87B /* icon_file_ai_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB87B1FCD006C0098B87B /* icon_file_ai_big@2x.png */; }; + B1BCB8891FCD006C0098B87B /* icon_file_ppt_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB87C1FCD006C0098B87B /* icon_file_ppt_big@2x.png */; }; + B1BCB88B1FCD0A6D0098B87B /* icon_file_xls_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB88A1FCD0A6D0098B87B /* icon_file_xls_big@2x.png */; }; + B1BCB88F1FCE61D60098B87B /* EAPayViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1BCB88D1FCE61D60098B87B /* EAPayViewController.m */; }; + B1BCB8901FCE61D60098B87B /* EAPayViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB88E1FCE61D60098B87B /* EAPayViewController.xib */; }; + B1BCB8931FCE662A0098B87B /* NSLayoutConstraintLine.m in Sources */ = {isa = PBXBuildFile; fileRef = B1BCB8911FCE662A0098B87B /* NSLayoutConstraintLine.m */; }; + B1BCB8991FCE93830098B87B /* alipay@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8951FCE93830098B87B /* alipay@2x.png */; }; + B1BCB89A1FCE93830098B87B /* alipay@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8961FCE93830098B87B /* alipay@3x.png */; }; + B1BCB89B1FCE93830098B87B /* wechat@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8971FCE93830098B87B /* wechat@2x.png */; }; + B1BCB89C1FCE93830098B87B /* wechat@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8981FCE93830098B87B /* wechat@3x.png */; }; + B1BFC4B620B2ACEE009427FC /* editBoardList@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BFC4B420B2ACED009427FC /* editBoardList@3x.png */; }; + B1BFC4B720B2ACEE009427FC /* editBoardList@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BFC4B520B2ACEE009427FC /* editBoardList@2x.png */; }; + B1BFC4C420B2B250009427FC /* task_activity_icon_add_milestone@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BFC4C020B2B24E009427FC /* task_activity_icon_add_milestone@2x.png */; }; + B1BFC4C520B2B250009427FC /* task_activity_icon_add_milestone@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BFC4C120B2B24E009427FC /* task_activity_icon_add_milestone@3x.png */; }; + B1BFC4C620B2B250009427FC /* task_activity_icon_remove_milestone@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BFC4C220B2B24F009427FC /* task_activity_icon_remove_milestone@3x.png */; }; + B1BFC4C720B2B250009427FC /* task_activity_icon_remove_milestone@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BFC4C320B2B250009427FC /* task_activity_icon_remove_milestone@2x.png */; }; + B1C60C7A20BFA2150073D3CA /* NProjectFileListView.m in Sources */ = {isa = PBXBuildFile; fileRef = B1C60C7920BFA2150073D3CA /* NProjectFileListView.m */; }; + B1C60C7B20BFA2150073D3CA /* NProjectFileListView.m in Sources */ = {isa = PBXBuildFile; fileRef = B1C60C7920BFA2150073D3CA /* NProjectFileListView.m */; }; + B1C60C7E20BFCDBE0073D3CA /* EditMemberTypeProjectListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1C60C7D20BFCDBD0073D3CA /* EditMemberTypeProjectListViewController.m */; }; + B1C60C7F20BFCDBE0073D3CA /* EditMemberTypeProjectListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1C60C7D20BFCDBD0073D3CA /* EditMemberTypeProjectListViewController.m */; }; + B1C60C8220BFCEFD0073D3CA /* NFileListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1C60C8020BFCEFD0073D3CA /* NFileListViewController.m */; }; + B1C60C8320BFCEFD0073D3CA /* NFileListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1C60C8020BFCEFD0073D3CA /* NFileListViewController.m */; }; + B1C60C8620BFE8220073D3CA /* NewProject.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B94C1B6A1AC945FB0000C271 /* NewProject.storyboard */; }; + B1C60C8E20BFF7950073D3CA /* ProjectTypeExplanationViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = B1C60C8B20BFF7940073D3CA /* ProjectTypeExplanationViewController.xib */; }; + B1C60C8F20BFF7950073D3CA /* ProjectTypeExplanationViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = B1C60C8B20BFF7940073D3CA /* ProjectTypeExplanationViewController.xib */; }; + B1C60C9020BFF7950073D3CA /* ProjectTypeExplanationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1C60C8D20BFF7950073D3CA /* ProjectTypeExplanationViewController.m */; }; + B1C60C9120BFF7950073D3CA /* ProjectTypeExplanationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1C60C8D20BFF7950073D3CA /* ProjectTypeExplanationViewController.m */; }; + B1C60C9820C004C80073D3CA /* TeamPurchaseTopCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B1C60C9320C004C70073D3CA /* TeamPurchaseTopCell.m */; }; + B1C60C9920C004C80073D3CA /* TeamPurchaseTopCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B1C60C9320C004C70073D3CA /* TeamPurchaseTopCell.m */; }; + B1C60C9A20C004C80073D3CA /* TeamPurchaseBillingCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B1C60C9420C004C70073D3CA /* TeamPurchaseBillingCell.m */; }; + B1C60C9B20C004C80073D3CA /* TeamPurchaseBillingCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B1C60C9420C004C70073D3CA /* TeamPurchaseBillingCell.m */; }; + B1C60C9C20C004C80073D3CA /* TeamPurchaseOrderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B1C60C9620C004C80073D3CA /* TeamPurchaseOrderCell.m */; }; + B1C60C9D20C004C80073D3CA /* TeamPurchaseOrderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B1C60C9620C004C80073D3CA /* TeamPurchaseOrderCell.m */; }; + B1C60CA420C0DDF60073D3CA /* TeamSettingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1C60CA020C0DDF40073D3CA /* TeamSettingViewController.m */; }; + B1C60CA520C0DDF60073D3CA /* TeamSettingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1C60CA020C0DDF40073D3CA /* TeamSettingViewController.m */; }; + B1C60CA620C0DDF60073D3CA /* TeamPurchaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1C60CA120C0DDF40073D3CA /* TeamPurchaseViewController.m */; }; + B1C60CA720C0DDF60073D3CA /* TeamPurchaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1C60CA120C0DDF40073D3CA /* TeamPurchaseViewController.m */; }; + B1C60CA820C0DDF60073D3CA /* TeamSupportViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1C60CA320C0DDF50073D3CA /* TeamSupportViewController.m */; }; + B1C60CA920C0DDF60073D3CA /* TeamSupportViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1C60CA320C0DDF50073D3CA /* TeamSupportViewController.m */; }; + B1C60CAB20C0FC750073D3CA /* Launch Screen_E.xib in Resources */ = {isa = PBXBuildFile; fileRef = B1C60CAA20C0FC750073D3CA /* Launch Screen_E.xib */; }; + B1C60CAC20C0FC750073D3CA /* Launch Screen_E.xib in Resources */ = {isa = PBXBuildFile; fileRef = B1C60CAA20C0FC750073D3CA /* Launch Screen_E.xib */; }; + B1C871131EADAEE1003DACF0 /* loading_monkey@2x.gif in Resources */ = {isa = PBXBuildFile; fileRef = B1C871121EADAEE1003DACF0 /* loading_monkey@2x.gif */; }; + B1C871181EADF0B1003DACF0 /* messageAT@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871141EADF0B1003DACF0 /* messageAT@3x.png */; }; + B1C871191EADF0B1003DACF0 /* messageComment@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871151EADF0B1003DACF0 /* messageComment@3x.png */; }; + B1C8711A1EADF0B1003DACF0 /* messageProjectFollows@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871161EADF0B1003DACF0 /* messageProjectFollows@3x.png */; }; + B1C8711B1EADF0B1003DACF0 /* messageSystem@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871171EADF0B1003DACF0 /* messageSystem@3x.png */; }; + B1C871241EADF0FF003DACF0 /* addBtn_Artboard@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8711C1EADF0FF003DACF0 /* addBtn_Artboard@2x.png */; }; + B1C871251EADF0FF003DACF0 /* addBtn_Artboard@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8711D1EADF0FF003DACF0 /* addBtn_Artboard@3x.png */; }; + B1C871261EADF0FF003DACF0 /* back_green_Nav@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8711E1EADF0FF003DACF0 /* back_green_Nav@2x.png */; }; + B1C871271EADF0FF003DACF0 /* back_green_Nav@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8711F1EADF0FF003DACF0 /* back_green_Nav@3x.png */; }; + B1C871281EADF0FF003DACF0 /* back_T_Nav@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871201EADF0FF003DACF0 /* back_T_Nav@2x.png */; }; + B1C871291EADF0FF003DACF0 /* back_T_Nav@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871211EADF0FF003DACF0 /* back_T_Nav@3x.png */; }; + B1C8712A1EADF0FF003DACF0 /* settingBtn_Nav@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871221EADF0FF003DACF0 /* settingBtn_Nav@2x.png */; }; + B1C8712B1EADF0FF003DACF0 /* settingBtn_Nav@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871231EADF0FF003DACF0 /* settingBtn_Nav@3x.png */; }; + B1C871351EADF155003DACF0 /* project_item_activity@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8712C1EADF155003DACF0 /* project_item_activity@3x.png */; }; + B1C871361EADF155003DACF0 /* project_item_code@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8712D1EADF155003DACF0 /* project_item_code@3x.png */; }; + B1C871371EADF155003DACF0 /* project_item_file@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8712E1EADF155003DACF0 /* project_item_file@3x.png */; }; + B1C871381EADF155003DACF0 /* project_item_member@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8712F1EADF155003DACF0 /* project_item_member@3x.png */; }; + B1C871391EADF155003DACF0 /* project_item_mr_pr@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871301EADF155003DACF0 /* project_item_mr_pr@3x.png */; }; + B1C8713A1EADF155003DACF0 /* project_item_readme@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871311EADF155003DACF0 /* project_item_readme@3x.png */; }; + B1C8713B1EADF155003DACF0 /* project_item_task@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871321EADF155003DACF0 /* project_item_task@3x.png */; }; + B1C8713C1EADF155003DACF0 /* project_item_wiki@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871331EADF155003DACF0 /* project_item_wiki@2x.png */; }; + B1C8713D1EADF155003DACF0 /* project_item_wiki@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871341EADF155003DACF0 /* project_item_wiki@3x.png */; }; + B1C871431EADF1C1003DACF0 /* taskDeadline@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8713E1EADF1C1003DACF0 /* taskDeadline@3x.png */; }; + B1C871441EADF1C1003DACF0 /* taskOwner@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8713F1EADF1C1003DACF0 /* taskOwner@3x.png */; }; + B1C871451EADF1C1003DACF0 /* taskPriority@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871401EADF1C1003DACF0 /* taskPriority@3x.png */; }; + B1C871461EADF1C1003DACF0 /* taskProgress@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871411EADF1C1003DACF0 /* taskProgress@3x.png */; }; + B1C871471EADF1C1003DACF0 /* taskProject@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871421EADF1C1003DACF0 /* taskProject@3x.png */; }; + B1C8714A1EADF217003DACF0 /* user_info_company@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871481EADF217003DACF0 /* user_info_company@2x.png */; }; + B1C8714B1EADF217003DACF0 /* user_info_company@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871491EADF217003DACF0 /* user_info_company@3x.png */; }; + B1C8714D1EADF3AC003DACF0 /* mrpr_icon_fileChange@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8714C1EADF3AC003DACF0 /* mrpr_icon_fileChange@3x.png */; }; + B1C871501EADF48B003DACF0 /* cell_arrow_left@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8714E1EADF48B003DACF0 /* cell_arrow_left@2x.png */; }; + B1C871511EADF48B003DACF0 /* cell_arrow_left@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8714F1EADF48B003DACF0 /* cell_arrow_left@3x.png */; }; + B1C871541EADF4D4003DACF0 /* UITableViewCell+Common.m in Sources */ = {isa = PBXBuildFile; fileRef = B1C871531EADF4D4003DACF0 /* UITableViewCell+Common.m */; }; + B1C871561EAE003A003DACF0 /* project_item_topic@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871551EAE003A003DACF0 /* project_item_topic@3x.png */; }; + B1C871581EB0884A003DACF0 /* little_phone_icon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871571EB0884A003DACF0 /* little_phone_icon@3x.png */; }; + B1C871631EB182C7003DACF0 /* checkbox_checked@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871591EB182C7003DACF0 /* checkbox_checked@3x.png */; }; + B1C871641EB182C7003DACF0 /* checkbox_unchecked@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8715A1EB182C7003DACF0 /* checkbox_unchecked@3x.png */; }; + B1C871651EB182C7003DACF0 /* taskPriority0_small@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8715B1EB182C7003DACF0 /* taskPriority0_small@3x.png */; }; + B1C871661EB182C7003DACF0 /* taskPriority0@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8715C1EB182C7003DACF0 /* taskPriority0@3x.png */; }; + B1C871671EB182C7003DACF0 /* taskPriority1_small@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8715D1EB182C7003DACF0 /* taskPriority1_small@3x.png */; }; + B1C871681EB182C7003DACF0 /* taskPriority1@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8715E1EB182C7003DACF0 /* taskPriority1@3x.png */; }; + B1C871691EB182C7003DACF0 /* taskPriority2_small@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8715F1EB182C7003DACF0 /* taskPriority2_small@3x.png */; }; + B1C8716A1EB182C7003DACF0 /* taskPriority2@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871601EB182C7003DACF0 /* taskPriority2@3x.png */; }; + B1C8716B1EB182C7003DACF0 /* taskPriority3_small@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871611EB182C7003DACF0 /* taskPriority3_small@3x.png */; }; + B1C8716C1EB182C7003DACF0 /* taskPriority3@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871621EB182C7003DACF0 /* taskPriority3@3x.png */; }; + B1C871701EB1832B003DACF0 /* task_description_icon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8716D1EB1832B003DACF0 /* task_description_icon@3x.png */; }; + B1C871711EB1832B003DACF0 /* topic_comment_icon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8716E1EB1832B003DACF0 /* topic_comment_icon@3x.png */; }; + B1C871721EB1832B003DACF0 /* time_clock_icon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8716F1EB1832B003DACF0 /* time_clock_icon@3x.png */; }; + B1C8717D1EB18599003DACF0 /* calendar_0x59A2FF@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871731EB18599003DACF0 /* calendar_0x59A2FF@2x.png */; }; + B1C8717E1EB18599003DACF0 /* calendar_0x59A2FF@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871741EB18599003DACF0 /* calendar_0x59A2FF@3x.png */; }; + B1C8717F1EB18599003DACF0 /* calendar_0xA1CF64@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871751EB18599003DACF0 /* calendar_0xA1CF64@2x.png */; }; + B1C871801EB18599003DACF0 /* calendar_0xA1CF64@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871761EB18599003DACF0 /* calendar_0xA1CF64@3x.png */; }; + B1C871811EB18599003DACF0 /* calendar_0xA9B3BE@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871771EB18599003DACF0 /* calendar_0xA9B3BE@2x.png */; }; + B1C871821EB18599003DACF0 /* calendar_0xA9B3BE@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871781EB18599003DACF0 /* calendar_0xA9B3BE@3x.png */; }; + B1C871831EB18599003DACF0 /* calendar_0xF56061@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871791EB18599003DACF0 /* calendar_0xF56061@2x.png */; }; + B1C871841EB18599003DACF0 /* calendar_0xF56061@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8717A1EB18599003DACF0 /* calendar_0xF56061@3x.png */; }; + B1C871851EB18599003DACF0 /* calendar_0xF68435@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8717B1EB18599003DACF0 /* calendar_0xF68435@2x.png */; }; + B1C871861EB18599003DACF0 /* calendar_0xF68435@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8717C1EB18599003DACF0 /* calendar_0xF68435@3x.png */; }; + B1C8718D1EB1E608003DACF0 /* btn_setFrequent@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871871EB1E608003DACF0 /* btn_setFrequent@3x.png */; }; + B1C8718E1EB1E608003DACF0 /* cell_checkmark@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871881EB1E608003DACF0 /* cell_checkmark@3x.png */; }; + B1C8718F1EB1E608003DACF0 /* icon_add_comment@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871891EB1E608003DACF0 /* icon_add_comment@3x.png */; }; + B1C871901EB1E608003DACF0 /* nav_page_selected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8718A1EB1E608003DACF0 /* nav_page_selected@3x.png */; }; + B1C871911EB1E608003DACF0 /* nav_page_unselected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8718B1EB1E608003DACF0 /* nav_page_unselected@3x.png */; }; + B1C871921EB1E608003DACF0 /* tasks_all@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8718C1EB1E608003DACF0 /* tasks_all@3x.png */; }; + B1C871A01EB2D9E6003DACF0 /* task_activity_icon_add_watcher@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871931EB2D9E6003DACF0 /* task_activity_icon_add_watcher@3x.png */; }; + B1C871A11EB2D9E6003DACF0 /* task_activity_icon_commit_refer@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871941EB2D9E6003DACF0 /* task_activity_icon_commit_refer@3x.png */; }; + B1C871A21EB2D9E6003DACF0 /* task_activity_icon_create@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871951EB2D9E6003DACF0 /* task_activity_icon_create@3x.png */; }; + B1C871A31EB2D9E6003DACF0 /* task_activity_icon_finish@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871961EB2D9E6003DACF0 /* task_activity_icon_finish@3x.png */; }; + B1C871A41EB2D9E6003DACF0 /* task_activity_icon_MergeRequestBean@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871971EB2D9E6003DACF0 /* task_activity_icon_MergeRequestBean@3x.png */; }; + B1C871A51EB2D9E6003DACF0 /* task_activity_icon_reassign@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871981EB2D9E6003DACF0 /* task_activity_icon_reassign@3x.png */; }; + B1C871A61EB2D9E6003DACF0 /* task_activity_icon_remove_watcher@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871991EB2D9E6003DACF0 /* task_activity_icon_remove_watcher@3x.png */; }; + B1C871A71EB2D9E6003DACF0 /* task_activity_icon_restore@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8719A1EB2D9E6003DACF0 /* task_activity_icon_restore@3x.png */; }; + B1C871A81EB2D9E6003DACF0 /* task_activity_icon_update_deadline@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8719B1EB2D9E6003DACF0 /* task_activity_icon_update_deadline@3x.png */; }; + B1C871A91EB2D9E6003DACF0 /* task_activity_icon_update_description@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8719C1EB2D9E6003DACF0 /* task_activity_icon_update_description@3x.png */; }; + B1C871AA1EB2D9E6003DACF0 /* task_activity_icon_update_label@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8719D1EB2D9E6003DACF0 /* task_activity_icon_update_label@3x.png */; }; + B1C871AB1EB2D9E6003DACF0 /* task_activity_icon_update_priority@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8719E1EB2D9E6003DACF0 /* task_activity_icon_update_priority@3x.png */; }; + B1C871AC1EB2D9E6003DACF0 /* task_activity_icon_update@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8719F1EB2D9E6003DACF0 /* task_activity_icon_update@3x.png */; }; + B1C871B21EB2D9F0003DACF0 /* file_activity_icon_create@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871AD1EB2D9F0003DACF0 /* file_activity_icon_create@3x.png */; }; + B1C871B31EB2D9F0003DACF0 /* file_activity_icon_delete_history@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871AE1EB2D9F0003DACF0 /* file_activity_icon_delete_history@3x.png */; }; + B1C871B41EB2D9F0003DACF0 /* file_activity_icon_move_file@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871AF1EB2D9F0003DACF0 /* file_activity_icon_move_file@3x.png */; }; + B1C871B51EB2D9F0003DACF0 /* file_activity_icon_update_file@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871B01EB2D9F0003DACF0 /* file_activity_icon_update_file@3x.png */; }; + B1C871B61EB2D9F0003DACF0 /* file_activity_icon_upload_file@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871B11EB2D9F0003DACF0 /* file_activity_icon_upload_file@3x.png */; }; + B1C871BA1EB338FD003DACF0 /* comment_bg@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871B71EB338FD003DACF0 /* comment_bg@3x.png */; }; + B1C871BB1EB338FD003DACF0 /* project_tag_btn@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871B81EB338FD003DACF0 /* project_tag_btn@3x.png */; }; + B1C871BC1EB338FD003DACF0 /* project_tag_icon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871B91EB338FD003DACF0 /* project_tag_icon@3x.png */; }; + B1C871BE1EB33B37003DACF0 /* task_icon_arrow@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871BD1EB33B37003DACF0 /* task_icon_arrow@3x.png */; }; + B1CB8DD22047F1D200872197 /* button_tip_notice@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1CB8DD02047F1D000872197 /* button_tip_notice@2x.png */; }; + B1CB8DD32047F1D200872197 /* button_tip_notice@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1CB8DD12047F1D100872197 /* button_tip_notice@3x.png */; }; + B1D5EBF420BC06CB00983FB6 /* RootTabViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CF3E19E240C40076D59C /* RootTabViewController.m */; }; + B1D5EBF520BC06CB00983FB6 /* WebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4ABBE91A653027004760D9 /* WebViewController.m */; }; + B1D5EBF620BC06CB00983FB6 /* ProjectTag.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6FB0541B5799B100B0A17B /* ProjectTag.m */; }; + B1D5EBF720BC06CB00983FB6 /* SendRewardManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E5D13141C0EDFE700985AEB /* SendRewardManager.m */; }; + B1D5EBF820BC06CB00983FB6 /* UIImageView+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6BA2CE1A1EE6AF005FD721 /* UIImageView+AFNetworking.m */; }; + B1D5EBF920BC06CB00983FB6 /* ExchangeGoodsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 927AFF571BFF755200AAE593 /* ExchangeGoodsViewController.m */; }; + B1D5EBFA20BC06CB00983FB6 /* ProjectMember.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CFE319E240C40076D59C /* ProjectMember.m */; }; + B1D5EBFB20BC06CB00983FB6 /* UserInfoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E996BCC1ABA773800C704F1 /* UserInfoViewController.m */; }; + B1D5EBFC20BC06CB00983FB6 /* Me_RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CF3619E240C40076D59C /* Me_RootViewController.m */; }; + B1D5EBFD20BC06CB00983FB6 /* ProjectActivity.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E787DE41B03342000F06E83 /* ProjectActivity.m */; }; + B1D5EBFE20BC06CB00983FB6 /* SWUtilityButtonTapGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E8765621A22E5B40090CFB9 /* SWUtilityButtonTapGestureRecognizer.m */; }; + B1D5EBFF20BC06CB00983FB6 /* UnReadManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8AFA1A3946C10021E29C /* UnReadManager.m */; }; + B1D5EC0020BC06CB00983FB6 /* ProjectFiles.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA679121A1466A6001A0324 /* ProjectFiles.m */; }; + B1D5EC0220BC06CB00983FB6 /* MRPRCommentCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6A571B1C5DC000FD2E49 /* MRPRCommentCell.m */; }; + B1D5EC0320BC06CB00983FB6 /* AudioPlayView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7EB02FEC1B6D111300D2166C /* AudioPlayView.m */; }; + B1D5EC0420BC06CB00983FB6 /* NewProjectTypeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B94C1B6D1AC98CCE0000C271 /* NewProjectTypeViewController.m */; }; + B1D5EC0520BC06CB00983FB6 /* EAIntroPage.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0022991B735075005308DE /* EAIntroPage.m */; }; + B1D5EC0620BC06CB00983FB6 /* PopFliterMenu.m in Sources */ = {isa = PBXBuildFile; fileRef = D0A32BF21BF19EF100336C52 /* PopFliterMenu.m */; }; + B1D5EC0720BC06CB00983FB6 /* ProjectPublicListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D09E6AC81BF9746F009D37F8 /* ProjectPublicListCell.m */; }; + B1D5EC0820BC06CB00983FB6 /* DirectoryWatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E96E7BA1A1B25D40037C098 /* DirectoryWatcher.m */; }; + B1D5EC0920BC06CB00983FB6 /* SVWebViewControllerActivityReport.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ED673211A8E0ECC00DF2D1A /* SVWebViewControllerActivityReport.m */; }; + B1D5EC0A20BC06CB00983FB6 /* TeamMember.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ED4B4A81D829C9F00EED8C6 /* TeamMember.m */; }; + B1D5EC0B20BC06CB00983FB6 /* UIButton+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6BA2CC1A1EE6AF005FD721 /* UIButton+AFNetworking.m */; }; + B1D5EC0C20BC06CB00983FB6 /* TopicCommentCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6439419FF7E2900F7EEB0 /* TopicCommentCell.m */; }; + B1D5EC0D20BC06CB00983FB6 /* AudioVolumeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7EB02FF51B6DAF3800D2166C /* AudioVolumeView.m */; }; + B1D5EC0E20BC06CB00983FB6 /* ZXScanCodeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E8D5D6D1B45400100B70936 /* ZXScanCodeViewController.m */; }; + B1D5EC0F20BC06CB00983FB6 /* LDNetTimer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E3068351E0B781A00AEE0CE /* LDNetTimer.m */; }; + B1D5EC1020BC06CB00983FB6 /* TaskBoardsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B16EEF12209080D7005ABFD5 /* TaskBoardsViewController.m */; }; + B1D5EC1120BC06CB00983FB6 /* Tweet.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECD72EE1AAD7EC300D69AE1 /* Tweet.m */; }; + B1D5EC1220BC06CB00983FB6 /* PRDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 13DA65E71CBE668E00810CB7 /* PRDetailViewController.m */; }; + B1D5EC1320BC06CB00983FB6 /* TweetCommentMoreCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6439C19FF7E2900F7EEB0 /* TweetCommentMoreCell.m */; }; + B1D5EC1420BC06CB00983FB6 /* CodeTree.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E59F0FF1A01133C009A905F /* CodeTree.m */; }; + B1D5EC1520BC06CB00983FB6 /* WikiMenuListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B1890C3A2015D8C800F52ABA /* WikiMenuListCell.m */; }; + B1D5EC1620BC06CB00983FB6 /* EALocalCodeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1944146206BB89100147158 /* EALocalCodeViewController.m */; }; + B1D5EC1720BC06CB00983FB6 /* KxMenu.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E93F2321B84243D00017916 /* KxMenu.m */; }; + B1D5EC1820BC06CB00983FB6 /* UserSearchCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D0C447B81C02C63000DC1C4B /* UserSearchCell.m */; }; + B1D5EC1920BC06CB00983FB6 /* SettingEmailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E83AE7A1CF30F1A006BA3BB /* SettingEmailViewController.m */; }; + B1D5EC1A20BC06CB00983FB6 /* MemberCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6437619FF7E2900F7EEB0 /* MemberCell.m */; }; + B1D5EC1B20BC06CB00983FB6 /* JobManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8AF61A3946C10021E29C /* JobManager.m */; }; + B1D5EC1C20BC06CB00983FB6 /* UIView+Frame.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0BD8551B6C7DFD0061CAA6 /* UIView+Frame.m */; }; + B1D5EC1D20BC06CB00983FB6 /* TagsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8AF81A3946C10021E29C /* TagsManager.m */; }; + B1D5EC1E20BC06CB00983FB6 /* AddCommentCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6AAB1B1EED6A00FD2E49 /* AddCommentCell.m */; }; + B1D5EC1F20BC06CB00983FB6 /* UITTTAttributedLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6D00A19E240C40076D59C /* UITTTAttributedLabel.m */; }; + B1D5EC2020BC06CB00983FB6 /* TitleValueCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6438E19FF7E2900F7EEB0 /* TitleValueCell.m */; }; + B1D5EC2120BC06CB00983FB6 /* ODRefreshControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA7F1581A6D192B00A046BD /* ODRefreshControl.m */; }; + B1D5EC2220BC06CB00983FB6 /* FileSearchCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D0C447971BFECDF200DC1C4B /* FileSearchCell.m */; }; + B1D5EC2320BC06CB00983FB6 /* RDVTabBarItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6D09819E240C40076D59C /* RDVTabBarItem.m */; }; + B1D5EC2420BC06CB00983FB6 /* PointShopCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E00228E1B721964005308DE /* PointShopCell.m */; }; + B1D5EC2520BC06CB00983FB6 /* ProjectTopicActivity.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EF818181B05C984005F974B /* ProjectTopicActivity.m */; }; + B1D5EC2620BC06CB00983FB6 /* FileChangeListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6A841B1C6D8200FD2E49 /* FileChangeListCell.m */; }; + B1D5EC2720BC06CB00983FB6 /* ProjectListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E996BE11ABA957B00C704F1 /* ProjectListViewController.m */; }; + B1D5EC2820BC06CB00983FB6 /* EaseMarkdownTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E743E6C1A88A3CC00DADDE5 /* EaseMarkdownTextView.m */; }; + B1D5EC2920BC06CB00983FB6 /* ActivityView.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A058841E0AA9AE00C1CA3F /* ActivityView.m */; }; + B1D5EC2A20BC06CB00983FB6 /* ListGroupItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CFDB19E240C40076D59C /* ListGroupItem.m */; }; + B1D5EC2B20BC06CB00983FB6 /* CodingSearchDisplayView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E80E93B1E02353900DE1BC6 /* CodingSearchDisplayView.m */; }; + B1D5EC2C20BC06CB00983FB6 /* MyTask_RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CF3A19E240C40076D59C /* MyTask_RootViewController.m */; }; + B1D5EC2D20BC06CB00983FB6 /* SettingAccountViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E1C3DFF19E8DFE300EF3032 /* SettingAccountViewController.m */; }; + B1D5EC2E20BC06CB00983FB6 /* SWTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E8765601A22E5B40090CFB9 /* SWTableViewCell.m */; }; + B1D5EC2F20BC06CB00983FB6 /* ScanBGView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E94C4E61B4A6AC700EB668A /* ScanBGView.m */; }; + B1D5EC3020BC06CB00983FB6 /* CodingVipTipManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B641E1FF2835800ACFDCC /* CodingVipTipManager.m */; }; + B1D5EC3120BC06CB00983FB6 /* CSTopicHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0BD8651B6C7E3D0061CAA6 /* CSTopicHeaderView.m */; }; + B1D5EC3220BC06CB00983FB6 /* NJKWebViewProgressView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EBB624B1A6F526C0045DAEF /* NJKWebViewProgressView.m */; }; + B1D5EC3320BC06CB00983FB6 /* TaskActivityCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6383F11B32CC7600D98648 /* TaskActivityCell.m */; }; + B1D5EC3420BC06CB00983FB6 /* ActivenessModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A0587F1E0AA97000C1CA3F /* ActivenessModel.m */; }; + B1D5EC3520BC06CB00983FB6 /* Close2FAViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E554D6D1C9804F40008686A /* Close2FAViewController.m */; }; + B1D5EC3620BC06CB00983FB6 /* NSDate+Common.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8AB81A3943E80021E29C /* NSDate+Common.m */; }; + B1D5EC3720BC06CB00983FB6 /* RDVTabBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6D09419E240C40076D59C /* RDVTabBar.m */; }; + B1D5EC3820BC06CB00983FB6 /* TMCacheExtend.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0BD87F1B6C7F0A0061CAA6 /* TMCacheExtend.m */; }; + B1D5EC3920BC06CB00983FB6 /* CodingShareView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E2BF3D81B96D0FA00A5A0A8 /* CodingShareView.m */; }; + B1D5EC3A20BC06CB00983FB6 /* DistancePickerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E1C3DE719E7D58A00EF3032 /* DistancePickerView.m */; }; + B1D5EC3B20BC06CB00983FB6 /* FileVersionsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EAE06AD1B7B241A00179F4B /* FileVersionsViewController.m */; }; + B1D5EC3C20BC06CB00983FB6 /* FileVersion.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EAE06B91B7B47A700179F4B /* FileVersion.m */; }; + B1D5EC3D20BC06CB00983FB6 /* Depot.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CFD519E240C40076D59C /* Depot.m */; }; + B1D5EC3E20BC06CB00983FB6 /* ReportIllegalViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ED6731D1A8DD38C00DF2D1A /* ReportIllegalViewController.m */; }; + B1D5EC3F20BC06CB00983FB6 /* ShopBannerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 923399681C0044C900F29E04 /* ShopBannerView.m */; }; + B1D5EC4020BC06CB00983FB6 /* TweetDetailCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6439E19FF7E2900F7EEB0 /* TweetDetailCell.m */; }; + B1D5EC4120BC06CB00983FB6 /* ProjectTransferSettingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E2ECEAC1BD4D51000CB6EC9 /* ProjectTransferSettingViewController.m */; }; + B1D5EC4220BC06CB00983FB6 /* UIMessageInputView_Add.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EABD2561AD3CAAC005E515F /* UIMessageInputView_Add.m */; }; + B1D5EC4320BC06CB00983FB6 /* UIMessageInputView_Voice.m in Sources */ = {isa = PBXBuildFile; fileRef = 7EB02FCD1B6CF5D500D2166C /* UIMessageInputView_Voice.m */; }; + B1D5EC4420BC06CB00983FB6 /* UIScrollView+SVInfiniteScrolling.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E59F0DF1A0098BA009A905F /* UIScrollView+SVInfiniteScrolling.m */; }; + B1D5EC4520BC06CB00983FB6 /* PointRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0022821B72095E005308DE /* PointRecord.m */; }; + B1D5EC4620BC06CB00983FB6 /* ShopGoodsCCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 927AFF3D1BFF608700AAE593 /* ShopGoodsCCell.m */; }; + B1D5EC4720BC06CB00983FB6 /* FolderToMoveViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E15C7CF1A26D2F000FB8DAD /* FolderToMoveViewController.m */; }; + B1D5EC4820BC06CB00983FB6 /* Shop.m in Sources */ = {isa = PBXBuildFile; fileRef = 927AFF3A1BFF2EB300AAE593 /* Shop.m */; }; + B1D5EC4920BC06CB00983FB6 /* CategorySearchBar.m in Sources */ = {isa = PBXBuildFile; fileRef = D000E0491BFC45CF00A33C2B /* CategorySearchBar.m */; }; + B1D5EC4A20BC06CB00983FB6 /* UISearchBar+Common.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EE5481D1AE7B7CA00A92306 /* UISearchBar+Common.m */; }; + B1D5EC4B20BC06CB00983FB6 /* UIImage+GIF.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA7F14D1A6D192B00A046BD /* UIImage+GIF.m */; }; + B1D5EC4C20BC06CB00983FB6 /* MessageCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6437819FF7E2900F7EEB0 /* MessageCell.m */; }; + B1D5EC4D20BC06CB00983FB6 /* SettingMineInfoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E1C3E0119E8DFE300EF3032 /* SettingMineInfoViewController.m */; }; + B1D5EC4E20BC06CB00983FB6 /* TweetSendImageCCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6436219FF7E2900F7EEB0 /* TweetSendImageCCell.m */; }; + B1D5EC4F20BC06CB00983FB6 /* OTPGenerator.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E8D5D521B45295D00B70936 /* OTPGenerator.m */; }; + B1D5EC5020BC06CB00983FB6 /* AddUserViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EABB20019EE7A85009EB53A /* AddUserViewController.m */; }; + B1D5EC5120BC06CB00983FB6 /* TaskResourceReferenceCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EB52F411C7C480200B5EBEA /* TaskResourceReferenceCell.m */; }; + B1D5EC5220BC06CB00983FB6 /* UIButton+Bootstrap.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8AC41A3943E80021E29C /* UIButton+Bootstrap.m */; }; + B1D5EC5320BC06CB00983FB6 /* NSDate+Helper.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E64ED8819EE484A006E99DA /* NSDate+Helper.m */; }; + B1D5EC5420BC06CB00983FB6 /* MJPhotoView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6D07519E240C40076D59C /* MJPhotoView.m */; }; + B1D5EC5520BC06CB00983FB6 /* CodeListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E59F1091A021053009A905F /* CodeListViewController.m */; }; + B1D5EC5620BC06CB00983FB6 /* NProjectItemCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECF702B1B1704C5000280FF /* NProjectItemCell.m */; }; + B1D5EC5720BC06CB00983FB6 /* EACodeReleases.m in Sources */ = {isa = PBXBuildFile; fileRef = B1817EC6206397F500E9BAD1 /* EACodeReleases.m */; }; + B1D5EC5820BC06CB00983FB6 /* TeamMembersViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ED4B4AE1D82B28B00EED8C6 /* TeamMembersViewController.m */; }; + B1D5EC5920BC06CB00983FB6 /* ActionSheetDatePicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E1C3DDF19E7D58A00EF3032 /* ActionSheetDatePicker.m */; }; + B1D5EC5A20BC06CB00983FB6 /* Input_OnlyText_Cell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6436F19FF7E2900F7EEB0 /* Input_OnlyText_Cell.m */; }; + B1D5EC5B20BC06CB00983FB6 /* FileListUploadCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E07D3071A4A96EA009EDDF2 /* FileListUploadCell.m */; }; + B1D5EC5C20BC06CB00983FB6 /* ProjectServiceInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6CBE5B1D8FC7A500644086 /* ProjectServiceInfo.m */; }; + B1D5EC5D20BC06CB00983FB6 /* ProjectListView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EE1A2221B5D02CA004284F1 /* ProjectListView.m */; }; + B1D5EC5E20BC06CB00983FB6 /* EAIntroView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E00229B1B735075005308DE /* EAIntroView.m */; }; + B1D5EC5F20BC06CB00983FB6 /* ProjectFolders.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA679151A1496A7001A0324 /* ProjectFolders.m */; }; + B1D5EC6020BC06CB00983FB6 /* ProjectTagLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EE1A2351B5DF568004284F1 /* ProjectTagLabel.m */; }; + B1D5EC6120BC06CB00983FB6 /* NSData+ImageContentType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA7F13A1A6D192B00A046BD /* NSData+ImageContentType.m */; }; + B1D5EC6220BC06CB00983FB6 /* UIColor+MobileColors.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E8D5D571B45295D00B70936 /* UIColor+MobileColors.m */; }; + B1D5EC6320BC06CB00983FB6 /* MJPhotoProgressView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6D07119E240C40076D59C /* MJPhotoProgressView.m */; }; + B1D5EC6420BC06CB00983FB6 /* EADeviceToServerLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E3068281E0B781A00AEE0CE /* EADeviceToServerLog.m */; }; + B1D5EC6520BC06CB00983FB6 /* MRPRFilesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6A631B1C65F700FD2E49 /* MRPRFilesViewController.m */; }; + B1D5EC6620BC06CB00983FB6 /* PHAsset+Common.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B64811FFC73A900ACFDCC /* PHAsset+Common.m */; }; + B1D5EC6720BC06CB00983FB6 /* FileListFolderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA6791C1A15A943001A0324 /* FileListFolderCell.m */; }; + B1D5EC6820BC06CB00983FB6 /* Users.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CFF919E240C40076D59C /* Users.m */; }; + B1D5EC6920BC06CB00983FB6 /* UserCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF643A619FF7E2900F7EEB0 /* UserCell.m */; }; + B1D5EC6A20BC06CB00983FB6 /* PointRecordsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0022881B721516005308DE /* PointRecordsViewController.m */; }; + B1D5EC6B20BC06CB00983FB6 /* OTPAuthClock.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E8D5D721B454D5000B70936 /* OTPAuthClock.m */; }; + B1D5EC6C20BC06CB00983FB6 /* TOTPGenerator.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E8D5D541B45295D00B70936 /* TOTPGenerator.m */; }; + B1D5EC6D20BC06CB00983FB6 /* CSHotTopicView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0BD8591B6C7E3D0061CAA6 /* CSHotTopicView.m */; }; + B1D5EC6E20BC06CB00983FB6 /* CodingTip.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CFCD19E240C40076D59C /* CodingTip.m */; }; + B1D5EC6F20BC06CB00983FB6 /* NProjectViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E2719B71AB02F31006AE214 /* NProjectViewController.m */; }; + B1D5EC7020BC06CB00983FB6 /* SettingPhoneViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E74EC001C311B6300EC0E1B /* SettingPhoneViewController.m */; }; + B1D5EC7120BC06CB00983FB6 /* PrivateMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CFDF19E240C40076D59C /* PrivateMessage.m */; }; + B1D5EC7220BC06CB00983FB6 /* ProjectTaskListViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6437E19FF7E2900F7EEB0 /* ProjectTaskListViewCell.m */; }; + B1D5EC7320BC06CB00983FB6 /* UIDevice+Info.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8ACA1A3943E80021E29C /* UIDevice+Info.m */; }; + B1D5EC7420BC06CB00983FB6 /* UIMessageInputView_Media.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EABD25C1AD3CBB9005E515F /* UIMessageInputView_Media.m */; }; + B1D5EC7520BC06CB00983FB6 /* QBAlbumCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B64681FFB61AD00ACFDCC /* QBAlbumCell.m */; }; + B1D5EC7620BC06CB00983FB6 /* FileActivityCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EAE06B61B7B330900179F4B /* FileActivityCell.m */; }; + B1D5EC7720BC06CB00983FB6 /* UIAlertView+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6BA2CA1A1EE6AF005FD721 /* UIAlertView+AFNetworking.m */; }; + B1D5EC7820BC06CB00983FB6 /* WikiHistoryListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1890C442015D92500F52ABA /* WikiHistoryListViewController.m */; }; + B1D5EC7920BC06CB00983FB6 /* CommitCommentCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6AAE1B2047DE00FD2E49 /* CommitCommentCell.m */; }; + B1D5EC7A20BC06CB00983FB6 /* ProjectAboutOthersListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D066BB3F1BF623DD005AB5D6 /* ProjectAboutOthersListCell.m */; }; + B1D5EC7B20BC06CB00983FB6 /* SDWebImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA7F1461A6D192B00A046BD /* SDWebImageManager.m */; }; + B1D5EC7C20BC06CB00983FB6 /* amrFileCodec.m in Sources */ = {isa = PBXBuildFile; fileRef = 7EB02FD21B6D0F3E00D2166C /* amrFileCodec.m */; }; + B1D5EC7D20BC06CB00983FB6 /* SettingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E1C3E0519E8DFE300EF3032 /* SettingViewController.m */; }; + B1D5EC7E20BC06CB00983FB6 /* ActivityMonScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A058821E0AA9AE00C1CA3F /* ActivityMonScrollView.m */; }; + B1D5EC7F20BC06CB00983FB6 /* ActionSheetStringPicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E1C3DE519E7D58A00EF3032 /* ActionSheetStringPicker.m */; }; + B1D5EC8020BC06CB00983FB6 /* LeftImage_LRTextCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6437419FF7E2900F7EEB0 /* LeftImage_LRTextCell.m */; }; + B1D5EC8120BC06CB00983FB6 /* ProjectSettingEntranceController.m in Sources */ = {isa = PBXBuildFile; fileRef = B152ED4D2090B223004A6E8A /* ProjectSettingEntranceController.m */; }; + B1D5EC8220BC06CB00983FB6 /* UINavigationBar+Common.m in Sources */ = {isa = PBXBuildFile; fileRef = B1890C4B2019B29800F52ABA /* UINavigationBar+Common.m */; }; + B1D5EC8320BC06CB00983FB6 /* ShopOrderListView.m in Sources */ = {isa = PBXBuildFile; fileRef = 926C043D1C01A212004937D8 /* ShopOrderListView.m */; }; + B1D5EC8420BC06CB00983FB6 /* SWActionSheet.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E1C3DE919E7D58A00EF3032 /* SWActionSheet.m */; }; + B1D5EC8520BC06CB00983FB6 /* ProjectInfoCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E1A22811AB1729700CFC14F /* ProjectInfoCell.m */; }; + B1D5EC8620BC06CB00983FB6 /* Task.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CFEF19E240C40076D59C /* Task.m */; }; + B1D5EC8720BC06CB00983FB6 /* TweetSendDetailLoctionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A0519E01ABA918100551B61 /* TweetSendDetailLoctionCell.m */; }; + B1D5EC8820BC06CB00983FB6 /* CannotLoginViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E5C06EA1AC4009100F427C5 /* CannotLoginViewController.m */; }; + B1D5EC8920BC06CB00983FB6 /* ShopViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 927AFF371BFF1CC200AAE593 /* ShopViewController.m */; }; + B1D5EC8A20BC06CB00983FB6 /* Reviewer.m in Sources */ = {isa = PBXBuildFile; fileRef = 1309BA011CA2EF370034C7A3 /* Reviewer.m */; }; + B1D5EC8B20BC06CB00983FB6 /* EALocalCodeListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1944143206BB87F00147158 /* EALocalCodeListViewController.m */; }; + B1D5EC8C20BC06CB00983FB6 /* AMPopTip+Exit.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B64051FE900D400ACFDCC /* AMPopTip+Exit.m */; }; + B1D5EC8D20BC06CB00983FB6 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CF1619E240C40076D59C /* AppDelegate.m */; }; + B1D5EC8E20BC06CB00983FB6 /* AudioAmrUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 7EB02FD41B6D0F3E00D2166C /* AudioAmrUtil.m */; }; + B1D5EC8F20BC06CB00983FB6 /* Coding_NetAPIManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8AF01A3946C10021E29C /* Coding_NetAPIManager.m */; }; + B1D5EC9020BC06CB00983FB6 /* FileListFileCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E59F0F91A00F3F3009A905F /* FileListFileCell.m */; }; + B1D5EC9120BC06CB00983FB6 /* TipsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CF4C19E240C40076D59C /* TipsViewController.m */; }; + B1D5EC9220BC06CB00983FB6 /* ReviewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 134E1B981CA41217002A3E0D /* ReviewCell.m */; }; + B1D5EC9320BC06CB00983FB6 /* TopicHotkeyView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0BD8891B6C7F5B0061CAA6 /* TopicHotkeyView.m */; }; + B1D5EC9420BC06CB00983FB6 /* UIPlaceHolderTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6D00619E240C40076D59C /* UIPlaceHolderTextView.m */; }; + B1D5EC9520BC06CB00983FB6 /* TopicSearchCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D0C4481A1C034C3F00DC1C4B /* TopicSearchCell.m */; }; + B1D5EC9620BC06CB00983FB6 /* ProjectCommitsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6A6C1B1C68D700FD2E49 /* ProjectCommitsViewController.m */; }; + B1D5EC9720BC06CB00983FB6 /* UIProgressView+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6BA2D11A1EE6AF005FD721 /* UIProgressView+AFNetworking.m */; }; + B1D5EC9820BC06CB00983FB6 /* UserActiveGraphCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A0588E1E0AA9D600C1CA3F /* UserActiveGraphCell.m */; }; + B1D5EC9920BC06CB00983FB6 /* NSURL+Common.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EB0C1FF1A807ED00042FC4F /* NSURL+Common.m */; }; + B1D5EC9A20BC06CB00983FB6 /* UIRefreshControl+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6BA2D31A1EE6AF005FD721 /* UIRefreshControl+AFNetworking.m */; }; + B1D5EC9B20BC06CB00983FB6 /* WikiHistoryCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B1890C3B2015D8C800F52ABA /* WikiHistoryCell.m */; }; + B1D5EC9C20BC06CB00983FB6 /* ProjectCodeListView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EE1A21E1B5D02CA004284F1 /* ProjectCodeListView.m */; }; + B1D5EC9D20BC06CB00983FB6 /* LocalFilesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EF374181BB1255E00DDA662 /* LocalFilesViewController.m */; }; + B1D5EC9E20BC06CB00983FB6 /* SettingTextCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6438019FF7E2900F7EEB0 /* SettingTextCell.m */; }; + B1D5EC9F20BC06CB00983FB6 /* LDNetConnect.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E30682D1E0B781A00AEE0CE /* LDNetConnect.m */; }; + B1D5ECA020BC06CB00983FB6 /* MRDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 136A6DBE1CAF6BAC004AA983 /* MRDetailViewController.m */; }; + B1D5ECA120BC06CB00983FB6 /* UITableView+Common.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8AD21A3943E80021E29C /* UITableView+Common.m */; }; + B1D5ECA220BC06CB00983FB6 /* JDStatusBarNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E996BC31ABA754600C704F1 /* JDStatusBarNotification.m */; }; + B1D5ECA320BC06CB00983FB6 /* RFKeyboardToolbar.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6C411C1A846AC30098DC17 /* RFKeyboardToolbar.m */; }; + B1D5ECA420BC06CB00983FB6 /* CSSearchDisplayVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0BD8771B6C7F0A0061CAA6 /* CSSearchDisplayVC.m */; }; + B1D5ECA520BC06CB00983FB6 /* CodeBranchOrTag.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E38CF611A7B7C99005536C0 /* CodeBranchOrTag.m */; }; + B1D5ECA620BC06CB00983FB6 /* EasePageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ED20A771AFC7C8B00C63498 /* EasePageViewController.m */; }; + B1D5ECA720BC06CB00983FB6 /* ObjcRuntime.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6D01219E240C40076D59C /* ObjcRuntime.m */; }; + B1D5ECA820BC06CB00983FB6 /* UIVerticalAlignmentLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E03ACA51A5D2060002B000B /* UIVerticalAlignmentLabel.m */; }; + B1D5ECA920BC06CB00983FB6 /* TaskSelectionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A0589D1E0AAA8800C1CA3F /* TaskSelectionCell.m */; }; + B1D5ECAA20BC06CB00983FB6 /* EANetTraceRoute.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E30682A1E0B781A00AEE0CE /* EANetTraceRoute.m */; }; + B1D5ECAB20BC06CB00983FB6 /* AFURLRequestSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6BA2C11A1EE6AF005FD721 /* AFURLRequestSerialization.m */; }; + B1D5ECAC20BC06CB00983FB6 /* UIUnderlinedButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6D00C19E240C40076D59C /* UIUnderlinedButton.m */; }; + B1D5ECAD20BC06CB00983FB6 /* TaskCommentCCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E5F39011AC951060010515D /* TaskCommentCCell.m */; }; + B1D5ECAE20BC06CB00983FB6 /* AutoSlideScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E095A5F1B6909F9008DC439 /* AutoSlideScrollView.m */; }; + B1D5ECAF20BC06CB00983FB6 /* LocalFoldersViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EF374151BB1254700DDA662 /* LocalFoldersViewController.m */; }; + B1D5ECB020BC06CB00983FB6 /* LDNetGetAddress.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E3068311E0B781A00AEE0CE /* LDNetGetAddress.m */; }; + B1D5ECB120BC06CB00983FB6 /* UIViewController+DownMenu.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8AB61A3943E80021E29C /* UIViewController+DownMenu.m */; }; + B1D5ECB220BC06CB00983FB6 /* PopMenu.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E94C4FD1B4D2B9300EB668A /* PopMenu.m */; }; + B1D5ECB320BC06CB00983FB6 /* LikersViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CF2719E240C40076D59C /* LikersViewController.m */; }; + B1D5ECB420BC06CB00983FB6 /* TitleValueMoreCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6439019FF7E2900F7EEB0 /* TitleValueMoreCell.m */; }; + B1D5ECB520BC06CB00983FB6 /* CSSearchModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0BD8791B6C7F0A0061CAA6 /* CSSearchModel.m */; }; + B1D5ECB620BC06CB00983FB6 /* WikiHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = B1890C402015D8F700F52ABA /* WikiHeaderView.m */; }; + B1D5ECB720BC06CB00983FB6 /* TaskCommentCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6438419FF7E2900F7EEB0 /* TaskCommentCell.m */; }; + B1D5ECB820BC06CB00983FB6 /* AGEmojiPageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E97CE461A0A2DF8006F9AD7 /* AGEmojiPageView.m */; }; + B1D5ECB920BC06CB00983FB6 /* ASProgressPopUpView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E9113A11A1C426000AC9431 /* ASProgressPopUpView.m */; }; + B1D5ECBA20BC06CB00983FB6 /* EditLabelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A3878361AE293D50078D5DE /* EditLabelViewController.m */; }; + B1D5ECBB20BC06CB00983FB6 /* AddMDCommentViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6A661B1C686F00FD2E49 /* AddMDCommentViewController.m */; }; + B1D5ECBC20BC06CB00983FB6 /* Coding_FileManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8AEE1A3946C10021E29C /* Coding_FileManager.m */; }; + B1D5ECBD20BC06CB00983FB6 /* UIMessageInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EABD2531AD3CA7E005E515F /* UIMessageInputView.m */; }; + B1D5ECBE20BC06CB00983FB6 /* AudioManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 7EB02FD61B6D0F3E00D2166C /* AudioManager.m */; }; + B1D5ECBF20BC06CB00983FB6 /* MRPRPreInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 136A6DBB1CAF52F2004AA983 /* MRPRPreInfo.m */; }; + B1D5ECC020BC06CB00983FB6 /* NSMutableString+Common.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E72F82C1B144778001B6CE6 /* NSMutableString+Common.m */; }; + B1D5ECC120BC06CB00983FB6 /* UIViewController+BackButtonHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E2527191C327FAE0032A7F4 /* UIViewController+BackButtonHandler.m */; }; + B1D5ECC220BC06CB00983FB6 /* CountryCodeCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EBD7FB31CE4833D00B3AF49 /* CountryCodeCell.m */; }; + B1D5ECC320BC06CB00983FB6 /* RATaskBoardListListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B152ED67209420CD004A6E8A /* RATaskBoardListListViewController.m */; }; + B1D5ECC420BC06CB00983FB6 /* DynamicActivityCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 13C8FE7E1CA79B90001E30FA /* DynamicActivityCell.m */; }; + B1D5ECC520BC06CB00983FB6 /* MRPRDetailCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6A781B1C6C7800FD2E49 /* MRPRDetailCell.m */; }; + B1D5ECC620BC06CB00983FB6 /* TopicContentCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6439619FF7E2900F7EEB0 /* TopicContentCell.m */; }; + B1D5ECC720BC06CB00983FB6 /* ForkTreeCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0B9A361BAD377600D57D54 /* ForkTreeCell.m */; }; + B1D5ECC820BC06CB00983FB6 /* AMPopTip.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B63FD1FE900D400ACFDCC /* AMPopTip.m */; }; + B1D5ECC920BC06CB00983FB6 /* MRPRAcceptViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6A691B1C688200FD2E49 /* MRPRAcceptViewController.m */; }; + B1D5ECCA20BC06CB00983FB6 /* UIView+Common.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8AD41A3943E80021E29C /* UIView+Common.m */; }; + B1D5ECCB20BC06CB00983FB6 /* SDWebImageDownloaderOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA7F1441A6D192B00A046BD /* SDWebImageDownloaderOperation.m */; }; + B1D5ECCC20BC06CB00983FB6 /* QBAssetsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B646D1FFB61AD00ACFDCC /* QBAssetsViewController.m */; }; + B1D5ECCD20BC06CB00983FB6 /* UserInfoIconCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E996BD41ABA776500C704F1 /* UserInfoIconCell.m */; }; + B1D5ECCE20BC06CB00983FB6 /* ShopOderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 923399771C00BFC700F29E04 /* ShopOderCell.m */; }; + B1D5ECCF20BC06CB00983FB6 /* SettingPasswordViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E1C3E0319E8DFE300EF3032 /* SettingPasswordViewController.m */; }; + B1D5ECD020BC06CB00983FB6 /* FileCommentCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EAE06B31B7B325600179F4B /* FileCommentCell.m */; }; + B1D5ECD120BC06CB00983FB6 /* ASPopUpView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E91139F1A1C426000AC9431 /* ASPopUpView.m */; }; + B1D5ECD220BC06CB00983FB6 /* UIActivityIndicatorView+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6BA2C81A1EE6AF005FD721 /* UIActivityIndicatorView+AFNetworking.m */; }; + B1D5ECD320BC06CB00983FB6 /* ProjectCodeListSearchCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EAAD05E1E545516008AA957 /* ProjectCodeListSearchCell.m */; }; + B1D5ECD420BC06CB00983FB6 /* TweetSendCreateLocationCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A782FDB1AB5B78B00E96661 /* TweetSendCreateLocationCell.m */; }; + B1D5ECD520BC06CB00983FB6 /* EaseStartView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E07D3101A4D1484009EDDF2 /* EaseStartView.m */; }; + B1D5ECD620BC06CB00983FB6 /* ProjectTopicListView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EE1A2281B5D02CA004284F1 /* ProjectTopicListView.m */; }; + B1D5ECD720BC06CB00983FB6 /* Message_RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CF3819E240C40076D59C /* Message_RootViewController.m */; }; + B1D5ECD820BC06CB00983FB6 /* LDSimplePing.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E3068391E0B781A00AEE0CE /* LDSimplePing.m */; }; + B1D5ECD920BC06CB00983FB6 /* HelpViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E44DCF91D81486600E7F9AF /* HelpViewController.m */; }; + B1D5ECDA20BC06CB00983FB6 /* CSSearchVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0BD87B1B6C7F0A0061CAA6 /* CSSearchVC.m */; }; + B1D5ECDB20BC06CB00983FB6 /* FunctionTipsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EC461AC1B39084100D08970 /* FunctionTipsManager.m */; }; + B1D5ECDC20BC06CB00983FB6 /* TweetSendCreateLocationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A782FD61AB5B69200E96661 /* TweetSendCreateLocationViewController.m */; }; + B1D5ECDD20BC06CB00983FB6 /* Commits.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6AB11B21A96100FD2E49 /* Commits.m */; }; + B1D5ECDE20BC06CB00983FB6 /* QcTask.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CFEB19E240C40076D59C /* QcTask.m */; }; + B1D5ECDF20BC06CB00983FB6 /* FileViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E35A99E1A3EC47E00CE35F1 /* FileViewController.m */; }; + B1D5ECE020BC06CB00983FB6 /* UIImage+WebP.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EF818211B09D43D005F974B /* UIImage+WebP.m */; }; + B1D5ECE120BC06CB00983FB6 /* TweetSendLocation.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A6E6BAC1AB08540004C0107 /* TweetSendLocation.m */; }; + B1D5ECE220BC06CB00983FB6 /* CodingNetAPIClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8AF21A3946C10021E29C /* CodingNetAPIClient.m */; }; + B1D5ECE320BC06CB00983FB6 /* ShopOrderTextFieldCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 927AFF5A1BFF772A00AAE593 /* ShopOrderTextFieldCell.m */; }; + B1D5ECE420BC06CB00983FB6 /* ScreenCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A0589A1E0AAA7200C1CA3F /* ScreenCell.m */; }; + B1D5ECE520BC06CB00983FB6 /* ConversationCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6436719FF7E2900F7EEB0 /* ConversationCell.m */; }; + B1D5ECE620BC06CB00983FB6 /* TeamListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ED4B4991D8295EA00EED8C6 /* TeamListViewController.m */; }; + B1D5ECE720BC06CB00983FB6 /* TweetSendImagesCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF643A219FF7E2900F7EEB0 /* TweetSendImagesCell.m */; }; + B1D5ECE820BC06CB00983FB6 /* WikiEditViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1890C432015D92500F52ABA /* WikiEditViewController.m */; }; + B1D5ECE920BC06CB00983FB6 /* MRPRListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECF704B1B1876CB000280FF /* MRPRListCell.m */; }; + B1D5ECEA20BC06CB00983FB6 /* TopicPreviewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A38784E1AE557700078D5DE /* TopicPreviewCell.m */; }; + B1D5ECEB20BC06CB00983FB6 /* NSString+Emojize.m in Sources */ = {isa = PBXBuildFile; fileRef = 8ED0D87419FBA6EA00FBA818 /* NSString+Emojize.m */; }; + B1D5ECEC20BC06CB00983FB6 /* EaseGitButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E1A228A1AB1844F00CFC14F /* EaseGitButton.m */; }; + B1D5ECED20BC06CB00983FB6 /* ProjectListTaCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E996BE41ABAB1D700C704F1 /* ProjectListTaCell.m */; }; + B1D5ECEE20BC06CB00983FB6 /* UIImageView+MJWebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EE72BE319E3F2E8002C11D9 /* UIImageView+MJWebCache.m */; }; + B1D5ECEF20BC06CB00983FB6 /* Commit.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CFD319E240C40076D59C /* Commit.m */; }; + B1D5ECF020BC06CB00983FB6 /* FileVersionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EAE06C71B7C9EFF00179F4B /* FileVersionCell.m */; }; + B1D5ECF120BC06CB00983FB6 /* TeamListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ED4B4A21D82980F00EED8C6 /* TeamListCell.m */; }; + B1D5ECF220BC06CB00983FB6 /* UIView+WebCacheOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA7F1551A6D192B00A046BD /* UIView+WebCacheOperation.m */; }; + B1D5ECF320BC06CB00983FB6 /* TweetSendTextCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF643A419FF7E2900F7EEB0 /* TweetSendTextCell.m */; }; + B1D5ECF420BC06CB00983FB6 /* XTSegmentControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6D0CC19E240C40076D59C /* XTSegmentControl.m */; }; + B1D5ECF520BC06CB00983FB6 /* YLGIFImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6D71861A75F00E005AD988 /* YLGIFImage.m */; }; + B1D5ECF620BC06CB00983FB6 /* CountryCodeListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EBD7FAE1CE4827A00B3AF49 /* CountryCodeListViewController.m */; }; + B1D5ECF720BC06CB00983FB6 /* AllSearchDisplayVC.m in Sources */ = {isa = PBXBuildFile; fileRef = D09AA5B61BFDA38D008CA9EB /* AllSearchDisplayVC.m */; }; + B1D5ECF820BC06CB00983FB6 /* TweetSendLocationDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A27A05C1AB5A13B00067833 /* TweetSendLocationDetailViewController.m */; }; + B1D5ECF920BC06CB00983FB6 /* EATerminalViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1816062202063440022B4C6 /* EATerminalViewController.m */; }; + B1D5ECFA20BC06CB00983FB6 /* TweetSendMapAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = 0AB591AF1AB6D6BE0076C454 /* TweetSendMapAnnotation.m */; }; + B1D5ECFB20BC06CB00983FB6 /* MRPR.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECF70481B185BCC000280FF /* MRPR.m */; }; + B1D5ECFC20BC06CB00983FB6 /* EaseUserInfoCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A058911E0AA9FB00C1CA3F /* EaseUserInfoCell.m */; }; + B1D5ECFD20BC06CB00983FB6 /* CodingBannersView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E095A5B1B6907AA008DC439 /* CodingBannersView.m */; }; + B1D5ECFE20BC06CB00983FB6 /* OTPListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E8D5D651B45306900B70936 /* OTPListViewController.m */; }; + B1D5ECFF20BC06CB00983FB6 /* UIImageView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA7F1531A6D192B00A046BD /* UIImageView+WebCache.m */; }; + B1D5ED0020BC06CB00983FB6 /* InputOnlyTextPlainCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6437219FF7E2900F7EEB0 /* InputOnlyTextPlainCell.m */; }; + B1D5ED0120BC06CB00983FB6 /* NSTimer+Addition.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E095A631B6909F9008DC439 /* NSTimer+Addition.m */; }; + B1D5ED0220BC06CB00983FB6 /* AFURLSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6BA2B71A1EE6AF005FD721 /* AFURLSessionManager.m */; }; + B1D5ED0320BC06CB00983FB6 /* MeRootServiceCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E87DDFF1D813B4500D1B5B1 /* MeRootServiceCell.m */; }; + B1D5ED0420BC06CB00983FB6 /* ActionSheetLocalePicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E1C3DE319E7D58A00EF3032 /* ActionSheetLocalePicker.m */; }; + B1D5ED0520BC06CB00983FB6 /* UIViewController+Swizzle.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8AD61A3943E80021E29C /* UIViewController+Swizzle.m */; }; + B1D5ED0620BC06CB00983FB6 /* PublicSearchModel.m in Sources */ = {isa = PBXBuildFile; fileRef = D09AA5B91BFDBA4B008CA9EB /* PublicSearchModel.m */; }; + B1D5ED0720BC06CB00983FB6 /* MJPhotoLoadingView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6D06F19E240C40076D59C /* MJPhotoLoadingView.m */; }; + B1D5ED0820BC06CB00983FB6 /* FileEditViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E753D431B8AFDEC003A00B9 /* FileEditViewController.m */; }; + B1D5ED0920BC06CB00983FB6 /* TopicDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CF5019E240C40076D59C /* TopicDetailViewController.m */; }; + B1D5ED0A20BC06CB00983FB6 /* UIImageView+HighlightedWebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA7F1511A6D192B00A046BD /* UIImageView+HighlightedWebCache.m */; }; + B1D5ED0B20BC06CB00983FB6 /* Helper.m in Sources */ = {isa = PBXBuildFile; fileRef = E7A0469F1A47279E00528C12 /* Helper.m */; }; + B1D5ED0C20BC06CB00983FB6 /* PointTopCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E00228B1B721955005308DE /* PointTopCell.m */; }; + B1D5ED0D20BC06CB00983FB6 /* TeamMemberCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ED4B4AB1D829E1200EED8C6 /* TeamMemberCell.m */; }; + B1D5ED0E20BC06CB00983FB6 /* ReviewerListController.m in Sources */ = {isa = PBXBuildFile; fileRef = 13972E2B1CA616AC00489EBA /* ReviewerListController.m */; }; + B1D5ED0F20BC06CB00983FB6 /* UserInfoDetailTagCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E996BD21ABA776500C704F1 /* UserInfoDetailTagCell.m */; }; + B1D5ED1020BC06CB00983FB6 /* SWUtilityButtonView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E8765641A22E5B40090CFB9 /* SWUtilityButtonView.m */; }; + B1D5ED1120BC06CB00983FB6 /* VoiceMedia.m in Sources */ = {isa = PBXBuildFile; fileRef = 7EB02FFB1B6E001300D2166C /* VoiceMedia.m */; }; + B1D5ED1220BC06CB00983FB6 /* TaskComment.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EABE3C719F10D2400A17784 /* TaskComment.m */; }; + B1D5ED1320BC06CB00983FB6 /* EACodeReleaseTopCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B1817EE62064FC6100E9BAD1 /* EACodeReleaseTopCell.m */; }; + B1D5ED1420BC06CB00983FB6 /* EAPayViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1BCB88D1FCE61D60098B87B /* EAPayViewController.m */; }; + B1D5ED1520BC06CB00983FB6 /* AGEmojiKeyBoardView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E97CE441A0A2DF8006F9AD7 /* AGEmojiKeyBoardView.m */; }; + B1D5ED1620BC06CB00983FB6 /* RKSwipeBetweenViewControllers.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E53EB511AFA03990034FE1C /* RKSwipeBetweenViewControllers.m */; }; + B1D5ED1720BC06CB00983FB6 /* EditTopicViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CF1F19E240C40076D59C /* EditTopicViewController.m */; }; + B1D5ED1820BC06CB00983FB6 /* GlowImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E94C4F71B4D2B9300EB668A /* GlowImageView.m */; }; + B1D5ED1920BC06CB00983FB6 /* ProjectToChooseListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E24B2671B43D33F004D7989 /* ProjectToChooseListViewController.m */; }; + B1D5ED1A20BC06CB00983FB6 /* SDWebImageCompat.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA7F13E1A6D192B00A046BD /* SDWebImageCompat.m */; }; + B1D5ED1B20BC06CB00983FB6 /* EACodeReleaseBodyCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B1817EE92064FC7300E9BAD1 /* EACodeReleaseBodyCell.m */; }; + B1D5ED1C20BC06CB00983FB6 /* Project_RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CF3C19E240C40076D59C /* Project_RootViewController.m */; }; + B1D5ED1D20BC06CB00983FB6 /* EaseGitButtonsView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECF703F1B180740000280FF /* EaseGitButtonsView.m */; }; + B1D5ED1E20BC06CB00983FB6 /* SettingTagsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF83F8919E92AA500E86DE7 /* SettingTagsViewController.m */; }; + B1D5ED1F20BC06CB00983FB6 /* EALocalCodeListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B1944149206BB8BB00147158 /* EALocalCodeListCell.m */; }; + B1D5ED2020BC06CB00983FB6 /* ValueListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF643A819FF7E2900F7EEB0 /* ValueListCell.m */; }; + B1D5ED2120BC06CB00983FB6 /* TaskResourceReferenceViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EB52F3E1C7C464400B5EBEA /* TaskResourceReferenceViewController.m */; }; + B1D5ED2220BC06CB00983FB6 /* SVModalWebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E217EF91A70EDC700F6DF88 /* SVModalWebViewController.m */; }; + B1D5ED2320BC06CB00983FB6 /* ShopSwitchCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B19D4EF01F710EF900C598F3 /* ShopSwitchCell.m */; }; + B1D5ED2520BC06CB00983FB6 /* IntroductionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EF17E5E1B3AB10F003CDD2D /* IntroductionViewController.m */; }; + B1D5ED2620BC06CB00983FB6 /* SDWebImagePrefetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA7F1491A6D192B00A046BD /* SDWebImagePrefetcher.m */; }; + B1D5ED2720BC06CB00983FB6 /* FileChanges.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6A931B1D851E00FD2E49 /* FileChanges.m */; }; + B1D5ED2820BC06CB00983FB6 /* UIWebView+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6BA2D51A1EE6AF005FD721 /* UIWebView+AFNetworking.m */; }; + B1D5ED2920BC06CB00983FB6 /* EAWiki.m in Sources */ = {isa = PBXBuildFile; fileRef = B1890C342015D87800F52ABA /* EAWiki.m */; }; + B1D5ED2A20BC06CB00983FB6 /* WikiMenuListView.m in Sources */ = {isa = PBXBuildFile; fileRef = B1890C362015D89A00F52ABA /* WikiMenuListView.m */; }; + B1D5ED2B20BC06CB00983FB6 /* EACodeRelease.m in Sources */ = {isa = PBXBuildFile; fileRef = B1817EC3206397E000E9BAD1 /* EACodeRelease.m */; }; + B1D5ED2C20BC06CB00983FB6 /* ForkTreeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0B9A331BAC1CD100D57D54 /* ForkTreeViewController.m */; }; + B1D5ED2D20BC06CB00983FB6 /* CommitContentCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6A7E1B1C6D1E00FD2E49 /* CommitContentCell.m */; }; + B1D5ED2E20BC06CB00983FB6 /* ProjectViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CF3119E240C40076D59C /* ProjectViewController.m */; }; + B1D5ED2F20BC06CB00983FB6 /* TagCCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6435A19FF7E2900F7EEB0 /* TagCCell.m */; }; + B1D5ED3020BC06CB00983FB6 /* UserInfoDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E996BDB1ABA79AB00C704F1 /* UserInfoDetailViewController.m */; }; + B1D5ED3120BC06CB00983FB6 /* ProjectAdvancedSettingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B9A00D841ACA3A55008BA008 /* ProjectAdvancedSettingViewController.m */; }; + B1D5ED3220BC06CB00983FB6 /* SWLongPressGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E87655E1A22E5B40090CFB9 /* SWLongPressGestureRecognizer.m */; }; + B1D5ED3320BC06CB00983FB6 /* QBAlbumsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B646B1FFB61AD00ACFDCC /* QBAlbumsViewController.m */; }; + B1D5ED3420BC06CB00983FB6 /* TweetSendLocaitonMapViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0AB591AB1AB6D2F60076C454 /* TweetSendLocaitonMapViewController.m */; }; + B1D5ED3520BC06CB00983FB6 /* UIButton+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA7F14B1A6D192B00A046BD /* UIButton+WebCache.m */; }; + B1D5ED3620BC06CB00983FB6 /* EABoardTaskListBlankView.m in Sources */ = {isa = PBXBuildFile; fileRef = B152ED6220935524004A6E8A /* EABoardTaskListBlankView.m */; }; + B1D5ED3720BC06CB00983FB6 /* SDWebImageManager+MJ.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EE72BE119E3F2E8002C11D9 /* SDWebImageManager+MJ.m */; }; + B1D5ED3820BC06CB00983FB6 /* TopicListView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A38784B1AE36EF00078D5DE /* TopicListView.m */; }; + B1D5ED3920BC06CB00983FB6 /* AbstractActionSheetPicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E1C3DDA19E7D58A00EF3032 /* AbstractActionSheetPicker.m */; }; + B1D5ED3A20BC06CB00983FB6 /* CodingTips.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CFCF19E240C40076D59C /* CodingTips.m */; }; + B1D5ED3B20BC06CB00983FB6 /* MRPRCommentCCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6A5A1B1C5DDF00FD2E49 /* MRPRCommentCCell.m */; }; + B1D5ED3C20BC06CB00983FB6 /* AMPopTip+Animation.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B63FB1FE900D400ACFDCC /* AMPopTip+Animation.m */; }; + B1D5ED3D20BC06CB00983FB6 /* TaskCommentTopCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6438619FF7E2900F7EEB0 /* TaskCommentTopCell.m */; }; + B1D5ED3E20BC06CB00983FB6 /* MRPRCommitsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6A601B1C65C100FD2E49 /* MRPRCommitsViewController.m */; }; + B1D5ED3F20BC06CB00983FB6 /* EABasePageModel.m in Sources */ = {isa = PBXBuildFile; fileRef = B1817EBE2063951000E9BAD1 /* EABasePageModel.m */; }; + B1D5ED4020BC06CB00983FB6 /* UITableViewCell+Common.m in Sources */ = {isa = PBXBuildFile; fileRef = B1C871531EADF4D4003DACF0 /* UITableViewCell+Common.m */; }; + B1D5ED4120BC06CB00983FB6 /* EACodeReleaseListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B1817EC920639E9500E9BAD1 /* EACodeReleaseListCell.m */; }; + B1D5ED4220BC06CB00983FB6 /* CSLikesVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0BD85B1B6C7E3D0061CAA6 /* CSLikesVC.m */; }; + B1D5ED4320BC06CB00983FB6 /* UserOrProjectTweetsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CF5A19E240C40076D59C /* UserOrProjectTweetsViewController.m */; }; + B1D5ED4420BC06CB00983FB6 /* CommitDetail.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6A9F1B1D89D400FD2E49 /* CommitDetail.m */; }; + B1D5ED4520BC06CB00983FB6 /* DownMenuCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8AB21A3943E80021E29C /* DownMenuCell.m */; }; + B1D5ED4620BC06CB00983FB6 /* RFToolbarButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6C411E1A846AC30098DC17 /* RFToolbarButton.m */; }; + B1D5ED4720BC06CB00983FB6 /* TopicListButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A3878481AE36ED70078D5DE /* TopicListButton.m */; }; + B1D5ED4820BC06CB00983FB6 /* ImageSizeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8AF41A3946C10021E29C /* ImageSizeManager.m */; }; + B1D5ED4920BC06CB00983FB6 /* File.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CFD719E240C40076D59C /* File.m */; }; + B1D5ED4A20BC06CB00983FB6 /* ShopOrderViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 923399741C00ABDE00F29E04 /* ShopOrderViewController.m */; }; + B1D5ED4B20BC06CB00983FB6 /* OTPTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E8D5D7C1B462ADB00B70936 /* OTPTableViewCell.m */; }; + B1D5ED4C20BC06CB00983FB6 /* UIMessageInputView_CCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EABD2591AD3CB4A005E515F /* UIMessageInputView_CCell.m */; }; + B1D5ED4D20BC06CB00983FB6 /* DemoModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 134E1BA51CA41671002A3E0D /* DemoModel.m */; }; + B1D5ED4E20BC06CB00983FB6 /* TaskCommentBlankCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6438219FF7E2900F7EEB0 /* TaskCommentBlankCell.m */; }; + B1D5ED4F20BC06CB00983FB6 /* AFNetworkActivityIndicatorManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6BA2C61A1EE6AF005FD721 /* AFNetworkActivityIndicatorManager.m */; }; + B1D5ED5020BC06CB00983FB6 /* Login.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CFDD19E240C40076D59C /* Login.m */; }; + B1D5ED5120BC06CB00983FB6 /* TitleDisclosureCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6438A19FF7E2900F7EEB0 /* TitleDisclosureCell.m */; }; + B1D5ED5220BC06CB00983FB6 /* FileDownloadView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E2906A11A403B7D008A5B97 /* FileDownloadView.m */; }; + B1D5ED5320BC06CB00983FB6 /* AFNetworkReachabilityManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6BA2BA1A1EE6AF005FD721 /* AFNetworkReachabilityManager.m */; }; + B1D5ED5420BC06CB00983FB6 /* LDNetTraceRoute.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E3068371E0B781A00AEE0CE /* LDNetTraceRoute.m */; }; + B1D5ED5520BC06CB00983FB6 /* SearchViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D09E6AD01BF9D999009D37F8 /* SearchViewController.m */; }; + B1D5ED5620BC06CB00983FB6 /* QBImagePickerController.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B646E1FFB61AD00ACFDCC /* QBImagePickerController.m */; }; + B1D5ED5720BC06CB00983FB6 /* EditColorViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EB52F241C76C16300B5EBEA /* EditColorViewController.m */; }; + B1D5ED5820BC06CB00983FB6 /* UIScrollView+SVPullToRefresh.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E59F0E11A0098BA009A905F /* UIScrollView+SVPullToRefresh.m */; }; + B1D5ED5920BC06CB00983FB6 /* NSData+OTPBase32Encoding.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E8D5D451B45295D00B70936 /* NSData+OTPBase32Encoding.m */; }; + B1D5ED5A20BC06CB00983FB6 /* StartImagesManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E8AF7851A53D69F00CDC3AE /* StartImagesManager.m */; }; + B1D5ED5B20BC06CB00983FB6 /* ProjectMemberListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CF2F19E240C40076D59C /* ProjectMemberListViewController.m */; }; + B1D5ED5C20BC06CB00983FB6 /* ProjectActivitiesView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EE1A21A1B5D02CA004284F1 /* ProjectActivitiesView.m */; }; + B1D5ED5D20BC06CB00983FB6 /* MRReviewerCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 13FB5D581CA194D600EE127C /* MRReviewerCell.m */; }; + B1D5ED5E20BC06CB00983FB6 /* TweetCommentCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6439A19FF7E2900F7EEB0 /* TweetCommentCell.m */; }; + B1D5ED5F20BC06CB00983FB6 /* BaseNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6C41181A834EA90098DC17 /* BaseNavigationController.m */; }; + B1D5ED6020BC06CB00983FB6 /* LocationHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A03E6D21ABD0F690034BB8E /* LocationHelper.m */; }; + B1D5ED6120BC06CB00983FB6 /* CSHotTopicPagesVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B888E411B72618200806CEE /* CSHotTopicPagesVC.m */; }; + B1D5ED6220BC06CB00983FB6 /* TaskSearchCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D0C448171C03187100DC1C4B /* TaskSearchCell.m */; }; + B1D5ED6320BC06CB00983FB6 /* AFURLConnectionOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6BA2B21A1EE6AF005FD721 /* AFURLConnectionOperation.m */; }; + B1D5ED6420BC06CB00983FB6 /* ProjectTopic.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CFE719E240C40076D59C /* ProjectTopic.m */; }; + B1D5ED6520BC06CB00983FB6 /* EACodeBranchListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1817EB52063899400E9BAD1 /* EACodeBranchListViewController.m */; }; + B1D5ED6620BC06CB00983FB6 /* TeamProjectsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ED4B49F1D82962100EED8C6 /* TeamProjectsViewController.m */; }; + B1D5ED6720BC06CB00983FB6 /* RegisterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CF2C19E240C40076D59C /* RegisterViewController.m */; }; + B1D5ED6820BC06CB00983FB6 /* ShopBanner.m in Sources */ = {isa = PBXBuildFile; fileRef = 923399651C00441700F29E04 /* ShopBanner.m */; }; + B1D5ED6920BC06CB00983FB6 /* TitleRImageMoreCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6438C19FF7E2900F7EEB0 /* TitleRImageMoreCell.m */; }; + B1D5ED6A20BC06CB00983FB6 /* EABoardTaskListView.m in Sources */ = {isa = PBXBuildFile; fileRef = B152ED5F2093018A004A6E8A /* EABoardTaskListView.m */; }; + B1D5ED6B20BC06CB00983FB6 /* FileShare.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E49693F1DCB0BCE0065028E /* FileShare.m */; }; + B1D5ED6C20BC06CB00983FB6 /* ShopMutileValueCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ED6181A1C3A72AE0017946C /* ShopMutileValueCell.m */; }; + B1D5ED6D20BC06CB00983FB6 /* SVWebViewControllerActivitySafari.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E217F081A70EDC700F6DF88 /* SVWebViewControllerActivitySafari.m */; }; + B1D5ED6E20BC06CB00983FB6 /* HOTPGenerator.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E8D5D431B45295D00B70936 /* HOTPGenerator.m */; }; + B1D5ED6F20BC06CB00983FB6 /* WikiViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1890C472015D92600F52ABA /* WikiViewController.m */; }; + B1D5ED7020BC06CB00983FB6 /* TweetDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CF5219E240C40076D59C /* TweetDetailViewController.m */; }; + B1D5ED7120BC06CB00983FB6 /* Team.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ED4B4961D82939700EED8C6 /* Team.m */; }; + B1D5ED7220BC06CB00983FB6 /* LoginViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CF2A19E240C40076D59C /* LoginViewController.m */; }; + B1D5ED7320BC06CB00983FB6 /* NSData+gzip.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E30683C1E0B781A00AEE0CE /* NSData+gzip.m */; }; + B1D5ED7420BC06CB00983FB6 /* NSString+OTPURLArguments.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E8D5D471B45295D00B70936 /* NSString+OTPURLArguments.m */; }; + B1D5ED7520BC06CB00983FB6 /* ProjectSquareViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D066BB391BF30EB9005AB5D6 /* ProjectSquareViewController.m */; }; + B1D5ED7620BC06CB00983FB6 /* EACodeBranches.m in Sources */ = {isa = PBXBuildFile; fileRef = B1817EBB2063936100E9BAD1 /* EACodeBranches.m */; }; + B1D5ED7720BC06CB00983FB6 /* NSLayoutConstraintLine.m in Sources */ = {isa = PBXBuildFile; fileRef = B1BCB8911FCE662A0098B87B /* NSLayoutConstraintLine.m */; }; + B1D5ED7820BC06CB00983FB6 /* ProjectMemberActivityListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E6F1C941A03BD6000BF79C8 /* ProjectMemberActivityListViewController.m */; }; + B1D5ED7920BC06CB00983FB6 /* BaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CF3419E240C40076D59C /* BaseViewController.m */; }; + B1D5ED7A20BC06CB00983FB6 /* TopicCommentCCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E5F39041ACA958C0010515D /* TopicCommentCCell.m */; }; + B1D5ED7B20BC06CB00983FB6 /* EaseToolBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E15C7D51A271A6300FB8DAD /* EaseToolBar.m */; }; + B1D5ED7C20BC06CB00983FB6 /* Project.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EE548201AE8DB5600A92306 /* Project.m */; }; + B1D5ED7D20BC06CB00983FB6 /* ProjectActivityListView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EE1A21C1B5D02CA004284F1 /* ProjectActivityListView.m */; }; + B1D5ED7E20BC06CB00983FB6 /* AFHTTPRequestOperationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6BA2B01A1EE6AF005FD721 /* AFHTTPRequestOperationManager.m */; }; + B1D5ED7F20BC06CB00983FB6 /* BubblePlayView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7EB02FEE1B6D111300D2166C /* BubblePlayView.m */; }; + B1D5ED8020BC06CB00983FB6 /* FRDLivelyButton.m in Sources */ = {isa = PBXBuildFile; fileRef = D031F5DA1BFAD6690008E964 /* FRDLivelyButton.m */; }; + B1D5ED8120BC06CB00983FB6 /* UIColor+expanded.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8AC81A3943E80021E29C /* UIColor+expanded.m */; }; + B1D5ED8220BC06CB00983FB6 /* MRListView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6318A11BDA261100EFED97 /* MRListView.m */; }; + B1D5ED8320BC06CB00983FB6 /* UserActiveStatusView.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A058881E0AA9AE00C1CA3F /* UserActiveStatusView.m */; }; + B1D5ED8420BC06CB00983FB6 /* ScreenView.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A058971E0AAA5300C1CA3F /* ScreenView.m */; }; + B1D5ED8520BC06CB00983FB6 /* ProjectCount.m in Sources */ = {isa = PBXBuildFile; fileRef = D0A32BF51BF1CA8F00336C52 /* ProjectCount.m */; }; + B1D5ED8620BC06CB00983FB6 /* ResourceReference.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EB52F371C7C38F600B5EBEA /* ResourceReference.m */; }; + B1D5ED8720BC06CB00983FB6 /* SDWebImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA7F1421A6D192B00A046BD /* SDWebImageDownloader.m */; }; + B1D5ED8820BC06CB00983FB6 /* HtmlMedia.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CFD919E240C40076D59C /* HtmlMedia.m */; }; + B1D5ED8920BC06CB00983FB6 /* EditLabelCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A3878421AE296240078D5DE /* EditLabelCell.m */; }; + B1D5ED8A20BC06CB00983FB6 /* NSString+Common.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8AC01A3943E80021E29C /* NSString+Common.m */; }; + B1D5ED8B20BC06CB00983FB6 /* BasicPreviewItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8B071A3947300021E29C /* BasicPreviewItem.m */; }; + B1D5ED8C20BC06CB00983FB6 /* MeDisplayViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E2247FB1D82C98800551EA4 /* MeDisplayViewController.m */; }; + B1D5ED8D20BC06CB00983FB6 /* SDImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA7F13C1A6D192B00A046BD /* SDImageCache.m */; }; + B1D5ED8E20BC06CB00983FB6 /* AddReviewerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 134E1B9F1CA414DB002A3E0D /* AddReviewerViewController.m */; }; + B1D5ED8F20BC06CB00983FB6 /* FunctionIntroManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E00229F1B7360B1005308DE /* FunctionIntroManager.m */; }; + B1D5ED9020BC06CB00983FB6 /* NJKWebViewProgress.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EBB62491A6F526C0045DAEF /* NJKWebViewProgress.m */; }; + B1D5ED9120BC06CB00983FB6 /* MRPRTopCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6A751B1C6C6100FD2E49 /* MRPRTopCell.m */; }; + B1D5ED9220BC06CB00983FB6 /* ProjectTaskListView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EE1A2241B5D02CA004284F1 /* ProjectTaskListView.m */; }; + B1D5ED9320BC06CB00983FB6 /* ResetLabelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A3878391AE2949E0078D5DE /* ResetLabelViewController.m */; }; + B1D5ED9420BC06CB00983FB6 /* FileComment.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EAE06A31B7AE4EF00179F4B /* FileComment.m */; }; + B1D5ED9520BC06CB00983FB6 /* Tweet_RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CF4019E240C40076D59C /* Tweet_RootViewController.m */; }; + B1D5ED9620BC06CB00983FB6 /* ProjectDeleteAlertControllerVisualStyle.m in Sources */ = {isa = PBXBuildFile; fileRef = B93D904A1ACBA3110057A6EE /* ProjectDeleteAlertControllerVisualStyle.m */; }; + B1D5ED9720BC06CB00983FB6 /* ProjectItemsCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E1A22841AB172C400CFC14F /* ProjectItemsCell.m */; }; + B1D5ED9820BC06CB00983FB6 /* WebContentManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8AFC1A3946C10021E29C /* WebContentManager.m */; }; + B1D5ED9920BC06CB00983FB6 /* Login2FATipCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E94C4F31B4D007600EB668A /* Login2FATipCell.m */; }; + B1D5ED9A20BC06CB00983FB6 /* FileChangeDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6A721B1C694100FD2E49 /* FileChangeDetailViewController.m */; }; + B1D5ED9B20BC06CB00983FB6 /* MJPhotoBrowser.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6D06D19E240C40076D59C /* MJPhotoBrowser.m */; }; + B1D5ED9C20BC06CB00983FB6 /* CSMyTopicVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0BD85D1B6C7E3D0061CAA6 /* CSMyTopicVC.m */; }; + B1D5ED9D20BC06CB00983FB6 /* LocationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ED618141C3A6B4B0017946C /* LocationViewController.m */; }; + B1D5ED9E20BC06CB00983FB6 /* JDStatusBarLayoutMarginHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B641B1FF0F5E300ACFDCC /* JDStatusBarLayoutMarginHelper.m */; }; + B1D5ED9F20BC06CB00983FB6 /* iCarousel.m in Sources */ = {isa = PBXBuildFile; fileRef = 8ED4611F19E4DC470059B3BE /* iCarousel.m */; }; + B1D5EDA020BC06CB00983FB6 /* ProjectDescriptionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E1A22871AB1731600CFC14F /* ProjectDescriptionCell.m */; }; + B1D5EDA120BC06CB00983FB6 /* UIButton+Common.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8AC61A3943E80021E29C /* UIButton+Common.m */; }; + B1D5EDA220BC06CB00983FB6 /* UIDownMenuButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8AB41A3943E80021E29C /* UIDownMenuButton.m */; }; + B1D5EDA320BC06CB00983FB6 /* TopicAnswerDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6CBE501D8E962300644086 /* TopicAnswerDetailViewController.m */; }; + B1D5EDA420BC06CB00983FB6 /* UsersViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CF5819E240C40076D59C /* UsersViewController.m */; }; + B1D5EDA520BC06CB00983FB6 /* SkillCCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B64141FF0DE4800ACFDCC /* SkillCCell.m */; }; + B1D5EDA620BC06CB00983FB6 /* MenuButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E94C4F91B4D2B9300EB668A /* MenuButton.m */; }; + B1D5EDA720BC06CB00983FB6 /* AMPopTip+Draw.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B64031FE900D400ACFDCC /* AMPopTip+Draw.m */; }; + B1D5EDA820BC06CB00983FB6 /* ProjectArchiveViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B152ED532091B7CB004A6E8A /* ProjectArchiveViewController.m */; }; + B1D5EDA920BC06CB00983FB6 /* TeamViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ED4B49C1D8295F600EED8C6 /* TeamViewController.m */; }; + B1D5EDAA20BC06CB00983FB6 /* LocalFileViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EF3741B1BB1258600DDA662 /* LocalFileViewController.m */; }; + B1D5EDAB20BC06CB00983FB6 /* ResetLabelCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A38783F1AE295970078D5DE /* ResetLabelCell.m */; }; + B1D5EDAD20BC06CB00983FB6 /* EACodeBranchListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B1817ECC20639F0A00E9BAD1 /* EACodeBranchListCell.m */; }; + B1D5EDAE20BC06CB00983FB6 /* ValueListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CF4A19E240C40076D59C /* ValueListViewController.m */; }; + B1D5EDAF20BC06CB00983FB6 /* ActivateViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EB52F141C7599FC00B5EBEA /* ActivateViewController.m */; }; + B1D5EDB020BC06CB00983FB6 /* MRPRListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EAAD0131E5306F3008AA957 /* MRPRListViewController.m */; }; + B1D5EDB120BC06CB00983FB6 /* NSObject+ObjectMap.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8ABE1A3943E80021E29C /* NSObject+ObjectMap.m */; }; + B1D5EDB220BC06CB00983FB6 /* SWCellScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E87655C1A22E5B40090CFB9 /* SWCellScrollView.m */; }; + B1D5EDB320BC06CB00983FB6 /* ActionSheetCustomPicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E1C3DDC19E7D58A00EF3032 /* ActionSheetCustomPicker.m */; }; + B1D5EDB420BC06CB00983FB6 /* PRMRSearchCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D02BE0AE1C0434DB008374C0 /* PRMRSearchCell.m */; }; + B1D5EDB520BC06CB00983FB6 /* TweetSendViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CF5419E240C40076D59C /* TweetSendViewController.m */; }; + B1D5EDB620BC06CB00983FB6 /* PrivateMessages.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CFE119E240C40076D59C /* PrivateMessages.m */; }; + B1D5EDB720BC06CB00983FB6 /* YLImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6D71881A75F00E005AD988 /* YLImageView.m */; }; + B1D5EDB820BC06CB00983FB6 /* CodingBanner.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E095A581B690494008DC439 /* CodingBanner.m */; }; + B1D5EDB920BC06CB00983FB6 /* ShopOrderModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 9233997A1C00C55600F29E04 /* ShopOrderModel.m */; }; + B1D5EDBA20BC06CB00983FB6 /* MartFunctionTipView.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B63F81FE8FF0300ACFDCC /* MartFunctionTipView.m */; }; + B1D5EDBB20BC06CB00983FB6 /* CodingSkill.m in Sources */ = {isa = PBXBuildFile; fileRef = B19D4EED1F6FCEAC00C598F3 /* CodingSkill.m */; }; + B1D5EDBC20BC06CB00983FB6 /* DashesLineView.m in Sources */ = {isa = PBXBuildFile; fileRef = 923399711C00A9EF00F29E04 /* DashesLineView.m */; }; + B1D5EDBD20BC06CB00983FB6 /* Tweets.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CFF319E240C40076D59C /* Tweets.m */; }; + B1D5EDBE20BC06CB00983FB6 /* OTPAuthURL.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E8D5D4D1B45295D00B70936 /* OTPAuthURL.m */; }; + B1D5EDBF20BC06CB00983FB6 /* MJPhoto.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6D06A19E240C40076D59C /* MJPhoto.m */; }; + B1D5EDC020BC06CB00983FB6 /* TweetCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6439819FF7E2900F7EEB0 /* TweetCell.m */; }; + B1D5EDC120BC06CB00983FB6 /* UIBarButtonItem+Common.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8AC21A3943E80021E29C /* UIBarButtonItem+Common.m */; }; + B1D5EDC220BC06CB00983FB6 /* RRFPSBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E5D12FD1C0C5EE600985AEB /* RRFPSBar.m */; }; + B1D5EDC320BC06CB00983FB6 /* EaseUserHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E996BCF1ABA774800C704F1 /* EaseUserHeaderView.m */; }; + B1D5EDC420BC06CB00983FB6 /* PointRecordCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0022911B721973005308DE /* PointRecordCell.m */; }; + B1D5EDC520BC06CB00983FB6 /* UIView+PressMenu.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E5A66941B268D160007A0AD /* UIView+PressMenu.m */; }; + B1D5EDC620BC06CB00983FB6 /* Tasks.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CFF119E240C40076D59C /* Tasks.m */; }; + B1D5EDC720BC06CB00983FB6 /* MBProgressHUD+Add.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EE72BE719E3F4A8002C11D9 /* MBProgressHUD+Add.m */; }; + B1D5EDC820BC06CB00983FB6 /* CodeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E59F10C1A02188D009A905F /* CodeViewController.m */; }; + B1D5EDC920BC06CB00983FB6 /* ProjectTweetSendViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E59D32E1D3E1920008C914B /* ProjectTweetSendViewController.m */; }; + B1D5EDCA20BC06CB00983FB6 /* CommitListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6A7B1B1C6CDE00FD2E49 /* CommitListCell.m */; }; + B1D5EDCB20BC06CB00983FB6 /* EARestrictedScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0022951B73506A005308DE /* EARestrictedScrollView.m */; }; + B1D5EDCC20BC06CB00983FB6 /* RDVTabBarController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6D09619E240C40076D59C /* RDVTabBarController.m */; }; + B1D5EDCD20BC06CB00983FB6 /* ProjectLineNote.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E787DE11B0329B300F06E83 /* ProjectLineNote.m */; }; + B1D5EDCE20BC06CB00983FB6 /* ProjectAboutMeListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D066BB3C1BF38844005AB5D6 /* ProjectAboutMeListCell.m */; }; + B1D5EDCF20BC06CB00983FB6 /* EAFliterMenu.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EAAD0161E53EFF2008AA957 /* EAFliterMenu.m */; }; + B1D5EDD020BC06CB00983FB6 /* HotTopicBannerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BDF9AA51B7456060093BF2C /* HotTopicBannerView.m */; }; + B1D5EDD120BC06CB00983FB6 /* EditTaskViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CF2319E240C40076D59C /* EditTaskViewController.m */; }; + B1D5EDD220BC06CB00983FB6 /* TagColorDisplayCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EB52F2A1C76ED7000B5EBEA /* TagColorDisplayCell.m */; }; + B1D5EDD320BC06CB00983FB6 /* ProjectTopics.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CFE919E240C40076D59C /* ProjectTopics.m */; }; + B1D5EDD420BC06CB00983FB6 /* ReviewersInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 1309B9FE1CA2E95F0034C7A3 /* ReviewersInfo.m */; }; + B1D5EDD520BC06CB00983FB6 /* ProjectTasksView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EE1A2261B5D02CA004284F1 /* ProjectTasksView.m */; }; + B1D5EDD620BC06CB00983FB6 /* UICustomCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6D00419E240C40076D59C /* UICustomCollectionView.m */; }; + B1D5EDD720BC06CB00983FB6 /* NSObject+Common.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8ABC1A3943E80021E29C /* NSObject+Common.m */; }; + B1D5EDD820BC06CB00983FB6 /* SMPageControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E97CEBE1A0CB7E3006F9AD7 /* SMPageControl.m */; }; + B1D5EDD920BC06CB00983FB6 /* Coding_iOS.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CF1919E240C40076D59C /* Coding_iOS.xcdatamodeld */; }; + B1D5EDDA20BC06CB00983FB6 /* ConversationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CF2119E240C40076D59C /* ConversationViewController.m */; }; + B1D5EDDB20BC06CB00983FB6 /* EaseInputTipsView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EDC33CD1AFB4DCC00698315 /* EaseInputTipsView.m */; }; + B1D5EDDC20BC06CB00983FB6 /* NSDate+convenience.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8ABA1A3943E80021E29C /* NSDate+convenience.m */; }; + B1D5EDDD20BC06CB00983FB6 /* CSTopicModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0BD8691B6C7E3D0061CAA6 /* CSTopicModel.m */; }; + B1D5EDDE20BC06CB00983FB6 /* FileLineChange.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6AA21B1DB63A00FD2E49 /* FileLineChange.m */; }; + B1D5EDDF20BC06CB00983FB6 /* PasswordViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E5C06ED1AC4405300F427C5 /* PasswordViewController.m */; }; + B1D5EDE020BC06CB00983FB6 /* BaseCollectionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 927AFF431BFF61FF00AAE593 /* BaseCollectionCell.m */; }; + B1D5EDE120BC06CB00983FB6 /* SVWebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E217EFC1A70EDC700F6DF88 /* SVWebViewController.m */; }; + B1D5EDE220BC06CB00983FB6 /* EACodeReleaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1817EE32064F92C00E9BAD1 /* EACodeReleaseViewController.m */; }; + B1D5EDE320BC06CB00983FB6 /* AFSecurityPolicy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6BA2BE1A1EE6AF005FD721 /* AFSecurityPolicy.m */; }; + B1D5EDE420BC06CB00983FB6 /* UIImage+MultiFormat.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA7F14F1A6D192B00A046BD /* UIImage+MultiFormat.m */; }; + B1D5EDE520BC06CB00983FB6 /* TweetMediaItemSingleCCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6436019FF7E2900F7EEB0 /* TweetMediaItemSingleCCell.m */; }; + B1D5EDE620BC06CB00983FB6 /* TweetLikeUserCCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6435C19FF7E2900F7EEB0 /* TweetLikeUserCCell.m */; }; + B1D5EDE720BC06CB00983FB6 /* RewardTipManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E80E9341E011D6000DE1BC6 /* RewardTipManager.m */; }; + B1D5EDE920BC06CB00983FB6 /* CommitFilesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6A6F1B1C68F100FD2E49 /* CommitFilesViewController.m */; }; + B1D5EDEA20BC06CB00983FB6 /* FileChange.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6A901B1D84B400FD2E49 /* FileChange.m */; }; + B1D5EDEB20BC06CB00983FB6 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CFC619E240C40076D59C /* main.m */; }; + B1D5EDEC20BC06CB00983FB6 /* NewProjectViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B94C1B681AC945D30000C271 /* NewProjectViewController.m */; }; + B1D5EDED20BC06CB00983FB6 /* TeamTopCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ED4B4A51D82990600EED8C6 /* TeamTopCell.m */; }; + B1D5EDEE20BC06CB00983FB6 /* UserInfoTextCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E996BD61ABA776500C704F1 /* UserInfoTextCell.m */; }; + B1D5EDEF20BC06CB00983FB6 /* MRPRDisclosureCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6AA51B1DBA3A00FD2E49 /* MRPRDisclosureCell.m */; }; + B1D5EDF020BC06CB00983FB6 /* AboutViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E1C3DFB19E8DFE300EF3032 /* AboutViewController.m */; }; + B1D5EDF120BC06CB00983FB6 /* QBAssetCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B64721FFB61AD00ACFDCC /* QBAssetCell.m */; }; + B1D5EDF220BC06CB00983FB6 /* EACodeReleaseListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1817EB8206389F500E9BAD1 /* EACodeReleaseListViewController.m */; }; + B1D5EDF320BC06CB00983FB6 /* MeRootUserCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E87DDFC1D813B1E00D1B5B1 /* MeRootUserCell.m */; }; + B1D5EDF420BC06CB00983FB6 /* ShopGoods.m in Sources */ = {isa = PBXBuildFile; fileRef = 9233996B1C00524A00F29E04 /* ShopGoods.m */; }; + B1D5EDF520BC06CB00983FB6 /* AMPopTip+Entrance.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B64021FE900D400ACFDCC /* AMPopTip+Entrance.m */; }; + B1D5EDF620BC06CB00983FB6 /* PointRecords.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0022851B720966005308DE /* PointRecords.m */; }; + B1D5EDF720BC06CB00983FB6 /* QBCheckmarkView.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B646F1FFB61AD00ACFDCC /* QBCheckmarkView.m */; }; + B1D5EDF820BC06CB00983FB6 /* AFHTTPRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6BA2AE1A1EE6AF005FD721 /* AFHTTPRequestOperation.m */; }; + B1D5EDF920BC06CB00983FB6 /* ProjectLineNoteActivity.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EF8181E1B05C9D8005F974B /* ProjectLineNoteActivity.m */; }; + B1D5EDFA20BC06CB00983FB6 /* MessageMediaItemCCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6435619FF7E2900F7EEB0 /* MessageMediaItemCCell.m */; }; + B1D5EDFB20BC06CB00983FB6 /* MRPRS.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECF70451B18557E000280FF /* MRPRS.m */; }; + B1D5EDFC20BC06CB00983FB6 /* EAEditCodeReleaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B1817F052069F67700E9BAD1 /* EAEditCodeReleaseViewController.m */; }; + B1D5EDFD20BC06CB00983FB6 /* UIImage+Common.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8ACC1A3943E80021E29C /* UIImage+Common.m */; }; + B1D5EDFE20BC06CB00983FB6 /* ProjectTopicCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF643D519FF7E9F00F7EEB0 /* ProjectTopicCell.m */; }; + B1D5EDFF20BC06CB00983FB6 /* TextCheckMarkCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6A8A1B1C6E3000FD2E49 /* TextCheckMarkCell.m */; }; + B1D5EE0020BC06CB00983FB6 /* AFHTTPSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6BA2B51A1EE6AF005FD721 /* AFHTTPSessionManager.m */; }; + B1D5EE0120BC06CB00983FB6 /* XHRealTimeBlur.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E94C5111B4E0C0300EB668A /* XHRealTimeBlur.m */; }; + B1D5EE0220BC06CB00983FB6 /* ProjectFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA679091A1461C3001A0324 /* ProjectFile.m */; }; + B1D5EE0320BC06CB00983FB6 /* CSTopiclistView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0BD8671B6C7E3D0061CAA6 /* CSTopiclistView.m */; }; + B1D5EE0420BC06CB00983FB6 /* UILabel+Common.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8AD01A3943E80021E29C /* UILabel+Common.m */; }; + B1D5EE0520BC06CB00983FB6 /* QBSlomoIconView.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B64711FFB61AD00ACFDCC /* QBSlomoIconView.m */; }; + B1D5EE0620BC06CB00983FB6 /* SDWebImageDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA7F1401A6D192B00A046BD /* SDWebImageDecoder.m */; }; + B1D5EE0720BC06CB00983FB6 /* TweetSearchCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D09AA5BC1BFDE5F5008CA9EB /* TweetSearchCell.m */; }; + B1D5EE0820BC06CB00983FB6 /* AFURLResponseSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6BA2C31A1EE6AF005FD721 /* AFURLResponseSerialization.m */; }; + B1D5EE0920BC06CB00983FB6 /* CodeFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E59F1021A0120F1009A905F /* CodeFile.m */; }; + B1D5EE0A20BC06CB00983FB6 /* EAMilestone.m in Sources */ = {isa = PBXBuildFile; fileRef = B1ACFE0C20A975E2000BC41E /* EAMilestone.m */; }; + B1D5EE0B20BC06CB00983FB6 /* CSSearchCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0BD8751B6C7F0A0061CAA6 /* CSSearchCell.m */; }; + B1D5EE0C20BC06CB00983FB6 /* JDStatusBarView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E996BC71ABA754600C704F1 /* JDStatusBarView.m */; }; + B1D5EE0D20BC06CB00983FB6 /* MRPRAcceptEditCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6A871B1C6E1B00FD2E49 /* MRPRAcceptEditCell.m */; }; + B1D5EE0E20BC06CB00983FB6 /* EACodeReleaseAttachmentsOrReferencesCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B1817EEC2064FD9400E9BAD1 /* EACodeReleaseAttachmentsOrReferencesCell.m */; }; + B1D5EE0F20BC06CB00983FB6 /* MenuItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E94C4FB1B4D2B9300EB668A /* MenuItem.m */; }; + B1D5EE1020BC06CB00983FB6 /* TweetMediaItemCCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6435E19FF7E2900F7EEB0 /* TweetMediaItemCCell.m */; }; + B1D5EE1120BC06CB00983FB6 /* EditLabelHeadCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A3878441AE296240078D5DE /* EditLabelHeadCell.m */; }; + B1D5EE1220BC06CB00983FB6 /* TaskContentCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6438819FF7E2900F7EEB0 /* TaskContentCell.m */; }; + B1D5EE1320BC06CB00983FB6 /* TaskDescriptionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E59E1D21A5E6B34004DAEEC /* TaskDescriptionViewController.m */; }; + B1D5EE1420BC06CB00983FB6 /* AddressManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ECE8AEC1A3946C10021E29C /* AddressManager.m */; }; + B1D5EE1520BC06CB00983FB6 /* ProjectSettingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B9A00D811ACA3A17008BA008 /* ProjectSettingViewController.m */; }; + B1D5EE1620BC06CB00983FB6 /* ActionSheetDistancePicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E1C3DE119E7D58A00EF3032 /* ActionSheetDistancePicker.m */; }; + B1D5EE1720BC06CB00983FB6 /* ProjectCodeListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E59F0F31A00F3B9009A905F /* ProjectCodeListCell.m */; }; + B1D5EE1820BC06CB00983FB6 /* UserServiceInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E87DE021D813BBE00D1B5B1 /* UserServiceInfo.m */; }; + B1D5EE1920BC06CB00983FB6 /* TweetSendLocationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A6E6BA91AAF4B24004C0107 /* TweetSendLocationViewController.m */; }; + B1D5EE1A20BC06CB00983FB6 /* ProjectFolderListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E59F0F61A00F3E2009A905F /* ProjectFolderListCell.m */; }; + B1D5EE1B20BC06CB00983FB6 /* User.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CFF719E240C40076D59C /* User.m */; }; + B1D5EE1C20BC06CB00983FB6 /* MJPhotoToolbar.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6D07319E240C40076D59C /* MJPhotoToolbar.m */; }; + B1D5EE1D20BC06CB00983FB6 /* TweetDetailCommentCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF643A019FF7E2900F7EEB0 /* TweetDetailCommentCell.m */; }; + B1D5EE1E20BC06CB00983FB6 /* SettingSkillsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B64111FF0D54800ACFDCC /* SettingSkillsViewController.m */; }; + B1D5EE1F20BC06CB00983FB6 /* MRPRBaseInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6A8D1B1D5B9A00FD2E49 /* MRPRBaseInfo.m */; }; + B1D5EE2020BC06CB00983FB6 /* AudioRecordView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7EB02FF01B6D111300D2166C /* AudioRecordView.m */; }; + B1D5EE2120BC06CB00983FB6 /* TagColorEditCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EB52F271C76ED4A00B5EBEA /* TagColorEditCell.m */; }; + B1D5EE2220BC06CB00983FB6 /* QBVideoIndicatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B64621FFB61AD00ACFDCC /* QBVideoIndicatorView.m */; }; + B1D5EE2320BC06CB00983FB6 /* FileInfoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E93F2421B85C4C300017916 /* FileInfoViewController.m */; }; + B1D5EE2420BC06CB00983FB6 /* CommitInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6A991B1D893500FD2E49 /* CommitInfo.m */; }; + B1D5EE2520BC06CB00983FB6 /* CodeBranchTagButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E38CF5E1A7A28AF005536C0 /* CodeBranchTagButton.m */; }; + B1D5EE2620BC06CB00983FB6 /* ShopGoodsInfoView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9233996E1C00970900F29E04 /* ShopGoodsInfoView.m */; }; + B1D5EE2720BC06CB00983FB6 /* UIBadgeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6D00219E240C40076D59C /* UIBadgeView.m */; }; + B1D5EE2820BC06CB00983FB6 /* BaseModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 927AFF401BFF613500AAE593 /* BaseModel.m */; }; + B1D5EE2920BC06CB00983FB6 /* TaskSelectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A058941E0AAA2F00C1CA3F /* TaskSelectionView.m */; }; + B1D5EE2A20BC06CB00983FB6 /* ProjectListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6437C19FF7E2900F7EEB0 /* ProjectListCell.m */; }; + B1D5EE2B20BC06CB00983FB6 /* EABoardTaskList.m in Sources */ = {isa = PBXBuildFile; fileRef = B152ED592092BF46004A6E8A /* EABoardTaskList.m */; }; + B1D5EE2C20BC06CB00983FB6 /* CSTopicDetailVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0BD8631B6C7E3D0061CAA6 /* CSTopicDetailVC.m */; }; + B1D5EE2D20BC06CB00983FB6 /* ToMessageCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6439219FF7E2900F7EEB0 /* ToMessageCell.m */; }; + B1D5EE2E20BC06CB00983FB6 /* SVWebViewControllerActivityChrome.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E217F021A70EDC700F6DF88 /* SVWebViewControllerActivityChrome.m */; }; + B1D5EE2F20BC06CB00983FB6 /* PhoneCodeButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EC4800B1C2936DA005F1772 /* PhoneCodeButton.m */; }; + B1D5EE3020BC06CB00983FB6 /* TopicAnswerCommentMoreCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6CBE4D1D8E7E8000644086 /* TopicAnswerCommentMoreCell.m */; }; + B1D5EE3120BC06CB00983FB6 /* LDNetPing.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E3068331E0B781A00AEE0CE /* LDNetPing.m */; }; + B1D5EE3220BC06CB00983FB6 /* DynamicCommentCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 13C8FE6D1CA75816001E30FA /* DynamicCommentCell.m */; }; + B1D5EE3320BC06CB00983FB6 /* CSScrollview.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0BD85F1B6C7E3D0061CAA6 /* CSScrollview.m */; }; + B1D5EE3420BC06CB00983FB6 /* NSString+Attribute.m in Sources */ = {isa = PBXBuildFile; fileRef = D09AA5BF1BFDEDD1008CA9EB /* NSString+Attribute.m */; }; + B1D5EE3520BC06CB00983FB6 /* ProjectTopicsView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EE1A22A1B5D02CA004284F1 /* ProjectTopicsView.m */; }; + B1D5EE3620BC06CB00983FB6 /* ProjectFolder.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA6790C1A1461DC001A0324 /* ProjectFolder.m */; }; + B1D5EE3720BC06CB00983FB6 /* ProjectActivityListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6437A19FF7E2900F7EEB0 /* ProjectActivityListCell.m */; }; + B1D5EE3820BC06CB00983FB6 /* JDStatusBarStyle.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E996BC51ABA754600C704F1 /* JDStatusBarStyle.m */; }; + B1D5EE3920BC06CB00983FB6 /* LDNetDiagnoService.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E30682F1E0B781A00AEE0CE /* LDNetDiagnoService.m */; }; + B1D5EE3A20BC06CB00983FB6 /* EditCodeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E2F6A561C437D1D00A25502 /* EditCodeViewController.m */; }; + B1D5EE3B20BC06CB00983FB6 /* SettingTextViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF83F9319EB78CC00E86DE7 /* SettingTextViewController.m */; }; + B1D5EE3C20BC06CB00983FB6 /* EATaskBoardListTaskCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B152ED5C2092D51E004A6E8A /* EATaskBoardListTaskCell.m */; }; + B1D5EE3D20BC06CB00983FB6 /* LocationCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ED618171C3A6CA50017946C /* LocationCell.m */; }; + B1D5EE3E20BC06CB00983FB6 /* QBVideoIconView.m in Sources */ = {isa = PBXBuildFile; fileRef = B12B64611FFB61AD00ACFDCC /* QBVideoIconView.m */; }; + B1D5EE3F20BC06CB00983FB6 /* Comment.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CFD119E240C40076D59C /* Comment.m */; }; + B1D5EE4020BC06CB00983FB6 /* TweetSendLocationCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A6E6BA61AAF4162004C0107 /* TweetSendLocationCell.m */; }; + B1D5EE4120BC06CB00983FB6 /* HtmlMediaViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E9E3B741DCC2DB10005FD79 /* HtmlMediaViewController.m */; }; + B1D5EE4220BC06CB00983FB6 /* CSTopicCreateVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0BD8611B6C7E3D0061CAA6 /* CSTopicCreateVC.m */; }; + B1D5EE4320BC06CB00983FB6 /* NSMutableArray+SWUtilityButtons.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E87655A1A22E5B40090CFB9 /* NSMutableArray+SWUtilityButtons.m */; }; + B1D5EE4420BC06CB00983FB6 /* MActivityInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 13972E2E1CA6D5C600489EBA /* MActivityInfo.m */; }; + B1D5EE4520BC06CB00983FB6 /* UILongPressMenuImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8ECA8BB319FB42CC00C598C6 /* UILongPressMenuImageView.m */; }; + B1D5EE4620BC06CB00983FB6 /* FileChangesIntroduceCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E4D6A811B1C6D5F00FD2E49 /* FileChangesIntroduceCell.m */; }; + B1D5EE4720BC06CB00983FB6 /* Register.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CFED19E240C40076D59C /* Register.m */; }; + B1D5EE4820BC06CB00983FB6 /* ShopOrder.m in Sources */ = {isa = PBXBuildFile; fileRef = 926C043A1C019CD3004937D8 /* ShopOrder.m */; }; + B1D5EE4920BC06CB00983FB6 /* TopicAnswerCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6CBE4A1D8E71DC00644086 /* TopicAnswerCell.m */; }; + B1D5EE4A20BC06CB00983FB6 /* NSTimer+Common.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E969CCF1AF0EB87005C0CCE /* NSTimer+Common.m */; }; + B1D5EE4B20BC06CB00983FB6 /* CodingTipCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6436519FF7E2900F7EEB0 /* CodingTipCell.m */; }; + B1D5EE4C20BC06CB00983FB6 /* AboutPointViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B19D4EE81F6FAA6000C598F3 /* AboutPointViewController.m */; }; + B1D5EE4D20BC06CB00983FB6 /* ProjectTagsView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E6FB0571B58DB0A00B0A17B /* ProjectTagsView.m */; }; + B1D5EE4E20BC06CB00983FB6 /* Projects.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6CFE519E240C40076D59C /* Projects.m */; }; + B1D5EE4F20BC06CB00983FB6 /* UserInfoDetailUserCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E996BDE1ABA7CE100C704F1 /* UserInfoDetailUserCell.m */; }; + B1D5EE5020BC06CB00983FB6 /* ProjectActivities.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EACB4451A2C60110097ABB3 /* ProjectActivities.m */; }; + B1D5EE5120BC06CB00983FB6 /* LocalFileCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E715A341BB1279D00A5D24B /* LocalFileCell.m */; }; + B1D5EE5220BC06CB00983FB6 /* MRReviewerListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 1309B9F91CA2D3960034C7A3 /* MRReviewerListCell.m */; }; + B1D5EE5320BC06CB00983FB6 /* UITapImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EA6D00819E240C40076D59C /* UITapImageView.m */; }; + B1D5EE5420BC06CB00983FB6 /* NSURL+OTPURLArguments.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E8D5D491B45295D00B70936 /* NSURL+OTPURLArguments.m */; }; + B1D5EE5520BC06CB00983FB6 /* FileActivitiesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EAE06AA1B7B23EA00179F4B /* FileActivitiesViewController.m */; }; + B1D5EE5620BC06CB00983FB6 /* LocalFolderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E715A311BB1278200A5D24B /* LocalFolderCell.m */; }; + B1D5EE5720BC06CB00983FB6 /* SVWebViewControllerActivity.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E217F0B1A70EDC700F6DF88 /* SVWebViewControllerActivity.m */; }; + B1D5EE5820BC06CB00983FB6 /* TagsScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A058A01E0AAACA00C1CA3F /* TagsScrollView.m */; }; + B1D5EE5920BC06CB00983FB6 /* TaskDescriptionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E996BE71ABBCD2D00C704F1 /* TaskDescriptionCell.m */; }; + B1D5EE5B20BC06CB00983FB6 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B19D4EFD1F724CDC00C598F3 /* CoreMotion.framework */; }; + B1D5EE5C20BC06CB00983FB6 /* libresolv.9.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFF5A761E0AE54800683D03 /* libresolv.9.tbd */; }; + B1D5EE5D20BC06CB00983FB6 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EDBECEA1B709EB3003E87C3 /* AVFoundation.framework */; }; + B1D5EE5E20BC06CB00983FB6 /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A6E6BBC1AB180AE004C0107 /* MapKit.framework */; }; + B1D5EE5F20BC06CB00983FB6 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A6E6BBE1AB180CB004C0107 /* CoreLocation.framework */; }; + B1D5EE6020BC06CB00983FB6 /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EDD8F5B1A36F52700E9E232 /* libsqlite3.0.dylib */; }; + B1D5EE6120BC06CB00983FB6 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EDD8F591A36F4FA00E9E232 /* Security.framework */; }; + B1D5EE6220BC06CB00983FB6 /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EDD8F571A36F4CA00E9E232 /* CoreTelephony.framework */; }; + B1D5EE6320BC06CB00983FB6 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EDD8F551A36F4BD00E9E232 /* SystemConfiguration.framework */; }; + B1D5EE6420BC06CB00983FB6 /* AlipaySDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B19D4EFA1F7247BA00C598F3 /* AlipaySDK.framework */; }; + B1D5EE6520BC06CB00983FB6 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EDD8F531A36F4AC00E9E232 /* CFNetwork.framework */; }; + B1D5EE6620BC06CB00983FB6 /* QuickLook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E96E7C71A1B46740037C098 /* QuickLook.framework */; }; + B1D5EE6720BC06CB00983FB6 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E03D4A319F696970092F8C8 /* libz.dylib */; }; + B1D5EE6820BC06CB00983FB6 /* libicucore.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8EF5E74419C68CC7009346D5 /* libicucore.dylib */; }; + B1D5EE6920BC06CB00983FB6 /* libXG-SDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EDD8F4D1A36F42200E9E232 /* libXG-SDK.a */; }; + B1D5EE6A20BC06CB00983FB6 /* libopencore-amrnb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7EB02FE21B6D0F3E00D2166C /* libopencore-amrnb.a */; }; + B1D5EE6B20BC06CB00983FB6 /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E61D27A19C028CC00C00414 /* AssetsLibrary.framework */; }; + B1D5EE6C20BC06CB00983FB6 /* libxml2.2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8EBAA73E19B9695600829E2A /* libxml2.2.dylib */; }; + B1D5EE6D20BC06CB00983FB6 /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E9866C1198E416C00ABFFA0 /* CoreText.framework */; }; + B1D5EE6E20BC06CB00983FB6 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E477015198770E700997D05 /* CoreGraphics.framework */; }; + B1D5EE6F20BC06CB00983FB6 /* libopencore-amrwb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7EB02FE31B6D0F3E00D2166C /* libopencore-amrwb.a */; }; + B1D5EE7020BC06CB00983FB6 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E477019198770E700997D05 /* CoreData.framework */; }; + B1D5EE7120BC06CB00983FB6 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E477017198770E700997D05 /* UIKit.framework */; }; + B1D5EE7220BC06CB00983FB6 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E477013198770E700997D05 /* Foundation.framework */; }; + B1D5EE7320BC06CB00983FB6 /* WebP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EF818231B09D8D8005F974B /* WebP.framework */; }; + B1D5EE7420BC06CB00983FB6 /* libPods-Coding_iOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 645969FE6A8616A74543C249 /* libPods-Coding_iOS.a */; }; + B1D5EE7620BC06CB00983FB6 /* hot_topic_Nav@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E09DCA31C156387001C9392 /* hot_topic_Nav@2x.png */; }; + B1D5EE7720BC06CB00983FB6 /* keyboard_add@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE6B1A0B243B006F9AD7 /* keyboard_add@2x.png */; }; + B1D5EE7820BC06CB00983FB6 /* register_step_un@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EC4800F1C2A909D005F1772 /* register_step_un@2x.png */; }; + B1D5EE7920BC06CB00983FB6 /* task_activity_icon_restore@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383F61B33C18700D98648 /* task_activity_icon_restore@2x.png */; }; + B1D5EE7A20BC06CB00983FB6 /* tipIcon_tweetReward@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9F5D1F1C03051D007CCDCC /* tipIcon_tweetReward@2x.png */; }; + B1D5EE7B20BC06CB00983FB6 /* icon_file_folder_normal@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EA679181A14BFA0001A0324 /* icon_file_folder_normal@2x.png */; }; + B1D5EE7C20BC06CB00983FB6 /* taskboard_add_page_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED8A209453F2004A6E8A /* taskboard_add_page_selected@2x.png */; }; + B1D5EE7D20BC06CB00983FB6 /* time_clock_icon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8716F1EB1832B003DACF0 /* time_clock_icon@3x.png */; }; + B1D5EE7E20BC06CB00983FB6 /* task_activity_icon_add_watcher@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871931EB2D9E6003DACF0 /* task_activity_icon_add_watcher@3x.png */; }; + B1D5EE7F20BC06CB00983FB6 /* tipIcon_ProjectTopic@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CFB419E240C40076D59C /* tipIcon_ProjectTopic@2x.png */; }; + B1D5EE8020BC06CB00983FB6 /* SVWebViewControllerActivityReport@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ED673251A8E127100DF2D1A /* SVWebViewControllerActivityReport@2x.png */; }; + B1D5EE8120BC06CB00983FB6 /* wiki_menu_icon_share@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1890C272015D82600F52ABA /* wiki_menu_icon_share@2x.png */; }; + B1D5EE8220BC06CB00983FB6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF5B19E240C40076D59C /* InfoPlist.strings */; }; + B1D5EE8320BC06CB00983FB6 /* mrpr_icon_accepted@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383BE1B3265DC00D98648 /* mrpr_icon_accepted@2x.png */; }; + B1D5EE8420BC06CB00983FB6 /* mrpr_icon_status_refused@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD01F1E540551008AA957 /* mrpr_icon_status_refused@2x.png */; }; + B1D5EE8520BC06CB00983FB6 /* privatemessage_normal@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447D41C02DB8900DC1C4B /* privatemessage_normal@3x.png */; }; + B1D5EE8620BC06CB00983FB6 /* btn_project_added@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E8F7B2A19EF6306006BA8BD /* btn_project_added@2x.png */; }; + B1D5EE8720BC06CB00983FB6 /* nav_tweet_all@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF8119E240C40076D59C /* nav_tweet_all@2x.png */; }; + B1D5EE8820BC06CB00983FB6 /* button_file_createFolder_unable@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EACB43C1A2C448F0097ABB3 /* button_file_createFolder_unable@2x.png */; }; + B1D5EE8920BC06CB00983FB6 /* button_file_denete_unable@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5CAC202D7D4F0075A669 /* button_file_denete_unable@3x.png */; }; + B1D5EE8A20BC06CB00983FB6 /* file_activity_icon_upload_file@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871B11EB2D9F0003DACF0 /* file_activity_icon_upload_file@3x.png */; }; + B1D5EE8B20BC06CB00983FB6 /* QBImagePicker.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B12B64691FFB61AD00ACFDCC /* QBImagePicker.storyboard */; }; + B1D5EE8C20BC06CB00983FB6 /* taskProject@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EED9DCB1B539366000E5827 /* taskProject@2x.png */; }; + B1D5EE8E20BC06CB00983FB6 /* button_file_upload_enable@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5CA9202D7D4E0075A669 /* button_file_upload_enable@3x.png */; }; + B1D5EE8F20BC06CB00983FB6 /* tag_button_randomColor@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F1C1C76BA3B00B5EBEA /* tag_button_randomColor@3x.png */; }; + B1D5EE9020BC06CB00983FB6 /* user_info_help@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ED4B47A1D82646000EED8C6 /* user_info_help@3x.png */; }; + B1D5EE9120BC06CB00983FB6 /* messageComment@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383B21B32640900D98648 /* messageComment@2x.png */; }; + B1D5EE9220BC06CB00983FB6 /* upgrade_success@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B12B64241FF33E0000ACFDCC /* upgrade_success@3x.png */; }; + B1D5EE9320BC06CB00983FB6 /* tweet_comment_btn@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CFBE19E240C40076D59C /* tweet_comment_btn@2x.png */; }; + B1D5EE9420BC06CB00983FB6 /* fliter_square@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D09E6ACD1BF9CCCF009D37F8 /* fliter_square@2x.png */; }; + B1D5EE9520BC06CB00983FB6 /* PR_create@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1319D1071CA7FE6E00729F82 /* PR_create@2x.png */; }; + B1D5EE9620BC06CB00983FB6 /* user_info_tweet@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ED4B4841D82646000EED8C6 /* user_info_tweet@3x.png */; }; + B1D5EE9720BC06CB00983FB6 /* taskPriority2_small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383A01B3262D300D98648 /* taskPriority2_small@2x.png */; }; + B1D5EE9820BC06CB00983FB6 /* pop_2FA@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447C61C02DB6700DC1C4B /* pop_2FA@3x.png */; }; + B1D5EE9920BC06CB00983FB6 /* code_release_resource_Zip@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC31720731FF10077C956 /* code_release_resource_Zip@2x.png */; }; + B1D5EE9A20BC06CB00983FB6 /* topic_add_watcher_btn@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E59D3301D409C8C008C914B /* topic_add_watcher_btn@2x.png */; }; + B1D5EE9B20BC06CB00983FB6 /* bubble_right_play_1@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E8E597D1B6F91C40083CA02 /* bubble_right_play_1@2x.png */; }; + B1D5EE9C20BC06CB00983FB6 /* search_tweet_colck@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8B35164C1B6CE9460049BC45 /* search_tweet_colck@2x.png */; }; + B1D5EE9D20BC06CB00983FB6 /* keyboard_page_unselected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE601A0A3424006F9AD7 /* keyboard_page_unselected@2x.png */; }; + B1D5EE9E20BC06CB00983FB6 /* blankpage_image_Project@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423CA1E69401B0095F1CD /* blankpage_image_Project@2x.png */; }; + B1D5EEA020BC06CB00983FB6 /* PR_more@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 134116EE1CB529E1005E6550 /* PR_more@2x.png */; }; + B1D5EEA120BC06CB00983FB6 /* user_info_edit@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E54C24A1D8FE19100A61023 /* user_info_edit@3x.png */; }; + B1D5EEA220BC06CB00983FB6 /* file_changeType_MODIFY@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CEC200EFDC600DEDF78 /* file_changeType_MODIFY@3x.png */; }; + B1D5EEA320BC06CB00983FB6 /* icon_file_apk@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E96E7CB1A1B537E0037C098 /* icon_file_apk@2x.png */; }; + B1D5EEA420BC06CB00983FB6 /* n_btn_followed_both@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E996BFA1ABBF56A00C704F1 /* n_btn_followed_both@2x.png */; }; + B1D5EEA520BC06CB00983FB6 /* messageSystem@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383B51B32640900D98648 /* messageSystem@2x.png */; }; + B1D5EEA620BC06CB00983FB6 /* PR_del_watcher@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CF6200EFEA400DEDF78 /* PR_del_watcher@2x.png */; }; + B1D5EEA720BC06CB00983FB6 /* taskWatchers@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ED618231C3CB1AF0017946C /* taskWatchers@3x.png */; }; + B1D5EEA820BC06CB00983FB6 /* mrpr_icon_status_canmerge@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD01C1E540551008AA957 /* mrpr_icon_status_canmerge@3x.png */; }; + B1D5EEA920BC06CB00983FB6 /* topic_comment_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E095A821B6B24DE008DC439 /* topic_comment_icon@2x.png */; }; + B1D5EEAA20BC06CB00983FB6 /* project_item_activity@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8712C1EADF155003DACF0 /* project_item_activity@3x.png */; }; + B1D5EEAB20BC06CB00983FB6 /* member_type_75@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2F6A691C43CA4B00A25502 /* member_type_75@3x.png */; }; + B1D5EEAC20BC06CB00983FB6 /* bubble_right_play_2@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E8E597E1B6F91C40083CA02 /* bubble_right_play_2@2x.png */; }; + B1D5EEAD20BC06CB00983FB6 /* share_btn_coding@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2BF3C71B96CDF800A5A0A8 /* share_btn_coding@2x.png */; }; + B1D5EEAE20BC06CB00983FB6 /* commentOrLikeBeginImg@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF6319E240C40076D59C /* commentOrLikeBeginImg@2x.png */; }; + B1D5EEAF20BC06CB00983FB6 /* task_resource_reference_ProjectFile@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F571C7C5C4F00B5EBEA /* task_resource_reference_ProjectFile@3x.png */; }; + B1D5EEB020BC06CB00983FB6 /* PR_mergeChanges@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D271CA17A6400EE127C /* PR_mergeChanges@3x.png */; }; + B1D5EEB120BC06CB00983FB6 /* user_info_shop@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B19D4EF41F7210C300C598F3 /* user_info_shop@2x.png */; }; + B1D5EEB220BC06CB00983FB6 /* ReviewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 134E1B991CA41217002A3E0D /* ReviewCell.xib */; }; + B1D5EEB320BC06CB00983FB6 /* login_suffix@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF7319E240C40076D59C /* login_suffix@2x.png */; }; + B1D5EEB420BC06CB00983FB6 /* password_look@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F0C1C74691B00B5EBEA /* password_look@3x.png */; }; + B1D5EEB520BC06CB00983FB6 /* emotion_list.plist in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE711A0B8C6C006F9AD7 /* emotion_list.plist */; }; + B1D5EEB620BC06CB00983FB6 /* wiki_menu_1@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1890C252015D82600F52ABA /* wiki_menu_1@3x.png */; }; + B1D5EEB720BC06CB00983FB6 /* file_changeType_ADD@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EC461AF1B39360F00D08970 /* file_changeType_ADD@2x.png */; }; + B1D5EEB820BC06CB00983FB6 /* icon_best_answer@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6CBE521D8EA9D100644086 /* icon_best_answer@2x.png */; }; + B1D5EEB920BC06CB00983FB6 /* git_icon_watched@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E4D6ACA1B2571B100FD2E49 /* git_icon_watched@2x.png */; }; + B1D5EEBA20BC06CB00983FB6 /* coding_emoji_26@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE8D1A0C7E26006F9AD7 /* coding_emoji_26@2x.png */; }; + B1D5EEBB20BC06CB00983FB6 /* coding_emoji_35@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE961A0C7E26006F9AD7 /* coding_emoji_35@2x.png */; }; + B1D5EEBC20BC06CB00983FB6 /* task_activity_icon_update_description@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8719C1EB2D9E6003DACF0 /* task_activity_icon_update_description@3x.png */; }; + B1D5EEBD20BC06CB00983FB6 /* vip_4_40@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689AF1EE100B200B01371 /* vip_4_40@3x.png */; }; + B1D5EEBE20BC06CB00983FB6 /* keyboard_keyboard@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE5E1A0A3424006F9AD7 /* keyboard_keyboard@2x.png */; }; + B1D5EEBF20BC06CB00983FB6 /* icon_release_tag@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1817EFF2069197C00E9BAD1 /* icon_release_tag@2x.png */; }; + B1D5EEC020BC06CB00983FB6 /* placeholder_monkey_round_48@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF9119E240C40076D59C /* placeholder_monkey_round_48@2x.png */; }; + B1D5EEC120BC06CB00983FB6 /* PR_plus@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD0A31E5D8D90008AA957 /* PR_plus@2x.png */; }; + B1D5EEC220BC06CB00983FB6 /* xtsegment_bordor_left@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CFC319E240C40076D59C /* xtsegment_bordor_left@2x.png */; }; + B1D5EEC320BC06CB00983FB6 /* task_resource_reference_MergeRequestBean@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F541C7C5C4F00B5EBEA /* task_resource_reference_MergeRequestBean@2x.png */; }; + B1D5EEC420BC06CB00983FB6 /* icon_file_folder_out@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E1D99121DCAE67D00BAE585 /* icon_file_folder_out@2x.png */; }; + B1D5EEC520BC06CB00983FB6 /* messageProjectFollows@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6CBE571D8FBDF500644086 /* messageProjectFollows@2x.png */; }; + B1D5EEC620BC06CB00983FB6 /* tweet_btn_comment@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E5D12FF1C0ECB3400985AEB /* tweet_btn_comment@2x.png */; }; + B1D5EEC720BC06CB00983FB6 /* blankpage_image_ShopOrder@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423CD1E69401B0095F1CD /* blankpage_image_ShopOrder@3x.png */; }; + B1D5EEC820BC06CB00983FB6 /* banner__page_unselected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E095A6C1B69F920008DC439 /* banner__page_unselected@2x.png */; }; + B1D5EEC920BC06CB00983FB6 /* mrpr_icon_status_accepted@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD0191E540551008AA957 /* mrpr_icon_status_accepted@2x.png */; }; + B1D5EECA20BC06CB00983FB6 /* icon_file_ai@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E96E7CA1A1B537E0037C098 /* icon_file_ai@2x.png */; }; + B1D5EECB20BC06CB00983FB6 /* PR_plus@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD0A41E5D8D90008AA957 /* PR_plus@3x.png */; }; + B1D5EECC20BC06CB00983FB6 /* user_info_tweet@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ED4B4831D82646000EED8C6 /* user_info_tweet@2x.png */; }; + B1D5EECD20BC06CB00983FB6 /* coding_emoji_21@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE881A0C7E26006F9AD7 /* coding_emoji_21@2x.png */; }; + B1D5EECE20BC06CB00983FB6 /* bubble_left_play_2@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E8E597B1B6F91C40083CA02 /* bubble_left_play_2@2x.png */; }; + B1D5EECF20BC06CB00983FB6 /* task_resource_reference_Task@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F5B1C7C5C4F00B5EBEA /* task_resource_reference_Task@3x.png */; }; + B1D5EED020BC06CB00983FB6 /* PR_add_watcher@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CF4200EFEA400DEDF78 /* PR_add_watcher@2x.png */; }; + B1D5EED120BC06CB00983FB6 /* file_menu_icon_delete@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E93F2351B84356500017916 /* file_menu_icon_delete@2x.png */; }; + B1D5EED220BC06CB00983FB6 /* button_red_close@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B12B64201FF33DFE00ACFDCC /* button_red_close@3x.png */; }; + B1D5EED320BC06CB00983FB6 /* PR_merge@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1319D10A1CA81FE100729F82 /* PR_merge@3x.png */; }; + B1D5EED420BC06CB00983FB6 /* coding_emoji_25@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE8C1A0C7E26006F9AD7 /* coding_emoji_25@2x.png */; }; + B1D5EED520BC06CB00983FB6 /* keyboard_arrow_down@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E335D9A1B6F5E94003D0F3D /* keyboard_arrow_down@2x.png */; }; + B1D5EED620BC06CB00983FB6 /* taskResourceReference@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F3A1C7C45E700B5EBEA /* taskResourceReference@3x.png */; }; + B1D5EED720BC06CB00983FB6 /* tag_button_add@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F171C76BA3B00B5EBEA /* tag_button_add@2x.png */; }; + B1D5EED820BC06CB00983FB6 /* tweetsBtn_Nav@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E59D32A1D3E106D008C914B /* tweetsBtn_Nav@3x.png */; }; + B1D5EED920BC06CB00983FB6 /* icon_branch_protected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1817EFB206918D200E9BAD1 /* icon_branch_protected@2x.png */; }; + B1D5EEDA20BC06CB00983FB6 /* taskboard_normal_page_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED88209453F2004A6E8A /* taskboard_normal_page_selected@2x.png */; }; + B1D5EEDB20BC06CB00983FB6 /* user_info_about@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ED4B4751D82646000EED8C6 /* user_info_about@2x.png */; }; + B1D5EEDC20BC06CB00983FB6 /* icon_branch_protected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1817EFA206918D100E9BAD1 /* icon_branch_protected@3x.png */; }; + B1D5EEDE20BC06CB00983FB6 /* task_activity_icon_create@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6384021B33C8E900D98648 /* task_activity_icon_create@2x.png */; }; + B1D5EEDF20BC06CB00983FB6 /* button_file_download_unable@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EACB43D1A2C448F0097ABB3 /* button_file_download_unable@2x.png */; }; + B1D5EEE020BC06CB00983FB6 /* btn_setFrequent@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D09E6ABF1BF82DC6009D37F8 /* btn_setFrequent@2x.png */; }; + B1D5EEE120BC06CB00983FB6 /* task_activity_icon_remove_watcher@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871991EB2D9E6003DACF0 /* task_activity_icon_remove_watcher@3x.png */; }; + B1D5EEE220BC06CB00983FB6 /* markdown.html in Resources */ = {isa = PBXBuildFile; fileRef = B177F5C22060E6B1006709C2 /* markdown.html */; }; + B1D5EEE320BC06CB00983FB6 /* code_release_resource_ProjectTopic@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC3262073212D0077C956 /* code_release_resource_ProjectTopic@3x.png */; }; + B1D5EEE420BC06CB00983FB6 /* diff-ios.html in Resources */ = {isa = PBXBuildFile; fileRef = 4ECEF9F61D1BB7FB002A27D3 /* diff-ios.html */; }; + B1D5EEE520BC06CB00983FB6 /* little_phone_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAC8B691BA01F190060B0FC /* little_phone_icon@2x.png */; }; + B1D5EEE620BC06CB00983FB6 /* share_btn_sina@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2BF3CC1B96CDF800A5A0A8 /* share_btn_sina@2x.png */; }; + B1D5EEE820BC06CB00983FB6 /* icon_file_pdf@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E96E7D21A1B537E0037C098 /* icon_file_pdf@2x.png */; }; + B1D5EEE920BC06CB00983FB6 /* tipIcon_TweetComment@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E4972DB1BB52A8300F3AC15 /* tipIcon_TweetComment@2x.png */; }; + B1D5EEEA20BC06CB00983FB6 /* blankpage_image_LoadFail@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423C51E69401B0095F1CD /* blankpage_image_LoadFail@3x.png */; }; + B1D5EEEB20BC06CB00983FB6 /* taskboard_add_page_unselected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED89209453F2004A6E8A /* taskboard_add_page_unselected@2x.png */; }; + B1D5EEEC20BC06CB00983FB6 /* PR_grant_undo@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D221CA17A6400EE127C /* PR_grant_undo@2x.png */; }; + B1D5EEED20BC06CB00983FB6 /* back_green_Nav@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8711E1EADF0FF003DACF0 /* back_green_Nav@2x.png */; }; + B1D5EEEE20BC06CB00983FB6 /* file_changeType_COPY@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EFE8DAA1B394A0D004B7559 /* file_changeType_COPY@2x.png */; }; + B1D5EEEF20BC06CB00983FB6 /* shop_exchange_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 927AFF481BFF6DAD00AAE593 /* shop_exchange_icon@2x.png */; }; + B1D5EEF020BC06CB00983FB6 /* timeBtn_Nav@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C448061C02DCAC00DC1C4B /* timeBtn_Nav@3x.png */; }; + B1D5EEF120BC06CB00983FB6 /* close@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D171CA17A6400EE127C /* close@2x.png */; }; + B1D5EEF220BC06CB00983FB6 /* PR_update_content@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D1C1CA17A6400EE127C /* PR_update_content@3x.png */; }; + B1D5EEF320BC06CB00983FB6 /* user_info_detail@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E996BFF1ABBF56A00C704F1 /* user_info_detail@2x.png */; }; + B1D5EEF420BC06CB00983FB6 /* vip_4_45@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689B01EE100B200B01371 /* vip_4_45@2x.png */; }; + B1D5EEF520BC06CB00983FB6 /* icon_recommended@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E8C51AF1AC1081500B4C51F /* icon_recommended@2x.png */; }; + B1D5EEF620BC06CB00983FB6 /* icon_file_doc@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E96E7CC1A1B537E0037C098 /* icon_file_doc@2x.png */; }; + B1D5EEF720BC06CB00983FB6 /* hot_topic_Nav@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E09DCA41C156387001C9392 /* hot_topic_Nav@3x.png */; }; + B1D5EEF820BC06CB00983FB6 /* EACodeReleaseListCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B1817EF02068F4B400E9BAD1 /* EACodeReleaseListCell.xib */; }; + B1D5EEF920BC06CB00983FB6 /* user_info_setup@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ED4B4801D82646000EED8C6 /* user_info_setup@3x.png */; }; + B1D5EEFA20BC06CB00983FB6 /* tipIcon_ProjectTweet@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E4972DD1BB535B400F3AC15 /* tipIcon_ProjectTweet@2x.png */; }; + B1D5EEFB20BC06CB00983FB6 /* share_Nav@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E09DCA71C15662E001C9392 /* share_Nav@2x.png */; }; + B1D5EEFC20BC06CB00983FB6 /* tipIcon_User@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E62ADD919E28DA800963870 /* tipIcon_User@2x.png */; }; + B1D5EEFD20BC06CB00983FB6 /* taskPriority0_small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E63839C1B3262D300D98648 /* taskPriority0_small@2x.png */; }; + B1D5EEFE20BC06CB00983FB6 /* file_changeType_COPY@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CEA200EFDC600DEDF78 /* file_changeType_COPY@3x.png */; }; + B1D5EEFF20BC06CB00983FB6 /* btn_project_quit@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E8F7B2B19EF6306006BA8BD /* btn_project_quit@2x.png */; }; + B1D5EF0020BC06CB00983FB6 /* member_type_100@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2F6A661C43CA4B00A25502 /* member_type_100@2x.png */; }; + B1D5EF0120BC06CB00983FB6 /* dismissBtn_Nav@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ED558311B4FA68400FC10CB /* dismissBtn_Nav@2x.png */; }; + B1D5EF0220BC06CB00983FB6 /* coding_emoji_38@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E08497A1A918A7F00BD27F6 /* coding_emoji_38@2x.png */; }; + B1D5EF0320BC06CB00983FB6 /* keyboard_emotion_emoji@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE5C1A0A3424006F9AD7 /* keyboard_emotion_emoji@2x.png */; }; + B1D5EF0420BC06CB00983FB6 /* taskOwner@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EED9DCA1B539366000E5827 /* taskOwner@2x.png */; }; + B1D5EF0520BC06CB00983FB6 /* task_activity_icon_commit_refer@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EC461B51B3939DC00D08970 /* task_activity_icon_commit_refer@2x.png */; }; + B1D5EF0620BC06CB00983FB6 /* project_item_file@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8712E1EADF155003DACF0 /* project_item_file@3x.png */; }; + B1D5EF0720BC06CB00983FB6 /* btn_followed_yes@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E8F7B2419EF6306006BA8BD /* btn_followed_yes@2x.png */; }; + B1D5EF0820BC06CB00983FB6 /* btn_project_add@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E8F7B2919EF6306006BA8BD /* btn_project_add@2x.png */; }; + B1D5EF0920BC06CB00983FB6 /* project_item_activity@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383C91B32665700D98648 /* project_item_activity@2x.png */; }; + B1D5EF0A20BC06CB00983FB6 /* tips_menu_icon_status@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E4972E71BB5446900F3AC15 /* tips_menu_icon_status@2x.png */; }; + B1D5EF0B20BC06CB00983FB6 /* task_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447A01C02A3C700DC1C4B /* task_selected@2x.png */; }; + B1D5EF0C20BC06CB00983FB6 /* project_item_code@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8712D1EADF155003DACF0 /* project_item_code@3x.png */; }; + B1D5EF0D20BC06CB00983FB6 /* terminal_tail@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5C90202953E40075A669 /* terminal_tail@2x.png */; }; + B1D5EF0E20BC06CB00983FB6 /* PR_add_reviewer@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CF8200EFEA400DEDF78 /* PR_add_reviewer@2x.png */; }; + B1D5EF0F20BC06CB00983FB6 /* PR_push@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D1A1CA17A6400EE127C /* PR_push@3x.png */; }; + B1D5EF1020BC06CB00983FB6 /* shop_coding_coin_icon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 927AFF471BFF6DAD00AAE593 /* shop_coding_coin_icon@3x.png */; }; + B1D5EF1220BC06CB00983FB6 /* project_tag_icon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871B91EB338FD003DACF0 /* project_tag_icon@3x.png */; }; + B1D5EF1320BC06CB00983FB6 /* code_lang.plist in Resources */ = {isa = PBXBuildFile; fileRef = B1944153206CBE8C00147158 /* code_lang.plist */; }; + B1D5EF1420BC06CB00983FB6 /* logo_coding@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B10341272024633800853447 /* logo_coding@2x.png */; }; + B1D5EF1520BC06CB00983FB6 /* user_info_project@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ED4B47D1D82646000EED8C6 /* user_info_project@2x.png */; }; + B1D5EF1620BC06CB00983FB6 /* button_file_createFolder_unable@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5CB0202D7D500075A669 /* button_file_createFolder_unable@3x.png */; }; + B1D5EF1720BC06CB00983FB6 /* icon_project_cell_setNormal@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D09E6ABB1BF829F2009D37F8 /* icon_project_cell_setNormal@2x.png */; }; + B1D5EF1820BC06CB00983FB6 /* search_Nav@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C448041C02DCAC00DC1C4B /* search_Nav@3x.png */; }; + B1D5EF1920BC06CB00983FB6 /* keyboard_emotion_monkey@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE5D1A0A3424006F9AD7 /* keyboard_emotion_monkey@2x.png */; }; + B1D5EF1A20BC06CB00983FB6 /* icon_file_ppt_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB87C1FCD006C0098B87B /* icon_file_ppt_big@2x.png */; }; + B1D5EF1B20BC06CB00983FB6 /* calendar_0xA1CF64@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871751EB18599003DACF0 /* calendar_0xA1CF64@2x.png */; }; + B1D5EF1C20BC06CB00983FB6 /* blankpage_image_File@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423C31E69401B0095F1CD /* blankpage_image_File@3x.png */; }; + B1D5EF1D20BC06CB00983FB6 /* SVWebViewControllerActivityChrome-iPad.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E217EFF1A70EDC700F6DF88 /* SVWebViewControllerActivityChrome-iPad.png */; }; + B1D5EF1E20BC06CB00983FB6 /* settingBtn_Nav@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871231EADF0FF003DACF0 /* settingBtn_Nav@3x.png */; }; + B1D5EF1F20BC06CB00983FB6 /* PR_del_watcher@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CF9200EFEA400DEDF78 /* PR_del_watcher@3x.png */; }; + B1D5EF2020BC06CB00983FB6 /* tweet_btn_comment@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E5D13001C0ECB3400985AEB /* tweet_btn_comment@3x.png */; }; + B1D5EF2120BC06CB00983FB6 /* task_activity_icon_update_deadline@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8719B1EB2D9E6003DACF0 /* task_activity_icon_update_deadline@3x.png */; }; + B1D5EF2220BC06CB00983FB6 /* close@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D181CA17A6400EE127C /* close@3x.png */; }; + B1D5EF2320BC06CB00983FB6 /* coding_emoji_14@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE811A0C7E26006F9AD7 /* coding_emoji_14@2x.png */; }; + B1D5EF2420BC06CB00983FB6 /* taskboard_normal_page_unselected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED8E209453F2004A6E8A /* taskboard_normal_page_unselected@2x.png */; }; + B1D5EF2520BC06CB00983FB6 /* loading_monkey@2x.gif in Resources */ = {isa = PBXBuildFile; fileRef = B1C871121EADAEE1003DACF0 /* loading_monkey@2x.gif */; }; + B1D5EF2620BC06CB00983FB6 /* search_icon_topic@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9411E02911E00DE1BC6 /* search_icon_topic@3x.png */; }; + B1D5EF2720BC06CB00983FB6 /* pop_User@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447CB1C02DB6700DC1C4B /* pop_User@3x.png */; }; + B1D5EF2820BC06CB00983FB6 /* taskPriority2_small@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8715F1EB182C7003DACF0 /* taskPriority2_small@3x.png */; }; + B1D5EF2920BC06CB00983FB6 /* project_tag_btn@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871B81EB338FD003DACF0 /* project_tag_btn@3x.png */; }; + B1D5EF2A20BC06CB00983FB6 /* task_resource_reference_Task@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F5A1C7C5C4F00B5EBEA /* task_resource_reference_Task@2x.png */; }; + B1D5EF2B20BC06CB00983FB6 /* tips_menu_icon_mkread@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E4972E61BB5446900F3AC15 /* tips_menu_icon_mkread@2x.png */; }; + B1D5EF2C20BC06CB00983FB6 /* coding_emoji_15@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE821A0C7E26006F9AD7 /* coding_emoji_15@2x.png */; }; + B1D5EF2D20BC06CB00983FB6 /* shortcut_task@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9291DFFF06E00DE1BC6 /* shortcut_task@2x.png */; }; + B1D5EF2E20BC06CB00983FB6 /* terminal_triangle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5C98202953E40075A669 /* terminal_triangle@2x.png */; }; + B1D5EF2F20BC06CB00983FB6 /* topic_comment_icon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8716E1EB1832B003DACF0 /* topic_comment_icon@3x.png */; }; + B1D5EF3020BC06CB00983FB6 /* placeholder_monkey_round_40@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF9019E240C40076D59C /* placeholder_monkey_round_40@2x.png */; }; + B1D5EF3120BC06CB00983FB6 /* PR_merge@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1319D1091CA81FE100729F82 /* PR_merge@2x.png */; }; + B1D5EF3220BC06CB00983FB6 /* tweet_btn_like@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E5D13011C0ECB3400985AEB /* tweet_btn_like@2x.png */; }; + B1D5EF3320BC06CB00983FB6 /* PR_update@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 134116F61CB55E69005E6550 /* PR_update@2x.png */; }; + B1D5EF3420BC06CB00983FB6 /* login_email@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF7119E240C40076D59C /* login_email@2x.png */; }; + B1D5EF3520BC06CB00983FB6 /* tweetBtn_Nav@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C448071C02DCAC00DC1C4B /* tweetBtn_Nav@3x.png */; }; + B1D5EF3620BC06CB00983FB6 /* mrpr_icon_status_refused@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD0201E540551008AA957 /* mrpr_icon_status_refused@3x.png */; }; + B1D5EF3720BC06CB00983FB6 /* login_wechat@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B12B640C1FECB58F00ACFDCC /* login_wechat@3x.png */; }; + B1D5EF3820BC06CB00983FB6 /* ReleaseNotes.txt in Resources */ = {isa = PBXBuildFile; fileRef = 4EDD8F4E1A36F42200E9E232 /* ReleaseNotes.txt */; }; + B1D5EF3920BC06CB00983FB6 /* PR_update_content@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D1B1CA17A6400EE127C /* PR_update_content@2x.png */; }; + B1D5EF3A20BC06CB00983FB6 /* ReviewerListController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13972E281CA6157C00489EBA /* ReviewerListController.xib */; }; + B1D5EF3B20BC06CB00983FB6 /* file_activity_icon_create@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871AD1EB2D9F0003DACF0 /* file_activity_icon_create@3x.png */; }; + B1D5EF3C20BC06CB00983FB6 /* tipIcon_MergeRequestComment@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CFB119E240C40076D59C /* tipIcon_MergeRequestComment@2x.png */; }; + B1D5EF3D20BC06CB00983FB6 /* private_message_send_fail@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383B61B32640900D98648 /* private_message_send_fail@2x.png */; }; + B1D5EF3E20BC06CB00983FB6 /* terminal_box_unselected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5C91202953E40075A669 /* terminal_box_unselected@2x.png */; }; + B1D5EF3F20BC06CB00983FB6 /* keyboard_at@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE591A0A3424006F9AD7 /* keyboard_at@2x.png */; }; + B1D5EF4020BC06CB00983FB6 /* coding_emoji_13@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE801A0C7E26006F9AD7 /* coding_emoji_13@2x.png */; }; + B1D5EF4120BC06CB00983FB6 /* blankpage_image_Wiki@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423D81E69401B0095F1CD /* blankpage_image_Wiki@2x.png */; }; + B1D5EF4220BC06CB00983FB6 /* PR_update_title@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 133DAA621CC13A30004D8501 /* PR_update_title@2x.png */; }; + B1D5EF4320BC06CB00983FB6 /* project_item_task@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383CF1B32665700D98648 /* project_item_task@2x.png */; }; + B1D5EF4420BC06CB00983FB6 /* icon_file_apk_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8771FCD006B0098B87B /* icon_file_apk_big@2x.png */; }; + B1D5EF4520BC06CB00983FB6 /* file_menu_icon_share@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E93F2391B84356500017916 /* file_menu_icon_share@2x.png */; }; + B1D5EF4620BC06CB00983FB6 /* btn_delete_tweetimage@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF5F19E240C40076D59C /* btn_delete_tweetimage@2x.png */; }; + B1D5EF4720BC06CB00983FB6 /* task_activity_icon_commit_refer@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871941EB2D9E6003DACF0 /* task_activity_icon_commit_refer@3x.png */; }; + B1D5EF4820BC06CB00983FB6 /* icon_code_executable@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD04A1E542B2D008AA957 /* icon_code_executable@3x.png */; }; + B1D5EF4920BC06CB00983FB6 /* calendar_0x59A2FF@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871741EB18599003DACF0 /* calendar_0x59A2FF@3x.png */; }; + B1D5EF4A20BC06CB00983FB6 /* task_activity_icon_create@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871951EB2D9E6003DACF0 /* task_activity_icon_create@3x.png */; }; + B1D5EF4B20BC06CB00983FB6 /* icon_file_cell_move@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EC5AD901A258DF8006FA97C /* icon_file_cell_move@2x.png */; }; + B1D5EF4C20BC06CB00983FB6 /* mrpr_icon_status_cannotmerge@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD01E1E540551008AA957 /* mrpr_icon_status_cannotmerge@3x.png */; }; + B1D5EF4D20BC06CB00983FB6 /* member_cell_edit_alias@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAECBBD1C44CB860096CA74 /* member_cell_edit_alias@3x.png */; }; + B1D5EF4E20BC06CB00983FB6 /* icon_file_cell_rename@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EC5AD911A258DF8006FA97C /* icon_file_cell_rename@2x.png */; }; + B1D5EF4F20BC06CB00983FB6 /* PR_grant@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D351CA17A6400EE127C /* PR_grant@3x.png */; }; + B1D5EF5020BC06CB00983FB6 /* coding_emoji_03@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE761A0C7E26006F9AD7 /* coding_emoji_03@2x.png */; }; + B1D5EF5120BC06CB00983FB6 /* cell_checkmark@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871881EB1E608003DACF0 /* cell_checkmark@3x.png */; }; + B1D5EF5220BC06CB00983FB6 /* taskWatchers@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ED618221C3CB1AF0017946C /* taskWatchers@2x.png */; }; + B1D5EF5320BC06CB00983FB6 /* icon_file_psd@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E96E7D41A1B537E0037C098 /* icon_file_psd@2x.png */; }; + B1D5EF5420BC06CB00983FB6 /* sex_man_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF9819E240C40076D59C /* sex_man_icon@2x.png */; }; + B1D5EF5520BC06CB00983FB6 /* file_changeType_DELETE@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EC461B01B39360F00D08970 /* file_changeType_DELETE@2x.png */; }; + B1D5EF5620BC06CB00983FB6 /* button_file_move_unable@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5CAF202D7D4F0075A669 /* button_file_move_unable@3x.png */; }; + B1D5EF5720BC06CB00983FB6 /* button_file_history@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5CAA202D7D4E0075A669 /* button_file_history@3x.png */; }; + B1D5EF5820BC06CB00983FB6 /* shortcut_2FA@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9271DFFF06E00DE1BC6 /* shortcut_2FA@2x.png */; }; + B1D5EF5920BC06CB00983FB6 /* button_file_download_enable@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5CA8202D7D4E0075A669 /* button_file_download_enable@3x.png */; }; + B1D5EF5A20BC06CB00983FB6 /* icon_file_ai_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB87B1FCD006C0098B87B /* icon_file_ai_big@2x.png */; }; + B1D5EF5B20BC06CB00983FB6 /* tipIcon_ProjectPayment@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EBDC27A1BC501C00037EB66 /* tipIcon_ProjectPayment@2x.png */; }; + B1D5EF5C20BC06CB00983FB6 /* MIDAUTUMNIMAGE.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 4E6B07151BA4045E007D6027 /* MIDAUTUMNIMAGE.jpg */; }; + B1D5EF5D20BC06CB00983FB6 /* calendar_0xA9B3BE@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871771EB18599003DACF0 /* calendar_0xA9B3BE@2x.png */; }; + B1D5EF5E20BC06CB00983FB6 /* project_item_topic@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871551EAE003A003DACF0 /* project_item_topic@3x.png */; }; + B1D5EF5F20BC06CB00983FB6 /* service_terms.html in Resources */ = {isa = PBXBuildFile; fileRef = 4EE083DB1ADB736800CA342E /* service_terms.html */; }; + B1D5EF6020BC06CB00983FB6 /* task_activity_icon_update_priority@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383FA1B33C18700D98648 /* task_activity_icon_update_priority@2x.png */; }; + B1D5EF6120BC06CB00983FB6 /* icon_search_searchbar@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C448131C02F76600DC1C4B /* icon_search_searchbar@3x.png */; }; + B1D5EF6220BC06CB00983FB6 /* keyboard_voice@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E335D9C1B6F5E94003D0F3D /* keyboard_voice@2x.png */; }; + B1D5EF6320BC06CB00983FB6 /* search_icon_project@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E94B1E02911E00DE1BC6 /* search_icon_project@3x.png */; }; + B1D5EF6420BC06CB00983FB6 /* button_close@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E5D13171C0EF48200985AEB /* button_close@3x.png */; }; + B1D5EF6520BC06CB00983FB6 /* btn_followed_not@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E8F7B2319EF6306006BA8BD /* btn_followed_not@2x.png */; }; + B1D5EF6720BC06CB00983FB6 /* mrpr_icon_fileChange@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383DA1B3266C200D98648 /* mrpr_icon_fileChange@2x.png */; }; + B1D5EF6820BC06CB00983FB6 /* task_activity_icon_finish@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383F41B33C18700D98648 /* task_activity_icon_finish@2x.png */; }; + B1D5EF6920BC06CB00983FB6 /* vip_4_40@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689AE1EE100B200B01371 /* vip_4_40@2x.png */; }; + B1D5EF6A20BC06CB00983FB6 /* taskDeadline@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8713E1EADF1C1003DACF0 /* taskDeadline@3x.png */; }; + B1D5EF6B20BC06CB00983FB6 /* button_arrow_left@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ED6181E1C3A732F0017946C /* button_arrow_left@2x.png */; }; + B1D5EF6C20BC06CB00983FB6 /* taskProgress@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383DF1B32676600D98648 /* taskProgress@2x.png */; }; + B1D5EF6D20BC06CB00983FB6 /* tweetBtn_Nav@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447F31C02DCA200DC1C4B /* tweetBtn_Nav@2x.png */; }; + B1D5EF6E20BC06CB00983FB6 /* bubble_left_play_1@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E8E597A1B6F91C40083CA02 /* bubble_left_play_1@2x.png */; }; + B1D5EF6F20BC06CB00983FB6 /* placeholder_monkey_round_54@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF9319E240C40076D59C /* placeholder_monkey_round_54@2x.png */; }; + B1D5EF7020BC06CB00983FB6 /* tweet_btn_rewarded@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E5D13081C0ECB3400985AEB /* tweet_btn_rewarded@3x.png */; }; + B1D5EF7120BC06CB00983FB6 /* vip_4_75@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689B21EE100B200B01371 /* vip_4_75@2x.png */; }; + B1D5EF7220BC06CB00983FB6 /* task_activity_icon_update_deadline@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383F81B33C18700D98648 /* task_activity_icon_update_deadline@2x.png */; }; + B1D5EF7320BC06CB00983FB6 /* TweetSendDetailLoctionCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0A0519E11ABA918100551B61 /* TweetSendDetailLoctionCell.xib */; }; + B1D5EF7420BC06CB00983FB6 /* project_item_readme@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871311EADF155003DACF0 /* project_item_readme@3x.png */; }; + B1D5EF7520BC06CB00983FB6 /* icon_file_doc_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8701FCD006A0098B87B /* icon_file_doc_big@2x.png */; }; + B1D5EF7620BC06CB00983FB6 /* icon_locationed@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF91F611B00B62A0021C951 /* icon_locationed@2x.png */; }; + B1D5EF7720BC06CB00983FB6 /* tip_normal_Nav@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ECEF9F91D1D0B3D002A27D3 /* tip_normal_Nav@3x.png */; }; + B1D5EF7820BC06CB00983FB6 /* tweet_btn_like@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E5D13021C0ECB3400985AEB /* tweet_btn_like@3x.png */; }; + B1D5EF7920BC06CB00983FB6 /* icon_project_cell_nopin@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EE548261AE9166B00A92306 /* icon_project_cell_nopin@2x.png */; }; + B1D5EF7A20BC06CB00983FB6 /* coding_emoji_39@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E08497B1A918A7F00BD27F6 /* coding_emoji_39@2x.png */; }; + B1D5EF7C20BC06CB00983FB6 /* coding_emoji_08@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE7B1A0C7E26006F9AD7 /* coding_emoji_08@2x.png */; }; + B1D5EF7D20BC06CB00983FB6 /* tweet_btn_liked@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E5D13031C0ECB3400985AEB /* tweet_btn_liked@2x.png */; }; + B1D5EF7E20BC06CB00983FB6 /* FileInfoViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4E93F2431B85C4C300017916 /* FileInfoViewController.xib */; }; + B1D5EF7F20BC06CB00983FB6 /* register_step_un@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EC480101C2A909D005F1772 /* register_step_un@3x.png */; }; + B1D5EF8020BC06CB00983FB6 /* blankpage_image_Task@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423CF1E69401B0095F1CD /* blankpage_image_Task@3x.png */; }; + B1D5EF8120BC06CB00983FB6 /* TweetSendCreateLocationCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0A782FDC1AB5B78B00E96661 /* TweetSendCreateLocationCell.xib */; }; + B1D5EF8320BC06CB00983FB6 /* coding_emoji_36@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE971A0C7E26006F9AD7 /* coding_emoji_36@2x.png */; }; + B1D5EF8420BC06CB00983FB6 /* n_btn_followed_yes@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E996BFC1ABBF56A00C704F1 /* n_btn_followed_yes@2x.png */; }; + B1D5EF8520BC06CB00983FB6 /* store_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAE068F1B784E9200179F4B /* store_icon@2x.png */; }; + B1D5EF8620BC06CB00983FB6 /* vip_4_75@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689B31EE100B200B01371 /* vip_4_75@3x.png */; }; + B1D5EF8720BC06CB00983FB6 /* button_tip_notice@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1CB8DD02047F1D000872197 /* button_tip_notice@2x.png */; }; + B1D5EF8820BC06CB00983FB6 /* addPictureBgImage@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF818151B049C89005F974B /* addPictureBgImage@2x.png */; }; + B1D5EF8920BC06CB00983FB6 /* PRReviewer@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D2F1CA17A6400EE127C /* PRReviewer@3x.png */; }; + B1D5EF8A20BC06CB00983FB6 /* button_tip_notice@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1CB8DD12047F1D100872197 /* button_tip_notice@3x.png */; }; + B1D5EF8B20BC06CB00983FB6 /* password_look@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F0B1C74691B00B5EBEA /* password_look@2x.png */; }; + B1D5EF8C20BC06CB00983FB6 /* SVWebViewControllerActivityReport-iPad@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ED673271A8E12F900DF2D1A /* SVWebViewControllerActivityReport-iPad@2x.png */; }; + B1D5EF8D20BC06CB00983FB6 /* PointLikeHead@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D2A1CA17A6400EE127C /* PointLikeHead@3x.png */; }; + B1D5EF8E20BC06CB00983FB6 /* btn_file_reDo@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E07D30C1A4A9F45009EDDF2 /* btn_file_reDo@2x.png */; }; + B1D5EF8F20BC06CB00983FB6 /* vip_4_30@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689AC1EE100B200B01371 /* vip_4_30@2x.png */; }; + B1D5EF9020BC06CB00983FB6 /* mrpr_icon_fileChange@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8714C1EADF3AC003DACF0 /* mrpr_icon_fileChange@3x.png */; }; + B1D5EF9120BC06CB00983FB6 /* project_item_reading@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B131E20F2074D2ED00D84FAA /* project_item_reading@3x.png */; }; + B1D5EF9220BC06CB00983FB6 /* icon_code_executable@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD0491E542B2D008AA957 /* icon_code_executable@2x.png */; }; + B1D5EF9320BC06CB00983FB6 /* user_info_company@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871491EADF217003DACF0 /* user_info_company@3x.png */; }; + B1D5EF9420BC06CB00983FB6 /* upgrade_success@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B12B64231FF33DFF00ACFDCC /* upgrade_success@2x.png */; }; + B1D5EF9520BC06CB00983FB6 /* pop_Tweet@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447BE1C02DB5400DC1C4B /* pop_Tweet@2x.png */; }; + B1D5EF9620BC06CB00983FB6 /* taskPriority1@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E63839D1B3262D300D98648 /* taskPriority1@2x.png */; }; + B1D5EF9720BC06CB00983FB6 /* search_icon_pr@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9481E02911E00DE1BC6 /* search_icon_pr@2x.png */; }; + B1D5EF9820BC06CB00983FB6 /* logo_about@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF7419E240C40076D59C /* logo_about@2x.png */; }; + B1D5EF9920BC06CB00983FB6 /* button_file_upload_enable@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E66EE251A28226000DA1B3E /* button_file_upload_enable@2x.png */; }; + B1D5EF9A20BC06CB00983FB6 /* share_btn_qq@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2BF3CA1B96CDF800A5A0A8 /* share_btn_qq@2x.png */; }; + B1D5EF9B20BC06CB00983FB6 /* PR_review@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D2B1CA17A6400EE127C /* PR_review@2x.png */; }; + B1D5EF9C20BC06CB00983FB6 /* pop_Message@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447BB1C02DB5400DC1C4B /* pop_Message@2x.png */; }; + B1D5EF9D20BC06CB00983FB6 /* terminal_box_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5C99202953E40075A669 /* terminal_box_selected@2x.png */; }; + B1D5EF9E20BC06CB00983FB6 /* git_icon_watch@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D09E6AC31BF84AE5009D37F8 /* git_icon_watch@2x.png */; }; + B1D5EF9F20BC06CB00983FB6 /* icon_file_pdf_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8721FCD006B0098B87B /* icon_file_pdf_big@2x.png */; }; + B1D5EFA120BC06CB00983FB6 /* placeholder_coding_square_80@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF8D19E240C40076D59C /* placeholder_coding_square_80@2x.png */; }; + B1D5EFA220BC06CB00983FB6 /* mrpr_icon_status_cannotmerge@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD01D1E540551008AA957 /* mrpr_icon_status_cannotmerge@2x.png */; }; + B1D5EFA420BC06CB00983FB6 /* loading_loop@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8ED2AAF819F60D5200607A1D /* loading_loop@2x.png */; }; + B1D5EFA520BC06CB00983FB6 /* code_release_resource_Task@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC31C20731FF10077C956 /* code_release_resource_Task@3x.png */; }; + B1D5EFA620BC06CB00983FB6 /* PR_refuse@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D201CA17A6400EE127C /* PR_refuse@2x.png */; }; + B1D5EFA720BC06CB00983FB6 /* icon_topic_hotTop@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8B35164B1B6CE9460049BC45 /* icon_topic_hotTop@2x.png */; }; + B1D5EFA820BC06CB00983FB6 /* wiki_revert@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1890C222015D82600F52ABA /* wiki_revert@3x.png */; }; + B1D5EFA920BC06CB00983FB6 /* share_btn_qzone@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2BF3CB1B96CDF800A5A0A8 /* share_btn_qzone@2x.png */; }; + B1D5EFAA20BC06CB00983FB6 /* project_tag_btn@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EE1A23B1B5F3834004284F1 /* project_tag_btn@2x.png */; }; + B1D5EFAB20BC06CB00983FB6 /* tipIcon_BranchMember@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E5C06E71AC2B34800F427C5 /* tipIcon_BranchMember@2x.png */; }; + B1D5EFAC20BC06CB00983FB6 /* messageRight_bg_highlight_img@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E774C241B870DC70026E5AB /* messageRight_bg_highlight_img@2x.png */; }; + B1D5EFAD20BC06CB00983FB6 /* tipIcon_PullRequestBean@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CFB519E240C40076D59C /* tipIcon_PullRequestBean@2x.png */; }; + B1D5EFAE20BC06CB00983FB6 /* btn_privateMsg_friend@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E8F7B2619EF6306006BA8BD /* btn_privateMsg_friend@2x.png */; }; + B1D5EFAF20BC06CB00983FB6 /* btn_file_cancel@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E07D30B1A4A9F45009EDDF2 /* btn_file_cancel@2x.png */; }; + B1D5EFB020BC06CB00983FB6 /* task_activity_icon_restore@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8719A1EB2D9E6003DACF0 /* task_activity_icon_restore@3x.png */; }; + B1D5EFB120BC06CB00983FB6 /* user_info_file@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ED4B4781D82646000EED8C6 /* user_info_file@3x.png */; }; + B1D5EFB220BC06CB00983FB6 /* shop_coding_coin_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 927AFF461BFF6DAD00AAE593 /* shop_coding_coin_icon@2x.png */; }; + B1D5EFB320BC06CB00983FB6 /* shortcut_task@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E92A1DFFF06E00DE1BC6 /* shortcut_task@3x.png */; }; + B1D5EFB520BC06CB00983FB6 /* taskPriority1_small@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8715D1EB182C7003DACF0 /* taskPriority1_small@3x.png */; }; + B1D5EFB620BC06CB00983FB6 /* tasks_all@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8718C1EB1E608003DACF0 /* tasks_all@3x.png */; }; + B1D5EFB720BC06CB00983FB6 /* coding_emoji_09@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE7C1A0C7E26006F9AD7 /* coding_emoji_09@2x.png */; }; + B1D5EFB820BC06CB00983FB6 /* map_annotation@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 0A06C2521AB9E57900AB3B03 /* map_annotation@2x.png */; }; + B1D5EFB920BC06CB00983FB6 /* code_release_resource_MergeRequestBean@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC3272073212E0077C956 /* code_release_resource_MergeRequestBean@2x.png */; }; + B1D5EFBA20BC06CB00983FB6 /* task_resource_reference_ProjectTopic@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F581C7C5C4F00B5EBEA /* task_resource_reference_ProjectTopic@2x.png */; }; + B1D5EFBB20BC06CB00983FB6 /* task_activity_icon_update@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383F71B33C18700D98648 /* task_activity_icon_update@2x.png */; }; + B1D5EFBC20BC06CB00983FB6 /* button_file_activity@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5CAB202D7D4F0075A669 /* button_file_activity@3x.png */; }; + B1D5EFBD20BC06CB00983FB6 /* coding_emoji_41@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E08497D1A918A7F00BD27F6 /* coding_emoji_41@2x.png */; }; + B1D5EFBE20BC06CB00983FB6 /* project_item_task@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871321EADF155003DACF0 /* project_item_task@3x.png */; }; + B1D5EFBF20BC06CB00983FB6 /* icon_code_image@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD0801E55AC6E008AA957 /* icon_code_image@2x.png */; }; + B1D5EFC020BC06CB00983FB6 /* icon_file_xls_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB88A1FCD0A6D0098B87B /* icon_file_xls_big@2x.png */; }; + B1D5EFC120BC06CB00983FB6 /* user_info_topic@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ED4B4821D82646000EED8C6 /* user_info_topic@3x.png */; }; + B1D5EFC220BC06CB00983FB6 /* task_activity_icon_remove_watcher@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ED618201C3BD79B0017946C /* task_activity_icon_remove_watcher@2x.png */; }; + B1D5EFC320BC06CB00983FB6 /* project_item_reading@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B131E2102074D2EE00D84FAA /* project_item_reading@2x.png */; }; + B1D5EFC420BC06CB00983FB6 /* shop_nar_history_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 927AFF4A1BFF6DAD00AAE593 /* shop_nar_history_icon@2x.png */; }; + B1D5EFC520BC06CB00983FB6 /* taskPriority3_small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383A21B3262D300D98648 /* taskPriority3_small@2x.png */; }; + B1D5EFC620BC06CB00983FB6 /* coding_emoji_18@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE851A0C7E26006F9AD7 /* coding_emoji_18@2x.png */; }; + B1D5EFC720BC06CB00983FB6 /* user_info_about@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ED4B4761D82646000EED8C6 /* user_info_about@3x.png */; }; + B1D5EFC820BC06CB00983FB6 /* WeiboSDK.bundle in Resources */ = {isa = PBXBuildFile; fileRef = B12B63F51FE8A77200ACFDCC /* WeiboSDK.bundle */; }; + B1D5EFC920BC06CB00983FB6 /* EAPayViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB88E1FCE61D60098B87B /* EAPayViewController.xib */; }; + B1D5EFCA20BC06CB00983FB6 /* calendar_0xA1CF64@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871761EB18599003DACF0 /* calendar_0xA1CF64@3x.png */; }; + B1D5EFCB20BC06CB00983FB6 /* user_info_file@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ED4B4771D82646000EED8C6 /* user_info_file@2x.png */; }; + B1D5EFCC20BC06CB00983FB6 /* ShopSwitchCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B19D4EF11F710EF900C598F3 /* ShopSwitchCell.xib */; }; + B1D5EFCD20BC06CB00983FB6 /* cell_arrow_left@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8714E1EADF48B003DACF0 /* cell_arrow_left@2x.png */; }; + B1D5EFCE20BC06CB00983FB6 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = B12B64571FFB61AD00ACFDCC /* LICENSE */; }; + B1D5EFCF20BC06CB00983FB6 /* member_type_90@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2F6A6B1C43CA4B00A25502 /* member_type_90@3x.png */; }; + B1D5EFD120BC06CB00983FB6 /* location_checkmark@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 0A6E6BB81AB168B0004C0107 /* location_checkmark@2x.png */; }; + B1D5EFD220BC06CB00983FB6 /* icon_code_tree@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD04B1E542B2D008AA957 /* icon_code_tree@2x.png */; }; + B1D5EFD320BC06CB00983FB6 /* nav_project_task@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF7F19E240C40076D59C /* nav_project_task@2x.png */; }; + B1D5EFD420BC06CB00983FB6 /* calendar_0xF68435@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8717B1EB18599003DACF0 /* calendar_0xF68435@2x.png */; }; + B1D5EFD520BC06CB00983FB6 /* share_btn_evernote@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2BF3C91B96CDF800A5A0A8 /* share_btn_evernote@2x.png */; }; + B1D5EFD620BC06CB00983FB6 /* project_item_branch@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1817EF32069186C00E9BAD1 /* project_item_branch@2x.png */; }; + B1D5EFD720BC06CB00983FB6 /* PR_push@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D191CA17A6400EE127C /* PR_push@2x.png */; }; + B1D5EFD820BC06CB00983FB6 /* vip_4_45@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689B11EE100B200B01371 /* vip_4_45@3x.png */; }; + B1D5EFD920BC06CB00983FB6 /* tipIcon_ProjectTopicCommentVote@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E54C24D1D90E05400A61023 /* tipIcon_ProjectTopicCommentVote@2x.png */; }; + B1D5EFDB20BC06CB00983FB6 /* icon_file_share_logo@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E1D991B1DCAE69600BAE585 /* icon_file_share_logo@3x.png */; }; + B1D5EFDC20BC06CB00983FB6 /* calendar_0xF68435@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8717C1EB18599003DACF0 /* calendar_0xF68435@3x.png */; }; + B1D5EFDD20BC06CB00983FB6 /* file_activity_icon_create@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAE06BC1B7B51AF00179F4B /* file_activity_icon_create@2x.png */; }; + B1D5EFDE20BC06CB00983FB6 /* tasks_all@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CFA819E240C40076D59C /* tasks_all@2x.png */; }; + B1D5EFDF20BC06CB00983FB6 /* EACodeReleaseTopCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B1817F0220691B2700E9BAD1 /* EACodeReleaseTopCell.xib */; }; + B1D5EFE020BC06CB00983FB6 /* merge-request coding@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D241CA17A6400EE127C /* merge-request coding@2x.png */; }; + B1D5EFE120BC06CB00983FB6 /* file_changeType_ADD@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CE9200EFDC600DEDF78 /* file_changeType_ADD@3x.png */; }; + B1D5EFE220BC06CB00983FB6 /* calendar_0xA9B3BE@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871781EB18599003DACF0 /* calendar_0xA9B3BE@3x.png */; }; + B1D5EFE320BC06CB00983FB6 /* messageLeft_bg_highlight_img@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E774C231B870DC70026E5AB /* messageLeft_bg_highlight_img@2x.png */; }; + B1D5EFE420BC06CB00983FB6 /* PR_update@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 134116F71CB55E69005E6550 /* PR_update@3x.png */; }; + B1D5EFE520BC06CB00983FB6 /* nav_project_topic@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF8019E240C40076D59C /* nav_project_topic@2x.png */; }; + B1D5EFE620BC06CB00983FB6 /* share_btn_wxtimeline@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2BF3CE1B96CDF800A5A0A8 /* share_btn_wxtimeline@2x.png */; }; + B1D5EFE720BC06CB00983FB6 /* icon_file_zip@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E96E7D71A1B537E0037C098 /* icon_file_zip@2x.png */; }; + B1D5EFE820BC06CB00983FB6 /* me_normal@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447D21C02DB8900DC1C4B /* me_normal@3x.png */; }; + B1D5EFE920BC06CB00983FB6 /* pop_Project@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447BC1C02DB5400DC1C4B /* pop_Project@2x.png */; }; + B1D5EFEB20BC06CB00983FB6 /* logo_coding_top@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EFE8DAE1B3960E6004B7559 /* logo_coding_top@2x.png */; }; + B1D5EFEC20BC06CB00983FB6 /* tipIcon_ProjectTweetComment@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E4972DE1BB535B400F3AC15 /* tipIcon_ProjectTweetComment@2x.png */; }; + B1D5EFED20BC06CB00983FB6 /* button_file_createFolder_enable@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E66EE211A28226000DA1B3E /* button_file_createFolder_enable@2x.png */; }; + B1D5EFEE20BC06CB00983FB6 /* wiki_menu_2@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1890C202015D82600F52ABA /* wiki_menu_2@2x.png */; }; + B1D5EFEF20BC06CB00983FB6 /* skill_delete@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B12B64161FF0E4CA00ACFDCC /* skill_delete@2x.png */; }; + B1D5EFF020BC06CB00983FB6 /* calendar_0xF56061@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871791EB18599003DACF0 /* calendar_0xF56061@2x.png */; }; + B1D5EFF120BC06CB00983FB6 /* project_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C4479E1C02A3C700DC1C4B /* project_selected@2x.png */; }; + B1D5EFF220BC06CB00983FB6 /* tipIcon_QcTask@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CFB719E240C40076D59C /* tipIcon_QcTask@2x.png */; }; + B1D5EFF320BC06CB00983FB6 /* time_clock_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E095A811B6B24DE008DC439 /* time_clock_icon@2x.png */; }; + B1D5EFF420BC06CB00983FB6 /* tag_button_randomColor@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F1B1C76BA3B00B5EBEA /* tag_button_randomColor@2x.png */; }; + B1D5EFF520BC06CB00983FB6 /* blankpage_image_Notice@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423C91E69401B0095F1CD /* blankpage_image_Notice@3x.png */; }; + B1D5EFF620BC06CB00983FB6 /* project_item_mr_pr@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871301EADF155003DACF0 /* project_item_mr_pr@3x.png */; }; + B1D5EFF720BC06CB00983FB6 /* button_tip_close@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B12B64251FF33E0000ACFDCC /* button_tip_close@2x.png */; }; + B1D5EFF820BC06CB00983FB6 /* task_activity_icon_reassign@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383F51B33C18700D98648 /* task_activity_icon_reassign@2x.png */; }; + B1D5EFF920BC06CB00983FB6 /* task_resource_reference_ProjectFile@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F561C7C5C4F00B5EBEA /* task_resource_reference_ProjectFile@2x.png */; }; + B1D5EFFA20BC06CB00983FB6 /* messageAT@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383B11B32640900D98648 /* messageAT@2x.png */; }; + B1D5EFFB20BC06CB00983FB6 /* tweet_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447A21C02A3C700DC1C4B /* tweet_selected@2x.png */; }; + B1D5EFFC20BC06CB00983FB6 /* icon_file_code@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E96E7CD1A1B537E0037C098 /* icon_file_code@2x.png */; }; + B1D5EFFE20BC06CB00983FB6 /* back_T_Nav@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871211EADF0FF003DACF0 /* back_T_Nav@3x.png */; }; + B1D5EFFF20BC06CB00983FB6 /* me_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C4479A1C02A3C700DC1C4B /* me_selected@2x.png */; }; + B1D5F00020BC06CB00983FB6 /* tipIcon_PullRequestComment@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CFB619E240C40076D59C /* tipIcon_PullRequestComment@2x.png */; }; + B1D5F00120BC06CB00983FB6 /* tipIcon_Depot@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E4972E31BB543A900F3AC15 /* tipIcon_Depot@2x.png */; }; + B1D5F00220BC06CB00983FB6 /* cell_checkmark@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EF6433B19FE696B00F7EEB0 /* cell_checkmark@2x.png */; }; + B1D5F00320BC06CB00983FB6 /* PR_add_label@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CFC200EFEA400DEDF78 /* PR_add_label@2x.png */; }; + B1D5F00520BC06CB00983FB6 /* logo_coding@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B10341282024633900853447 /* logo_coding@3x.png */; }; + B1D5F00620BC06CB00983FB6 /* PR_del_reviewer@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CFD200EFEA400DEDF78 /* PR_del_reviewer@2x.png */; }; + B1D5F00720BC06CB00983FB6 /* task_activity_icon_reassign@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871981EB2D9E6003DACF0 /* task_activity_icon_reassign@3x.png */; }; + B1D5F00820BC06CB00983FB6 /* placeholder_coding_square_150@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF8B19E240C40076D59C /* placeholder_coding_square_150@2x.png */; }; + B1D5F00920BC06CB00983FB6 /* member_cell_edit_remove@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAECBBE1C44CB860096CA74 /* member_cell_edit_remove@2x.png */; }; + B1D5F00B20BC06CB00983FB6 /* PR_TaskResource@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 134116F21CB54AF8005E6550 /* PR_TaskResource@2x.png */; }; + B1D5F00C20BC06CB00983FB6 /* icon_file_share_logo@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E1D991A1DCAE69600BAE585 /* icon_file_share_logo@2x.png */; }; + B1D5F00D20BC06CB00983FB6 /* blankpage_image_Notice@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423C81E69401B0095F1CD /* blankpage_image_Notice@2x.png */; }; + B1D5F00E20BC06CB00983FB6 /* placeholder_monkey_round_25@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF8E19E240C40076D59C /* placeholder_monkey_round_25@2x.png */; }; + B1D5F00F20BC06CB00983FB6 /* coding_emoji_gif_05@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2DB3431BA6AEB4002F27C4 /* coding_emoji_gif_05@2x.png */; }; + B1D5F01020BC06CB00983FB6 /* addBtn_Artboard@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8711D1EADF0FF003DACF0 /* addBtn_Artboard@3x.png */; }; + B1D5F01120BC06CB00983FB6 /* coding_emoji_22@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE891A0C7E26006F9AD7 /* coding_emoji_22@2x.png */; }; + B1D5F01220BC06CB00983FB6 /* tweet_btn_rewarded@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E5D13071C0ECB3400985AEB /* tweet_btn_rewarded@2x.png */; }; + B1D5F01320BC06CB00983FB6 /* button_file_move_enable@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E66EE241A28226000DA1B3E /* button_file_move_enable@2x.png */; }; + B1D5F01420BC06CB00983FB6 /* messageSystem@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871171EADF0B1003DACF0 /* messageSystem@3x.png */; }; + B1D5F01520BC06CB00983FB6 /* button_red_close@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B12B64211FF33DFF00ACFDCC /* button_red_close@2x.png */; }; + B1D5F01620BC06CB00983FB6 /* blankpage_image_Wiki@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423D91E69401B0095F1CD /* blankpage_image_Wiki@3x.png */; }; + B1D5F01720BC06CB00983FB6 /* project_tag_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EE1A23C1B5F3834004284F1 /* project_tag_icon@2x.png */; }; + B1D5F01820BC06CB00983FB6 /* button_terminal@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B11DC7BF20245728004E76A9 /* button_terminal@3x.png */; }; + B1D5F01920BC06CB00983FB6 /* wiki_menu_0@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1890C212015D82600F52ABA /* wiki_menu_0@3x.png */; }; + B1D5F01A20BC06CB00983FB6 /* PR_update_title@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 133DAA631CC13A30004D8501 /* PR_update_title@3x.png */; }; + B1D5F01B20BC06CB00983FB6 /* wiki.html in Resources */ = {isa = PBXBuildFile; fileRef = B177F5C02060E6B1006709C2 /* wiki.html */; }; + B1D5F01C20BC06CB00983FB6 /* task_activity_icon_update@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8719F1EB2D9E6003DACF0 /* task_activity_icon_update@3x.png */; }; + B1D5F01D20BC06CB00983FB6 /* timeline_line_read@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CFAD19E240C40076D59C /* timeline_line_read@2x.png */; }; + B1D5F01E20BC06CB00983FB6 /* git_icon_fork@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D09E6AC51BF84AF9009D37F8 /* git_icon_fork@2x.png */; }; + B1D5F01F20BC06CB00983FB6 /* tag_button_add@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F181C76BA3B00B5EBEA /* tag_button_add@3x.png */; }; + B1D5F02020BC06CB00983FB6 /* taskProgress@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871411EADF1C1003DACF0 /* taskProgress@3x.png */; }; + B1D5F02120BC06CB00983FB6 /* taskboard_blankpage@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED81209453E8004A6E8A /* taskboard_blankpage@3x.png */; }; + B1D5F02320BC06CB00983FB6 /* blankpage_image_Task@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423CE1E69401B0095F1CD /* blankpage_image_Task@2x.png */; }; + B1D5F02420BC06CB00983FB6 /* task_activity_icon_update_label@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8719D1EB2D9E6003DACF0 /* task_activity_icon_update_label@3x.png */; }; + B1D5F02520BC06CB00983FB6 /* search_icon_mr@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9451E02911E00DE1BC6 /* search_icon_mr@3x.png */; }; + B1D5F02620BC06CB00983FB6 /* blankpage_image_Tweet@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423D71E69401B0095F1CD /* blankpage_image_Tweet@3x.png */; }; + B1D5F02720BC06CB00983FB6 /* user_info_company@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871481EADF217003DACF0 /* user_info_company@2x.png */; }; + B1D5F02820BC06CB00983FB6 /* scan_line@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E94C4EE1B4B73BB00EB668A /* scan_line@2x.png */; }; + B1D5F02920BC06CB00983FB6 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = B12B64581FFB61AD00ACFDCC /* README.md */; }; + B1D5F02A20BC06CB00983FB6 /* icon_file_unknown@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E96E7D11A1B537E0037C098 /* icon_file_unknown@2x.png */; }; + B1D5F02B20BC06CB00983FB6 /* search_icon_tweet@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E93E1E02911E00DE1BC6 /* search_icon_tweet@2x.png */; }; + B1D5F02C20BC06CB00983FB6 /* tip_bg@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ECEFA001D1D0B4B002A27D3 /* tip_bg@2x.png */; }; + B1D5F02D20BC06CB00983FB6 /* SVWebViewControllerActivityChrome-iPad@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E217F001A70EDC700F6DF88 /* SVWebViewControllerActivityChrome-iPad@2x.png */; }; + B1D5F02E20BC06CB00983FB6 /* PR_grant@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D341CA17A6400EE127C /* PR_grant@2x.png */; }; + B1D5F02F20BC06CB00983FB6 /* settingBtn_Nav@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871221EADF0FF003DACF0 /* settingBtn_Nav@2x.png */; }; + B1D5F03020BC06CB00983FB6 /* user_info_topic@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ED4B4811D82646000EED8C6 /* user_info_topic@2x.png */; }; + B1D5F03120BC06CB00983FB6 /* project_item_file@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383EB1B32A2C300D98648 /* project_item_file@2x.png */; }; + B1D5F03220BC06CB00983FB6 /* icon_arrow_searchHistory@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8B35164A1B6CE9460049BC45 /* icon_arrow_searchHistory@2x.png */; }; + B1D5F03320BC06CB00983FB6 /* icon_file_movie_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8751FCD006B0098B87B /* icon_file_movie_big@2x.png */; }; + B1D5F03420BC06CB00983FB6 /* icon_file_md_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8761FCD006B0098B87B /* icon_file_md_big@2x.png */; }; + B1D5F03520BC06CB00983FB6 /* nav_project_member@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF7E19E240C40076D59C /* nav_project_member@2x.png */; }; + B1D5F03620BC06CB00983FB6 /* blankpage_image_MessageList@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423C61E69401B0095F1CD /* blankpage_image_MessageList@2x.png */; }; + B1D5F03720BC06CB00983FB6 /* password_unlook@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F0E1C74691B00B5EBEA /* password_unlook@3x.png */; }; + B1D5F03820BC06CB00983FB6 /* timeline_icon_unread@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16EEF07208DDBB6005ABFD5 /* timeline_icon_unread@3x.png */; }; + B1D5F03920BC06CB00983FB6 /* task_activity_icon_add_milestone@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BFC4C120B2B24E009427FC /* task_activity_icon_add_milestone@3x.png */; }; + B1D5F03A20BC06CB00983FB6 /* pop_Message@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447C71C02DB6700DC1C4B /* pop_Message@3x.png */; }; + B1D5F03B20BC06CB00983FB6 /* EABoardTaskListBlankView.xib in Resources */ = {isa = PBXBuildFile; fileRef = B152ED6420935594004A6E8A /* EABoardTaskListBlankView.xib */; }; + B1D5F03C20BC06CB00983FB6 /* comment_bg@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E63840A1B33F9B400D98648 /* comment_bg@2x.png */; }; + B1D5F03D20BC06CB00983FB6 /* button_scan@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F2C1C77138A00B5EBEA /* button_scan@2x.png */; }; + B1D5F03E20BC06CB00983FB6 /* terminal_triangle@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5C96202953E40075A669 /* terminal_triangle@3x.png */; }; + B1D5F03F20BC06CB00983FB6 /* tweetsBtn_Nav@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E59D3291D3E106D008C914B /* tweetsBtn_Nav@2x.png */; }; + B1D5F04020BC06CB00983FB6 /* coding_emoji_12@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE7F1A0C7E26006F9AD7 /* coding_emoji_12@2x.png */; }; + B1D5F04120BC06CB00983FB6 /* terminal_box_unselected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5C92202953E40075A669 /* terminal_box_unselected@3x.png */; }; + B1D5F04420BC06CB00983FB6 /* terminal_tail@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5C93202953E40075A669 /* terminal_tail@3x.png */; }; + B1D5F04520BC06CB00983FB6 /* task_normal@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447D81C02DB8900DC1C4B /* task_normal@3x.png */; }; + B1D5F04620BC06CB00983FB6 /* vip_3_75@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689AA1EE100B200B01371 /* vip_3_75@2x.png */; }; + B1D5F04720BC06CB00983FB6 /* mock_hotTopiclist.geojson in Resources */ = {isa = PBXBuildFile; fileRef = 4E0BD87C1B6C7F0A0061CAA6 /* mock_hotTopiclist.geojson */; }; + B1D5F04820BC06CB00983FB6 /* icon_project_cell_pin@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EE548271AE9166B00A92306 /* icon_project_cell_pin@2x.png */; }; + B1D5F04920BC06CB00983FB6 /* pop_2FA@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447BA1C02DB5400DC1C4B /* pop_2FA@2x.png */; }; + B1D5F04A20BC06CB00983FB6 /* PR_add_reviewer@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CF7200EFEA400DEDF78 /* PR_add_reviewer@3x.png */; }; + B1D5F04B20BC06CB00983FB6 /* nav_project_file@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EBD0C651A1F2011004B4284 /* nav_project_file@2x.png */; }; + B1D5F04C20BC06CB00983FB6 /* user_info_shop@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B19D4EF51F7210C300C598F3 /* user_info_shop@3x.png */; }; + B1D5F04D20BC06CB00983FB6 /* pop_Task@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447BD1C02DB5400DC1C4B /* pop_Task@2x.png */; }; + B1D5F04E20BC06CB00983FB6 /* section_btn_close@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF9619E240C40076D59C /* section_btn_close@2x.png */; }; + B1D5F04F20BC06CB00983FB6 /* country_code.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4EBD7FB01CE482A400B3AF49 /* country_code.plist */; }; + B1D5F05020BC06CB00983FB6 /* file_menu_icon_info@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E93F2371B84356500017916 /* file_menu_icon_info@2x.png */; }; + B1D5F05120BC06CB00983FB6 /* coding_emoji_07@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE7A1A0C7E26006F9AD7 /* coding_emoji_07@2x.png */; }; + B1D5F05220BC06CB00983FB6 /* project_item_taskboard@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED7B20945377004A6E8A /* project_item_taskboard@3x.png */; }; + B1D5F05320BC06CB00983FB6 /* merge-request coding@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D251CA17A6400EE127C /* merge-request coding@3x.png */; }; + B1D5F05520BC06CB00983FB6 /* blankpage_image_Team@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423D11E69401B0095F1CD /* blankpage_image_Team@3x.png */; }; + B1D5F05620BC06CB00983FB6 /* mrpr_icon_status_canmerge@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD01B1E540551008AA957 /* mrpr_icon_status_canmerge@2x.png */; }; + B1D5F05720BC06CB00983FB6 /* blankpage_image_MessageList@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423C71E69401B0095F1CD /* blankpage_image_MessageList@3x.png */; }; + B1D5F05820BC06CB00983FB6 /* taskPriority1_small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E63839E1B3262D300D98648 /* taskPriority1_small@2x.png */; }; + B1D5F05920BC06CB00983FB6 /* me_selected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447D31C02DB8900DC1C4B /* me_selected@3x.png */; }; + B1D5F05A20BC06CB00983FB6 /* timeBtn_Nav@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447F21C02DCA200DC1C4B /* timeBtn_Nav@2x.png */; }; + B1D5F05B20BC06CB00983FB6 /* bubble_right_play_0@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E8E597C1B6F91C40083CA02 /* bubble_right_play_0@2x.png */; }; + B1D5F05C20BC06CB00983FB6 /* ShopMutileValueCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4ED6181C1C3A72CF0017946C /* ShopMutileValueCell.xib */; }; + B1D5F05D20BC06CB00983FB6 /* task_activity_icon_update_priority@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8719E1EB2D9E6003DACF0 /* task_activity_icon_update_priority@3x.png */; }; + B1D5F05E20BC06CB00983FB6 /* icon_file_movie@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E96E7CF1A1B537E0037C098 /* icon_file_movie@2x.png */; }; + B1D5F05F20BC06CB00983FB6 /* file_menu_icon_open@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E93F2381B84356500017916 /* file_menu_icon_open@2x.png */; }; + B1D5F06020BC06CB00983FB6 /* addBtn_Nav@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447EA1C02DCA200DC1C4B /* addBtn_Nav@2x.png */; }; + B1D5F06120BC06CB00983FB6 /* messageAT@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871141EADF0B1003DACF0 /* messageAT@3x.png */; }; + B1D5F06220BC06CB00983FB6 /* search_icon_file@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9431E02911E00DE1BC6 /* search_icon_file@3x.png */; }; + B1D5F06420BC06CB00983FB6 /* PR_review@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D2C1CA17A6400EE127C /* PR_review@3x.png */; }; + B1D5F06520BC06CB00983FB6 /* keyboard_emotion_monkey_gif@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2DB33E1BA6A2FE002F27C4 /* keyboard_emotion_monkey_gif@2x.png */; }; + B1D5F06620BC06CB00983FB6 /* coding_emoji_29@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE901A0C7E26006F9AD7 /* coding_emoji_29@2x.png */; }; + B1D5F06720BC06CB00983FB6 /* file_activity_icon_move_file@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAE06BD1B7B51AF00179F4B /* file_activity_icon_move_file@2x.png */; }; + B1D5F06820BC06CB00983FB6 /* addBtn_Nav@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447FE1C02DCAC00DC1C4B /* addBtn_Nav@3x.png */; }; + B1D5F06920BC06CB00983FB6 /* vip_3_75@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689AB1EE100B200B01371 /* vip_3_75@3x.png */; }; + B1D5F06A20BC06CB00983FB6 /* info_Nav@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C448021C02DCAC00DC1C4B /* info_Nav@3x.png */; }; + B1D5F06B20BC06CB00983FB6 /* terminal_more@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5C95202953E40075A669 /* terminal_more@2x.png */; }; + B1D5F06C20BC06CB00983FB6 /* task_selected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447D91C02DB8900DC1C4B /* task_selected@3x.png */; }; + B1D5F06D20BC06CB00983FB6 /* blankpage_image_Project@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423CB1E69401B0095F1CD /* blankpage_image_Project@3x.png */; }; + B1D5F06E20BC06CB00983FB6 /* keyboard_emotion@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE5A1A0A3424006F9AD7 /* keyboard_emotion@2x.png */; }; + B1D5F06F20BC06CB00983FB6 /* button_file_history@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAE06A61B7B1AE100179F4B /* button_file_history@2x.png */; }; + B1D5F07020BC06CB00983FB6 /* wechat@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8971FCE93830098B87B /* wechat@2x.png */; }; + B1D5F07120BC06CB00983FB6 /* coding_emoji_43@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E08497F1A918A7F00BD27F6 /* coding_emoji_43@2x.png */; }; + B1D5F07220BC06CB00983FB6 /* tweet_btn_liked@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E5D13041C0ECB3400985AEB /* tweet_btn_liked@3x.png */; }; + B1D5F07320BC06CB00983FB6 /* icon_file_music@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E96E7D01A1B537E0037C098 /* icon_file_music@2x.png */; }; + B1D5F07420BC06CB00983FB6 /* tipIcon_UserFollow@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CFBC19E240C40076D59C /* tipIcon_UserFollow@2x.png */; }; + B1D5F07520BC06CB00983FB6 /* icon_code_git_link@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD0501E542B2D008AA957 /* icon_code_git_link@3x.png */; }; + B1D5F07620BC06CB00983FB6 /* file_changeType_RENAME@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CE8200EFDC600DEDF78 /* file_changeType_RENAME@3x.png */; }; + B1D5F07720BC06CB00983FB6 /* member_type_100@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2F6A671C43CA4B00A25502 /* member_type_100@3x.png */; }; + B1D5F07820BC06CB00983FB6 /* code_release_resource__Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC31A20731FF10077C956 /* code_release_resource__Default@2x.png */; }; + B1D5F07920BC06CB00983FB6 /* button_close@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E5D13161C0EF48200985AEB /* button_close@2x.png */; }; + B1D5F07A20BC06CB00983FB6 /* PR_TaskResource@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 134116F31CB54AF8005E6550 /* PR_TaskResource@3x.png */; }; + B1D5F07C20BC06CB00983FB6 /* tipIcon_Project@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CFB219E240C40076D59C /* tipIcon_Project@2x.png */; }; + B1D5F07D20BC06CB00983FB6 /* icon_code_tree@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD04C1E542B2D008AA957 /* icon_code_tree@3x.png */; }; + B1D5F07E20BC06CB00983FB6 /* pop_Task@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447C91C02DB6700DC1C4B /* pop_Task@3x.png */; }; + B1D5F07F20BC06CB00983FB6 /* tag_button_editColor@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F191C76BA3B00B5EBEA /* tag_button_editColor@2x.png */; }; + B1D5F08020BC06CB00983FB6 /* icon_best_answer@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6CBE531D8EA9D100644086 /* icon_best_answer@3x.png */; }; + B1D5F08220BC06CB00983FB6 /* tip_bg@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ECEFA011D1D0B4B002A27D3 /* tip_bg@3x.png */; }; + B1D5F08320BC06CB00983FB6 /* addUserBtn_Nav@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447FF1C02DCAC00DC1C4B /* addUserBtn_Nav@3x.png */; }; + B1D5F08420BC06CB00983FB6 /* taskOwner@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8713F1EADF1C1003DACF0 /* taskOwner@3x.png */; }; + B1D5F08520BC06CB00983FB6 /* addUserBtn_Nav@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447EB1C02DCA200DC1C4B /* addUserBtn_Nav@2x.png */; }; + B1D5F08620BC06CB00983FB6 /* mrpr_icon_status_accepted@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD01A1E540551008AA957 /* mrpr_icon_status_accepted@3x.png */; }; + B1D5F08720BC06CB00983FB6 /* tweet_btn_reward@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E5D13061C0ECB3400985AEB /* tweet_btn_reward@3x.png */; }; + B1D5F08820BC06CB00983FB6 /* member_cell_edit_remove@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAECBBF1C44CB860096CA74 /* member_cell_edit_remove@3x.png */; }; + B1D5F08A20BC06CB00983FB6 /* shortcut_tweet@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E92C1DFFF06E00DE1BC6 /* shortcut_tweet@3x.png */; }; + B1D5F08B20BC06CB00983FB6 /* coding_emoji_34@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE951A0C7E26006F9AD7 /* coding_emoji_34@2x.png */; }; + B1D5F08C20BC06CB00983FB6 /* task_description_icon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8716D1EB1832B003DACF0 /* task_description_icon@3x.png */; }; + B1D5F08E20BC06CB00983FB6 /* me_info_arrow_left@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAE06911B7880BA00179F4B /* me_info_arrow_left@2x.png */; }; + B1D5F08F20BC06CB00983FB6 /* keyboard_photo@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E5F39061ACBFDCD0010515D /* keyboard_photo@2x.png */; }; + B1D5F09020BC06CB00983FB6 /* wechat@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8981FCE93830098B87B /* wechat@3x.png */; }; + B1D5F09220BC06CB00983FB6 /* text_clear_btn@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E76D4DD1A5A7B4A0094A35E /* text_clear_btn@2x.png */; }; + B1D5F09320BC06CB00983FB6 /* task_normal@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C4479F1C02A3C700DC1C4B /* task_normal@2x.png */; }; + B1D5F09420BC06CB00983FB6 /* icon_file_xls@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E96E7D61A1B537E0037C098 /* icon_file_xls@2x.png */; }; + B1D5F09520BC06CB00983FB6 /* coding_emoji_gif_04@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2DB3421BA6AEB4002F27C4 /* coding_emoji_gif_04@2x.png */; }; + B1D5F09620BC06CB00983FB6 /* messageProjectFans@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6CBE561D8FBDF500644086 /* messageProjectFans@2x.png */; }; + B1D5F09720BC06CB00983FB6 /* shop_nar_history_icon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 927AFF4B1BFF6DAD00AAE593 /* shop_nar_history_icon@3x.png */; }; + B1D5F09820BC06CB00983FB6 /* file_changeType_MODIFY@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EC461B11B39360F00D08970 /* file_changeType_MODIFY@2x.png */; }; + B1D5F09920BC06CB00983FB6 /* project_normal@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C4479D1C02A3C700DC1C4B /* project_normal@2x.png */; }; + B1D5F09A20BC06CB00983FB6 /* reward_tip_logo@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9361E01218300DE1BC6 /* reward_tip_logo@2x.png */; }; + B1D5F09B20BC06CB00983FB6 /* taskProject@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871421EADF1C1003DACF0 /* taskProject@3x.png */; }; + B1D5F09C20BC06CB00983FB6 /* user_info_point@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ED4B47C1D82646000EED8C6 /* user_info_point@3x.png */; }; + B1D5F09D20BC06CB00983FB6 /* icon_file_folder_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EA679171A14BFA0001A0324 /* icon_file_folder_default@2x.png */; }; + B1D5F09E20BC06CB00983FB6 /* icon_code_file@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD04E1E542B2D008AA957 /* icon_code_file@3x.png */; }; + B1D5F09F20BC06CB00983FB6 /* project_item_readme@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383CE1B32665700D98648 /* project_item_readme@2x.png */; }; + B1D5F0A020BC06CB00983FB6 /* EACodeBranchListCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B1817EEE2068C7A100E9BAD1 /* EACodeBranchListCell.xib */; }; + B1D5F0A120BC06CB00983FB6 /* code_release_resource_Default@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC31920731FF10077C956 /* code_release_resource_Default@3x.png */; }; + B1D5F0A220BC06CB00983FB6 /* info_Nav@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447EE1C02DCA200DC1C4B /* info_Nav@2x.png */; }; + B1D5F0A420BC06CB00983FB6 /* file_activity_icon_update_file@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871B01EB2D9F0003DACF0 /* file_activity_icon_update_file@3x.png */; }; + B1D5F0A520BC06CB00983FB6 /* bubble.html in Resources */ = {isa = PBXBuildFile; fileRef = B177F5C12060E6B1006709C2 /* bubble.html */; }; + B1D5F0A620BC06CB00983FB6 /* coding_emoji_gif_06@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2DB3441BA6AEB4002F27C4 /* coding_emoji_gif_06@2x.png */; }; + B1D5F0A820BC06CB00983FB6 /* project_item_member@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383CC1B32665700D98648 /* project_item_member@2x.png */; }; + B1D5F0A920BC06CB00983FB6 /* tipIcon_Tweet@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CFB919E240C40076D59C /* tipIcon_Tweet@2x.png */; }; + B1D5F0AA20BC06CB00983FB6 /* coding_emoji_04@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE771A0C7E26006F9AD7 /* coding_emoji_04@2x.png */; }; + B1D5F0AB20BC06CB00983FB6 /* nav_tweet_hot@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF8319E240C40076D59C /* nav_tweet_hot@2x.png */; }; + B1D5F0AC20BC06CB00983FB6 /* project_item_topic@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383D01B32665700D98648 /* project_item_topic@2x.png */; }; + B1D5F0AD20BC06CB00983FB6 /* wiki_menu_1@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1890C242015D82600F52ABA /* wiki_menu_1@2x.png */; }; + B1D5F0AE20BC06CB00983FB6 /* file_activity_icon_move_file@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871AF1EB2D9F0003DACF0 /* file_activity_icon_move_file@3x.png */; }; + B1D5F0AF20BC06CB00983FB6 /* icon_file_md@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E96E7CE1A1B537E0037C098 /* icon_file_md@2x.png */; }; + B1D5F0B020BC06CB00983FB6 /* tweet_normal@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447A11C02A3C700DC1C4B /* tweet_normal@2x.png */; }; + B1D5F0B120BC06CB00983FB6 /* PR_review_undo@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D301CA17A6400EE127C /* PR_review_undo@2x.png */; }; + B1D5F0B220BC06CB00983FB6 /* blankpage_image_Tweet@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423D61E69401B0095F1CD /* blankpage_image_Tweet@2x.png */; }; + B1D5F0B320BC06CB00983FB6 /* taskBoardList@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED7E209453E6004A6E8A /* taskBoardList@3x.png */; }; + B1D5F0B420BC06CB00983FB6 /* search_tweet_like@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E62410A1B74D65400E1533C /* search_tweet_like@2x.png */; }; + B1D5F0B520BC06CB00983FB6 /* scan_bg@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E94C4EC1B4A867A00EB668A /* scan_bg@2x.png */; }; + B1D5F0B620BC06CB00983FB6 /* task_icon_arrow@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871BD1EB33B37003DACF0 /* task_icon_arrow@3x.png */; }; + B1D5F0B720BC06CB00983FB6 /* n_btn_followed_not@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E996BFB1ABBF56A00C704F1 /* n_btn_followed_not@2x.png */; }; + B1D5F0B820BC06CB00983FB6 /* section_btn_open@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF9719E240C40076D59C /* section_btn_open@2x.png */; }; + B1D5F0BA20BC06CB00983FB6 /* task_resource_reference_ProjectTopic@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F591C7C5C4F00B5EBEA /* task_resource_reference_ProjectTopic@3x.png */; }; + B1D5F0BB20BC06CB00983FB6 /* skill_delete@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B12B64171FF0E4CA00ACFDCC /* skill_delete@3x.png */; }; + B1D5F0BD20BC06CB00983FB6 /* button_file_move_unable@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EACB43E1A2C448F0097ABB3 /* button_file_move_unable@2x.png */; }; + B1D5F0BE20BC06CB00983FB6 /* mock_topicAdlist.geojson in Resources */ = {isa = PBXBuildFile; fileRef = 4E0BD87D1B6C7F0A0061CAA6 /* mock_topicAdlist.geojson */; }; + B1D5F0BF20BC06CB00983FB6 /* placeholder_coding_square_55@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF8C19E240C40076D59C /* placeholder_coding_square_55@2x.png */; }; + B1D5F0C020BC06CB00983FB6 /* pop_Project@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447C81C02DB6700DC1C4B /* pop_Project@3x.png */; }; + B1D5F0C120BC06CB00983FB6 /* task_activity_icon_remove_milestone@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BFC4C220B2B24F009427FC /* task_activity_icon_remove_milestone@3x.png */; }; + B1D5F0C220BC06CB00983FB6 /* button_file_download_unable@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5CAD202D7D4F0075A669 /* button_file_download_unable@3x.png */; }; + B1D5F0C320BC06CB00983FB6 /* search_icon_task@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E94C1E02911E00DE1BC6 /* search_icon_task@2x.png */; }; + B1D5F0C420BC06CB00983FB6 /* code_release_resource_Task@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC31B20731FF10077C956 /* code_release_resource_Task@2x.png */; }; + B1D5F0C520BC06CB00983FB6 /* moreBtn_Nav@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C448031C02DCAC00DC1C4B /* moreBtn_Nav@3x.png */; }; + B1D5F0C620BC06CB00983FB6 /* tweet_comment_btn@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B184166820513CA000207666 /* tweet_comment_btn@3x.png */; }; + B1D5F0C720BC06CB00983FB6 /* vip_3_30@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689A41EE100B200B01371 /* vip_3_30@2x.png */; }; + B1D5F0C820BC06CB00983FB6 /* PR_del_label@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CF5200EFEA400DEDF78 /* PR_del_label@3x.png */; }; + B1D5F0C920BC06CB00983FB6 /* blankpage_image_Team@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423D01E69401B0095F1CD /* blankpage_image_Team@2x.png */; }; + B1D5F0CA20BC06CB00983FB6 /* icon_release_tag_blue@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC31320731E910077C956 /* icon_release_tag_blue@2x.png */; }; + B1D5F0CB20BC06CB00983FB6 /* btn_privateMsg_stranger@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E8F7B2719EF6306006BA8BD /* btn_privateMsg_stranger@2x.png */; }; + B1D5F0CC20BC06CB00983FB6 /* project_item_wiki@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871341EADF155003DACF0 /* project_item_wiki@3x.png */; }; + B1D5F0CD20BC06CB00983FB6 /* STARTIMAGE.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 4E03AC991A5BDDF9002B000B /* STARTIMAGE.jpg */; }; + B1D5F0CE20BC06CB00983FB6 /* messageComment@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871151EADF0B1003DACF0 /* messageComment@3x.png */; }; + B1D5F0CF20BC06CB00983FB6 /* coding_emoji_02@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE751A0C7E26006F9AD7 /* coding_emoji_02@2x.png */; }; + B1D5F0D020BC06CB00983FB6 /* checkbox_checked@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383E71B32791600D98648 /* checkbox_checked@2x.png */; }; + B1D5F0D120BC06CB00983FB6 /* taskboard_blankpage@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED7F209453E7004A6E8A /* taskboard_blankpage@2x.png */; }; + B1D5F0D220BC06CB00983FB6 /* member_cell_edit_type@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAECBC11C44CB860096CA74 /* member_cell_edit_type@3x.png */; }; + B1D5F0D320BC06CB00983FB6 /* PR_del_label@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CFA200EFEA400DEDF78 /* PR_del_label@2x.png */; }; + B1D5F0D420BC06CB00983FB6 /* SVWebViewController.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4E217F1C1A71007800F6DF88 /* SVWebViewController.strings */; }; + B1D5F0D520BC06CB00983FB6 /* blankpage_image_Topic@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423D51E69401B0095F1CD /* blankpage_image_Topic@3x.png */; }; + B1D5F0D720BC06CB00983FB6 /* placeholder_monkey_round_33@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF8F19E240C40076D59C /* placeholder_monkey_round_33@2x.png */; }; + B1D5F0D820BC06CB00983FB6 /* coding_emoji_30@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE911A0C7E26006F9AD7 /* coding_emoji_30@2x.png */; }; + B1D5F0D920BC06CB00983FB6 /* project_item_code@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383CA1B32665700D98648 /* project_item_code@2x.png */; }; + B1D5F0DA20BC06CB00983FB6 /* search_icon_user@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9471E02911E00DE1BC6 /* search_icon_user@3x.png */; }; + B1D5F0DB20BC06CB00983FB6 /* code_release_resource_MergeRequestBean@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC3242073212D0077C956 /* code_release_resource_MergeRequestBean@3x.png */; }; + B1D5F0DD20BC06CB00983FB6 /* blankpage_image_Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423C01E69401B0095F1CD /* blankpage_image_Default@2x.png */; }; + B1D5F0DE20BC06CB00983FB6 /* project_item_tag@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1817EF22069186C00E9BAD1 /* project_item_tag@2x.png */; }; + B1D5F0DF20BC06CB00983FB6 /* PRReviewer@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D2E1CA17A6400EE127C /* PRReviewer@2x.png */; }; + B1D5F0E020BC06CB00983FB6 /* login_wechat@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B12B640D1FECB58F00ACFDCC /* login_wechat@2x.png */; }; + B1D5F0E120BC06CB00983FB6 /* task_activity_icon_finish@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871961EB2D9E6003DACF0 /* task_activity_icon_finish@3x.png */; }; + B1D5F0E220BC06CB00983FB6 /* taskboard_normal_page_unselected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED8D209453F2004A6E8A /* taskboard_normal_page_unselected@3x.png */; }; + B1D5F0E420BC06CB00983FB6 /* nav_page_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E53EB571AFB090E0034FE1C /* nav_page_selected@2x.png */; }; + B1D5F0E520BC06CB00983FB6 /* coding_emoji_28@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE8F1A0C7E26006F9AD7 /* coding_emoji_28@2x.png */; }; + B1D5F0E720BC06CB00983FB6 /* placeholder_monkey_round_50@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF9219E240C40076D59C /* placeholder_monkey_round_50@2x.png */; }; + B1D5F0E820BC06CB00983FB6 /* vip_3_45@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689A81EE100B200B01371 /* vip_3_45@2x.png */; }; + B1D5F0E920BC06CB00983FB6 /* n_sex_man_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E996BFD1ABBF56A00C704F1 /* n_sex_man_icon@2x.png */; }; + B1D5F0EA20BC06CB00983FB6 /* AppIcon120x120.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF6E19E240C40076D59C /* AppIcon120x120.png */; }; + B1D5F0EB20BC06CB00983FB6 /* privatemessage_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C4479C1C02A3C700DC1C4B /* privatemessage_selected@2x.png */; }; + B1D5F0EC20BC06CB00983FB6 /* coding_emoji_gif_07@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2DB3451BA6AEB4002F27C4 /* coding_emoji_gif_07@2x.png */; }; + B1D5F0ED20BC06CB00983FB6 /* calendar_0x59A2FF@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871731EB18599003DACF0 /* calendar_0x59A2FF@2x.png */; }; + B1D5F0EE20BC06CB00983FB6 /* file_activity_icon_rename@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B19D4EE01F690F5E00C598F3 /* file_activity_icon_rename@3x.png */; }; + B1D5F0EF20BC06CB00983FB6 /* button_file_denete_enable@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5CA7202D7D4E0075A669 /* button_file_denete_enable@3x.png */; }; + B1D5F0F020BC06CB00983FB6 /* coding_emoji_32@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE931A0C7E26006F9AD7 /* coding_emoji_32@2x.png */; }; + B1D5F0F120BC06CB00983FB6 /* coding_emoji_16@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE831A0C7E26006F9AD7 /* coding_emoji_16@2x.png */; }; + B1D5F0F220BC06CB00983FB6 /* icon_triangle@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD05A1E544006008AA957 /* icon_triangle@3x.png */; }; + B1D5F0F320BC06CB00983FB6 /* mrpr_icon_arrow@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD09C1E5D8558008AA957 /* mrpr_icon_arrow@3x.png */; }; + B1D5F0F420BC06CB00983FB6 /* comment_bg@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871B71EB338FD003DACF0 /* comment_bg@3x.png */; }; + B1D5F0F620BC06CB00983FB6 /* btn_followed_both@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E8F7B2219EF6306006BA8BD /* btn_followed_both@2x.png */; }; + B1D5F0F720BC06CB00983FB6 /* PR_refuse@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D211CA17A6400EE127C /* PR_refuse@3x.png */; }; + B1D5F0F820BC06CB00983FB6 /* shortcut_tweet@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E92B1DFFF06E00DE1BC6 /* shortcut_tweet@2x.png */; }; + B1D5F0F920BC06CB00983FB6 /* vip_3_30@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689A51EE100B200B01371 /* vip_3_30@3x.png */; }; + B1D5F0FA20BC06CB00983FB6 /* coding_emoji_42@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E08497E1A918A7F00BD27F6 /* coding_emoji_42@2x.png */; }; + B1D5F0FB20BC06CB00983FB6 /* coding_emoji_31@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE921A0C7E26006F9AD7 /* coding_emoji_31@2x.png */; }; + B1D5F0FC20BC06CB00983FB6 /* user_info_setup@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ED4B47F1D82646000EED8C6 /* user_info_setup@2x.png */; }; + B1D5F0FD20BC06CB00983FB6 /* calendar_0xF56061@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8717A1EB18599003DACF0 /* calendar_0xF56061@3x.png */; }; + B1D5F0FE20BC06CB00983FB6 /* blankpage_image_File@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423C21E69401B0095F1CD /* blankpage_image_File@2x.png */; }; + B1D5F0FF20BC06CB00983FB6 /* icon_add_comment@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871891EB1E608003DACF0 /* icon_add_comment@3x.png */; }; + B1D5F10020BC06CB00983FB6 /* button_file_download_enable@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EACB4421A2C45300097ABB3 /* button_file_download_enable@2x.png */; }; + B1D5F10120BC06CB00983FB6 /* keyboard_page_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE5F1A0A3424006F9AD7 /* keyboard_page_selected@2x.png */; }; + B1D5F10220BC06CB00983FB6 /* taskPriority3@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871621EB182C7003DACF0 /* taskPriority3@3x.png */; }; + B1D5F10320BC06CB00983FB6 /* code.html in Resources */ = {isa = PBXBuildFile; fileRef = B177F5C42060E6B1006709C2 /* code.html */; }; + B1D5F10420BC06CB00983FB6 /* timeline_icon_read@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B16EEF06208DDBB5005ABFD5 /* timeline_icon_read@3x.png */; }; + B1D5F10520BC06CB00983FB6 /* file_activity_icon_delete_history@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871AE1EB2D9F0003DACF0 /* file_activity_icon_delete_history@3x.png */; }; + B1D5F10620BC06CB00983FB6 /* mrpr_icon_commit@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383D91B3266C200D98648 /* mrpr_icon_commit@2x.png */; }; + B1D5F10720BC06CB00983FB6 /* editBoardList@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BFC4B520B2ACEE009427FC /* editBoardList@2x.png */; }; + B1D5F10820BC06CB00983FB6 /* pop_User@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447BF1C02DB5400DC1C4B /* pop_User@2x.png */; }; + B1D5F10920BC06CB00983FB6 /* keyboard_add_photo@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE571A0A3424006F9AD7 /* keyboard_add_photo@2x.png */; }; + B1D5F10A20BC06CB00983FB6 /* member_cell_edit_type@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAECBC01C44CB860096CA74 /* member_cell_edit_type@2x.png */; }; + B1D5F10B20BC06CB00983FB6 /* wiki_menu_icon_delete@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1890C282015D82600F52ABA /* wiki_menu_icon_delete@2x.png */; }; + B1D5F10C20BC06CB00983FB6 /* file_menu_icon_edit@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E93F2361B84356500017916 /* file_menu_icon_edit@2x.png */; }; + B1D5F10D20BC06CB00983FB6 /* AboutPointViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = B19D4EE91F6FAA6000C598F3 /* AboutPointViewController.xib */; }; + B1D5F10E20BC06CB00983FB6 /* address.json in Resources */ = {isa = PBXBuildFile; fileRef = 8E1C3DF519E7F4CA00EF3032 /* address.json */; }; + B1D5F10F20BC06CB00983FB6 /* reward_tip_logo@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9371E01218300DE1BC6 /* reward_tip_logo@3x.png */; }; + B1D5F11020BC06CB00983FB6 /* code_release_resource_ProjectFile@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC3252073212D0077C956 /* code_release_resource_ProjectFile@2x.png */; }; + B1D5F11120BC06CB00983FB6 /* share_Nav@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E09DCA81C15662E001C9392 /* share_Nav@3x.png */; }; + B1D5F11220BC06CB00983FB6 /* task_activity_icon_add_milestone@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BFC4C020B2B24E009427FC /* task_activity_icon_add_milestone@2x.png */; }; + B1D5F11320BC06CB00983FB6 /* share_btn_copylink@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2BF3C81B96CDF800A5A0A8 /* share_btn_copylink@2x.png */; }; + B1D5F11420BC06CB00983FB6 /* project_item_branch@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1817EF42069186D00E9BAD1 /* project_item_branch@3x.png */; }; + B1D5F11620BC06CB00983FB6 /* bubble_left_play_0@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E8E59791B6F91C40083CA02 /* bubble_left_play_0@2x.png */; }; + B1D5F11720BC06CB00983FB6 /* little_phone_icon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871571EB0884A003DACF0 /* little_phone_icon@3x.png */; }; + B1D5F11820BC06CB00983FB6 /* icon_file_ppt@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E96E7D31A1B537E0037C098 /* icon_file_ppt@2x.png */; }; + B1D5F11920BC06CB00983FB6 /* member_type_75@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2F6A681C43CA4B00A25502 /* member_type_75@2x.png */; }; + B1D5F11A20BC06CB00983FB6 /* icon_search_searchbar@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C448121C02F76600DC1C4B /* icon_search_searchbar@2x.png */; }; + B1D5F11B20BC06CB00983FB6 /* register_step_ed@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EC4800D1C2A909D005F1772 /* register_step_ed@2x.png */; }; + B1D5F11C20BC06CB00983FB6 /* project_normal@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447D61C02DB8900DC1C4B /* project_normal@3x.png */; }; + B1D5F11D20BC06CB00983FB6 /* button_terminal@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B11DC7BE20245727004E76A9 /* button_terminal@2x.png */; }; + B1D5F11E20BC06CB00983FB6 /* privatemessage_normal@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C4479B1C02A3C700DC1C4B /* privatemessage_normal@2x.png */; }; + B1D5F11F20BC06CB00983FB6 /* tipIcon_ProjectMember@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CFB319E240C40076D59C /* tipIcon_ProjectMember@2x.png */; }; + B1D5F12020BC06CB00983FB6 /* file_activity_icon_rename@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B19D4EDF1F690F5E00C598F3 /* file_activity_icon_rename@2x.png */; }; + B1D5F12120BC06CB00983FB6 /* code_release_resource_ProjectTopic@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC3282073212E0077C956 /* code_release_resource_ProjectTopic@2x.png */; }; + B1D5F12220BC06CB00983FB6 /* coding_emoji_17@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE841A0C7E26006F9AD7 /* coding_emoji_17@2x.png */; }; + B1D5F12320BC06CB00983FB6 /* messageLeft_bg_img@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383B31B32640900D98648 /* messageLeft_bg_img@2x.png */; }; + B1D5F12420BC06CB00983FB6 /* search_icon_project@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E94A1E02911E00DE1BC6 /* search_icon_project@2x.png */; }; + B1D5F12520BC06CB00983FB6 /* mrpr_icon_status_cancel@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD0291E5405B4008AA957 /* mrpr_icon_status_cancel@2x.png */; }; + B1D5F12620BC06CB00983FB6 /* mrpr_icon_status_cancel@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD02A1E5405B4008AA957 /* mrpr_icon_status_cancel@3x.png */; }; + B1D5F12720BC06CB00983FB6 /* button_file_createFolder_enable@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5CA6202D7D4D0075A669 /* button_file_createFolder_enable@3x.png */; }; + B1D5F12820BC06CB00983FB6 /* PR_mergeChanges@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D261CA17A6400EE127C /* PR_mergeChanges@2x.png */; }; + B1D5F12920BC06CB00983FB6 /* coding_emoji_20@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE871A0C7E26006F9AD7 /* coding_emoji_20@2x.png */; }; + B1D5F12A20BC06CB00983FB6 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CFC519E240C40076D59C /* Images.xcassets */; }; + B1D5F12B20BC06CB00983FB6 /* task_icon_arrow@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E63840E1B34124000D98648 /* task_icon_arrow@2x.png */; }; + B1D5F12C20BC06CB00983FB6 /* mrpr_icon_refaused@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383C21B3265DC00D98648 /* mrpr_icon_refaused@2x.png */; }; + B1D5F12D20BC06CB00983FB6 /* loading_monkey@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8ED2AAF919F60D5200607A1D /* loading_monkey@2x.png */; }; + B1D5F12E20BC06CB00983FB6 /* coding_emoji_01@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE741A0C7E26006F9AD7 /* coding_emoji_01@2x.png */; }; + B1D5F12F20BC06CB00983FB6 /* taskPriority0@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8715C1EB182C7003DACF0 /* taskPriority0@3x.png */; }; + B1D5F13020BC06CB00983FB6 /* taskPriority3_small@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871611EB182C7003DACF0 /* taskPriority3_small@3x.png */; }; + B1D5F13120BC06CB00983FB6 /* taskResourceReference@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F391C7C45E700B5EBEA /* taskResourceReference@2x.png */; }; + B1D5F13220BC06CB00983FB6 /* tipIcon_MergeRequestBean@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CFB019E240C40076D59C /* tipIcon_MergeRequestBean@2x.png */; }; + B1D5F13320BC06CB00983FB6 /* button_file_denete_enable@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E66EE221A28226000DA1B3E /* button_file_denete_enable@2x.png */; }; + B1D5F13520BC06CB00983FB6 /* dot_line@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2719C61AB07ED6006AE214 /* dot_line@2x.png */; }; + B1D5F13620BC06CB00983FB6 /* PR_grant_undo@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D231CA17A6400EE127C /* PR_grant_undo@3x.png */; }; + B1D5F13720BC06CB00983FB6 /* PR_add_watcher@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CFB200EFEA400DEDF78 /* PR_add_watcher@3x.png */; }; + B1D5F13820BC06CB00983FB6 /* coding_emoji_gif_01@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2DB3461BA6AEB4002F27C4 /* coding_emoji_gif_01@2x.png */; }; + B1D5F13920BC06CB00983FB6 /* addBtn_Artboard@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8711C1EADF0FF003DACF0 /* addBtn_Artboard@2x.png */; }; + B1D5F13B20BC06CB00983FB6 /* project_item_wiki@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871331EADF155003DACF0 /* project_item_wiki@2x.png */; }; + B1D5F13C20BC06CB00983FB6 /* member_type_90@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2F6A6A1C43CA4B00A25502 /* member_type_90@2x.png */; }; + B1D5F13D20BC06CB00983FB6 /* share_btn_inform@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E5D131A1C11865D00985AEB /* share_btn_inform@2x.png */; }; + B1D5F13E20BC06CB00983FB6 /* back_green_Nav@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8711F1EADF0FF003DACF0 /* back_green_Nav@3x.png */; }; + B1D5F13F20BC06CB00983FB6 /* README.textile in Resources */ = {isa = PBXBuildFile; fileRef = 8E64ED8919EE484A006E99DA /* README.textile */; }; + B1D5F14020BC06CB00983FB6 /* PR_del_reviewer@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CFE200EFEA400DEDF78 /* PR_del_reviewer@3x.png */; }; + B1D5F14120BC06CB00983FB6 /* search_icon_task@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E94D1E02911E00DE1BC6 /* search_icon_task@3x.png */; }; + B1D5F14220BC06CB00983FB6 /* task_activity_icon_remove_milestone@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BFC4C320B2B250009427FC /* task_activity_icon_remove_milestone@2x.png */; }; + B1D5F14320BC06CB00983FB6 /* checkbox_unchecked@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8715A1EB182C7003DACF0 /* checkbox_unchecked@3x.png */; }; + B1D5F14420BC06CB00983FB6 /* coding_emoji_06@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE791A0C7E26006F9AD7 /* coding_emoji_06@2x.png */; }; + B1D5F14520BC06CB00983FB6 /* button_tip_close@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B12B64221FF33DFF00ACFDCC /* button_tip_close@3x.png */; }; + B1D5F14620BC06CB00983FB6 /* blankpage_image_ShopOrder@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423CC1E69401B0095F1CD /* blankpage_image_ShopOrder@2x.png */; }; + B1D5F14720BC06CB00983FB6 /* coding_emoji_40@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E08497C1A918A7F00BD27F6 /* coding_emoji_40@2x.png */; }; + B1D5F14820BC06CB00983FB6 /* blankpage_image_Default@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423C11E69401B0095F1CD /* blankpage_image_Default@3x.png */; }; + B1D5F14920BC06CB00983FB6 /* member_cell_edit_alias@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAECBBC1C44CB860096CA74 /* member_cell_edit_alias@2x.png */; }; + B1D5F14A20BC06CB00983FB6 /* messageRight_bg_img@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383B41B32640900D98648 /* messageRight_bg_img@2x.png */; }; + B1D5F14B20BC06CB00983FB6 /* project_item_taskboard@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED7A20945377004A6E8A /* project_item_taskboard@2x.png */; }; + B1D5F14C20BC06CB00983FB6 /* nav_page_selected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8718A1EB1E608003DACF0 /* nav_page_selected@3x.png */; }; + B1D5F14D20BC06CB00983FB6 /* terminal_more@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5C94202953E40075A669 /* terminal_more@3x.png */; }; + B1D5F14E20BC06CB00983FB6 /* btn_setFrequent@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871871EB1E608003DACF0 /* btn_setFrequent@3x.png */; }; + B1D5F14F20BC06CB00983FB6 /* tweet_normal@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447DA1C02DB8900DC1C4B /* tweet_normal@3x.png */; }; + B1D5F15020BC06CB00983FB6 /* icon_search_clock@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8B3516541B6CF69E0049BC45 /* icon_search_clock@2x.png */; }; + B1D5F15120BC06CB00983FB6 /* taskPriority2@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E63839F1B3262D300D98648 /* taskPriority2@2x.png */; }; + B1D5F15220BC06CB00983FB6 /* file_activity_icon_upload_file@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAE06BF1B7B51AF00179F4B /* file_activity_icon_upload_file@2x.png */; }; + B1D5F15320BC06CB00983FB6 /* tip_normal_Nav@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ECEF9F81D1D0B3D002A27D3 /* tip_normal_Nav@2x.png */; }; + B1D5F15420BC06CB00983FB6 /* search_icon_user@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9461E02911E00DE1BC6 /* search_icon_user@2x.png */; }; + B1D5F15520BC06CB00983FB6 /* button_file_denete_unable@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E66EE231A28226000DA1B3E /* button_file_denete_unable@2x.png */; }; + B1D5F15620BC06CB00983FB6 /* nav_page_unselected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8718B1EB1E608003DACF0 /* nav_page_unselected@3x.png */; }; + B1D5F15720BC06CB00983FB6 /* EmojisList.plist in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE491A0A2E11006F9AD7 /* EmojisList.plist */; }; + B1D5F15820BC06CB00983FB6 /* keyboard_topic@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8BDF9AB01B7474990093BF2C /* keyboard_topic@2x.png */; }; + B1D5F15920BC06CB00983FB6 /* project_item_tag@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1817EF52069186E00E9BAD1 /* project_item_tag@3x.png */; }; + B1D5F15A20BC06CB00983FB6 /* add_user_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EBFBD171AA85B8500E4B10E /* add_user_icon@2x.png */; }; + B1D5F15B20BC06CB00983FB6 /* coding_emoji_11@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE7E1A0C7E26006F9AD7 /* coding_emoji_11@2x.png */; }; + B1D5F15C20BC06CB00983FB6 /* coding_emoji_gif_02@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2DB3401BA6AEB4002F27C4 /* coding_emoji_gif_02@2x.png */; }; + B1D5F15D20BC06CB00983FB6 /* n_sex_woman_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E996BFE1ABBF56A00C704F1 /* n_sex_woman_icon@2x.png */; }; + B1D5F15E20BC06CB00983FB6 /* vip_4_30@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689AD1EE100B200B01371 /* vip_4_30@3x.png */; }; + B1D5F15F20BC06CB00983FB6 /* taskPriority@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871401EADF1C1003DACF0 /* taskPriority@3x.png */; }; + B1D5F16020BC06CB00983FB6 /* tipIcon_TeamMember@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB862AC1CABB21E008074D1 /* tipIcon_TeamMember@2x.png */; }; + B1D5F16120BC06CB00983FB6 /* keyboard_emotion_delete@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE5B1A0A3424006F9AD7 /* keyboard_emotion_delete@2x.png */; }; + B1D5F16220BC06CB00983FB6 /* nav_tweet_friend@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF8219E240C40076D59C /* nav_tweet_friend@2x.png */; }; + B1D5F16320BC06CB00983FB6 /* nav_tweet_mine@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF8419E240C40076D59C /* nav_tweet_mine@2x.png */; }; + B1D5F16420BC06CB00983FB6 /* shortcut_2FA@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9281DFFF06E00DE1BC6 /* shortcut_2FA@3x.png */; }; + B1D5F16520BC06CB00983FB6 /* PR_add@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D161CA17A6400EE127C /* PR_add@3x.png */; }; + B1D5F16620BC06CB00983FB6 /* code_release_resource_Zip@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC31820731FF10077C956 /* code_release_resource_Zip@3x.png */; }; + B1D5F16720BC06CB00983FB6 /* taskboard_add_page_unselected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED8C209453F2004A6E8A /* taskboard_add_page_unselected@3x.png */; }; + B1D5F16820BC06CB00983FB6 /* blankpage_image_Activity@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423BF1E69401B0095F1CD /* blankpage_image_Activity@3x.png */; }; + B1D5F16920BC06CB00983FB6 /* pop_Tweet@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447CA1C02DB6700DC1C4B /* pop_Tweet@3x.png */; }; + B1D5F16A20BC06CB00983FB6 /* icon_code_image@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD0811E55AC6E008AA957 /* icon_code_image@3x.png */; }; + B1D5F16B20BC06CB00983FB6 /* taskboard_normal_page_selected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED87209453F2004A6E8A /* taskboard_normal_page_selected@3x.png */; }; + B1D5F16D20BC06CB00983FB6 /* icon_file_txt_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8791FCD006C0098B87B /* icon_file_txt_big@2x.png */; }; + B1D5F16E20BC06CB00983FB6 /* git_icon_stared@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E4D6AC91B2571B100FD2E49 /* git_icon_stared@2x.png */; }; + B1D5F16F20BC06CB00983FB6 /* search_icon_mr@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9441E02911E00DE1BC6 /* search_icon_mr@2x.png */; }; + B1D5F17020BC06CB00983FB6 /* button_download_cancel@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ED20A791AFCC43600C63498 /* button_download_cancel@2x.png */; }; + B1D5F17120BC06CB00983FB6 /* SVWebViewController.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 4E217EFA1A70EDC700F6DF88 /* SVWebViewController.bundle */; }; + B1D5F17220BC06CB00983FB6 /* register_step_ed@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EC4800E1C2A909D005F1772 /* register_step_ed@3x.png */; }; + B1D5F17320BC06CB00983FB6 /* keyboard_emotion_emoji_code@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9DEEC51E30CA3C001B8D1B /* keyboard_emotion_emoji_code@2x.png */; }; + B1D5F17420BC06CB00983FB6 /* cell_arrow_left@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8714F1EADF48B003DACF0 /* cell_arrow_left@3x.png */; }; + B1D5F17520BC06CB00983FB6 /* vip_3_40@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689A61EE100B200B01371 /* vip_3_40@2x.png */; }; + B1D5F17620BC06CB00983FB6 /* icon_code_git_link@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD04F1E542B2D008AA957 /* icon_code_git_link@2x.png */; }; + B1D5F17720BC06CB00983FB6 /* icon_add_comment@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E4D6AC71B252F4800FD2E49 /* icon_add_comment@2x.png */; }; + B1D5F17920BC06CB00983FB6 /* icon_file_code_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8781FCD006C0098B87B /* icon_file_code_big@2x.png */; }; + B1D5F17A20BC06CB00983FB6 /* file_changeType_DELETE@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CEB200EFDC600DEDF78 /* file_changeType_DELETE@3x.png */; }; + B1D5F17B20BC06CB00983FB6 /* tweet_more_comment_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E872CFF19EFEFF7002C8F34 /* tweet_more_comment_icon@2x.png */; }; + B1D5F17C20BC06CB00983FB6 /* task_activity_icon_add_watcher@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E3DB53A1BFDD0F40062BA52 /* task_activity_icon_add_watcher@2x.png */; }; + B1D5F17D20BC06CB00983FB6 /* tipIcon_TweetLike@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CFBB19E240C40076D59C /* tipIcon_TweetLike@2x.png */; }; + B1D5F17E20BC06CB00983FB6 /* blankpage_image_LoadFail@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423C41E69401B0095F1CD /* blankpage_image_LoadFail@2x.png */; }; + B1D5F17F20BC06CB00983FB6 /* gif_mark@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E72F8321B15B811001B6CE6 /* gif_mark@2x.png */; }; + B1D5F18020BC06CB00983FB6 /* icon_file_cell_delete@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EC5AD8F1A258DF8006FA97C /* icon_file_cell_delete@2x.png */; }; + B1D5F18120BC06CB00983FB6 /* blankpage_image_Topic@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423D41E69401B0095F1CD /* blankpage_image_Topic@2x.png */; }; + B1D5F18220BC06CB00983FB6 /* MJPhotoBrowser.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6D06B19E240C40076D59C /* MJPhotoBrowser.bundle */; }; + B1D5F18320BC06CB00983FB6 /* icon_file_folder_share@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E1D99141DCAE67D00BAE585 /* icon_file_folder_share@2x.png */; }; + B1D5F18420BC06CB00983FB6 /* search_icon_pr@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9491E02911E00DE1BC6 /* search_icon_pr@3x.png */; }; + B1D5F18520BC06CB00983FB6 /* SVWebViewControllerActivityChrome@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E217F031A70EDC700F6DF88 /* SVWebViewControllerActivityChrome@2x.png */; }; + B1D5F18620BC06CB00983FB6 /* taskboard_add_page_selected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED8B209453F2004A6E8A /* taskboard_add_page_selected@3x.png */; }; + B1D5F18720BC06CB00983FB6 /* SVWebViewControllerActivitySafari@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E217F091A70EDC700F6DF88 /* SVWebViewControllerActivitySafari@2x.png */; }; + B1D5F18820BC06CB00983FB6 /* editBoardList@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BFC4B420B2ACED009427FC /* editBoardList@3x.png */; }; + B1D5F18A20BC06CB00983FB6 /* PR_add@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D151CA17A6400EE127C /* PR_add@2x.png */; }; + B1D5F18B20BC06CB00983FB6 /* tweet_btn_reward@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E5D13051C0ECB3400985AEB /* tweet_btn_reward@2x.png */; }; + B1D5F18C20BC06CB00983FB6 /* project_item_mr_pr@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383CD1B32665700D98648 /* project_item_mr_pr@2x.png */; }; + B1D5F18D20BC06CB00983FB6 /* user_info_point@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ED4B47B1D82646000EED8C6 /* user_info_point@2x.png */; }; + B1D5F18E20BC06CB00983FB6 /* btn_fliter_down@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447B31C02B1DE00DC1C4B /* btn_fliter_down@2x.png */; }; + B1D5F18F20BC06CB00983FB6 /* nav_project_activity@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF7D19E240C40076D59C /* nav_project_activity@2x.png */; }; + B1D5F19020BC06CB00983FB6 /* file_changeType_RENAME@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EFE8DAB1B394A0D004B7559 /* file_changeType_RENAME@2x.png */; }; + B1D5F19120BC06CB00983FB6 /* blankpage_image_Tip@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423D31E69401B0095F1CD /* blankpage_image_Tip@3x.png */; }; + B1D5F19220BC06CB00983FB6 /* ProjectSetting.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B9A00D7E1ACA3A05008BA008 /* ProjectSetting.storyboard */; }; + B1D5F19320BC06CB00983FB6 /* icon_release_tag@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1817EFE2069197C00E9BAD1 /* icon_release_tag@3x.png */; }; + B1D5F19420BC06CB00983FB6 /* timeline_icon_unread@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CFAC19E240C40076D59C /* timeline_icon_unread@2x.png */; }; + B1D5F19520BC06CB00983FB6 /* user_info_edit@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E54C2491D8FE19100A61023 /* user_info_edit@2x.png */; }; + B1D5F19620BC06CB00983FB6 /* AlipaySDK.bundle in Resources */ = {isa = PBXBuildFile; fileRef = B19D4EF91F7247BA00C598F3 /* AlipaySDK.bundle */; }; + B1D5F19720BC06CB00983FB6 /* banner__page_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E095A6B1B69F920008DC439 /* banner__page_selected@2x.png */; }; + B1D5F19820BC06CB00983FB6 /* task_resource_reference_MergeRequestBean@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F551C7C5C4F00B5EBEA /* task_resource_reference_MergeRequestBean@3x.png */; }; + B1D5F19920BC06CB00983FB6 /* tipIcon_ProjectFileComment@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E86FEE41BB556D6005E53F3 /* tipIcon_ProjectFileComment@2x.png */; }; + B1D5F19A20BC06CB00983FB6 /* SVWebViewControllerActivitySafari-iPad@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E217F061A70EDC700F6DF88 /* SVWebViewControllerActivitySafari-iPad@2x.png */; }; + B1D5F19B20BC06CB00983FB6 /* icon_not_locationed@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EF91F621B00B62A0021C951 /* icon_not_locationed@2x.png */; }; + B1D5F19C20BC06CB00983FB6 /* checkbox_unchecked@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383E81B32791600D98648 /* checkbox_unchecked@2x.png */; }; + B1D5F19D20BC06CB00983FB6 /* icon_file_psd_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8731FCD006B0098B87B /* icon_file_psd_big@2x.png */; }; + B1D5F19E20BC06CB00983FB6 /* timeline_icon_read@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CFAB19E240C40076D59C /* timeline_icon_read@2x.png */; }; + B1D5F19F20BC06CB00983FB6 /* topic_add_watcher_btn@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B184166720513CA000207666 /* topic_add_watcher_btn@3x.png */; }; + B1D5F1A020BC06CB00983FB6 /* coding_emoji_27@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE8E1A0C7E26006F9AD7 /* coding_emoji_27@2x.png */; }; + B1D5F1A120BC06CB00983FB6 /* QBImagePicker.strings in Resources */ = {isa = PBXBuildFile; fileRef = B12B645A1FFB61AD00ACFDCC /* QBImagePicker.strings */; }; + B1D5F1A220BC06CB00983FB6 /* icon_file_zip_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8711FCD006B0098B87B /* icon_file_zip_big@2x.png */; }; + B1D5F1A320BC06CB00983FB6 /* messageProjectFollows@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871161EADF0B1003DACF0 /* messageProjectFollows@3x.png */; }; + B1D5F1A420BC06CB00983FB6 /* tipIcon_CommitLineNote@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E4972E11BB5395B00F3AC15 /* tipIcon_CommitLineNote@2x.png */; }; + B1D5F1A520BC06CB00983FB6 /* wiki_revert@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1890C232015D82600F52ABA /* wiki_revert@2x.png */; }; + B1D5F1A620BC06CB00983FB6 /* search_icon_tweet@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E93F1E02911E00DE1BC6 /* search_icon_tweet@3x.png */; }; + B1D5F1A720BC06CB00983FB6 /* taskPriority0_small@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8715B1EB182C7003DACF0 /* taskPriority0_small@3x.png */; }; + B1D5F1A820BC06CB00983FB6 /* coding_emoji_24@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE8B1A0C7E26006F9AD7 /* coding_emoji_24@2x.png */; }; + B1D5F1A920BC06CB00983FB6 /* PointLikeHead@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D291CA17A6400EE127C /* PointLikeHead@2x.png */; }; + B1D5F1AA20BC06CB00983FB6 /* coding_emoji_10@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE7D1A0C7E26006F9AD7 /* coding_emoji_10@2x.png */; }; + B1D5F1AB20BC06CB00983FB6 /* me_normal@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447991C02A3C700DC1C4B /* me_normal@2x.png */; }; + B1D5F1AC20BC06CB00983FB6 /* taskPriority2@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871601EB182C7003DACF0 /* taskPriority2@3x.png */; }; + B1D5F1AD20BC06CB00983FB6 /* blankpage_image_Activity@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423BE1E69401B0095F1CD /* blankpage_image_Activity@2x.png */; }; + B1D5F1AE20BC06CB00983FB6 /* coding_emoji_33@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE941A0C7E26006F9AD7 /* coding_emoji_33@2x.png */; }; + B1D5F1AF20BC06CB00983FB6 /* coding_emoji_23@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE8A1A0C7E26006F9AD7 /* coding_emoji_23@2x.png */; }; + B1D5F1B020BC06CB00983FB6 /* taskPriority@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383DE1B32676600D98648 /* taskPriority@2x.png */; }; + B1D5F1B120BC06CB00983FB6 /* code_release_resource_ProjectFile@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC3232073212D0077C956 /* code_release_resource_ProjectFile@3x.png */; }; + B1D5F1B220BC06CB00983FB6 /* tipIcon_Task@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CFB819E240C40076D59C /* tipIcon_Task@2x.png */; }; + B1D5F1B320BC06CB00983FB6 /* icon_code_file@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD04D1E542B2D008AA957 /* icon_code_file@2x.png */; }; + B1D5F1B420BC06CB00983FB6 /* task_activity_icon_update_description@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383F91B33C18700D98648 /* task_activity_icon_update_description@2x.png */; }; + B1D5F1B520BC06CB00983FB6 /* git_icon_star@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D09E6AC11BF84AC5009D37F8 /* git_icon_star@2x.png */; }; + B1D5F1B620BC06CB00983FB6 /* task_description_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E095A801B6B24DE008DC439 /* task_description_icon@2x.png */; }; + B1D5F1B720BC06CB00983FB6 /* tag_button_editColor@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F1A1C76BA3B00B5EBEA /* tag_button_editColor@3x.png */; }; + B1D5F1B820BC06CB00983FB6 /* moreBtn_Nav@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447EF1C02DCA200DC1C4B /* moreBtn_Nav@2x.png */; }; + B1D5F1BB20BC06CB00983FB6 /* coding_emoji_19@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE861A0C7E26006F9AD7 /* coding_emoji_19@2x.png */; }; + B1D5F1BC20BC06CB00983FB6 /* PR_review_undo@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 13FB5D311CA17A6400EE127C /* PR_review_undo@3x.png */; }; + B1D5F1BD20BC06CB00983FB6 /* taskPriority1@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8715E1EB182C7003DACF0 /* taskPriority1@3x.png */; }; + B1D5F1BE20BC06CB00983FB6 /* alipay@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8961FCE93830098B87B /* alipay@3x.png */; }; + B1D5F1BF20BC06CB00983FB6 /* PR_more@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 134116EF1CB529E1005E6550 /* PR_more@3x.png */; }; + B1D5F1C020BC06CB00983FB6 /* share_btn_wxsession@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2BF3CD1B96CDF800A5A0A8 /* share_btn_wxsession@2x.png */; }; + B1D5F1C120BC06CB00983FB6 /* task_activity_icon_MergeRequestBean@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E3DB53B1BFDD0F40062BA52 /* task_activity_icon_MergeRequestBean@2x.png */; }; + B1D5F1C220BC06CB00983FB6 /* icon_file_txt@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E96E7D51A1B537E0037C098 /* icon_file_txt@2x.png */; }; + B1D5F1C320BC06CB00983FB6 /* project_item_member@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C8712F1EADF155003DACF0 /* project_item_member@3x.png */; }; + B1D5F1C420BC06CB00983FB6 /* timeline_line_unread@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CFAE19E240C40076D59C /* timeline_line_unread@2x.png */; }; + B1D5F1C520BC06CB00983FB6 /* tip_2FA@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E94C4F01B4B75DB00EB668A /* tip_2FA@2x.png */; }; + B1D5F1C620BC06CB00983FB6 /* PR_add_label@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1280CF3200EFEA400DEDF78 /* PR_add_label@3x.png */; }; + B1D5F1C720BC06CB00983FB6 /* back_T_Nav@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871201EADF0FF003DACF0 /* back_T_Nav@2x.png */; }; + B1D5F1C820BC06CB00983FB6 /* checkbox_checked@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871591EB182C7003DACF0 /* checkbox_checked@3x.png */; }; + B1D5F1C920BC06CB00983FB6 /* coding_emoji_05@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE781A0C7E26006F9AD7 /* coding_emoji_05@2x.png */; }; + B1D5F1CA20BC06CB00983FB6 /* alipay@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8951FCE93830098B87B /* alipay@2x.png */; }; + B1D5F1CC20BC06CB00983FB6 /* taskPriority0@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E63839B1B3262D300D98648 /* taskPriority0@2x.png */; }; + B1D5F1CD20BC06CB00983FB6 /* task_activity_icon_update_label@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E0EF6EB1BF42E4B00F2FCC8 /* task_activity_icon_update_label@2x.png */; }; + B1D5F1CE20BC06CB00983FB6 /* wiki_menu_2@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1890C1F2015D82600F52ABA /* wiki_menu_2@3x.png */; }; + B1D5F1CF20BC06CB00983FB6 /* blankpage_image_Tip@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E9423D21E69401B0095F1CD /* blankpage_image_Tip@2x.png */; }; + B1D5F1D020BC06CB00983FB6 /* keyboard_add_camera@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E97CE581A0A3424006F9AD7 /* keyboard_add_camera@2x.png */; }; + B1D5F1D120BC06CB00983FB6 /* btn_fliter_down@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447E81C02DBC200DC1C4B /* btn_fliter_down@3x.png */; }; + B1D5F1D220BC06CB00983FB6 /* topic-ios.html in Resources */ = {isa = PBXBuildFile; fileRef = B177F5C32060E6B1006709C2 /* topic-ios.html */; }; + B1D5F1D320BC06CB00983FB6 /* user_info_help@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ED4B4791D82646000EED8C6 /* user_info_help@2x.png */; }; + B1D5F1D420BC06CB00983FB6 /* SVWebViewControllerActivitySafari-iPad.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E217F051A70EDC700F6DF88 /* SVWebViewControllerActivitySafari-iPad.png */; }; + B1D5F1D520BC06CB00983FB6 /* icon_triangle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD0591E544006008AA957 /* icon_triangle@2x.png */; }; + B1D5F1D620BC06CB00983FB6 /* comment_count_top_line@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EF6434F19FF4E1600F7EEB0 /* comment_count_top_line@2x.png */; }; + B1D5F1D720BC06CB00983FB6 /* keyboard_voice_record@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E335D9B1B6F5E94003D0F3D /* keyboard_voice_record@2x.png */; }; + B1D5F1D820BC06CB00983FB6 /* icon_file_music_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB87A1FCD006C0098B87B /* icon_file_music_big@2x.png */; }; + B1D5F1D920BC06CB00983FB6 /* password_unlook@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EB52F0D1C74691B00B5EBEA /* password_unlook@2x.png */; }; + B1D5F1DA20BC06CB00983FB6 /* coding_emoji_gif_03@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2DB3411BA6AEB4002F27C4 /* coding_emoji_gif_03@2x.png */; }; + B1D5F1DB20BC06CB00983FB6 /* mrpr_icon_arrow@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAAD09B1E5D8558008AA957 /* mrpr_icon_arrow@2x.png */; }; + B1D5F1DC20BC06CB00983FB6 /* vip_3_45@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689A91EE100B200B01371 /* vip_3_45@3x.png */; }; + B1D5F1DD20BC06CB00983FB6 /* splitlineImg@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF9A19E240C40076D59C /* splitlineImg@2x.png */; }; + B1D5F1DE20BC06CB00983FB6 /* button_file_move_enable@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5CAE202D7D4F0075A669 /* button_file_move_enable@3x.png */; }; + B1D5F1DF20BC06CB00983FB6 /* wiki_menu_0@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1890C1E2015D82600F52ABA /* wiki_menu_0@2x.png */; }; + B1D5F1E020BC06CB00983FB6 /* icon_release_tag_blue@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B17CC31220731E900077C956 /* icon_release_tag_blue@3x.png */; }; + B1D5F1E120BC06CB00983FB6 /* search_icon_topic@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9401E02911E00DE1BC6 /* search_icon_topic@2x.png */; }; + B1D5F1E220BC06CB00983FB6 /* file_activity_icon_delete_history@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2BF3BB1B957D4F00A5A0A8 /* file_activity_icon_delete_history@2x.png */; }; + B1D5F1E320BC06CB00983FB6 /* icon_file_unknown_big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1BCB8741FCD006B0098B87B /* icon_file_unknown_big@2x.png */; }; + B1D5F1E420BC06CB00983FB6 /* sex_woman_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EA6CF9919E240C40076D59C /* sex_woman_icon@2x.png */; }; + B1D5F1E520BC06CB00983FB6 /* privatemessage_selected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447D51C02DB8900DC1C4B /* privatemessage_selected@3x.png */; }; + B1D5F1E620BC06CB00983FB6 /* tipIcon_TaskComment@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E7612F31A08B1EA005BE797 /* tipIcon_TaskComment@2x.png */; }; + B1D5F1E720BC06CB00983FB6 /* taskDeadline@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383DD1B32676600D98648 /* taskDeadline@2x.png */; }; + B1D5F1E820BC06CB00983FB6 /* AddReviewerViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 136526881CAABA2E00C0341D /* AddReviewerViewController.xib */; }; + B1D5F1E920BC06CB00983FB6 /* shop_exchange_icon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 927AFF491BFF6DAD00AAE593 /* shop_exchange_icon@3x.png */; }; + B1D5F1EA20BC06CB00983FB6 /* vip_3_40@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B14689A71EE100B200B01371 /* vip_3_40@3x.png */; }; + B1D5F1EC20BC06CB00983FB6 /* button_file_activity@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAE06A51B7B1AE100179F4B /* button_file_activity@2x.png */; }; + B1D5F1ED20BC06CB00983FB6 /* file_activity_icon_update_file@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EAE06BE1B7B51AF00179F4B /* file_activity_icon_update_file@2x.png */; }; + B1D5F1EE20BC06CB00983FB6 /* nav_project_code@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8EC911281A027A54009EAE99 /* nav_project_code@2x.png */; }; + B1D5F1EF20BC06CB00983FB6 /* user_info_project@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ED4B47E1D82646000EED8C6 /* user_info_project@3x.png */; }; + B1D5F1F020BC06CB00983FB6 /* taskBoardList@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B152ED80209453E7004A6E8A /* taskBoardList@2x.png */; }; + B1D5F1F120BC06CB00983FB6 /* coding_emoji_gif_08@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2DB33C1BA6A1FC002F27C4 /* coding_emoji_gif_08@2x.png */; }; + B1D5F1F220BC06CB00983FB6 /* icon_project_private@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D09E6AB91BF829A1009D37F8 /* icon_project_private@2x.png */; }; + B1D5F1F320BC06CB00983FB6 /* search_Nav@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447F01C02DCA200DC1C4B /* search_Nav@2x.png */; }; + B1D5F1F420BC06CB00983FB6 /* terminal_box_selected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1AB5C97202953E40075A669 /* terminal_box_selected@3x.png */; }; + B1D5F1F520BC06CB00983FB6 /* twoFABtn_Nav@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EED9DD01B53BBCF000E5827 /* twoFABtn_Nav@2x.png */; }; + B1D5F1F620BC06CB00983FB6 /* project_selected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447D71C02DB8900DC1C4B /* project_selected@3x.png */; }; + B1D5F1F720BC06CB00983FB6 /* task_activity_icon_MergeRequestBean@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1C871971EB2D9E6003DACF0 /* task_activity_icon_MergeRequestBean@3x.png */; }; + B1D5F1F820BC06CB00983FB6 /* tweet_selected@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C447DB1C02DB8900DC1C4B /* tweet_selected@3x.png */; }; + B1D5F1F920BC06CB00983FB6 /* taskPriority3@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E6383A11B3262D300D98648 /* taskPriority3@2x.png */; }; + B1D5F1FA20BC06CB00983FB6 /* search_icon_file@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E80E9421E02911E00DE1BC6 /* search_icon_file@2x.png */; }; + B1D5F1FB20BC06CB00983FB6 /* nav_page_unselected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E53EB581AFB090E0034FE1C /* nav_page_unselected@2x.png */; }; + B1D5F20A20BCF6A900983FB6 /* Launch Screen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4EFE8DB81B3A5727004B7559 /* Launch Screen.xib */; }; + B1D5F20E20BD3BF400983FB6 /* UINavigationController+FullscreenPopGesture.m in Sources */ = {isa = PBXBuildFile; fileRef = B1D5F20D20BD3BF300983FB6 /* UINavigationController+FullscreenPopGesture.m */; }; + B1D5F20F20BD3BF400983FB6 /* UINavigationController+FullscreenPopGesture.m in Sources */ = {isa = PBXBuildFile; fileRef = B1D5F20D20BD3BF300983FB6 /* UINavigationController+FullscreenPopGesture.m */; }; + B1D5F21620BD485D00983FB6 /* TeamPurchaseOrder.m in Sources */ = {isa = PBXBuildFile; fileRef = B1D5F21220BD485B00983FB6 /* TeamPurchaseOrder.m */; }; + B1D5F21720BD485D00983FB6 /* TeamPurchaseOrder.m in Sources */ = {isa = PBXBuildFile; fileRef = B1D5F21220BD485B00983FB6 /* TeamPurchaseOrder.m */; }; + B1D5F21820BD485D00983FB6 /* TeamPurchaseBilling.m in Sources */ = {isa = PBXBuildFile; fileRef = B1D5F21320BD485B00983FB6 /* TeamPurchaseBilling.m */; }; + B1D5F21920BD485D00983FB6 /* TeamPurchaseBilling.m in Sources */ = {isa = PBXBuildFile; fileRef = B1D5F21320BD485B00983FB6 /* TeamPurchaseBilling.m */; }; + B1D5F21A20BD485D00983FB6 /* TeamPurchaseBillingDetail.m in Sources */ = {isa = PBXBuildFile; fileRef = B1D5F21520BD485C00983FB6 /* TeamPurchaseBillingDetail.m */; }; + B1D5F21B20BD485D00983FB6 /* TeamPurchaseBillingDetail.m in Sources */ = {isa = PBXBuildFile; fileRef = B1D5F21520BD485C00983FB6 /* TeamPurchaseBillingDetail.m */; }; + B1D5F21E20BD50D000983FB6 /* ProjectRole.m in Sources */ = {isa = PBXBuildFile; fileRef = B1D5F21D20BD50D000983FB6 /* ProjectRole.m */; }; + B1D5F21F20BD50D000983FB6 /* ProjectRole.m in Sources */ = {isa = PBXBuildFile; fileRef = B1D5F21D20BD50D000983FB6 /* ProjectRole.m */; }; + B1D5F22220BEA37600983FB6 /* MeRootCompanyCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B1D5F22120BEA37500983FB6 /* MeRootCompanyCell.m */; }; + B1D5F22320BEA37600983FB6 /* MeRootCompanyCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B1D5F22120BEA37500983FB6 /* MeRootCompanyCell.m */; }; + B1D5F23220BEADD200983FB6 /* TeamSupportCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B1D5F23020BEADD100983FB6 /* TeamSupportCell.m */; }; + B1D5F23320BEADD200983FB6 /* TeamSupportCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B1D5F23020BEADD100983FB6 /* TeamSupportCell.m */; }; + B1DFD0A120C67D3F00F75F2F /* btn_followed_yes@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1DFD09D20C67D3D00F75F2F /* btn_followed_yes@3x.png */; }; + B1DFD0A220C67D3F00F75F2F /* btn_followed_yes@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1DFD09D20C67D3D00F75F2F /* btn_followed_yes@3x.png */; }; + B1DFD0A320C67D3F00F75F2F /* btn_followed_not@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1DFD09E20C67D3E00F75F2F /* btn_followed_not@3x.png */; }; + B1DFD0A420C67D3F00F75F2F /* btn_followed_not@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1DFD09E20C67D3E00F75F2F /* btn_followed_not@3x.png */; }; + B1DFD0A520C67D3F00F75F2F /* btn_followed_both@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1DFD09F20C67D3E00F75F2F /* btn_followed_both@3x.png */; }; + B1DFD0A620C67D3F00F75F2F /* btn_followed_both@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1DFD09F20C67D3E00F75F2F /* btn_followed_both@3x.png */; }; + B1DFD0A720C67D3F00F75F2F /* btn_privateMsg_friend@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1DFD0A020C67D3E00F75F2F /* btn_privateMsg_friend@3x.png */; }; + B1DFD0A820C67D3F00F75F2F /* btn_privateMsg_friend@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B1DFD0A020C67D3E00F75F2F /* btn_privateMsg_friend@3x.png */; }; B93D904B1ACBA3110057A6EE /* ProjectDeleteAlertControllerVisualStyle.m in Sources */ = {isa = PBXBuildFile; fileRef = B93D904A1ACBA3110057A6EE /* ProjectDeleteAlertControllerVisualStyle.m */; }; B94C1B691AC945D30000C271 /* NewProjectViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B94C1B681AC945D30000C271 /* NewProjectViewController.m */; }; - B94C1B6B1AC945FB0000C271 /* NewProject.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B94C1B6A1AC945FB0000C271 /* NewProject.storyboard */; }; B94C1B6E1AC98CCE0000C271 /* NewProjectTypeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B94C1B6D1AC98CCE0000C271 /* NewProjectTypeViewController.m */; }; B9A00D7F1ACA3A05008BA008 /* ProjectSetting.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B9A00D7E1ACA3A05008BA008 /* ProjectSetting.storyboard */; }; B9A00D821ACA3A17008BA008 /* ProjectSettingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B9A00D811ACA3A17008BA008 /* ProjectSettingViewController.m */; }; @@ -1181,13 +3203,55 @@ D0C448151C02F76600DC1C4B /* icon_search_searchbar@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0C448131C02F76600DC1C4B /* icon_search_searchbar@3x.png */; }; D0C448181C03187100DC1C4B /* TaskSearchCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D0C448171C03187100DC1C4B /* TaskSearchCell.m */; }; D0C4481B1C034C3F00DC1C4B /* TopicSearchCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D0C4481A1C034C3F00DC1C4B /* TopicSearchCell.m */; }; - D0FE4DB81C103FA0006E5A76 /* git_icon_fork_old@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0FE4DB51C103FA0006E5A76 /* git_icon_fork_old@2x.png */; }; - D0FE4DB91C103FA0006E5A76 /* git_icon_star_old@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0FE4DB61C103FA0006E5A76 /* git_icon_star_old@2x.png */; }; - D0FE4DBA1C103FA0006E5A76 /* git_icon_watch_old@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0FE4DB71C103FA0006E5A76 /* git_icon_watch_old@2x.png */; }; E7A046A01A47279E00528C12 /* Helper.m in Sources */ = {isa = PBXBuildFile; fileRef = E7A0469F1A47279E00528C12 /* Helper.m */; }; /* End PBXBuildFile section */ +/* Begin PBXCopyFilesBuildPhase section */ + 4E3068251E0B77DF00AEE0CE /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + B1D5F1FD20BC06CB00983FB6 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + /* Begin PBXFileReference section */ + 09A0587E1E0AA97000C1CA3F /* ActivenessModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActivenessModel.h; sourceTree = ""; }; + 09A0587F1E0AA97000C1CA3F /* ActivenessModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ActivenessModel.m; sourceTree = ""; }; + 09A058811E0AA9AE00C1CA3F /* ActivityMonScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActivityMonScrollView.h; sourceTree = ""; }; + 09A058821E0AA9AE00C1CA3F /* ActivityMonScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ActivityMonScrollView.m; sourceTree = ""; }; + 09A058831E0AA9AE00C1CA3F /* ActivityView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActivityView.h; sourceTree = ""; }; + 09A058841E0AA9AE00C1CA3F /* ActivityView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ActivityView.m; sourceTree = ""; }; + 09A058871E0AA9AE00C1CA3F /* UserActiveStatusView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserActiveStatusView.h; sourceTree = ""; }; + 09A058881E0AA9AE00C1CA3F /* UserActiveStatusView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UserActiveStatusView.m; sourceTree = ""; }; + 09A0588D1E0AA9D600C1CA3F /* UserActiveGraphCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserActiveGraphCell.h; sourceTree = ""; }; + 09A0588E1E0AA9D600C1CA3F /* UserActiveGraphCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UserActiveGraphCell.m; sourceTree = ""; }; + 09A058901E0AA9FB00C1CA3F /* EaseUserInfoCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EaseUserInfoCell.h; sourceTree = ""; }; + 09A058911E0AA9FB00C1CA3F /* EaseUserInfoCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EaseUserInfoCell.m; sourceTree = ""; }; + 09A058931E0AAA2F00C1CA3F /* TaskSelectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TaskSelectionView.h; sourceTree = ""; }; + 09A058941E0AAA2F00C1CA3F /* TaskSelectionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TaskSelectionView.m; sourceTree = ""; }; + 09A058961E0AAA5300C1CA3F /* ScreenView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScreenView.h; sourceTree = ""; }; + 09A058971E0AAA5300C1CA3F /* ScreenView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ScreenView.m; sourceTree = ""; }; + 09A058991E0AAA7200C1CA3F /* ScreenCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScreenCell.h; sourceTree = ""; }; + 09A0589A1E0AAA7200C1CA3F /* ScreenCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ScreenCell.m; sourceTree = ""; }; + 09A0589C1E0AAA8800C1CA3F /* TaskSelectionCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TaskSelectionCell.h; sourceTree = ""; }; + 09A0589D1E0AAA8800C1CA3F /* TaskSelectionCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TaskSelectionCell.m; sourceTree = ""; }; + 09A0589F1E0AAACA00C1CA3F /* TagsScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TagsScrollView.h; sourceTree = ""; }; + 09A058A01E0AAACA00C1CA3F /* TagsScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TagsScrollView.m; sourceTree = ""; }; 0A03E6D11ABD0F690034BB8E /* LocationHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocationHelper.h; sourceTree = ""; }; 0A03E6D21ABD0F690034BB8E /* LocationHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LocationHelper.m; sourceTree = ""; }; 0A0519DF1ABA918100551B61 /* TweetSendDetailLoctionCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TweetSendDetailLoctionCell.h; sourceTree = ""; }; @@ -1262,9 +3326,6 @@ 13FB5D1A1CA17A6400EE127C /* PR_push@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PR_push@3x.png"; sourceTree = ""; }; 13FB5D1B1CA17A6400EE127C /* PR_update_content@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PR_update_content@2x.png"; sourceTree = ""; }; 13FB5D1C1CA17A6400EE127C /* PR_update_content@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PR_update_content@3x.png"; sourceTree = ""; }; - 13FB5D1D1CA17A6400EE127C /* EPointLikeHead@1x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "EPointLikeHead@1x.png"; sourceTree = ""; }; - 13FB5D1E1CA17A6400EE127C /* EPointLikeHead@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "EPointLikeHead@2x.png"; sourceTree = ""; }; - 13FB5D1F1CA17A6400EE127C /* EPointLikeHead@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "EPointLikeHead@3x.png"; sourceTree = ""; }; 13FB5D201CA17A6400EE127C /* PR_refuse@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PR_refuse@2x.png"; sourceTree = ""; }; 13FB5D211CA17A6400EE127C /* PR_refuse@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PR_refuse@3x.png"; sourceTree = ""; }; 13FB5D221CA17A6400EE127C /* PR_grant_undo@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PR_grant_undo@2x.png"; sourceTree = ""; }; @@ -1273,12 +3334,10 @@ 13FB5D251CA17A6400EE127C /* merge-request coding@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "merge-request coding@3x.png"; sourceTree = ""; }; 13FB5D261CA17A6400EE127C /* PR_mergeChanges@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PR_mergeChanges@2x.png"; sourceTree = ""; }; 13FB5D271CA17A6400EE127C /* PR_mergeChanges@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PR_mergeChanges@3x.png"; sourceTree = ""; }; - 13FB5D281CA17A6400EE127C /* PointLikeHead@1x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PointLikeHead@1x.png"; sourceTree = ""; }; 13FB5D291CA17A6400EE127C /* PointLikeHead@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PointLikeHead@2x.png"; sourceTree = ""; }; 13FB5D2A1CA17A6400EE127C /* PointLikeHead@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PointLikeHead@3x.png"; sourceTree = ""; }; 13FB5D2B1CA17A6400EE127C /* PR_review@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PR_review@2x.png"; sourceTree = ""; }; 13FB5D2C1CA17A6400EE127C /* PR_review@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PR_review@3x.png"; sourceTree = ""; }; - 13FB5D2D1CA17A6400EE127C /* PRReviewer@1x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PRReviewer@1x.png"; sourceTree = ""; }; 13FB5D2E1CA17A6400EE127C /* PRReviewer@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PRReviewer@2x.png"; sourceTree = ""; }; 13FB5D2F1CA17A6400EE127C /* PRReviewer@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PRReviewer@3x.png"; sourceTree = ""; }; 13FB5D301CA17A6400EE127C /* PR_review_undo@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PR_review_undo@2x.png"; sourceTree = ""; }; @@ -1287,7 +3346,10 @@ 13FB5D351CA17A6400EE127C /* PR_grant@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PR_grant@3x.png"; sourceTree = ""; }; 13FB5D571CA194D600EE127C /* MRReviewerCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MRReviewerCell.h; path = Cell/MRReviewerCell.h; sourceTree = ""; }; 13FB5D581CA194D600EE127C /* MRReviewerCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MRReviewerCell.m; path = Cell/MRReviewerCell.m; sourceTree = ""; }; - 1F50C85531CF9D72938EE577 /* Pods-Coding_iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Coding_iOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-Coding_iOS/Pods-Coding_iOS.release.xcconfig"; sourceTree = ""; }; + 22A08D8B77355DB8A773B8E2 /* Pods-Coding_iOS-Coding_Enterprise_iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Coding_iOS-Coding_Enterprise_iOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-Coding_iOS-Coding_Enterprise_iOS/Pods-Coding_iOS-Coding_Enterprise_iOS.release.xcconfig"; sourceTree = ""; }; + 2FD5D8DD0689696D28A6D49E /* Pods-Coding_iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Coding_iOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-Coding_iOS/Pods-Coding_iOS.release.xcconfig"; sourceTree = ""; }; + 344214A4A1281EB0C9B3DE71 /* Pods-Coding_iOS-CodingEnterprise_iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Coding_iOS-CodingEnterprise_iOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Coding_iOS-CodingEnterprise_iOS/Pods-Coding_iOS-CodingEnterprise_iOS.debug.xcconfig"; sourceTree = ""; }; + 34E37865A7DAAE68AEF68258 /* Pods-Coding_iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Coding_iOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Coding_iOS/Pods-Coding_iOS.debug.xcconfig"; sourceTree = ""; }; 3A3878351AE293D50078D5DE /* EditLabelViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EditLabelViewController.h; sourceTree = ""; }; 3A3878361AE293D50078D5DE /* EditLabelViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EditLabelViewController.m; sourceTree = ""; }; 3A3878381AE2949E0078D5DE /* ResetLabelViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResetLabelViewController.h; sourceTree = ""; }; @@ -1304,7 +3366,6 @@ 3A38784B1AE36EF00078D5DE /* TopicListView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TopicListView.m; sourceTree = ""; }; 3A38784D1AE557700078D5DE /* TopicPreviewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TopicPreviewCell.h; sourceTree = ""; }; 3A38784E1AE557700078D5DE /* TopicPreviewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TopicPreviewCell.m; sourceTree = ""; }; - 3B024F2227BD4152BC7C9A7A /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; 4E0022811B72095E005308DE /* PointRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PointRecord.h; sourceTree = ""; }; 4E0022821B72095E005308DE /* PointRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PointRecord.m; sourceTree = ""; }; 4E0022841B720966005308DE /* PointRecords.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PointRecords.h; sourceTree = ""; }; @@ -1325,10 +3386,6 @@ 4E00229B1B735075005308DE /* EAIntroView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EAIntroView.m; sourceTree = ""; }; 4E00229E1B7360B1005308DE /* FunctionIntroManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FunctionIntroManager.h; sourceTree = ""; }; 4E00229F1B7360B1005308DE /* FunctionIntroManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FunctionIntroManager.m; sourceTree = ""; }; - 4E0022A21B7362EF005308DE /* intro_page0_ip4@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page0_ip4@2x.png"; sourceTree = ""; }; - 4E0022A31B7362EF005308DE /* intro_page0_ip5@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page0_ip5@2x.png"; sourceTree = ""; }; - 4E0022A41B7362EF005308DE /* intro_page0_ip6+@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page0_ip6+@3x.png"; sourceTree = ""; }; - 4E0022A51B7362EF005308DE /* intro_page0_ip6@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page0_ip6@2x.png"; sourceTree = ""; }; 4E03AC991A5BDDF9002B000B /* STARTIMAGE.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = STARTIMAGE.jpg; sourceTree = ""; }; 4E03ACA41A5D2060002B000B /* UIVerticalAlignmentLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIVerticalAlignmentLabel.h; sourceTree = ""; }; 4E03ACA51A5D2060002B000B /* UIVerticalAlignmentLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIVerticalAlignmentLabel.m; sourceTree = ""; }; @@ -1338,18 +3395,12 @@ 4E07D30C1A4A9F45009EDDF2 /* btn_file_reDo@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_file_reDo@2x.png"; sourceTree = ""; }; 4E07D30F1A4D1484009EDDF2 /* EaseStartView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EaseStartView.h; sourceTree = ""; }; 4E07D3101A4D1484009EDDF2 /* EaseStartView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EaseStartView.m; sourceTree = ""; }; - 4E07D3121A4D3CA6009EDDF2 /* icon_user_monkey@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_user_monkey@2x.png"; sourceTree = ""; }; - 4E07D3131A4D3CA6009EDDF2 /* logo_coding@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "logo_coding@2x.png"; sourceTree = ""; }; 4E08497A1A918A7F00BD27F6 /* coding_emoji_38@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "coding_emoji_38@2x.png"; sourceTree = ""; }; 4E08497B1A918A7F00BD27F6 /* coding_emoji_39@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "coding_emoji_39@2x.png"; sourceTree = ""; }; 4E08497C1A918A7F00BD27F6 /* coding_emoji_40@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "coding_emoji_40@2x.png"; sourceTree = ""; }; 4E08497D1A918A7F00BD27F6 /* coding_emoji_41@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "coding_emoji_41@2x.png"; sourceTree = ""; }; 4E08497E1A918A7F00BD27F6 /* coding_emoji_42@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "coding_emoji_42@2x.png"; sourceTree = ""; }; 4E08497F1A918A7F00BD27F6 /* coding_emoji_43@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "coding_emoji_43@2x.png"; sourceTree = ""; }; - 4E095A111D9534CB00E63D9E /* intro_page_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page_selected@2x.png"; sourceTree = ""; }; - 4E095A121D9534CB00E63D9E /* intro_page_selected@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page_selected@3x.png"; sourceTree = ""; }; - 4E095A131D9534CB00E63D9E /* intro_page_unselected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page_unselected@2x.png"; sourceTree = ""; }; - 4E095A141D9534CB00E63D9E /* intro_page_unselected@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page_unselected@3x.png"; sourceTree = ""; }; 4E095A571B690494008DC439 /* CodingBanner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodingBanner.h; sourceTree = ""; }; 4E095A581B690494008DC439 /* CodingBanner.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CodingBanner.m; sourceTree = ""; }; 4E095A5A1B6907AA008DC439 /* CodingBannersView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodingBannersView.h; sourceTree = ""; }; @@ -1360,11 +3411,6 @@ 4E095A631B6909F9008DC439 /* NSTimer+Addition.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSTimer+Addition.m"; sourceTree = ""; }; 4E095A6B1B69F920008DC439 /* banner__page_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "banner__page_selected@2x.png"; sourceTree = ""; }; 4E095A6C1B69F920008DC439 /* banner__page_unselected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "banner__page_unselected@2x.png"; sourceTree = ""; }; - 4E095A761B6B1E40008DC439 /* calendar_0x95B763@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "calendar_0x95B763@2x.png"; sourceTree = ""; }; - 4E095A771B6B1E40008DC439 /* calendar_0x9AAFC2@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "calendar_0x9AAFC2@2x.png"; sourceTree = ""; }; - 4E095A781B6B1E40008DC439 /* calendar_0xB5B5B5@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "calendar_0xB5B5B5@2x.png"; sourceTree = ""; }; - 4E095A791B6B1E40008DC439 /* calendar_0xF24B4B@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "calendar_0xF24B4B@2x.png"; sourceTree = ""; }; - 4E095A7A1B6B1E40008DC439 /* calendar_0xF5A523@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "calendar_0xF5A523@2x.png"; sourceTree = ""; }; 4E095A801B6B24DE008DC439 /* task_description_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "task_description_icon@2x.png"; sourceTree = ""; }; 4E095A811B6B24DE008DC439 /* time_clock_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "time_clock_icon@2x.png"; sourceTree = ""; }; 4E095A821B6B24DE008DC439 /* topic_comment_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "topic_comment_icon@2x.png"; sourceTree = ""; }; @@ -1415,8 +3461,6 @@ 4E15C7CF1A26D2F000FB8DAD /* FolderToMoveViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FolderToMoveViewController.m; sourceTree = ""; }; 4E15C7D41A271A6300FB8DAD /* EaseToolBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EaseToolBar.h; sourceTree = ""; }; 4E15C7D51A271A6300FB8DAD /* EaseToolBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EaseToolBar.m; sourceTree = ""; }; - 4E19E7051BCE03CD00C66DC6 /* UIActionSheet+Front.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIActionSheet+Front.h"; sourceTree = ""; }; - 4E19E7061BCE03CD00C66DC6 /* UIActionSheet+Front.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIActionSheet+Front.m"; sourceTree = ""; }; 4E1A22801AB1729700CFC14F /* ProjectInfoCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProjectInfoCell.h; sourceTree = ""; }; 4E1A22811AB1729700CFC14F /* ProjectInfoCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProjectInfoCell.m; sourceTree = ""; }; 4E1A22831AB172C400CFC14F /* ProjectItemsCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProjectItemsCell.h; sourceTree = ""; }; @@ -1426,9 +3470,7 @@ 4E1A22891AB1844F00CFC14F /* EaseGitButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EaseGitButton.h; sourceTree = ""; }; 4E1A228A1AB1844F00CFC14F /* EaseGitButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EaseGitButton.m; sourceTree = ""; }; 4E1D99121DCAE67D00BAE585 /* icon_file_folder_out@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_file_folder_out@2x.png"; sourceTree = ""; }; - 4E1D99131DCAE67D00BAE585 /* icon_file_folder_out@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_file_folder_out@3x.png"; sourceTree = ""; }; 4E1D99141DCAE67D00BAE585 /* icon_file_folder_share@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_file_folder_share@2x.png"; sourceTree = ""; }; - 4E1D99151DCAE67D00BAE585 /* icon_file_folder_share@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_file_folder_share@3x.png"; sourceTree = ""; }; 4E1D991A1DCAE69600BAE585 /* icon_file_share_logo@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_file_share_logo@2x.png"; sourceTree = ""; }; 4E1D991B1DCAE69600BAE585 /* icon_file_share_logo@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_file_share_logo@3x.png"; sourceTree = ""; }; 4E217EF81A70EDC700F6DF88 /* SVModalWebViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVModalWebViewController.h; sourceTree = ""; }; @@ -1491,13 +3533,33 @@ 4E2F6A691C43CA4B00A25502 /* member_type_75@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "member_type_75@3x.png"; sourceTree = ""; }; 4E2F6A6A1C43CA4B00A25502 /* member_type_90@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "member_type_90@2x.png"; sourceTree = ""; }; 4E2F6A6B1C43CA4B00A25502 /* member_type_90@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "member_type_90@3x.png"; sourceTree = ""; }; + 4E3068271E0B781A00AEE0CE /* EADeviceToServerLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EADeviceToServerLog.h; sourceTree = ""; }; + 4E3068281E0B781A00AEE0CE /* EADeviceToServerLog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EADeviceToServerLog.m; sourceTree = ""; }; + 4E3068291E0B781A00AEE0CE /* EANetTraceRoute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EANetTraceRoute.h; sourceTree = ""; }; + 4E30682A1E0B781A00AEE0CE /* EANetTraceRoute.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EANetTraceRoute.m; sourceTree = ""; }; + 4E30682C1E0B781A00AEE0CE /* LDNetConnect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LDNetConnect.h; sourceTree = ""; }; + 4E30682D1E0B781A00AEE0CE /* LDNetConnect.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LDNetConnect.m; sourceTree = ""; }; + 4E30682E1E0B781A00AEE0CE /* LDNetDiagnoService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LDNetDiagnoService.h; sourceTree = ""; }; + 4E30682F1E0B781A00AEE0CE /* LDNetDiagnoService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LDNetDiagnoService.m; sourceTree = ""; }; + 4E3068301E0B781A00AEE0CE /* LDNetGetAddress.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LDNetGetAddress.h; sourceTree = ""; }; + 4E3068311E0B781A00AEE0CE /* LDNetGetAddress.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LDNetGetAddress.m; sourceTree = ""; }; + 4E3068321E0B781A00AEE0CE /* LDNetPing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LDNetPing.h; sourceTree = ""; }; + 4E3068331E0B781A00AEE0CE /* LDNetPing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LDNetPing.m; sourceTree = ""; }; + 4E3068341E0B781A00AEE0CE /* LDNetTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LDNetTimer.h; sourceTree = ""; }; + 4E3068351E0B781A00AEE0CE /* LDNetTimer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LDNetTimer.m; sourceTree = ""; }; + 4E3068361E0B781A00AEE0CE /* LDNetTraceRoute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LDNetTraceRoute.h; sourceTree = ""; }; + 4E3068371E0B781A00AEE0CE /* LDNetTraceRoute.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LDNetTraceRoute.m; sourceTree = ""; }; + 4E3068381E0B781A00AEE0CE /* LDSimplePing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LDSimplePing.h; sourceTree = ""; }; + 4E3068391E0B781A00AEE0CE /* LDSimplePing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LDSimplePing.m; sourceTree = ""; }; + 4E30683A1E0B781A00AEE0CE /* Route.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Route.h; sourceTree = ""; }; + 4E30683B1E0B781A00AEE0CE /* NSData+gzip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+gzip.h"; sourceTree = ""; }; + 4E30683C1E0B781A00AEE0CE /* NSData+gzip.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+gzip.m"; sourceTree = ""; }; 4E35A99D1A3EC47E00CE35F1 /* FileViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileViewController.h; sourceTree = ""; }; 4E35A99E1A3EC47E00CE35F1 /* FileViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FileViewController.m; sourceTree = ""; }; 4E38CF5D1A7A28AF005536C0 /* CodeBranchTagButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeBranchTagButton.h; sourceTree = ""; }; 4E38CF5E1A7A28AF005536C0 /* CodeBranchTagButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CodeBranchTagButton.m; sourceTree = ""; }; 4E38CF601A7B7C99005536C0 /* CodeBranchOrTag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeBranchOrTag.h; sourceTree = ""; }; 4E38CF611A7B7C99005536C0 /* CodeBranchOrTag.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CodeBranchOrTag.m; sourceTree = ""; }; - 4E38CF631A7B8DD4005536C0 /* icon_triangle@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_triangle@2x.png"; sourceTree = ""; }; 4E3DB53A1BFDD0F40062BA52 /* task_activity_icon_add_watcher@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "task_activity_icon_add_watcher@2x.png"; sourceTree = ""; }; 4E3DB53B1BFDD0F40062BA52 /* task_activity_icon_MergeRequestBean@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "task_activity_icon_MergeRequestBean@2x.png"; sourceTree = ""; }; 4E44DCF81D81486600E7F9AF /* HelpViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HelpViewController.h; sourceTree = ""; }; @@ -1567,8 +3629,6 @@ 4E4D6AAE1B2047DE00FD2E49 /* CommitCommentCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CommitCommentCell.m; sourceTree = ""; }; 4E4D6AB01B21A96100FD2E49 /* Commits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Commits.h; sourceTree = ""; }; 4E4D6AB11B21A96100FD2E49 /* Commits.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Commits.m; sourceTree = ""; }; - 4E4D6ABF1B252CD400FD2E49 /* icon_code_file@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_code_file@2x.png"; sourceTree = ""; }; - 4E4D6AC01B252CD400FD2E49 /* icon_code_tree@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_code_tree@2x.png"; sourceTree = ""; }; 4E4D6AC71B252F4800FD2E49 /* icon_add_comment@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_add_comment@2x.png"; sourceTree = ""; }; 4E4D6AC91B2571B100FD2E49 /* git_icon_stared@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "git_icon_stared@2x.png"; sourceTree = ""; }; 4E4D6ACA1B2571B100FD2E49 /* git_icon_watched@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "git_icon_watched@2x.png"; sourceTree = ""; }; @@ -1618,8 +3678,6 @@ 4E5F39041ACA958C0010515D /* TopicCommentCCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TopicCommentCCell.m; sourceTree = ""; }; 4E5F39061ACBFDCD0010515D /* keyboard_photo@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "keyboard_photo@2x.png"; sourceTree = ""; }; 4E62410A1B74D65400E1533C /* search_tweet_like@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "search_tweet_like@2x.png"; sourceTree = ""; }; - 4E63189A1BDA198000EFED97 /* MRListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MRListViewController.h; sourceTree = ""; }; - 4E63189B1BDA198000EFED97 /* MRListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MRListViewController.m; sourceTree = ""; }; 4E6318A01BDA261100EFED97 /* MRListView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MRListView.h; sourceTree = ""; }; 4E6318A11BDA261100EFED97 /* MRListView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MRListView.m; sourceTree = ""; }; 4E63839B1B3262D300D98648 /* taskPriority0@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskPriority0@2x.png"; sourceTree = ""; }; @@ -1637,7 +3695,6 @@ 4E6383B51B32640900D98648 /* messageSystem@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "messageSystem@2x.png"; sourceTree = ""; }; 4E6383B61B32640900D98648 /* private_message_send_fail@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "private_message_send_fail@2x.png"; sourceTree = ""; }; 4E6383BE1B3265DC00D98648 /* mrpr_icon_accepted@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mrpr_icon_accepted@2x.png"; sourceTree = ""; }; - 4E6383BF1B3265DC00D98648 /* mrpr_icon_arrow@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mrpr_icon_arrow@2x.png"; sourceTree = ""; }; 4E6383C21B3265DC00D98648 /* mrpr_icon_refaused@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mrpr_icon_refaused@2x.png"; sourceTree = ""; }; 4E6383C91B32665700D98648 /* project_item_activity@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "project_item_activity@2x.png"; sourceTree = ""; }; 4E6383CA1B32665700D98648 /* project_item_code@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "project_item_code@2x.png"; sourceTree = ""; }; @@ -1671,10 +3728,6 @@ 4E66EE231A28226000DA1B3E /* button_file_denete_unable@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_file_denete_unable@2x.png"; sourceTree = ""; }; 4E66EE241A28226000DA1B3E /* button_file_move_enable@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_file_move_enable@2x.png"; sourceTree = ""; }; 4E66EE251A28226000DA1B3E /* button_file_upload_enable@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_file_upload_enable@2x.png"; sourceTree = ""; }; - 4E6B070D1BA3D9B5007D6027 /* intro_page1_ip4@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page1_ip4@2x.png"; sourceTree = ""; }; - 4E6B070E1BA3D9B5007D6027 /* intro_page1_ip5@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page1_ip5@2x.png"; sourceTree = ""; }; - 4E6B070F1BA3D9B5007D6027 /* intro_page1_ip6@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page1_ip6@2x.png"; sourceTree = ""; }; - 4E6B07101BA3D9B5007D6027 /* intro_page1_ip6+@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page1_ip6+@3x.png"; sourceTree = ""; }; 4E6B07151BA4045E007D6027 /* MIDAUTUMNIMAGE.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = MIDAUTUMNIMAGE.jpg; sourceTree = ""; }; 4E6BA2AA1A1EE6AF005FD721 /* AFNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFNetworking.h; sourceTree = ""; }; 4E6BA2AD1A1EE6AF005FD721 /* AFHTTPRequestOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFHTTPRequestOperation.h; sourceTree = ""; }; @@ -1747,7 +3800,6 @@ 4E72F8321B15B811001B6CE6 /* gif_mark@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "gif_mark@2x.png"; sourceTree = ""; }; 4E743E6B1A88A3CC00DADDE5 /* EaseMarkdownTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EaseMarkdownTextView.h; sourceTree = ""; }; 4E743E6C1A88A3CC00DADDE5 /* EaseMarkdownTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EaseMarkdownTextView.m; sourceTree = ""; }; - 4E743E6E1A88ABF700DADDE5 /* blankpage_image_Hi@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_Hi@2x.png"; sourceTree = ""; }; 4E74EBFF1C311B6300EC0E1B /* SettingPhoneViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingPhoneViewController.h; sourceTree = ""; }; 4E74EC001C311B6300EC0E1B /* SettingPhoneViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingPhoneViewController.m; sourceTree = ""; }; 4E753D421B8AFDEC003A00B9 /* FileEditViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileEditViewController.h; sourceTree = ""; }; @@ -1757,6 +3809,34 @@ 4E787DE11B0329B300F06E83 /* ProjectLineNote.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProjectLineNote.m; sourceTree = ""; }; 4E787DE31B03342000F06E83 /* ProjectActivity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProjectActivity.h; sourceTree = ""; }; 4E787DE41B03342000F06E83 /* ProjectActivity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProjectActivity.m; sourceTree = ""; }; + 4E80E9271DFFF06E00DE1BC6 /* shortcut_2FA@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut_2FA@2x.png"; sourceTree = ""; }; + 4E80E9281DFFF06E00DE1BC6 /* shortcut_2FA@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut_2FA@3x.png"; sourceTree = ""; }; + 4E80E9291DFFF06E00DE1BC6 /* shortcut_task@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut_task@2x.png"; sourceTree = ""; }; + 4E80E92A1DFFF06E00DE1BC6 /* shortcut_task@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut_task@3x.png"; sourceTree = ""; }; + 4E80E92B1DFFF06E00DE1BC6 /* shortcut_tweet@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut_tweet@2x.png"; sourceTree = ""; }; + 4E80E92C1DFFF06E00DE1BC6 /* shortcut_tweet@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shortcut_tweet@3x.png"; sourceTree = ""; }; + 4E80E9331E011D6000DE1BC6 /* RewardTipManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RewardTipManager.h; sourceTree = ""; }; + 4E80E9341E011D6000DE1BC6 /* RewardTipManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RewardTipManager.m; sourceTree = ""; }; + 4E80E9361E01218300DE1BC6 /* reward_tip_logo@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "reward_tip_logo@2x.png"; sourceTree = ""; }; + 4E80E9371E01218300DE1BC6 /* reward_tip_logo@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "reward_tip_logo@3x.png"; sourceTree = ""; }; + 4E80E93A1E02353900DE1BC6 /* CodingSearchDisplayView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodingSearchDisplayView.h; sourceTree = ""; }; + 4E80E93B1E02353900DE1BC6 /* CodingSearchDisplayView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CodingSearchDisplayView.m; sourceTree = ""; }; + 4E80E93E1E02911E00DE1BC6 /* search_icon_tweet@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "search_icon_tweet@2x.png"; sourceTree = ""; }; + 4E80E93F1E02911E00DE1BC6 /* search_icon_tweet@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "search_icon_tweet@3x.png"; sourceTree = ""; }; + 4E80E9401E02911E00DE1BC6 /* search_icon_topic@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "search_icon_topic@2x.png"; sourceTree = ""; }; + 4E80E9411E02911E00DE1BC6 /* search_icon_topic@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "search_icon_topic@3x.png"; sourceTree = ""; }; + 4E80E9421E02911E00DE1BC6 /* search_icon_file@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "search_icon_file@2x.png"; sourceTree = ""; }; + 4E80E9431E02911E00DE1BC6 /* search_icon_file@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "search_icon_file@3x.png"; sourceTree = ""; }; + 4E80E9441E02911E00DE1BC6 /* search_icon_mr@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "search_icon_mr@2x.png"; sourceTree = ""; }; + 4E80E9451E02911E00DE1BC6 /* search_icon_mr@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "search_icon_mr@3x.png"; sourceTree = ""; }; + 4E80E9461E02911E00DE1BC6 /* search_icon_user@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "search_icon_user@2x.png"; sourceTree = ""; }; + 4E80E9471E02911E00DE1BC6 /* search_icon_user@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "search_icon_user@3x.png"; sourceTree = ""; }; + 4E80E9481E02911E00DE1BC6 /* search_icon_pr@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "search_icon_pr@2x.png"; sourceTree = ""; }; + 4E80E9491E02911E00DE1BC6 /* search_icon_pr@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "search_icon_pr@3x.png"; sourceTree = ""; }; + 4E80E94A1E02911E00DE1BC6 /* search_icon_project@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "search_icon_project@2x.png"; sourceTree = ""; }; + 4E80E94B1E02911E00DE1BC6 /* search_icon_project@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "search_icon_project@3x.png"; sourceTree = ""; }; + 4E80E94C1E02911E00DE1BC6 /* search_icon_task@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "search_icon_task@2x.png"; sourceTree = ""; }; + 4E80E94D1E02911E00DE1BC6 /* search_icon_task@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "search_icon_task@3x.png"; sourceTree = ""; }; 4E83AE791CF30F1A006BA3BB /* SettingEmailViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingEmailViewController.h; sourceTree = ""; }; 4E83AE7A1CF30F1A006BA3BB /* SettingEmailViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingEmailViewController.m; sourceTree = ""; }; 4E86FEE41BB556D6005E53F3 /* tipIcon_ProjectFileComment@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tipIcon_ProjectFileComment@2x.png"; sourceTree = ""; }; @@ -1810,20 +3890,10 @@ 4E8D5D721B454D5000B70936 /* OTPAuthClock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTPAuthClock.m; sourceTree = ""; }; 4E8D5D7B1B462ADB00B70936 /* OTPTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTPTableViewCell.h; sourceTree = ""; }; 4E8D5D7C1B462ADB00B70936 /* OTPTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTPTableViewCell.m; sourceTree = ""; }; - 4E8F92DB1B67BE3C00033D8F /* icon_user_monkey_i6@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_user_monkey_i6@2x.png"; sourceTree = ""; }; - 4E8F92DC1B67BE3C00033D8F /* icon_user_monkey_i6p@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_user_monkey_i6p@3x.png"; sourceTree = ""; }; - 4E90F8971AF709C100B44F03 /* bubble.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = bubble.html; path = webview/app/build/bubble.html; sourceTree = ""; }; - 4E90F8981AF709C100B44F03 /* code.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = code.html; path = webview/app/build/code.html; sourceTree = ""; }; - 4E90F8991AF709C100B44F03 /* markdown.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = markdown.html; path = webview/app/build/markdown.html; sourceTree = ""; }; - 4E90F89A1AF709C100B44F03 /* topic-ios.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = "topic-ios.html"; path = "webview/app/build/topic-ios.html"; sourceTree = ""; }; 4E91139E1A1C426000AC9431 /* ASPopUpView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASPopUpView.h; sourceTree = ""; }; 4E91139F1A1C426000AC9431 /* ASPopUpView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASPopUpView.m; sourceTree = ""; }; 4E9113A01A1C426000AC9431 /* ASProgressPopUpView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASProgressPopUpView.h; sourceTree = ""; }; 4E9113A11A1C426000AC9431 /* ASProgressPopUpView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASProgressPopUpView.m; sourceTree = ""; }; - 4E9113A51A1CB19900AC9431 /* icon_file_state_download@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_file_state_download@2x.png"; sourceTree = ""; }; - 4E9113A61A1CB19900AC9431 /* icon_file_state_goon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_file_state_goon@2x.png"; sourceTree = ""; }; - 4E9113A71A1CB19900AC9431 /* icon_file_state_look@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_file_state_look@2x.png"; sourceTree = ""; }; - 4E9113A81A1CB19900AC9431 /* icon_file_state_pause@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_file_state_pause@2x.png"; sourceTree = ""; }; 4E93F2311B84243D00017916 /* KxMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KxMenu.h; sourceTree = ""; }; 4E93F2321B84243D00017916 /* KxMenu.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KxMenu.m; sourceTree = ""; }; 4E93F2351B84356500017916 /* file_menu_icon_delete@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "file_menu_icon_delete@2x.png"; sourceTree = ""; }; @@ -1834,6 +3904,34 @@ 4E93F2411B85C4C300017916 /* FileInfoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileInfoViewController.h; sourceTree = ""; }; 4E93F2421B85C4C300017916 /* FileInfoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FileInfoViewController.m; sourceTree = ""; }; 4E93F2431B85C4C300017916 /* FileInfoViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = FileInfoViewController.xib; sourceTree = ""; }; + 4E9423BE1E69401B0095F1CD /* blankpage_image_Activity@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_Activity@2x.png"; sourceTree = ""; }; + 4E9423BF1E69401B0095F1CD /* blankpage_image_Activity@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_Activity@3x.png"; sourceTree = ""; }; + 4E9423C01E69401B0095F1CD /* blankpage_image_Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_Default@2x.png"; sourceTree = ""; }; + 4E9423C11E69401B0095F1CD /* blankpage_image_Default@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_Default@3x.png"; sourceTree = ""; }; + 4E9423C21E69401B0095F1CD /* blankpage_image_File@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_File@2x.png"; sourceTree = ""; }; + 4E9423C31E69401B0095F1CD /* blankpage_image_File@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_File@3x.png"; sourceTree = ""; }; + 4E9423C41E69401B0095F1CD /* blankpage_image_LoadFail@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_LoadFail@2x.png"; sourceTree = ""; }; + 4E9423C51E69401B0095F1CD /* blankpage_image_LoadFail@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_LoadFail@3x.png"; sourceTree = ""; }; + 4E9423C61E69401B0095F1CD /* blankpage_image_MessageList@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_MessageList@2x.png"; sourceTree = ""; }; + 4E9423C71E69401B0095F1CD /* blankpage_image_MessageList@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_MessageList@3x.png"; sourceTree = ""; }; + 4E9423C81E69401B0095F1CD /* blankpage_image_Notice@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_Notice@2x.png"; sourceTree = ""; }; + 4E9423C91E69401B0095F1CD /* blankpage_image_Notice@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_Notice@3x.png"; sourceTree = ""; }; + 4E9423CA1E69401B0095F1CD /* blankpage_image_Project@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_Project@2x.png"; sourceTree = ""; }; + 4E9423CB1E69401B0095F1CD /* blankpage_image_Project@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_Project@3x.png"; sourceTree = ""; }; + 4E9423CC1E69401B0095F1CD /* blankpage_image_ShopOrder@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_ShopOrder@2x.png"; sourceTree = ""; }; + 4E9423CD1E69401B0095F1CD /* blankpage_image_ShopOrder@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_ShopOrder@3x.png"; sourceTree = ""; }; + 4E9423CE1E69401B0095F1CD /* blankpage_image_Task@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_Task@2x.png"; sourceTree = ""; }; + 4E9423CF1E69401B0095F1CD /* blankpage_image_Task@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_Task@3x.png"; sourceTree = ""; }; + 4E9423D01E69401B0095F1CD /* blankpage_image_Team@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_Team@2x.png"; sourceTree = ""; }; + 4E9423D11E69401B0095F1CD /* blankpage_image_Team@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_Team@3x.png"; sourceTree = ""; }; + 4E9423D21E69401B0095F1CD /* blankpage_image_Tip@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_Tip@2x.png"; sourceTree = ""; }; + 4E9423D31E69401B0095F1CD /* blankpage_image_Tip@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_Tip@3x.png"; sourceTree = ""; }; + 4E9423D41E69401B0095F1CD /* blankpage_image_Topic@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_Topic@2x.png"; sourceTree = ""; }; + 4E9423D51E69401B0095F1CD /* blankpage_image_Topic@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_Topic@3x.png"; sourceTree = ""; }; + 4E9423D61E69401B0095F1CD /* blankpage_image_Tweet@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_Tweet@2x.png"; sourceTree = ""; }; + 4E9423D71E69401B0095F1CD /* blankpage_image_Tweet@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_Tweet@3x.png"; sourceTree = ""; }; + 4E9423D81E69401B0095F1CD /* blankpage_image_Wiki@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_Wiki@2x.png"; sourceTree = ""; }; + 4E9423D91E69401B0095F1CD /* blankpage_image_Wiki@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_Wiki@3x.png"; sourceTree = ""; }; 4E94C4E51B4A6AC700EB668A /* ScanBGView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScanBGView.h; sourceTree = ""; }; 4E94C4E61B4A6AC700EB668A /* ScanBGView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ScanBGView.m; sourceTree = ""; }; 4E94C4EC1B4A867A00EB668A /* scan_bg@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "scan_bg@2x.png"; sourceTree = ""; }; @@ -1902,6 +4000,7 @@ 4E996BFD1ABBF56A00C704F1 /* n_sex_man_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "n_sex_man_icon@2x.png"; sourceTree = ""; }; 4E996BFE1ABBF56A00C704F1 /* n_sex_woman_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "n_sex_woman_icon@2x.png"; sourceTree = ""; }; 4E996BFF1ABBF56A00C704F1 /* user_info_detail@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "user_info_detail@2x.png"; sourceTree = ""; }; + 4E9DEEC51E30CA3C001B8D1B /* keyboard_emotion_emoji_code@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "keyboard_emotion_emoji_code@2x.png"; sourceTree = ""; }; 4E9E3B731DCC2DB10005FD79 /* HtmlMediaViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HtmlMediaViewController.h; sourceTree = ""; }; 4E9E3B741DCC2DB10005FD79 /* HtmlMediaViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HtmlMediaViewController.m; sourceTree = ""; }; 4E9F5D1F1C03051D007CCDCC /* tipIcon_tweetReward@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tipIcon_tweetReward@2x.png"; sourceTree = ""; }; @@ -1917,8 +4016,6 @@ 4EA679181A14BFA0001A0324 /* icon_file_folder_normal@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_file_folder_normal@2x.png"; sourceTree = ""; }; 4EA6791B1A15A943001A0324 /* FileListFolderCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileListFolderCell.h; sourceTree = ""; }; 4EA6791C1A15A943001A0324 /* FileListFolderCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FileListFolderCell.m; sourceTree = ""; }; - 4EA6791E1A15AB9F001A0324 /* FileListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileListViewController.h; sourceTree = ""; }; - 4EA6791F1A15AB9F001A0324 /* FileListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FileListViewController.m; sourceTree = ""; }; 4EA7F1391A6D192B00A046BD /* NSData+ImageContentType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+ImageContentType.h"; sourceTree = ""; }; 4EA7F13A1A6D192B00A046BD /* NSData+ImageContentType.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+ImageContentType.m"; sourceTree = ""; }; 4EA7F13B1A6D192B00A046BD /* SDImageCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDImageCache.h; sourceTree = ""; }; @@ -1950,6 +4047,38 @@ 4EA7F1551A6D192B00A046BD /* UIView+WebCacheOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+WebCacheOperation.m"; sourceTree = ""; }; 4EA7F1571A6D192B00A046BD /* ODRefreshControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ODRefreshControl.h; sourceTree = ""; }; 4EA7F1581A6D192B00A046BD /* ODRefreshControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ODRefreshControl.m; sourceTree = ""; }; + 4EAAD0121E5306F3008AA957 /* MRPRListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MRPRListViewController.h; sourceTree = ""; }; + 4EAAD0131E5306F3008AA957 /* MRPRListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MRPRListViewController.m; sourceTree = ""; }; + 4EAAD0151E53EFF2008AA957 /* EAFliterMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EAFliterMenu.h; sourceTree = ""; }; + 4EAAD0161E53EFF2008AA957 /* EAFliterMenu.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EAFliterMenu.m; sourceTree = ""; }; + 4EAAD0191E540551008AA957 /* mrpr_icon_status_accepted@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mrpr_icon_status_accepted@2x.png"; sourceTree = ""; }; + 4EAAD01A1E540551008AA957 /* mrpr_icon_status_accepted@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mrpr_icon_status_accepted@3x.png"; sourceTree = ""; }; + 4EAAD01B1E540551008AA957 /* mrpr_icon_status_canmerge@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mrpr_icon_status_canmerge@2x.png"; sourceTree = ""; }; + 4EAAD01C1E540551008AA957 /* mrpr_icon_status_canmerge@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mrpr_icon_status_canmerge@3x.png"; sourceTree = ""; }; + 4EAAD01D1E540551008AA957 /* mrpr_icon_status_cannotmerge@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mrpr_icon_status_cannotmerge@2x.png"; sourceTree = ""; }; + 4EAAD01E1E540551008AA957 /* mrpr_icon_status_cannotmerge@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mrpr_icon_status_cannotmerge@3x.png"; sourceTree = ""; }; + 4EAAD01F1E540551008AA957 /* mrpr_icon_status_refused@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mrpr_icon_status_refused@2x.png"; sourceTree = ""; }; + 4EAAD0201E540551008AA957 /* mrpr_icon_status_refused@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mrpr_icon_status_refused@3x.png"; sourceTree = ""; }; + 4EAAD0291E5405B4008AA957 /* mrpr_icon_status_cancel@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mrpr_icon_status_cancel@2x.png"; sourceTree = ""; }; + 4EAAD02A1E5405B4008AA957 /* mrpr_icon_status_cancel@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mrpr_icon_status_cancel@3x.png"; sourceTree = ""; }; + 4EAAD0491E542B2D008AA957 /* icon_code_executable@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_code_executable@2x.png"; sourceTree = ""; }; + 4EAAD04A1E542B2D008AA957 /* icon_code_executable@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_code_executable@3x.png"; sourceTree = ""; }; + 4EAAD04B1E542B2D008AA957 /* icon_code_tree@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_code_tree@2x.png"; sourceTree = ""; }; + 4EAAD04C1E542B2D008AA957 /* icon_code_tree@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_code_tree@3x.png"; sourceTree = ""; }; + 4EAAD04D1E542B2D008AA957 /* icon_code_file@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_code_file@2x.png"; sourceTree = ""; }; + 4EAAD04E1E542B2D008AA957 /* icon_code_file@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_code_file@3x.png"; sourceTree = ""; }; + 4EAAD04F1E542B2D008AA957 /* icon_code_git_link@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_code_git_link@2x.png"; sourceTree = ""; }; + 4EAAD0501E542B2D008AA957 /* icon_code_git_link@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_code_git_link@3x.png"; sourceTree = ""; }; + 4EAAD0591E544006008AA957 /* icon_triangle@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_triangle@2x.png"; sourceTree = ""; }; + 4EAAD05A1E544006008AA957 /* icon_triangle@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_triangle@3x.png"; sourceTree = ""; }; + 4EAAD05D1E545516008AA957 /* ProjectCodeListSearchCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProjectCodeListSearchCell.h; sourceTree = ""; }; + 4EAAD05E1E545516008AA957 /* ProjectCodeListSearchCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProjectCodeListSearchCell.m; sourceTree = ""; }; + 4EAAD0801E55AC6E008AA957 /* icon_code_image@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_code_image@2x.png"; sourceTree = ""; }; + 4EAAD0811E55AC6E008AA957 /* icon_code_image@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_code_image@3x.png"; sourceTree = ""; }; + 4EAAD09B1E5D8558008AA957 /* mrpr_icon_arrow@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mrpr_icon_arrow@2x.png"; sourceTree = ""; }; + 4EAAD09C1E5D8558008AA957 /* mrpr_icon_arrow@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mrpr_icon_arrow@3x.png"; sourceTree = ""; }; + 4EAAD0A31E5D8D90008AA957 /* PR_plus@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PR_plus@2x.png"; sourceTree = ""; }; + 4EAAD0A41E5D8D90008AA957 /* PR_plus@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PR_plus@3x.png"; sourceTree = ""; }; 4EABD2521AD3CA7E005E515F /* UIMessageInputView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIMessageInputView.h; sourceTree = ""; }; 4EABD2531AD3CA7E005E515F /* UIMessageInputView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIMessageInputView.m; sourceTree = ""; }; 4EABD2551AD3CAAC005E515F /* UIMessageInputView_Add.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIMessageInputView_Add.h; sourceTree = ""; }; @@ -1985,7 +4114,6 @@ 4EAE06BD1B7B51AF00179F4B /* file_activity_icon_move_file@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "file_activity_icon_move_file@2x.png"; sourceTree = ""; }; 4EAE06BE1B7B51AF00179F4B /* file_activity_icon_update_file@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "file_activity_icon_update_file@2x.png"; sourceTree = ""; }; 4EAE06BF1B7B51AF00179F4B /* file_activity_icon_upload_file@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "file_activity_icon_upload_file@2x.png"; sourceTree = ""; }; - 4EAE06C41B7B587200179F4B /* button_file_comment@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_file_comment@2x.png"; sourceTree = ""; }; 4EAE06C61B7C9EFF00179F4B /* FileVersionCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileVersionCell.h; sourceTree = ""; }; 4EAE06C71B7C9EFF00179F4B /* FileVersionCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FileVersionCell.m; sourceTree = ""; }; 4EAECBBC1C44CB860096CA74 /* member_cell_edit_alias@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "member_cell_edit_alias@2x.png"; sourceTree = ""; }; @@ -1996,10 +4124,6 @@ 4EAECBC11C44CB860096CA74 /* member_cell_edit_type@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "member_cell_edit_type@3x.png"; sourceTree = ""; }; 4EB0C1FE1A807ED00042FC4F /* NSURL+Common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURL+Common.h"; sourceTree = ""; }; 4EB0C1FF1A807ED00042FC4F /* NSURL+Common.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURL+Common.m"; sourceTree = ""; }; - 4EB119F41D953AE200A36341 /* intro_page2_ip4@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page2_ip4@2x.png"; sourceTree = ""; }; - 4EB119F51D953AE200A36341 /* intro_page2_ip5@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page2_ip5@2x.png"; sourceTree = ""; }; - 4EB119F61D953AE200A36341 /* intro_page2_ip6@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page2_ip6@2x.png"; sourceTree = ""; }; - 4EB119F71D953AE200A36341 /* intro_page2_ip6+@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page2_ip6+@3x.png"; sourceTree = ""; }; 4EB52F0B1C74691B00B5EBEA /* password_look@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "password_look@2x.png"; sourceTree = ""; }; 4EB52F0C1C74691B00B5EBEA /* password_look@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "password_look@3x.png"; sourceTree = ""; }; 4EB52F0D1C74691B00B5EBEA /* password_unlook@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "password_unlook@2x.png"; sourceTree = ""; }; @@ -2019,7 +4143,6 @@ 4EB52F291C76ED7000B5EBEA /* TagColorDisplayCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TagColorDisplayCell.h; sourceTree = ""; }; 4EB52F2A1C76ED7000B5EBEA /* TagColorDisplayCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TagColorDisplayCell.m; sourceTree = ""; }; 4EB52F2C1C77138A00B5EBEA /* button_scan@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_scan@2x.png"; sourceTree = ""; }; - 4EB52F2D1C77138A00B5EBEA /* button_scan@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_scan@3x.png"; sourceTree = ""; }; 4EB52F361C7C38F600B5EBEA /* ResourceReference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResourceReference.h; sourceTree = ""; }; 4EB52F371C7C38F600B5EBEA /* ResourceReference.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ResourceReference.m; sourceTree = ""; }; 4EB52F391C7C45E700B5EBEA /* taskResourceReference@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskResourceReference@2x.png"; sourceTree = ""; }; @@ -2036,20 +4159,6 @@ 4EB52F591C7C5C4F00B5EBEA /* task_resource_reference_ProjectTopic@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "task_resource_reference_ProjectTopic@3x.png"; sourceTree = ""; }; 4EB52F5A1C7C5C4F00B5EBEA /* task_resource_reference_Task@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "task_resource_reference_Task@2x.png"; sourceTree = ""; }; 4EB52F5B1C7C5C4F00B5EBEA /* task_resource_reference_Task@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "task_resource_reference_Task@3x.png"; sourceTree = ""; }; - 4EB5A9341BF1DB4600C23AC3 /* libSocialSinaSSO.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libSocialSinaSSO.a; sourceTree = ""; }; - 4EB5A9351BF1DB4600C23AC3 /* libWeiboSDK.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libWeiboSDK.a; sourceTree = ""; }; - 4EB5A9361BF1DB4600C23AC3 /* UMSocialSinaSSOHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UMSocialSinaSSOHandler.h; sourceTree = ""; }; - 4EB5A9371BF1DB4600C23AC3 /* WBHttpRequest+WeiboGame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "WBHttpRequest+WeiboGame.h"; sourceTree = ""; }; - 4EB5A9381BF1DB4600C23AC3 /* WBHttpRequest+WeiboShare.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "WBHttpRequest+WeiboShare.h"; sourceTree = ""; }; - 4EB5A9391BF1DB4600C23AC3 /* WBHttpRequest+WeiboToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "WBHttpRequest+WeiboToken.h"; sourceTree = ""; }; - 4EB5A93A1BF1DB4600C23AC3 /* WBHttpRequest+WeiboUser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "WBHttpRequest+WeiboUser.h"; sourceTree = ""; }; - 4EB5A93B1BF1DB4600C23AC3 /* WBHttpRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WBHttpRequest.h; sourceTree = ""; }; - 4EB5A93C1BF1DB4600C23AC3 /* WBSDKBasicButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WBSDKBasicButton.h; sourceTree = ""; }; - 4EB5A93D1BF1DB4600C23AC3 /* WBSDKCommentButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WBSDKCommentButton.h; sourceTree = ""; }; - 4EB5A93E1BF1DB4600C23AC3 /* WBSDKRelationshipButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WBSDKRelationshipButton.h; sourceTree = ""; }; - 4EB5A93F1BF1DB4600C23AC3 /* WeiboSDK.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = WeiboSDK.bundle; sourceTree = ""; }; - 4EB5A9401BF1DB4600C23AC3 /* WeiboSDK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeiboSDK.h; sourceTree = ""; }; - 4EB5A9411BF1DB4600C23AC3 /* WeiboUser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeiboUser.h; sourceTree = ""; }; 4EB862AC1CABB21E008074D1 /* tipIcon_TeamMember@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tipIcon_TeamMember@2x.png"; sourceTree = ""; }; 4EBB62481A6F526C0045DAEF /* NJKWebViewProgress.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NJKWebViewProgress.h; sourceTree = ""; }; 4EBB62491A6F526C0045DAEF /* NJKWebViewProgress.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NJKWebViewProgress.m; sourceTree = ""; }; @@ -2061,8 +4170,6 @@ 4EBD7FB01CE482A400B3AF49 /* country_code.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = country_code.plist; sourceTree = ""; }; 4EBD7FB21CE4833D00B3AF49 /* CountryCodeCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CountryCodeCell.h; sourceTree = ""; }; 4EBD7FB31CE4833D00B3AF49 /* CountryCodeCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CountryCodeCell.m; sourceTree = ""; }; - 4EBDA87A1A6640340035ED96 /* UIActionSheet+Common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIActionSheet+Common.h"; sourceTree = ""; }; - 4EBDA87B1A6640340035ED96 /* UIActionSheet+Common.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIActionSheet+Common.m"; sourceTree = ""; }; 4EBDC27A1BC501C00037EB66 /* tipIcon_ProjectPayment@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tipIcon_ProjectPayment@2x.png"; sourceTree = ""; }; 4EBED55A1D93C9F700E3684E /* Coding_iOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Coding_iOS.entitlements; sourceTree = ""; }; 4EBFBD171AA85B8500E4B10E /* add_user_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "add_user_icon@2x.png"; sourceTree = ""; }; @@ -2148,8 +4255,6 @@ 4ECF702B1B1704C5000280FF /* NProjectItemCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NProjectItemCell.m; sourceTree = ""; }; 4ECF703E1B180740000280FF /* EaseGitButtonsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EaseGitButtonsView.h; sourceTree = ""; }; 4ECF703F1B180740000280FF /* EaseGitButtonsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EaseGitButtonsView.m; sourceTree = ""; }; - 4ECF70411B18514F000280FF /* PRListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PRListViewController.h; sourceTree = ""; }; - 4ECF70421B18514F000280FF /* PRListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PRListViewController.m; sourceTree = ""; }; 4ECF70441B18557E000280FF /* MRPRS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MRPRS.h; sourceTree = ""; }; 4ECF70451B18557E000280FF /* MRPRS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MRPRS.m; sourceTree = ""; }; 4ECF70471B185BCC000280FF /* MRPR.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MRPR.h; sourceTree = ""; }; @@ -2230,8 +4335,6 @@ 4EE1A21C1B5D02CA004284F1 /* ProjectActivityListView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProjectActivityListView.m; sourceTree = ""; }; 4EE1A21D1B5D02CA004284F1 /* ProjectCodeListView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProjectCodeListView.h; sourceTree = ""; }; 4EE1A21E1B5D02CA004284F1 /* ProjectCodeListView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProjectCodeListView.m; sourceTree = ""; }; - 4EE1A21F1B5D02CA004284F1 /* ProjectFolderListView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProjectFolderListView.h; sourceTree = ""; }; - 4EE1A2201B5D02CA004284F1 /* ProjectFolderListView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProjectFolderListView.m; sourceTree = ""; }; 4EE1A2211B5D02CA004284F1 /* ProjectListView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProjectListView.h; sourceTree = ""; }; 4EE1A2221B5D02CA004284F1 /* ProjectListView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProjectListView.m; sourceTree = ""; }; 4EE1A2231B5D02CA004284F1 /* ProjectTaskListView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProjectTaskListView.h; sourceTree = ""; }; @@ -2257,36 +4360,6 @@ 4EED9DD01B53BBCF000E5827 /* twoFABtn_Nav@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "twoFABtn_Nav@2x.png"; sourceTree = ""; }; 4EF17E5D1B3AB10F003CDD2D /* IntroductionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntroductionViewController.h; sourceTree = ""; }; 4EF17E5E1B3AB10F003CDD2D /* IntroductionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IntroductionViewController.m; sourceTree = ""; }; - 4EF17EAD1B3C3112003CDD2D /* intro_dot_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_dot_selected@2x.png"; sourceTree = ""; }; - 4EF17EAE1B3C3112003CDD2D /* intro_dot_selected@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_dot_selected@3x.png"; sourceTree = ""; }; - 4EF17EAF1B3C3112003CDD2D /* intro_dot_unselected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_dot_unselected@2x.png"; sourceTree = ""; }; - 4EF17EB01B3C3112003CDD2D /* intro_dot_unselected@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_dot_unselected@3x.png"; sourceTree = ""; }; - 4EF17EB11B3C3112003CDD2D /* intro_icon_0@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_0@2x.png"; sourceTree = ""; }; - 4EF17EB21B3C3112003CDD2D /* intro_icon_0@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_0@3x.png"; sourceTree = ""; }; - 4EF17EB31B3C3112003CDD2D /* intro_icon_1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_1@2x.png"; sourceTree = ""; }; - 4EF17EB41B3C3112003CDD2D /* intro_icon_1@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_1@3x.png"; sourceTree = ""; }; - 4EF17EB51B3C3112003CDD2D /* intro_icon_2@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_2@2x.png"; sourceTree = ""; }; - 4EF17EB61B3C3112003CDD2D /* intro_icon_2@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_2@3x.png"; sourceTree = ""; }; - 4EF17EB71B3C3112003CDD2D /* intro_icon_3@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_3@2x.png"; sourceTree = ""; }; - 4EF17EB81B3C3112003CDD2D /* intro_icon_3@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_3@3x.png"; sourceTree = ""; }; - 4EF17EB91B3C3112003CDD2D /* intro_icon_4@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_4@2x.png"; sourceTree = ""; }; - 4EF17EBA1B3C3112003CDD2D /* intro_icon_4@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_4@3x.png"; sourceTree = ""; }; - 4EF17EBB1B3C3112003CDD2D /* intro_icon_5@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_5@2x.png"; sourceTree = ""; }; - 4EF17EBC1B3C3112003CDD2D /* intro_icon_5@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_5@3x.png"; sourceTree = ""; }; - 4EF17EBD1B3C3112003CDD2D /* intro_icon_6@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_6@3x.png"; sourceTree = ""; }; - 4EF17EBE1B3C3112003CDD2D /* intro_tip_0@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_tip_0@2x.png"; sourceTree = ""; }; - 4EF17EBF1B3C3112003CDD2D /* intro_tip_0@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_tip_0@3x.png"; sourceTree = ""; }; - 4EF17EC01B3C3112003CDD2D /* intro_tip_1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_tip_1@2x.png"; sourceTree = ""; }; - 4EF17EC11B3C3112003CDD2D /* intro_tip_1@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_tip_1@3x.png"; sourceTree = ""; }; - 4EF17EC21B3C3112003CDD2D /* intro_tip_2@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_tip_2@2x.png"; sourceTree = ""; }; - 4EF17EC31B3C3112003CDD2D /* intro_tip_2@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_tip_2@3x.png"; sourceTree = ""; }; - 4EF17EC41B3C3112003CDD2D /* intro_tip_3@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_tip_3@2x.png"; sourceTree = ""; }; - 4EF17EC51B3C3112003CDD2D /* intro_tip_3@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_tip_3@3x.png"; sourceTree = ""; }; - 4EF17EC61B3C3112003CDD2D /* intro_tip_4@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_tip_4@2x.png"; sourceTree = ""; }; - 4EF17EC71B3C3112003CDD2D /* intro_tip_4@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_tip_4@3x.png"; sourceTree = ""; }; - 4EF17EC81B3C3112003CDD2D /* intro_tip_5@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_tip_5@2x.png"; sourceTree = ""; }; - 4EF17EC91B3C3112003CDD2D /* intro_tip_5@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_tip_5@3x.png"; sourceTree = ""; }; - 4EF17ECA1B3C3112003CDD2D /* intro_icon_6@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_6@2x.png"; sourceTree = ""; }; 4EF374141BB1254700DDA662 /* LocalFoldersViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocalFoldersViewController.h; sourceTree = ""; }; 4EF374151BB1254700DDA662 /* LocalFoldersViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LocalFoldersViewController.m; sourceTree = ""; }; 4EF374171BB1255E00DDA662 /* LocalFilesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocalFilesViewController.h; sourceTree = ""; }; @@ -2307,6 +4380,10 @@ 4EFE8DAB1B394A0D004B7559 /* file_changeType_RENAME@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "file_changeType_RENAME@2x.png"; sourceTree = ""; }; 4EFE8DAE1B3960E6004B7559 /* logo_coding_top@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "logo_coding_top@2x.png"; sourceTree = ""; }; 4EFE8DB81B3A5727004B7559 /* Launch Screen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = "Launch Screen.xib"; sourceTree = ""; }; + 4EFF5A761E0AE54800683D03 /* libresolv.9.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libresolv.9.tbd; path = usr/lib/libresolv.9.tbd; sourceTree = SDKROOT; }; + 59EA81AF0F8C7610F675E1EB /* Pods-Coding_iOS-Coding_Enterprise_iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Coding_iOS-Coding_Enterprise_iOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Coding_iOS-Coding_Enterprise_iOS/Pods-Coding_iOS-Coding_Enterprise_iOS.debug.xcconfig"; sourceTree = ""; }; + 627CA7E44F0D5A025A49E2F0 /* libPods-Coding_iOS-Coding_Enterprise_iOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Coding_iOS-Coding_Enterprise_iOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 645969FE6A8616A74543C249 /* libPods-Coding_iOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Coding_iOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 7E335D9A1B6F5E94003D0F3D /* keyboard_arrow_down@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "keyboard_arrow_down@2x.png"; sourceTree = ""; }; 7E335D9B1B6F5E94003D0F3D /* keyboard_voice_record@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "keyboard_voice_record@2x.png"; sourceTree = ""; }; 7E335D9C1B6F5E94003D0F3D /* keyboard_voice@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "keyboard_voice@2x.png"; sourceTree = ""; }; @@ -2342,7 +4419,6 @@ 7EB02FF51B6DAF3800D2166C /* AudioVolumeView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AudioVolumeView.m; sourceTree = ""; }; 7EB02FFA1B6E001300D2166C /* VoiceMedia.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VoiceMedia.h; sourceTree = ""; }; 7EB02FFB1B6E001300D2166C /* VoiceMedia.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VoiceMedia.m; sourceTree = ""; }; - 8B18B0211092D3903D031B13 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; 8B35164A1B6CE9460049BC45 /* icon_arrow_searchHistory@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_arrow_searchHistory@2x.png"; sourceTree = ""; }; 8B35164B1B6CE9460049BC45 /* icon_topic_hotTop@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_topic_hotTop@2x.png"; sourceTree = ""; }; 8B35164C1B6CE9460049BC45 /* search_tweet_colck@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "search_tweet_colck@2x.png"; sourceTree = ""; }; @@ -2387,9 +4463,6 @@ 8E477017198770E700997D05 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 8E477019198770E700997D05 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 8E477031198770E700997D05 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; - 8E525C8219F7E3F800496B34 /* blankpage_button_reload@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_button_reload@2x.png"; sourceTree = ""; }; - 8E525C8319F7E3F800496B34 /* blankpage_image_loadFail@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_loadFail@2x.png"; sourceTree = ""; }; - 8E525C8619F7E3F800496B34 /* blankpage_image_Sleep@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blankpage_image_Sleep@2x.png"; sourceTree = ""; }; 8E59F0DD1A0098BA009A905F /* SVPullToRefresh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVPullToRefresh.h; sourceTree = ""; }; 8E59F0DE1A0098BA009A905F /* UIScrollView+SVInfiniteScrolling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIScrollView+SVInfiniteScrolling.h"; sourceTree = ""; }; 8E59F0DF1A0098BA009A905F /* UIScrollView+SVInfiniteScrolling.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIScrollView+SVInfiniteScrolling.m"; sourceTree = ""; }; @@ -2411,27 +4484,6 @@ 8E59F10C1A02188D009A905F /* CodeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CodeViewController.m; sourceTree = ""; }; 8E61D27A19C028CC00C00414 /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = System/Library/Frameworks/AssetsLibrary.framework; sourceTree = SDKROOT; }; 8E62ADD919E28DA800963870 /* tipIcon_User@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tipIcon_User@2x.png"; sourceTree = ""; }; - 8E64ED6619ED0CE3006E99DA /* QBAssetsCollectionCheckmarkView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBAssetsCollectionCheckmarkView.h; sourceTree = ""; }; - 8E64ED6719ED0CE3006E99DA /* QBAssetsCollectionCheckmarkView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBAssetsCollectionCheckmarkView.m; sourceTree = ""; }; - 8E64ED6819ED0CE3006E99DA /* QBAssetsCollectionFooterView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBAssetsCollectionFooterView.h; sourceTree = ""; }; - 8E64ED6919ED0CE3006E99DA /* QBAssetsCollectionFooterView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBAssetsCollectionFooterView.m; sourceTree = ""; }; - 8E64ED6A19ED0CE3006E99DA /* QBAssetsCollectionOverlayView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBAssetsCollectionOverlayView.h; sourceTree = ""; }; - 8E64ED6B19ED0CE3006E99DA /* QBAssetsCollectionOverlayView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBAssetsCollectionOverlayView.m; sourceTree = ""; }; - 8E64ED6C19ED0CE3006E99DA /* QBAssetsCollectionVideoIndicatorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBAssetsCollectionVideoIndicatorView.h; sourceTree = ""; }; - 8E64ED6D19ED0CE3006E99DA /* QBAssetsCollectionVideoIndicatorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBAssetsCollectionVideoIndicatorView.m; sourceTree = ""; }; - 8E64ED6E19ED0CE3006E99DA /* QBAssetsCollectionViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBAssetsCollectionViewCell.h; sourceTree = ""; }; - 8E64ED6F19ED0CE3006E99DA /* QBAssetsCollectionViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBAssetsCollectionViewCell.m; sourceTree = ""; }; - 8E64ED7019ED0CE3006E99DA /* QBAssetsCollectionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBAssetsCollectionViewController.h; sourceTree = ""; }; - 8E64ED7119ED0CE3006E99DA /* QBAssetsCollectionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBAssetsCollectionViewController.m; sourceTree = ""; }; - 8E64ED7219ED0CE3006E99DA /* QBAssetsCollectionViewLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBAssetsCollectionViewLayout.h; sourceTree = ""; }; - 8E64ED7319ED0CE3006E99DA /* QBAssetsCollectionViewLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBAssetsCollectionViewLayout.m; sourceTree = ""; }; - 8E64ED7419ED0CE3006E99DA /* QBImagePickerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBImagePickerController.h; sourceTree = ""; }; - 8E64ED7519ED0CE3006E99DA /* QBImagePickerController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBImagePickerController.m; sourceTree = ""; }; - 8E64ED7619ED0CE3006E99DA /* QBImagePickerController.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; path = QBImagePickerController.strings; sourceTree = ""; }; - 8E64ED7719ED0CE3006E99DA /* QBImagePickerGroupCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBImagePickerGroupCell.h; sourceTree = ""; }; - 8E64ED7819ED0CE3006E99DA /* QBImagePickerGroupCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBImagePickerGroupCell.m; sourceTree = ""; }; - 8E64ED7919ED0CE3006E99DA /* QBImagePickerThumbnailView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBImagePickerThumbnailView.h; sourceTree = ""; }; - 8E64ED7A19ED0CE3006E99DA /* QBImagePickerThumbnailView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBImagePickerThumbnailView.m; sourceTree = ""; }; 8E64ED8719EE484A006E99DA /* NSDate+Helper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDate+Helper.h"; sourceTree = ""; }; 8E64ED8819EE484A006E99DA /* NSDate+Helper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDate+Helper.m"; sourceTree = ""; }; 8E64ED8919EE484A006E99DA /* README.textile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.textile; sourceTree = ""; }; @@ -2442,10 +4494,8 @@ 8E8F7B2219EF6306006BA8BD /* btn_followed_both@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_followed_both@2x.png"; sourceTree = ""; }; 8E8F7B2319EF6306006BA8BD /* btn_followed_not@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_followed_not@2x.png"; sourceTree = ""; }; 8E8F7B2419EF6306006BA8BD /* btn_followed_yes@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_followed_yes@2x.png"; sourceTree = ""; }; - 8E8F7B2519EF6306006BA8BD /* btn_privateMsg_black@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_privateMsg_black@2x.png"; sourceTree = ""; }; 8E8F7B2619EF6306006BA8BD /* btn_privateMsg_friend@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_privateMsg_friend@2x.png"; sourceTree = ""; }; 8E8F7B2719EF6306006BA8BD /* btn_privateMsg_stranger@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_privateMsg_stranger@2x.png"; sourceTree = ""; }; - 8E8F7B2819EF6306006BA8BD /* btn_privateMsg_white@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_privateMsg_white@2x.png"; sourceTree = ""; }; 8E8F7B2919EF6306006BA8BD /* btn_project_add@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_project_add@2x.png"; sourceTree = ""; }; 8E8F7B2A19EF6306006BA8BD /* btn_project_added@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_project_added@2x.png"; sourceTree = ""; }; 8E8F7B2B19EF6306006BA8BD /* btn_project_quit@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_project_quit@2x.png"; sourceTree = ""; }; @@ -2824,13 +4874,559 @@ 927AFF491BFF6DAD00AAE593 /* shop_exchange_icon@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shop_exchange_icon@3x.png"; sourceTree = ""; }; 927AFF4A1BFF6DAD00AAE593 /* shop_nar_history_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shop_nar_history_icon@2x.png"; sourceTree = ""; }; 927AFF4B1BFF6DAD00AAE593 /* shop_nar_history_icon@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shop_nar_history_icon@3x.png"; sourceTree = ""; }; - 927AFF4C1BFF6DAD00AAE593 /* shop_unexchange_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shop_unexchange_icon@2x.png"; sourceTree = ""; }; - 927AFF4D1BFF6DAD00AAE593 /* shop_unexchange_icon@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shop_unexchange_icon@3x.png"; sourceTree = ""; }; 927AFF561BFF755200AAE593 /* ExchangeGoodsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExchangeGoodsViewController.h; sourceTree = ""; }; 927AFF571BFF755200AAE593 /* ExchangeGoodsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExchangeGoodsViewController.m; sourceTree = ""; }; 927AFF591BFF772A00AAE593 /* ShopOrderTextFieldCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShopOrderTextFieldCell.h; sourceTree = ""; }; 927AFF5A1BFF772A00AAE593 /* ShopOrderTextFieldCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShopOrderTextFieldCell.m; sourceTree = ""; }; - A64F1BDEE7EF5AF0AEA5F032 /* Pods-Coding_iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Coding_iOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Coding_iOS/Pods-Coding_iOS.debug.xcconfig"; sourceTree = ""; }; + B10341272024633800853447 /* logo_coding@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "logo_coding@2x.png"; sourceTree = ""; }; + B10341282024633900853447 /* logo_coding@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "logo_coding@3x.png"; sourceTree = ""; }; + B11DC7BE20245727004E76A9 /* button_terminal@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_terminal@2x.png"; sourceTree = ""; }; + B11DC7BF20245728004E76A9 /* button_terminal@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_terminal@3x.png"; sourceTree = ""; }; + B1280CE8200EFDC600DEDF78 /* file_changeType_RENAME@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "file_changeType_RENAME@3x.png"; sourceTree = ""; }; + B1280CE9200EFDC600DEDF78 /* file_changeType_ADD@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "file_changeType_ADD@3x.png"; sourceTree = ""; }; + B1280CEA200EFDC600DEDF78 /* file_changeType_COPY@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "file_changeType_COPY@3x.png"; sourceTree = ""; }; + B1280CEB200EFDC600DEDF78 /* file_changeType_DELETE@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "file_changeType_DELETE@3x.png"; sourceTree = ""; }; + B1280CEC200EFDC600DEDF78 /* file_changeType_MODIFY@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "file_changeType_MODIFY@3x.png"; sourceTree = ""; }; + B1280CF3200EFEA400DEDF78 /* PR_add_label@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PR_add_label@3x.png"; sourceTree = ""; }; + B1280CF4200EFEA400DEDF78 /* PR_add_watcher@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PR_add_watcher@2x.png"; sourceTree = ""; }; + B1280CF5200EFEA400DEDF78 /* PR_del_label@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PR_del_label@3x.png"; sourceTree = ""; }; + B1280CF6200EFEA400DEDF78 /* PR_del_watcher@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PR_del_watcher@2x.png"; sourceTree = ""; }; + B1280CF7200EFEA400DEDF78 /* PR_add_reviewer@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PR_add_reviewer@3x.png"; sourceTree = ""; }; + B1280CF8200EFEA400DEDF78 /* PR_add_reviewer@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PR_add_reviewer@2x.png"; sourceTree = ""; }; + B1280CF9200EFEA400DEDF78 /* PR_del_watcher@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PR_del_watcher@3x.png"; sourceTree = ""; }; + B1280CFA200EFEA400DEDF78 /* PR_del_label@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PR_del_label@2x.png"; sourceTree = ""; }; + B1280CFB200EFEA400DEDF78 /* PR_add_watcher@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PR_add_watcher@3x.png"; sourceTree = ""; }; + B1280CFC200EFEA400DEDF78 /* PR_add_label@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PR_add_label@2x.png"; sourceTree = ""; }; + B1280CFD200EFEA400DEDF78 /* PR_del_reviewer@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PR_del_reviewer@2x.png"; sourceTree = ""; }; + B1280CFE200EFEA400DEDF78 /* PR_del_reviewer@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "PR_del_reviewer@3x.png"; sourceTree = ""; }; + B12B63F51FE8A77200ACFDCC /* WeiboSDK.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = WeiboSDK.bundle; sourceTree = ""; }; + B12B63F71FE8FF0300ACFDCC /* MartFunctionTipView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MartFunctionTipView.h; sourceTree = ""; }; + B12B63F81FE8FF0300ACFDCC /* MartFunctionTipView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MartFunctionTipView.m; sourceTree = ""; }; + B12B63FB1FE900D400ACFDCC /* AMPopTip+Animation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "AMPopTip+Animation.m"; sourceTree = ""; }; + B12B63FC1FE900D400ACFDCC /* AMPopTip+Entrance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AMPopTip+Entrance.h"; sourceTree = ""; }; + B12B63FD1FE900D400ACFDCC /* AMPopTip.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AMPopTip.m; sourceTree = ""; }; + B12B63FE1FE900D400ACFDCC /* AMPopTipDefaults.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AMPopTipDefaults.h; sourceTree = ""; }; + B12B63FF1FE900D400ACFDCC /* AMPopTip+Draw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AMPopTip+Draw.h"; sourceTree = ""; }; + B12B64001FE900D400ACFDCC /* AMPopTip+Exit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AMPopTip+Exit.h"; sourceTree = ""; }; + B12B64011FE900D400ACFDCC /* AMPopTip+Animation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AMPopTip+Animation.h"; sourceTree = ""; }; + B12B64021FE900D400ACFDCC /* AMPopTip+Entrance.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "AMPopTip+Entrance.m"; sourceTree = ""; }; + B12B64031FE900D400ACFDCC /* AMPopTip+Draw.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "AMPopTip+Draw.m"; sourceTree = ""; }; + B12B64041FE900D400ACFDCC /* AMPopTip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AMPopTip.h; sourceTree = ""; }; + B12B64051FE900D400ACFDCC /* AMPopTip+Exit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "AMPopTip+Exit.m"; sourceTree = ""; }; + B12B640C1FECB58F00ACFDCC /* login_wechat@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "login_wechat@3x.png"; sourceTree = ""; }; + B12B640D1FECB58F00ACFDCC /* login_wechat@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "login_wechat@2x.png"; sourceTree = ""; }; + B12B64101FF0D54800ACFDCC /* SettingSkillsViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SettingSkillsViewController.h; sourceTree = ""; }; + B12B64111FF0D54800ACFDCC /* SettingSkillsViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SettingSkillsViewController.m; sourceTree = ""; }; + B12B64131FF0DE4800ACFDCC /* SkillCCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SkillCCell.h; sourceTree = ""; }; + B12B64141FF0DE4800ACFDCC /* SkillCCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SkillCCell.m; sourceTree = ""; }; + B12B64161FF0E4CA00ACFDCC /* skill_delete@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "skill_delete@2x.png"; sourceTree = ""; }; + B12B64171FF0E4CA00ACFDCC /* skill_delete@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "skill_delete@3x.png"; sourceTree = ""; }; + B12B641A1FF0F5E300ACFDCC /* JDStatusBarLayoutMarginHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JDStatusBarLayoutMarginHelper.h; sourceTree = ""; }; + B12B641B1FF0F5E300ACFDCC /* JDStatusBarLayoutMarginHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JDStatusBarLayoutMarginHelper.m; sourceTree = ""; }; + B12B641D1FF2835800ACFDCC /* CodingVipTipManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CodingVipTipManager.h; sourceTree = ""; }; + B12B641E1FF2835800ACFDCC /* CodingVipTipManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CodingVipTipManager.m; sourceTree = ""; }; + B12B64201FF33DFE00ACFDCC /* button_red_close@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_red_close@3x.png"; sourceTree = ""; }; + B12B64211FF33DFF00ACFDCC /* button_red_close@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_red_close@2x.png"; sourceTree = ""; }; + B12B64221FF33DFF00ACFDCC /* button_tip_close@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_tip_close@3x.png"; sourceTree = ""; }; + B12B64231FF33DFF00ACFDCC /* upgrade_success@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "upgrade_success@2x.png"; sourceTree = ""; }; + B12B64241FF33E0000ACFDCC /* upgrade_success@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "upgrade_success@3x.png"; sourceTree = ""; }; + B12B64251FF33E0000ACFDCC /* button_tip_close@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_tip_close@2x.png"; sourceTree = ""; }; + B12B64571FFB61AD00ACFDCC /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; + B12B64581FFB61AD00ACFDCC /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + B12B645B1FFB61AD00ACFDCC /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/QBImagePicker.strings; sourceTree = ""; }; + B12B645C1FFB61AD00ACFDCC /* QBImagePickerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBImagePickerController.h; sourceTree = ""; }; + B12B645D1FFB61AD00ACFDCC /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/QBImagePicker.strings"; sourceTree = ""; }; + B12B645E1FFB61AD00ACFDCC /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/QBImagePicker.strings; sourceTree = ""; }; + B12B645F1FFB61AD00ACFDCC /* QBAssetsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBAssetsViewController.h; sourceTree = ""; }; + B12B64601FFB61AD00ACFDCC /* QBAlbumsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBAlbumsViewController.h; sourceTree = ""; }; + B12B64611FFB61AD00ACFDCC /* QBVideoIconView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBVideoIconView.m; sourceTree = ""; }; + B12B64621FFB61AD00ACFDCC /* QBVideoIndicatorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBVideoIndicatorView.m; sourceTree = ""; }; + B12B64631FFB61AD00ACFDCC /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/QBImagePicker.strings; sourceTree = ""; }; + B12B64641FFB61AD00ACFDCC /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/QBImagePicker.strings; sourceTree = ""; }; + B12B64651FFB61AD00ACFDCC /* QBCheckmarkView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBCheckmarkView.h; sourceTree = ""; }; + B12B64661FFB61AD00ACFDCC /* QBAssetCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBAssetCell.h; sourceTree = ""; }; + B12B64671FFB61AD00ACFDCC /* QBSlomoIconView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBSlomoIconView.h; sourceTree = ""; }; + B12B64681FFB61AD00ACFDCC /* QBAlbumCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBAlbumCell.m; sourceTree = ""; }; + B12B64691FFB61AD00ACFDCC /* QBImagePicker.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = QBImagePicker.storyboard; sourceTree = ""; }; + B12B646A1FFB61AD00ACFDCC /* QBVideoIndicatorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBVideoIndicatorView.h; sourceTree = ""; }; + B12B646B1FFB61AD00ACFDCC /* QBAlbumsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBAlbumsViewController.m; sourceTree = ""; }; + B12B646C1FFB61AD00ACFDCC /* QBVideoIconView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBVideoIconView.h; sourceTree = ""; }; + B12B646D1FFB61AD00ACFDCC /* QBAssetsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBAssetsViewController.m; sourceTree = ""; }; + B12B646E1FFB61AD00ACFDCC /* QBImagePickerController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBImagePickerController.m; sourceTree = ""; }; + B12B646F1FFB61AD00ACFDCC /* QBCheckmarkView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBCheckmarkView.m; sourceTree = ""; }; + B12B64701FFB61AD00ACFDCC /* QBAlbumCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBAlbumCell.h; sourceTree = ""; }; + B12B64711FFB61AD00ACFDCC /* QBSlomoIconView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBSlomoIconView.m; sourceTree = ""; }; + B12B64721FFB61AD00ACFDCC /* QBAssetCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBAssetCell.m; sourceTree = ""; }; + B12B64801FFC73A900ACFDCC /* PHAsset+Common.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "PHAsset+Common.h"; sourceTree = ""; }; + B12B64811FFC73A900ACFDCC /* PHAsset+Common.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "PHAsset+Common.m"; sourceTree = ""; }; + B131E20F2074D2ED00D84FAA /* project_item_reading@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "project_item_reading@3x.png"; sourceTree = ""; }; + B131E2102074D2EE00D84FAA /* project_item_reading@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "project_item_reading@2x.png"; sourceTree = ""; }; + B14689A41EE100B200B01371 /* vip_3_30@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "vip_3_30@2x.png"; sourceTree = ""; }; + B14689A51EE100B200B01371 /* vip_3_30@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "vip_3_30@3x.png"; sourceTree = ""; }; + B14689A61EE100B200B01371 /* vip_3_40@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "vip_3_40@2x.png"; sourceTree = ""; }; + B14689A71EE100B200B01371 /* vip_3_40@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "vip_3_40@3x.png"; sourceTree = ""; }; + B14689A81EE100B200B01371 /* vip_3_45@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "vip_3_45@2x.png"; sourceTree = ""; }; + B14689A91EE100B200B01371 /* vip_3_45@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "vip_3_45@3x.png"; sourceTree = ""; }; + B14689AA1EE100B200B01371 /* vip_3_75@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "vip_3_75@2x.png"; sourceTree = ""; }; + B14689AB1EE100B200B01371 /* vip_3_75@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "vip_3_75@3x.png"; sourceTree = ""; }; + B14689AC1EE100B200B01371 /* vip_4_30@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "vip_4_30@2x.png"; sourceTree = ""; }; + B14689AD1EE100B200B01371 /* vip_4_30@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "vip_4_30@3x.png"; sourceTree = ""; }; + B14689AE1EE100B200B01371 /* vip_4_40@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "vip_4_40@2x.png"; sourceTree = ""; }; + B14689AF1EE100B200B01371 /* vip_4_40@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "vip_4_40@3x.png"; sourceTree = ""; }; + B14689B01EE100B200B01371 /* vip_4_45@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "vip_4_45@2x.png"; sourceTree = ""; }; + B14689B11EE100B200B01371 /* vip_4_45@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "vip_4_45@3x.png"; sourceTree = ""; }; + B14689B21EE100B200B01371 /* vip_4_75@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "vip_4_75@2x.png"; sourceTree = ""; }; + B14689B31EE100B200B01371 /* vip_4_75@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "vip_4_75@3x.png"; sourceTree = ""; }; + B14DE6DC20C914E60072ECEA /* AnimatedGIFImageSerialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnimatedGIFImageSerialization.h; sourceTree = ""; }; + B14DE6DD20C914E60072ECEA /* AnimatedGIFImageSerialization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AnimatedGIFImageSerialization.m; sourceTree = ""; }; + B152ED4C2090B223004A6E8A /* ProjectSettingEntranceController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ProjectSettingEntranceController.h; sourceTree = ""; }; + B152ED4D2090B223004A6E8A /* ProjectSettingEntranceController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ProjectSettingEntranceController.m; sourceTree = ""; }; + B152ED522091B7CB004A6E8A /* ProjectArchiveViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ProjectArchiveViewController.h; sourceTree = ""; }; + B152ED532091B7CB004A6E8A /* ProjectArchiveViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ProjectArchiveViewController.m; sourceTree = ""; }; + B152ED582092BF46004A6E8A /* EABoardTaskList.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EABoardTaskList.h; sourceTree = ""; }; + B152ED592092BF46004A6E8A /* EABoardTaskList.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EABoardTaskList.m; sourceTree = ""; }; + B152ED5B2092D51E004A6E8A /* EATaskBoardListTaskCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EATaskBoardListTaskCell.h; sourceTree = ""; }; + B152ED5C2092D51E004A6E8A /* EATaskBoardListTaskCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EATaskBoardListTaskCell.m; sourceTree = ""; }; + B152ED5E2093018A004A6E8A /* EABoardTaskListView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EABoardTaskListView.h; sourceTree = ""; }; + B152ED5F2093018A004A6E8A /* EABoardTaskListView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EABoardTaskListView.m; sourceTree = ""; }; + B152ED6120935524004A6E8A /* EABoardTaskListBlankView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EABoardTaskListBlankView.h; sourceTree = ""; }; + B152ED6220935524004A6E8A /* EABoardTaskListBlankView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EABoardTaskListBlankView.m; sourceTree = ""; }; + B152ED6420935594004A6E8A /* EABoardTaskListBlankView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = EABoardTaskListBlankView.xib; sourceTree = ""; }; + B152ED66209420CD004A6E8A /* RATaskBoardListListViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RATaskBoardListListViewController.h; sourceTree = ""; }; + B152ED67209420CD004A6E8A /* RATaskBoardListListViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RATaskBoardListListViewController.m; sourceTree = ""; }; + B152ED7A20945377004A6E8A /* project_item_taskboard@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "project_item_taskboard@2x.png"; sourceTree = ""; }; + B152ED7B20945377004A6E8A /* project_item_taskboard@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "project_item_taskboard@3x.png"; sourceTree = ""; }; + B152ED7E209453E6004A6E8A /* taskBoardList@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskBoardList@3x.png"; sourceTree = ""; }; + B152ED7F209453E7004A6E8A /* taskboard_blankpage@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskboard_blankpage@2x.png"; sourceTree = ""; }; + B152ED80209453E7004A6E8A /* taskBoardList@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskBoardList@2x.png"; sourceTree = ""; }; + B152ED81209453E8004A6E8A /* taskboard_blankpage@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskboard_blankpage@3x.png"; sourceTree = ""; }; + B152ED87209453F2004A6E8A /* taskboard_normal_page_selected@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskboard_normal_page_selected@3x.png"; sourceTree = ""; }; + B152ED88209453F2004A6E8A /* taskboard_normal_page_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskboard_normal_page_selected@2x.png"; sourceTree = ""; }; + B152ED89209453F2004A6E8A /* taskboard_add_page_unselected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskboard_add_page_unselected@2x.png"; sourceTree = ""; }; + B152ED8A209453F2004A6E8A /* taskboard_add_page_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskboard_add_page_selected@2x.png"; sourceTree = ""; }; + B152ED8B209453F2004A6E8A /* taskboard_add_page_selected@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskboard_add_page_selected@3x.png"; sourceTree = ""; }; + B152ED8C209453F2004A6E8A /* taskboard_add_page_unselected@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskboard_add_page_unselected@3x.png"; sourceTree = ""; }; + B152ED8D209453F2004A6E8A /* taskboard_normal_page_unselected@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskboard_normal_page_unselected@3x.png"; sourceTree = ""; }; + B152ED8E209453F2004A6E8A /* taskboard_normal_page_unselected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskboard_normal_page_unselected@2x.png"; sourceTree = ""; }; + B15C98AE20D39CA100DDA425 /* project_icon_edit@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "project_icon_edit@2x.png"; sourceTree = ""; }; + B15C98AF20D39CA200DDA425 /* project_icon_edit@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "project_icon_edit@3x.png"; sourceTree = ""; }; + B16E6C9F20C0FDB50076026D /* logo_coding_top@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "logo_coding_top@3x.png"; sourceTree = ""; }; + B16E6CA220C0FFFF0076026D /* Coding_Enterprise_iOS.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Coding_Enterprise_iOS.entitlements; sourceTree = ""; }; + B16E6CA420C13BA10076026D /* btn_dismiss@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_dismiss@3x.png"; sourceTree = ""; }; + B16E6CA520C13BA10076026D /* btn_dismiss@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_dismiss@2x.png"; sourceTree = ""; }; + B16E6CAB20C13BF40076026D /* btn_next_unable@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_next_unable@2x.png"; sourceTree = ""; }; + B16E6CAC20C13BF40076026D /* btn_next_unable@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_next_unable@3x.png"; sourceTree = ""; }; + B16E6CAD20C13BF40076026D /* btn_next_enable@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_next_enable@2x.png"; sourceTree = ""; }; + B16E6CAE20C13BF40076026D /* btn_next_enable@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_next_enable@3x.png"; sourceTree = ""; }; + B16E6CB820C13F5E0076026D /* btn_project_add@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_project_add@3x.png"; sourceTree = ""; }; + B16E6CB920C13F5E0076026D /* btn_project_added@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_project_added@3x.png"; sourceTree = ""; }; + B16E6CBA20C13F5E0076026D /* btn_project_quit@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_project_quit@3x.png"; sourceTree = ""; }; + B16E6CBB20C13F5E0076026D /* btn_privateMsg_stranger@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_privateMsg_stranger@3x.png"; sourceTree = ""; }; + B16E6CC620C144910076026D /* done_Nav@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "done_Nav@2x.png"; sourceTree = ""; }; + B16E6CC720C144920076026D /* done_Nav@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "done_Nav@3x.png"; sourceTree = ""; }; + B16E6CC820C144920076026D /* done_un_Nav@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "done_un_Nav@2x.png"; sourceTree = ""; }; + B16E6CC920C144920076026D /* done_un_Nav@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "done_un_Nav@3x.png"; sourceTree = ""; }; + B16E6CD320C145BE0076026D /* quick_menu_icon_message@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "quick_menu_icon_message@2x.png"; sourceTree = ""; }; + B16E6CD420C145BE0076026D /* quick_menu_icon_message@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "quick_menu_icon_message@3x.png"; sourceTree = ""; }; + B16E6CD520C145BE0076026D /* quick_menu_icon_task@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "quick_menu_icon_task@3x.png"; sourceTree = ""; }; + B16E6CD620C145BE0076026D /* quick_menu_icon_task@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "quick_menu_icon_task@2x.png"; sourceTree = ""; }; + B16E6CD720C145BE0076026D /* quick_menu_icon_project@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "quick_menu_icon_project@3x.png"; sourceTree = ""; }; + B16E6CD820C145BE0076026D /* quick_menu_icon_2fa@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "quick_menu_icon_2fa@3x.png"; sourceTree = ""; }; + B16E6CD920C145BE0076026D /* quick_menu_icon_2fa@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "quick_menu_icon_2fa@2x.png"; sourceTree = ""; }; + B16E6CDA20C145BE0076026D /* quick_menu_icon_project@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "quick_menu_icon_project@2x.png"; sourceTree = ""; }; + B16E6CEB20C147480076026D /* team_bg@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "team_bg@3x.png"; sourceTree = ""; }; + B16E6CEC20C147490076026D /* team_bg@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "team_bg@2x.png"; sourceTree = ""; }; + B16E6CF220C147760076026D /* team_info_pro@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "team_info_pro@3x.png"; sourceTree = ""; }; + B16E6CF320C147760076026D /* team_info_pro@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "team_info_pro@2x.png"; sourceTree = ""; }; + B16E6CF420C147760076026D /* team_info_order@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "team_info_order@2x.png"; sourceTree = ""; }; + B16E6CF520C147760076026D /* team_info_order@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "team_info_order@3x.png"; sourceTree = ""; }; + B16E6CF620C147760076026D /* team_info_sup@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "team_info_sup@2x.png"; sourceTree = ""; }; + B16E6CF720C147760076026D /* team_info_mem@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "team_info_mem@3x.png"; sourceTree = ""; }; + B16E6CF820C147760076026D /* team_info_mem@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "team_info_mem@2x.png"; sourceTree = ""; }; + B16E6CF920C147760076026D /* team_info_sup@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "team_info_sup@3x.png"; sourceTree = ""; }; + B16E6CFB20C147760076026D /* team_cell_edit_team@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "team_cell_edit_team@3x.png"; sourceTree = ""; }; + B16E6CFC20C147760076026D /* team_cell_edit_team@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "team_cell_edit_team@2x.png"; sourceTree = ""; }; + B16E6CFD20C147760076026D /* team_cell_edit_delete@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "team_cell_edit_delete@3x.png"; sourceTree = ""; }; + B16E6CFE20C147760076026D /* team_cell_edit_delete@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "team_cell_edit_delete@2x.png"; sourceTree = ""; }; + B16E6CFF20C147760076026D /* team_cell_edit_pro@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "team_cell_edit_pro@3x.png"; sourceTree = ""; }; + B16E6D0020C147760076026D /* team_cell_edit_pro@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "team_cell_edit_pro@2x.png"; sourceTree = ""; }; + B16E6D2020C148E50076026D /* intro_icon_4@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_4@3x.png"; sourceTree = ""; }; + B16E6D2120C148E50076026D /* intro_tip_2@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_tip_2@3x.png"; sourceTree = ""; }; + B16E6D2220C148E50076026D /* intro_icon_6@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_6@2x.png"; sourceTree = ""; }; + B16E6D2320C148E50076026D /* intro_tip_0@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_tip_0@2x.png"; sourceTree = ""; }; + B16E6D2420C148E50076026D /* intro_tip_0@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_tip_0@3x.png"; sourceTree = ""; }; + B16E6D2520C148E50076026D /* intro_icon_6@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_6@3x.png"; sourceTree = ""; }; + B16E6D2620C148E50076026D /* intro_tip_2@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_tip_2@2x.png"; sourceTree = ""; }; + B16E6D2720C148E50076026D /* intro_icon_4@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_4@2x.png"; sourceTree = ""; }; + B16E6D2820C148E50076026D /* intro_icon_0@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_0@2x.png"; sourceTree = ""; }; + B16E6D2920C148E50076026D /* intro_icon_2@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_2@3x.png"; sourceTree = ""; }; + B16E6D2A20C148E50076026D /* intro_tip_4@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_tip_4@3x.png"; sourceTree = ""; }; + B16E6D2B20C148E50076026D /* intro_tip_4@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_tip_4@2x.png"; sourceTree = ""; }; + B16E6D2C20C148E50076026D /* intro_icon_2@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_2@2x.png"; sourceTree = ""; }; + B16E6D2D20C148E50076026D /* intro_icon_0@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_0@3x.png"; sourceTree = ""; }; + B16E6D2E20C148E50076026D /* intro_tip_1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_tip_1@2x.png"; sourceTree = ""; }; + B16E6D2F20C148E50076026D /* intro_icon_5@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_5@3x.png"; sourceTree = ""; }; + B16E6D3020C148E50076026D /* intro_dot_unselected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_dot_unselected@2x.png"; sourceTree = ""; }; + B16E6D3120C148E50076026D /* intro_tip_3@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_tip_3@3x.png"; sourceTree = ""; }; + B16E6D3220C148E50076026D /* intro_tip_3@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_tip_3@2x.png"; sourceTree = ""; }; + B16E6D3320C148E50076026D /* intro_icon_5@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_5@2x.png"; sourceTree = ""; }; + B16E6D3420C148E50076026D /* intro_dot_unselected@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_dot_unselected@3x.png"; sourceTree = ""; }; + B16E6D3520C148E50076026D /* intro_tip_1@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_tip_1@3x.png"; sourceTree = ""; }; + B16E6D3620C148E50076026D /* intro_icon_3@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_3@3x.png"; sourceTree = ""; }; + B16E6D3720C148E50076026D /* intro_tip_5@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_tip_5@3x.png"; sourceTree = ""; }; + B16E6D3820C148E50076026D /* intro_icon_1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_1@2x.png"; sourceTree = ""; }; + B16E6D3920C148E50076026D /* intro_dot_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_dot_selected@2x.png"; sourceTree = ""; }; + B16E6D3A20C148E50076026D /* intro_dot_selected@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_dot_selected@3x.png"; sourceTree = ""; }; + B16E6D3B20C148E50076026D /* intro_icon_1@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_1@3x.png"; sourceTree = ""; }; + B16E6D3C20C148E50076026D /* intro_tip_5@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_tip_5@2x.png"; sourceTree = ""; }; + B16E6D3D20C148E50076026D /* intro_icon_3@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_icon_3@2x.png"; sourceTree = ""; }; + B16E6D3F20C148E50076026D /* intro_page0_ip5@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page0_ip5@2x.png"; sourceTree = ""; }; + B16E6D4020C148E50076026D /* intro_page_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page_selected@2x.png"; sourceTree = ""; }; + B16E6D4120C148E50076026D /* intro_page_unselected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page_unselected@2x.png"; sourceTree = ""; }; + B16E6D4220C148E50076026D /* intro_page0_ip4@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page0_ip4@2x.png"; sourceTree = ""; }; + B16E6D4320C148E50076026D /* intro_page_unselected@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page_unselected@3x.png"; sourceTree = ""; }; + B16E6D4420C148E50076026D /* intro_page_selected@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page_selected@3x.png"; sourceTree = ""; }; + B16E6D4520C148E50076026D /* intro_page0_ip6@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page0_ip6@2x.png"; sourceTree = ""; }; + B16E6D4620C148E50076026D /* intro_page0_ip6+@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page0_ip6+@3x.png"; sourceTree = ""; }; + B16E6D4720C148E50076026D /* intro_page0_ipX@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page0_ipX@3x.png"; sourceTree = ""; }; + B16E6D4920C148E50076026D /* icon_user_monkey_i6p@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_user_monkey_i6p@3x.png"; sourceTree = ""; }; + B16E6D4A20C148E50076026D /* icon_user_monkey_i6@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_user_monkey_i6@2x.png"; sourceTree = ""; }; + B16E6D4B20C148E50076026D /* icon_user_monkey@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_user_monkey@2x.png"; sourceTree = ""; }; + B16E6D4F20C148E50076026D /* intro_dot_light_unselected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_dot_light_unselected@2x.png"; sourceTree = ""; }; + B16E6D5020C148E50076026D /* intro_dot_light_unselected@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_dot_light_unselected@3x.png"; sourceTree = ""; }; + B16E6D5120C148E50076026D /* intro_dot_light_selected@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_dot_light_selected@3x.png"; sourceTree = ""; }; + B16E6D5220C148E50076026D /* intro_dot_light_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_dot_light_selected@2x.png"; sourceTree = ""; }; + B16E6D5320C148E50076026D /* intro_icon_wiki_down.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = intro_icon_wiki_down.gif; sourceTree = ""; }; + B16E6D5520C148E50076026D /* intro_dot_dark_unselected@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_dot_dark_unselected@3x.png"; sourceTree = ""; }; + B16E6D5620C148E50076026D /* intro_dot_dark_selected@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_dot_dark_selected@3x.png"; sourceTree = ""; }; + B16E6D5720C148E50076026D /* intro_dot_dark_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_dot_dark_selected@2x.png"; sourceTree = ""; }; + B16E6D5820C148E50076026D /* intro_dot_dark_unselected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_dot_dark_unselected@2x.png"; sourceTree = ""; }; + B16E6D5920C148E50076026D /* intro_icon_wiki_up.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = intro_icon_wiki_up.gif; sourceTree = ""; }; + B16E6D5A20C148E50076026D /* intro_icon_file_up.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = intro_icon_file_up.gif; sourceTree = ""; }; + B16E6D5B20C148E50076026D /* intro_icon_code_up.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = intro_icon_code_up.gif; sourceTree = ""; }; + B16E6D5C20C148E50076026D /* intro_icon_task_up.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = intro_icon_task_up.gif; sourceTree = ""; }; + B16E6D5D20C148E50076026D /* intro_icon_file_down.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = intro_icon_file_down.gif; sourceTree = ""; }; + B16E6D5E20C148E50076026D /* intro_icon_task_down.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = intro_icon_task_down.gif; sourceTree = ""; }; + B16E6D5F20C148E50076026D /* intro_icon_code_down.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = intro_icon_code_down.gif; sourceTree = ""; }; + B16E6D6120C148E50076026D /* intro_page0_ip5@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page0_ip5@2x.png"; sourceTree = ""; }; + B16E6D6220C148E50076026D /* intro_page2_ip6+@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page2_ip6+@3x.png"; sourceTree = ""; }; + B16E6D6320C148E50076026D /* intro_page1_ip6@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page1_ip6@2x.png"; sourceTree = ""; }; + B16E6D6420C148E50076026D /* intro_page1_ip4@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page1_ip4@2x.png"; sourceTree = ""; }; + B16E6D6520C148E50076026D /* intro_page2_ip5@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page2_ip5@2x.png"; sourceTree = ""; }; + B16E6D6620C148E50076026D /* intro_page1_ip6+@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page1_ip6+@3x.png"; sourceTree = ""; }; + B16E6D6720C148E50076026D /* intro_page_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page_selected@2x.png"; sourceTree = ""; }; + B16E6D6820C148E50076026D /* intro_page_unselected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page_unselected@2x.png"; sourceTree = ""; }; + B16E6D6920C148E50076026D /* intro_page0_ip4@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page0_ip4@2x.png"; sourceTree = ""; }; + B16E6D6A20C148E50076026D /* intro_page1_ip5@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page1_ip5@2x.png"; sourceTree = ""; }; + B16E6D6B20C148E50076026D /* intro_page_unselected@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page_unselected@3x.png"; sourceTree = ""; }; + B16E6D6C20C148E50076026D /* intro_page_selected@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page_selected@3x.png"; sourceTree = ""; }; + B16E6D6D20C148E50076026D /* intro_page0_ip6@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page0_ip6@2x.png"; sourceTree = ""; }; + B16E6D6E20C148E50076026D /* intro_page2_ip4@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page2_ip4@2x.png"; sourceTree = ""; }; + B16E6D6F20C148E50076026D /* intro_page0_ip6+@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page0_ip6+@3x.png"; sourceTree = ""; }; + B16E6D7020C148E50076026D /* intro_page2_ip6@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "intro_page2_ip6@2x.png"; sourceTree = ""; }; + B16E6D7220C148E50076026D /* icon_user_monkey@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_user_monkey@2x.png"; sourceTree = ""; }; + B16E6D7320C148E50076026D /* icon_user_monkey@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_user_monkey@3x.png"; sourceTree = ""; }; + B16EEF06208DDBB5005ABFD5 /* timeline_icon_read@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "timeline_icon_read@3x.png"; sourceTree = ""; }; + B16EEF07208DDBB6005ABFD5 /* timeline_icon_unread@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "timeline_icon_unread@3x.png"; sourceTree = ""; }; + B16EEF11209080D7005ABFD5 /* TaskBoardsViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TaskBoardsViewController.h; sourceTree = ""; }; + B16EEF12209080D7005ABFD5 /* TaskBoardsViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TaskBoardsViewController.m; sourceTree = ""; }; + B177F5C02060E6B1006709C2 /* wiki.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = wiki.html; sourceTree = ""; }; + B177F5C12060E6B1006709C2 /* bubble.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = bubble.html; sourceTree = ""; }; + B177F5C22060E6B1006709C2 /* markdown.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = markdown.html; sourceTree = ""; }; + B177F5C32060E6B1006709C2 /* topic-ios.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "topic-ios.html"; sourceTree = ""; }; + B177F5C42060E6B1006709C2 /* code.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = code.html; sourceTree = ""; }; + B17CC31220731E900077C956 /* icon_release_tag_blue@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_release_tag_blue@3x.png"; sourceTree = ""; }; + B17CC31320731E910077C956 /* icon_release_tag_blue@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_release_tag_blue@2x.png"; sourceTree = ""; }; + B17CC31720731FF10077C956 /* code_release_resource_Zip@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "code_release_resource_Zip@2x.png"; sourceTree = ""; }; + B17CC31820731FF10077C956 /* code_release_resource_Zip@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "code_release_resource_Zip@3x.png"; sourceTree = ""; }; + B17CC31920731FF10077C956 /* code_release_resource_Default@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "code_release_resource_Default@3x.png"; sourceTree = ""; }; + B17CC31A20731FF10077C956 /* code_release_resource__Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "code_release_resource__Default@2x.png"; sourceTree = ""; }; + B17CC31B20731FF10077C956 /* code_release_resource_Task@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "code_release_resource_Task@2x.png"; sourceTree = ""; }; + B17CC31C20731FF10077C956 /* code_release_resource_Task@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "code_release_resource_Task@3x.png"; sourceTree = ""; }; + B17CC3232073212D0077C956 /* code_release_resource_ProjectFile@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "code_release_resource_ProjectFile@3x.png"; sourceTree = ""; }; + B17CC3242073212D0077C956 /* code_release_resource_MergeRequestBean@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "code_release_resource_MergeRequestBean@3x.png"; sourceTree = ""; }; + B17CC3252073212D0077C956 /* code_release_resource_ProjectFile@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "code_release_resource_ProjectFile@2x.png"; sourceTree = ""; }; + B17CC3262073212D0077C956 /* code_release_resource_ProjectTopic@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "code_release_resource_ProjectTopic@3x.png"; sourceTree = ""; }; + B17CC3272073212E0077C956 /* code_release_resource_MergeRequestBean@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "code_release_resource_MergeRequestBean@2x.png"; sourceTree = ""; }; + B17CC3282073212E0077C956 /* code_release_resource_ProjectTopic@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "code_release_resource_ProjectTopic@2x.png"; sourceTree = ""; }; + B1816061202063440022B4C6 /* EATerminalViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EATerminalViewController.h; sourceTree = ""; }; + B1816062202063440022B4C6 /* EATerminalViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EATerminalViewController.m; sourceTree = ""; }; + B1817EB42063899400E9BAD1 /* EACodeBranchListViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EACodeBranchListViewController.h; sourceTree = ""; }; + B1817EB52063899400E9BAD1 /* EACodeBranchListViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EACodeBranchListViewController.m; sourceTree = ""; }; + B1817EB7206389F500E9BAD1 /* EACodeReleaseListViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EACodeReleaseListViewController.h; sourceTree = ""; }; + B1817EB8206389F500E9BAD1 /* EACodeReleaseListViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EACodeReleaseListViewController.m; sourceTree = ""; }; + B1817EBA2063936100E9BAD1 /* EACodeBranches.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EACodeBranches.h; sourceTree = ""; }; + B1817EBB2063936100E9BAD1 /* EACodeBranches.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EACodeBranches.m; sourceTree = ""; }; + B1817EBD2063951000E9BAD1 /* EABasePageModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EABasePageModel.h; sourceTree = ""; }; + B1817EBE2063951000E9BAD1 /* EABasePageModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EABasePageModel.m; sourceTree = ""; }; + B1817EC2206397E000E9BAD1 /* EACodeRelease.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EACodeRelease.h; sourceTree = ""; }; + B1817EC3206397E000E9BAD1 /* EACodeRelease.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EACodeRelease.m; sourceTree = ""; }; + B1817EC5206397F500E9BAD1 /* EACodeReleases.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EACodeReleases.h; sourceTree = ""; }; + B1817EC6206397F500E9BAD1 /* EACodeReleases.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EACodeReleases.m; sourceTree = ""; }; + B1817EC820639E9500E9BAD1 /* EACodeReleaseListCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EACodeReleaseListCell.h; sourceTree = ""; }; + B1817EC920639E9500E9BAD1 /* EACodeReleaseListCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EACodeReleaseListCell.m; sourceTree = ""; }; + B1817ECB20639F0A00E9BAD1 /* EACodeBranchListCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EACodeBranchListCell.h; sourceTree = ""; }; + B1817ECC20639F0A00E9BAD1 /* EACodeBranchListCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EACodeBranchListCell.m; sourceTree = ""; }; + B1817EE22064F92C00E9BAD1 /* EACodeReleaseViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EACodeReleaseViewController.h; sourceTree = ""; }; + B1817EE32064F92C00E9BAD1 /* EACodeReleaseViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EACodeReleaseViewController.m; sourceTree = ""; }; + B1817EE52064FC6100E9BAD1 /* EACodeReleaseTopCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EACodeReleaseTopCell.h; sourceTree = ""; }; + B1817EE62064FC6100E9BAD1 /* EACodeReleaseTopCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EACodeReleaseTopCell.m; sourceTree = ""; }; + B1817EE82064FC7300E9BAD1 /* EACodeReleaseBodyCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EACodeReleaseBodyCell.h; sourceTree = ""; }; + B1817EE92064FC7300E9BAD1 /* EACodeReleaseBodyCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EACodeReleaseBodyCell.m; sourceTree = ""; }; + B1817EEB2064FD9400E9BAD1 /* EACodeReleaseAttachmentsOrReferencesCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EACodeReleaseAttachmentsOrReferencesCell.h; sourceTree = ""; }; + B1817EEC2064FD9400E9BAD1 /* EACodeReleaseAttachmentsOrReferencesCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EACodeReleaseAttachmentsOrReferencesCell.m; sourceTree = ""; }; + B1817EEE2068C7A100E9BAD1 /* EACodeBranchListCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = EACodeBranchListCell.xib; sourceTree = ""; }; + B1817EF02068F4B400E9BAD1 /* EACodeReleaseListCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = EACodeReleaseListCell.xib; sourceTree = ""; }; + B1817EF22069186C00E9BAD1 /* project_item_tag@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "project_item_tag@2x.png"; sourceTree = ""; }; + B1817EF32069186C00E9BAD1 /* project_item_branch@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "project_item_branch@2x.png"; sourceTree = ""; }; + B1817EF42069186D00E9BAD1 /* project_item_branch@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "project_item_branch@3x.png"; sourceTree = ""; }; + B1817EF52069186E00E9BAD1 /* project_item_tag@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "project_item_tag@3x.png"; sourceTree = ""; }; + B1817EFA206918D100E9BAD1 /* icon_branch_protected@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_branch_protected@3x.png"; sourceTree = ""; }; + B1817EFB206918D200E9BAD1 /* icon_branch_protected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_branch_protected@2x.png"; sourceTree = ""; }; + B1817EFE2069197C00E9BAD1 /* icon_release_tag@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_release_tag@3x.png"; sourceTree = ""; }; + B1817EFF2069197C00E9BAD1 /* icon_release_tag@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_release_tag@2x.png"; sourceTree = ""; }; + B1817F0220691B2700E9BAD1 /* EACodeReleaseTopCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = EACodeReleaseTopCell.xib; sourceTree = ""; }; + B1817F042069F67700E9BAD1 /* EAEditCodeReleaseViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EAEditCodeReleaseViewController.h; sourceTree = ""; }; + B1817F052069F67700E9BAD1 /* EAEditCodeReleaseViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EAEditCodeReleaseViewController.m; sourceTree = ""; }; + B184166720513CA000207666 /* topic_add_watcher_btn@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "topic_add_watcher_btn@3x.png"; sourceTree = ""; }; + B184166820513CA000207666 /* tweet_comment_btn@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tweet_comment_btn@3x.png"; sourceTree = ""; }; + B186AEAE20F462F600A6AF35 /* UIAlertController+Common.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIAlertController+Common.h"; sourceTree = ""; }; + B186AEAF20F462F600A6AF35 /* UIAlertController+Common.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIAlertController+Common.m"; sourceTree = ""; }; + B1890C1E2015D82600F52ABA /* wiki_menu_0@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "wiki_menu_0@2x.png"; sourceTree = ""; }; + B1890C1F2015D82600F52ABA /* wiki_menu_2@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "wiki_menu_2@3x.png"; sourceTree = ""; }; + B1890C202015D82600F52ABA /* wiki_menu_2@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "wiki_menu_2@2x.png"; sourceTree = ""; }; + B1890C212015D82600F52ABA /* wiki_menu_0@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "wiki_menu_0@3x.png"; sourceTree = ""; }; + B1890C222015D82600F52ABA /* wiki_revert@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "wiki_revert@3x.png"; sourceTree = ""; }; + B1890C232015D82600F52ABA /* wiki_revert@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "wiki_revert@2x.png"; sourceTree = ""; }; + B1890C242015D82600F52ABA /* wiki_menu_1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "wiki_menu_1@2x.png"; sourceTree = ""; }; + B1890C252015D82600F52ABA /* wiki_menu_1@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "wiki_menu_1@3x.png"; sourceTree = ""; }; + B1890C272015D82600F52ABA /* wiki_menu_icon_share@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "wiki_menu_icon_share@2x.png"; sourceTree = ""; }; + B1890C282015D82600F52ABA /* wiki_menu_icon_delete@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "wiki_menu_icon_delete@2x.png"; sourceTree = ""; }; + B1890C332015D87800F52ABA /* EAWiki.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EAWiki.h; sourceTree = ""; }; + B1890C342015D87800F52ABA /* EAWiki.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EAWiki.m; sourceTree = ""; }; + B1890C362015D89A00F52ABA /* WikiMenuListView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WikiMenuListView.m; sourceTree = ""; }; + B1890C372015D89A00F52ABA /* WikiMenuListView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WikiMenuListView.h; sourceTree = ""; }; + B1890C392015D8C800F52ABA /* WikiMenuListCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WikiMenuListCell.h; sourceTree = ""; }; + B1890C3A2015D8C800F52ABA /* WikiMenuListCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WikiMenuListCell.m; sourceTree = ""; }; + B1890C3B2015D8C800F52ABA /* WikiHistoryCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WikiHistoryCell.m; sourceTree = ""; }; + B1890C3C2015D8C800F52ABA /* WikiHistoryCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WikiHistoryCell.h; sourceTree = ""; }; + B1890C3F2015D8F700F52ABA /* WikiHeaderView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WikiHeaderView.h; sourceTree = ""; }; + B1890C402015D8F700F52ABA /* WikiHeaderView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WikiHeaderView.m; sourceTree = ""; }; + B1890C422015D92500F52ABA /* WikiHistoryListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WikiHistoryListViewController.h; sourceTree = ""; }; + B1890C432015D92500F52ABA /* WikiEditViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WikiEditViewController.m; sourceTree = ""; }; + B1890C442015D92500F52ABA /* WikiHistoryListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WikiHistoryListViewController.m; sourceTree = ""; }; + B1890C452015D92600F52ABA /* WikiViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WikiViewController.h; sourceTree = ""; }; + B1890C462015D92600F52ABA /* WikiEditViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WikiEditViewController.h; sourceTree = ""; }; + B1890C472015D92600F52ABA /* WikiViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WikiViewController.m; sourceTree = ""; }; + B1890C4B2019B29800F52ABA /* UINavigationBar+Common.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UINavigationBar+Common.m"; sourceTree = ""; }; + B1890C4C2019B29800F52ABA /* UINavigationBar+Common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UINavigationBar+Common.h"; sourceTree = ""; }; + B1944142206BB87F00147158 /* EALocalCodeListViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EALocalCodeListViewController.h; sourceTree = ""; }; + B1944143206BB87F00147158 /* EALocalCodeListViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EALocalCodeListViewController.m; sourceTree = ""; }; + B1944145206BB89100147158 /* EALocalCodeViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EALocalCodeViewController.h; sourceTree = ""; }; + B1944146206BB89100147158 /* EALocalCodeViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EALocalCodeViewController.m; sourceTree = ""; }; + B1944148206BB8BB00147158 /* EALocalCodeListCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EALocalCodeListCell.h; sourceTree = ""; }; + B1944149206BB8BB00147158 /* EALocalCodeListCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EALocalCodeListCell.m; sourceTree = ""; }; + B1944153206CBE8C00147158 /* code_lang.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = code_lang.plist; sourceTree = ""; }; + B19D4EDF1F690F5E00C598F3 /* file_activity_icon_rename@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "file_activity_icon_rename@2x.png"; sourceTree = ""; }; + B19D4EE01F690F5E00C598F3 /* file_activity_icon_rename@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "file_activity_icon_rename@3x.png"; sourceTree = ""; }; + B19D4EE71F6FAA6000C598F3 /* AboutPointViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AboutPointViewController.h; sourceTree = ""; }; + B19D4EE81F6FAA6000C598F3 /* AboutPointViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AboutPointViewController.m; sourceTree = ""; }; + B19D4EE91F6FAA6000C598F3 /* AboutPointViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AboutPointViewController.xib; sourceTree = ""; }; + B19D4EEC1F6FCEAC00C598F3 /* CodingSkill.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodingSkill.h; sourceTree = ""; }; + B19D4EED1F6FCEAC00C598F3 /* CodingSkill.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CodingSkill.m; sourceTree = ""; }; + B19D4EEF1F710EF900C598F3 /* ShopSwitchCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShopSwitchCell.h; sourceTree = ""; }; + B19D4EF01F710EF900C598F3 /* ShopSwitchCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShopSwitchCell.m; sourceTree = ""; }; + B19D4EF11F710EF900C598F3 /* ShopSwitchCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ShopSwitchCell.xib; sourceTree = ""; }; + B19D4EF41F7210C300C598F3 /* user_info_shop@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "user_info_shop@2x.png"; sourceTree = ""; }; + B19D4EF51F7210C300C598F3 /* user_info_shop@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "user_info_shop@3x.png"; sourceTree = ""; }; + B19D4EF91F7247BA00C598F3 /* AlipaySDK.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = AlipaySDK.bundle; sourceTree = ""; }; + B19D4EFA1F7247BA00C598F3 /* AlipaySDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = AlipaySDK.framework; sourceTree = ""; }; + B19D4EFD1F724CDC00C598F3 /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = System/Library/Frameworks/CoreMotion.framework; sourceTree = SDKROOT; }; + B1AB5C90202953E40075A669 /* terminal_tail@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "terminal_tail@2x.png"; sourceTree = ""; }; + B1AB5C91202953E40075A669 /* terminal_box_unselected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "terminal_box_unselected@2x.png"; sourceTree = ""; }; + B1AB5C92202953E40075A669 /* terminal_box_unselected@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "terminal_box_unselected@3x.png"; sourceTree = ""; }; + B1AB5C93202953E40075A669 /* terminal_tail@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "terminal_tail@3x.png"; sourceTree = ""; }; + B1AB5C94202953E40075A669 /* terminal_more@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "terminal_more@3x.png"; sourceTree = ""; }; + B1AB5C95202953E40075A669 /* terminal_more@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "terminal_more@2x.png"; sourceTree = ""; }; + B1AB5C96202953E40075A669 /* terminal_triangle@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "terminal_triangle@3x.png"; sourceTree = ""; }; + B1AB5C97202953E40075A669 /* terminal_box_selected@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "terminal_box_selected@3x.png"; sourceTree = ""; }; + B1AB5C98202953E40075A669 /* terminal_triangle@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "terminal_triangle@2x.png"; sourceTree = ""; }; + B1AB5C99202953E40075A669 /* terminal_box_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "terminal_box_selected@2x.png"; sourceTree = ""; }; + B1AB5CA6202D7D4D0075A669 /* button_file_createFolder_enable@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_file_createFolder_enable@3x.png"; sourceTree = ""; }; + B1AB5CA7202D7D4E0075A669 /* button_file_denete_enable@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_file_denete_enable@3x.png"; sourceTree = ""; }; + B1AB5CA8202D7D4E0075A669 /* button_file_download_enable@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_file_download_enable@3x.png"; sourceTree = ""; }; + B1AB5CA9202D7D4E0075A669 /* button_file_upload_enable@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_file_upload_enable@3x.png"; sourceTree = ""; }; + B1AB5CAA202D7D4E0075A669 /* button_file_history@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_file_history@3x.png"; sourceTree = ""; }; + B1AB5CAB202D7D4F0075A669 /* button_file_activity@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_file_activity@3x.png"; sourceTree = ""; }; + B1AB5CAC202D7D4F0075A669 /* button_file_denete_unable@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_file_denete_unable@3x.png"; sourceTree = ""; }; + B1AB5CAD202D7D4F0075A669 /* button_file_download_unable@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_file_download_unable@3x.png"; sourceTree = ""; }; + B1AB5CAE202D7D4F0075A669 /* button_file_move_enable@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_file_move_enable@3x.png"; sourceTree = ""; }; + B1AB5CAF202D7D4F0075A669 /* button_file_move_unable@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_file_move_unable@3x.png"; sourceTree = ""; }; + B1AB5CB0202D7D500075A669 /* button_file_createFolder_unable@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_file_createFolder_unable@3x.png"; sourceTree = ""; }; + B1ACFE0B20A975E2000BC41E /* EAMilestone.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EAMilestone.h; sourceTree = ""; }; + B1ACFE0C20A975E2000BC41E /* EAMilestone.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EAMilestone.m; sourceTree = ""; }; + B1B2BDB01F79E74000645EAD /* net_route.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = net_route.h; sourceTree = ""; }; + B1BCB8701FCD006A0098B87B /* icon_file_doc_big@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_file_doc_big@2x.png"; sourceTree = ""; }; + B1BCB8711FCD006B0098B87B /* icon_file_zip_big@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_file_zip_big@2x.png"; sourceTree = ""; }; + B1BCB8721FCD006B0098B87B /* icon_file_pdf_big@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_file_pdf_big@2x.png"; sourceTree = ""; }; + B1BCB8731FCD006B0098B87B /* icon_file_psd_big@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_file_psd_big@2x.png"; sourceTree = ""; }; + B1BCB8741FCD006B0098B87B /* icon_file_unknown_big@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_file_unknown_big@2x.png"; sourceTree = ""; }; + B1BCB8751FCD006B0098B87B /* icon_file_movie_big@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_file_movie_big@2x.png"; sourceTree = ""; }; + B1BCB8761FCD006B0098B87B /* icon_file_md_big@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_file_md_big@2x.png"; sourceTree = ""; }; + B1BCB8771FCD006B0098B87B /* icon_file_apk_big@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_file_apk_big@2x.png"; sourceTree = ""; }; + B1BCB8781FCD006C0098B87B /* icon_file_code_big@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_file_code_big@2x.png"; sourceTree = ""; }; + B1BCB8791FCD006C0098B87B /* icon_file_txt_big@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_file_txt_big@2x.png"; sourceTree = ""; }; + B1BCB87A1FCD006C0098B87B /* icon_file_music_big@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_file_music_big@2x.png"; sourceTree = ""; }; + B1BCB87B1FCD006C0098B87B /* icon_file_ai_big@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_file_ai_big@2x.png"; sourceTree = ""; }; + B1BCB87C1FCD006C0098B87B /* icon_file_ppt_big@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_file_ppt_big@2x.png"; sourceTree = ""; }; + B1BCB88A1FCD0A6D0098B87B /* icon_file_xls_big@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_file_xls_big@2x.png"; sourceTree = ""; }; + B1BCB88C1FCE61D60098B87B /* EAPayViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EAPayViewController.h; sourceTree = ""; }; + B1BCB88D1FCE61D60098B87B /* EAPayViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EAPayViewController.m; sourceTree = ""; }; + B1BCB88E1FCE61D60098B87B /* EAPayViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = EAPayViewController.xib; sourceTree = ""; }; + B1BCB8911FCE662A0098B87B /* NSLayoutConstraintLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSLayoutConstraintLine.m; sourceTree = ""; }; + B1BCB8921FCE662A0098B87B /* NSLayoutConstraintLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSLayoutConstraintLine.h; sourceTree = ""; }; + B1BCB8951FCE93830098B87B /* alipay@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "alipay@2x.png"; sourceTree = ""; }; + B1BCB8961FCE93830098B87B /* alipay@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "alipay@3x.png"; sourceTree = ""; }; + B1BCB8971FCE93830098B87B /* wechat@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "wechat@2x.png"; sourceTree = ""; }; + B1BCB8981FCE93830098B87B /* wechat@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "wechat@3x.png"; sourceTree = ""; }; + B1BFC4B420B2ACED009427FC /* editBoardList@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "editBoardList@3x.png"; sourceTree = ""; }; + B1BFC4B520B2ACEE009427FC /* editBoardList@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "editBoardList@2x.png"; sourceTree = ""; }; + B1BFC4C020B2B24E009427FC /* task_activity_icon_add_milestone@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "task_activity_icon_add_milestone@2x.png"; sourceTree = ""; }; + B1BFC4C120B2B24E009427FC /* task_activity_icon_add_milestone@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "task_activity_icon_add_milestone@3x.png"; sourceTree = ""; }; + B1BFC4C220B2B24F009427FC /* task_activity_icon_remove_milestone@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "task_activity_icon_remove_milestone@3x.png"; sourceTree = ""; }; + B1BFC4C320B2B250009427FC /* task_activity_icon_remove_milestone@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "task_activity_icon_remove_milestone@2x.png"; sourceTree = ""; }; + B1C60C7820BFA2150073D3CA /* NProjectFileListView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NProjectFileListView.h; sourceTree = ""; }; + B1C60C7920BFA2150073D3CA /* NProjectFileListView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NProjectFileListView.m; sourceTree = ""; }; + B1C60C7C20BFCDBD0073D3CA /* EditMemberTypeProjectListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EditMemberTypeProjectListViewController.h; sourceTree = ""; }; + B1C60C7D20BFCDBD0073D3CA /* EditMemberTypeProjectListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EditMemberTypeProjectListViewController.m; sourceTree = ""; }; + B1C60C8020BFCEFD0073D3CA /* NFileListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NFileListViewController.m; sourceTree = ""; }; + B1C60C8120BFCEFD0073D3CA /* NFileListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NFileListViewController.h; sourceTree = ""; }; + B1C60C8B20BFF7940073D3CA /* ProjectTypeExplanationViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ProjectTypeExplanationViewController.xib; sourceTree = ""; }; + B1C60C8C20BFF7950073D3CA /* ProjectTypeExplanationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProjectTypeExplanationViewController.h; sourceTree = ""; }; + B1C60C8D20BFF7950073D3CA /* ProjectTypeExplanationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProjectTypeExplanationViewController.m; sourceTree = ""; }; + B1C60C9220C004C70073D3CA /* TeamPurchaseBillingCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TeamPurchaseBillingCell.h; sourceTree = ""; }; + B1C60C9320C004C70073D3CA /* TeamPurchaseTopCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TeamPurchaseTopCell.m; sourceTree = ""; }; + B1C60C9420C004C70073D3CA /* TeamPurchaseBillingCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TeamPurchaseBillingCell.m; sourceTree = ""; }; + B1C60C9520C004C80073D3CA /* TeamPurchaseOrderCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TeamPurchaseOrderCell.h; sourceTree = ""; }; + B1C60C9620C004C80073D3CA /* TeamPurchaseOrderCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TeamPurchaseOrderCell.m; sourceTree = ""; }; + B1C60C9720C004C80073D3CA /* TeamPurchaseTopCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TeamPurchaseTopCell.h; sourceTree = ""; }; + B1C60C9E20C0DDF30073D3CA /* TeamSettingViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TeamSettingViewController.h; sourceTree = ""; }; + B1C60C9F20C0DDF40073D3CA /* TeamPurchaseViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TeamPurchaseViewController.h; sourceTree = ""; }; + B1C60CA020C0DDF40073D3CA /* TeamSettingViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TeamSettingViewController.m; sourceTree = ""; }; + B1C60CA120C0DDF40073D3CA /* TeamPurchaseViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TeamPurchaseViewController.m; sourceTree = ""; }; + B1C60CA220C0DDF50073D3CA /* TeamSupportViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TeamSupportViewController.h; sourceTree = ""; }; + B1C60CA320C0DDF50073D3CA /* TeamSupportViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TeamSupportViewController.m; sourceTree = ""; }; + B1C60CAA20C0FC750073D3CA /* Launch Screen_E.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = "Launch Screen_E.xib"; sourceTree = ""; }; + B1C871121EADAEE1003DACF0 /* loading_monkey@2x.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = "loading_monkey@2x.gif"; sourceTree = ""; }; + B1C871141EADF0B1003DACF0 /* messageAT@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "messageAT@3x.png"; sourceTree = ""; }; + B1C871151EADF0B1003DACF0 /* messageComment@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "messageComment@3x.png"; sourceTree = ""; }; + B1C871161EADF0B1003DACF0 /* messageProjectFollows@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "messageProjectFollows@3x.png"; sourceTree = ""; }; + B1C871171EADF0B1003DACF0 /* messageSystem@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "messageSystem@3x.png"; sourceTree = ""; }; + B1C8711C1EADF0FF003DACF0 /* addBtn_Artboard@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "addBtn_Artboard@2x.png"; sourceTree = ""; }; + B1C8711D1EADF0FF003DACF0 /* addBtn_Artboard@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "addBtn_Artboard@3x.png"; sourceTree = ""; }; + B1C8711E1EADF0FF003DACF0 /* back_green_Nav@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "back_green_Nav@2x.png"; sourceTree = ""; }; + B1C8711F1EADF0FF003DACF0 /* back_green_Nav@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "back_green_Nav@3x.png"; sourceTree = ""; }; + B1C871201EADF0FF003DACF0 /* back_T_Nav@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "back_T_Nav@2x.png"; sourceTree = ""; }; + B1C871211EADF0FF003DACF0 /* back_T_Nav@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "back_T_Nav@3x.png"; sourceTree = ""; }; + B1C871221EADF0FF003DACF0 /* settingBtn_Nav@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "settingBtn_Nav@2x.png"; sourceTree = ""; }; + B1C871231EADF0FF003DACF0 /* settingBtn_Nav@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "settingBtn_Nav@3x.png"; sourceTree = ""; }; + B1C8712C1EADF155003DACF0 /* project_item_activity@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "project_item_activity@3x.png"; sourceTree = ""; }; + B1C8712D1EADF155003DACF0 /* project_item_code@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "project_item_code@3x.png"; sourceTree = ""; }; + B1C8712E1EADF155003DACF0 /* project_item_file@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "project_item_file@3x.png"; sourceTree = ""; }; + B1C8712F1EADF155003DACF0 /* project_item_member@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "project_item_member@3x.png"; sourceTree = ""; }; + B1C871301EADF155003DACF0 /* project_item_mr_pr@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "project_item_mr_pr@3x.png"; sourceTree = ""; }; + B1C871311EADF155003DACF0 /* project_item_readme@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "project_item_readme@3x.png"; sourceTree = ""; }; + B1C871321EADF155003DACF0 /* project_item_task@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "project_item_task@3x.png"; sourceTree = ""; }; + B1C871331EADF155003DACF0 /* project_item_wiki@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "project_item_wiki@2x.png"; sourceTree = ""; }; + B1C871341EADF155003DACF0 /* project_item_wiki@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "project_item_wiki@3x.png"; sourceTree = ""; }; + B1C8713E1EADF1C1003DACF0 /* taskDeadline@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskDeadline@3x.png"; sourceTree = ""; }; + B1C8713F1EADF1C1003DACF0 /* taskOwner@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskOwner@3x.png"; sourceTree = ""; }; + B1C871401EADF1C1003DACF0 /* taskPriority@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskPriority@3x.png"; sourceTree = ""; }; + B1C871411EADF1C1003DACF0 /* taskProgress@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskProgress@3x.png"; sourceTree = ""; }; + B1C871421EADF1C1003DACF0 /* taskProject@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskProject@3x.png"; sourceTree = ""; }; + B1C871481EADF217003DACF0 /* user_info_company@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "user_info_company@2x.png"; sourceTree = ""; }; + B1C871491EADF217003DACF0 /* user_info_company@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "user_info_company@3x.png"; sourceTree = ""; }; + B1C8714C1EADF3AC003DACF0 /* mrpr_icon_fileChange@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mrpr_icon_fileChange@3x.png"; sourceTree = ""; }; + B1C8714E1EADF48B003DACF0 /* cell_arrow_left@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "cell_arrow_left@2x.png"; sourceTree = ""; }; + B1C8714F1EADF48B003DACF0 /* cell_arrow_left@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "cell_arrow_left@3x.png"; sourceTree = ""; }; + B1C871521EADF4D4003DACF0 /* UITableViewCell+Common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITableViewCell+Common.h"; sourceTree = ""; }; + B1C871531EADF4D4003DACF0 /* UITableViewCell+Common.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITableViewCell+Common.m"; sourceTree = ""; }; + B1C871551EAE003A003DACF0 /* project_item_topic@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "project_item_topic@3x.png"; sourceTree = ""; }; + B1C871571EB0884A003DACF0 /* little_phone_icon@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "little_phone_icon@3x.png"; sourceTree = ""; }; + B1C871591EB182C7003DACF0 /* checkbox_checked@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "checkbox_checked@3x.png"; sourceTree = ""; }; + B1C8715A1EB182C7003DACF0 /* checkbox_unchecked@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "checkbox_unchecked@3x.png"; sourceTree = ""; }; + B1C8715B1EB182C7003DACF0 /* taskPriority0_small@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskPriority0_small@3x.png"; sourceTree = ""; }; + B1C8715C1EB182C7003DACF0 /* taskPriority0@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskPriority0@3x.png"; sourceTree = ""; }; + B1C8715D1EB182C7003DACF0 /* taskPriority1_small@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskPriority1_small@3x.png"; sourceTree = ""; }; + B1C8715E1EB182C7003DACF0 /* taskPriority1@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskPriority1@3x.png"; sourceTree = ""; }; + B1C8715F1EB182C7003DACF0 /* taskPriority2_small@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskPriority2_small@3x.png"; sourceTree = ""; }; + B1C871601EB182C7003DACF0 /* taskPriority2@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskPriority2@3x.png"; sourceTree = ""; }; + B1C871611EB182C7003DACF0 /* taskPriority3_small@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskPriority3_small@3x.png"; sourceTree = ""; }; + B1C871621EB182C7003DACF0 /* taskPriority3@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taskPriority3@3x.png"; sourceTree = ""; }; + B1C8716D1EB1832B003DACF0 /* task_description_icon@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "task_description_icon@3x.png"; sourceTree = ""; }; + B1C8716E1EB1832B003DACF0 /* topic_comment_icon@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "topic_comment_icon@3x.png"; sourceTree = ""; }; + B1C8716F1EB1832B003DACF0 /* time_clock_icon@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "time_clock_icon@3x.png"; sourceTree = ""; }; + B1C871731EB18599003DACF0 /* calendar_0x59A2FF@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "calendar_0x59A2FF@2x.png"; sourceTree = ""; }; + B1C871741EB18599003DACF0 /* calendar_0x59A2FF@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "calendar_0x59A2FF@3x.png"; sourceTree = ""; }; + B1C871751EB18599003DACF0 /* calendar_0xA1CF64@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "calendar_0xA1CF64@2x.png"; sourceTree = ""; }; + B1C871761EB18599003DACF0 /* calendar_0xA1CF64@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "calendar_0xA1CF64@3x.png"; sourceTree = ""; }; + B1C871771EB18599003DACF0 /* calendar_0xA9B3BE@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "calendar_0xA9B3BE@2x.png"; sourceTree = ""; }; + B1C871781EB18599003DACF0 /* calendar_0xA9B3BE@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "calendar_0xA9B3BE@3x.png"; sourceTree = ""; }; + B1C871791EB18599003DACF0 /* calendar_0xF56061@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "calendar_0xF56061@2x.png"; sourceTree = ""; }; + B1C8717A1EB18599003DACF0 /* calendar_0xF56061@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "calendar_0xF56061@3x.png"; sourceTree = ""; }; + B1C8717B1EB18599003DACF0 /* calendar_0xF68435@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "calendar_0xF68435@2x.png"; sourceTree = ""; }; + B1C8717C1EB18599003DACF0 /* calendar_0xF68435@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "calendar_0xF68435@3x.png"; sourceTree = ""; }; + B1C871871EB1E608003DACF0 /* btn_setFrequent@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_setFrequent@3x.png"; sourceTree = ""; }; + B1C871881EB1E608003DACF0 /* cell_checkmark@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "cell_checkmark@3x.png"; sourceTree = ""; }; + B1C871891EB1E608003DACF0 /* icon_add_comment@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_add_comment@3x.png"; sourceTree = ""; }; + B1C8718A1EB1E608003DACF0 /* nav_page_selected@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "nav_page_selected@3x.png"; sourceTree = ""; }; + B1C8718B1EB1E608003DACF0 /* nav_page_unselected@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "nav_page_unselected@3x.png"; sourceTree = ""; }; + B1C8718C1EB1E608003DACF0 /* tasks_all@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tasks_all@3x.png"; sourceTree = ""; }; + B1C871931EB2D9E6003DACF0 /* task_activity_icon_add_watcher@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "task_activity_icon_add_watcher@3x.png"; sourceTree = ""; }; + B1C871941EB2D9E6003DACF0 /* task_activity_icon_commit_refer@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "task_activity_icon_commit_refer@3x.png"; sourceTree = ""; }; + B1C871951EB2D9E6003DACF0 /* task_activity_icon_create@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "task_activity_icon_create@3x.png"; sourceTree = ""; }; + B1C871961EB2D9E6003DACF0 /* task_activity_icon_finish@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "task_activity_icon_finish@3x.png"; sourceTree = ""; }; + B1C871971EB2D9E6003DACF0 /* task_activity_icon_MergeRequestBean@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "task_activity_icon_MergeRequestBean@3x.png"; sourceTree = ""; }; + B1C871981EB2D9E6003DACF0 /* task_activity_icon_reassign@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "task_activity_icon_reassign@3x.png"; sourceTree = ""; }; + B1C871991EB2D9E6003DACF0 /* task_activity_icon_remove_watcher@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "task_activity_icon_remove_watcher@3x.png"; sourceTree = ""; }; + B1C8719A1EB2D9E6003DACF0 /* task_activity_icon_restore@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "task_activity_icon_restore@3x.png"; sourceTree = ""; }; + B1C8719B1EB2D9E6003DACF0 /* task_activity_icon_update_deadline@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "task_activity_icon_update_deadline@3x.png"; sourceTree = ""; }; + B1C8719C1EB2D9E6003DACF0 /* task_activity_icon_update_description@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "task_activity_icon_update_description@3x.png"; sourceTree = ""; }; + B1C8719D1EB2D9E6003DACF0 /* task_activity_icon_update_label@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "task_activity_icon_update_label@3x.png"; sourceTree = ""; }; + B1C8719E1EB2D9E6003DACF0 /* task_activity_icon_update_priority@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "task_activity_icon_update_priority@3x.png"; sourceTree = ""; }; + B1C8719F1EB2D9E6003DACF0 /* task_activity_icon_update@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "task_activity_icon_update@3x.png"; sourceTree = ""; }; + B1C871AD1EB2D9F0003DACF0 /* file_activity_icon_create@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "file_activity_icon_create@3x.png"; sourceTree = ""; }; + B1C871AE1EB2D9F0003DACF0 /* file_activity_icon_delete_history@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "file_activity_icon_delete_history@3x.png"; sourceTree = ""; }; + B1C871AF1EB2D9F0003DACF0 /* file_activity_icon_move_file@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "file_activity_icon_move_file@3x.png"; sourceTree = ""; }; + B1C871B01EB2D9F0003DACF0 /* file_activity_icon_update_file@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "file_activity_icon_update_file@3x.png"; sourceTree = ""; }; + B1C871B11EB2D9F0003DACF0 /* file_activity_icon_upload_file@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "file_activity_icon_upload_file@3x.png"; sourceTree = ""; }; + B1C871B71EB338FD003DACF0 /* comment_bg@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "comment_bg@3x.png"; sourceTree = ""; }; + B1C871B81EB338FD003DACF0 /* project_tag_btn@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "project_tag_btn@3x.png"; sourceTree = ""; }; + B1C871B91EB338FD003DACF0 /* project_tag_icon@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "project_tag_icon@3x.png"; sourceTree = ""; }; + B1C871BD1EB33B37003DACF0 /* task_icon_arrow@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "task_icon_arrow@3x.png"; sourceTree = ""; }; + B1CB8DD02047F1D000872197 /* button_tip_notice@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_tip_notice@2x.png"; sourceTree = ""; }; + B1CB8DD12047F1D100872197 /* button_tip_notice@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_tip_notice@3x.png"; sourceTree = ""; }; + B1D5F20220BC06CB00983FB6 /* Coding_Enterprise_iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Coding_Enterprise_iOS.app; sourceTree = BUILT_PRODUCTS_DIR; }; + B1D5F20620BCF5F800983FB6 /* Coding_Enterprise_iOS-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Coding_Enterprise_iOS-Info.plist"; sourceTree = ""; }; + B1D5F20B20BCF72300983FB6 /* Coding_Enterprise_iOS-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Coding_Enterprise_iOS-Prefix.pch"; sourceTree = ""; }; + B1D5F20C20BD3BF300983FB6 /* UINavigationController+FullscreenPopGesture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UINavigationController+FullscreenPopGesture.h"; sourceTree = ""; }; + B1D5F20D20BD3BF300983FB6 /* UINavigationController+FullscreenPopGesture.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UINavigationController+FullscreenPopGesture.m"; sourceTree = ""; }; + B1D5F21020BD485A00983FB6 /* TeamPurchaseOrder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TeamPurchaseOrder.h; sourceTree = ""; }; + B1D5F21120BD485A00983FB6 /* TeamPurchaseBillingDetail.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TeamPurchaseBillingDetail.h; sourceTree = ""; }; + B1D5F21220BD485B00983FB6 /* TeamPurchaseOrder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TeamPurchaseOrder.m; sourceTree = ""; }; + B1D5F21320BD485B00983FB6 /* TeamPurchaseBilling.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TeamPurchaseBilling.m; sourceTree = ""; }; + B1D5F21420BD485C00983FB6 /* TeamPurchaseBilling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TeamPurchaseBilling.h; sourceTree = ""; }; + B1D5F21520BD485C00983FB6 /* TeamPurchaseBillingDetail.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TeamPurchaseBillingDetail.m; sourceTree = ""; }; + B1D5F21C20BD50D000983FB6 /* ProjectRole.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProjectRole.h; sourceTree = ""; }; + B1D5F21D20BD50D000983FB6 /* ProjectRole.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProjectRole.m; sourceTree = ""; }; + B1D5F22020BEA37500983FB6 /* MeRootCompanyCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MeRootCompanyCell.h; sourceTree = ""; }; + B1D5F22120BEA37500983FB6 /* MeRootCompanyCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MeRootCompanyCell.m; sourceTree = ""; }; + B1D5F23020BEADD100983FB6 /* TeamSupportCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TeamSupportCell.m; sourceTree = ""; }; + B1D5F23120BEADD200983FB6 /* TeamSupportCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TeamSupportCell.h; sourceTree = ""; }; + B1DFD09D20C67D3D00F75F2F /* btn_followed_yes@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_followed_yes@3x.png"; sourceTree = ""; }; + B1DFD09E20C67D3E00F75F2F /* btn_followed_not@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_followed_not@3x.png"; sourceTree = ""; }; + B1DFD09F20C67D3E00F75F2F /* btn_followed_both@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_followed_both@3x.png"; sourceTree = ""; }; + B1DFD0A020C67D3E00F75F2F /* btn_privateMsg_friend@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "btn_privateMsg_friend@3x.png"; sourceTree = ""; }; B93D90491ACBA3110057A6EE /* ProjectDeleteAlertControllerVisualStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProjectDeleteAlertControllerVisualStyle.h; sourceTree = ""; }; B93D904A1ACBA3110057A6EE /* ProjectDeleteAlertControllerVisualStyle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProjectDeleteAlertControllerVisualStyle.m; sourceTree = ""; }; B94C1B671AC945D30000C271 /* NewProjectViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NewProjectViewController.h; sourceTree = ""; }; @@ -2843,8 +5439,7 @@ B9A00D811ACA3A17008BA008 /* ProjectSettingViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProjectSettingViewController.m; sourceTree = ""; }; B9A00D831ACA3A55008BA008 /* ProjectAdvancedSettingViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProjectAdvancedSettingViewController.h; sourceTree = ""; }; B9A00D841ACA3A55008BA008 /* ProjectAdvancedSettingViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProjectAdvancedSettingViewController.m; sourceTree = ""; }; - C613B8719C3D38FED828A1E2 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; - C664C272FECA8523C17A4109 /* libPods-Coding_iOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Coding_iOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + BA1AE837BA26B375F43A9343 /* Pods-Coding_iOS-CodingEnterprise_iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Coding_iOS-CodingEnterprise_iOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-Coding_iOS-CodingEnterprise_iOS/Pods-Coding_iOS-CodingEnterprise_iOS.release.xcconfig"; sourceTree = ""; }; D000E0481BFC45CF00A33C2B /* CategorySearchBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CategorySearchBar.h; sourceTree = ""; }; D000E0491BFC45CF00A33C2B /* CategorySearchBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CategorySearchBar.m; sourceTree = ""; }; D02BE0AD1C0434DB008374C0 /* PRMRSearchCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PRMRSearchCell.h; sourceTree = ""; }; @@ -2938,9 +5533,6 @@ D0C448171C03187100DC1C4B /* TaskSearchCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TaskSearchCell.m; sourceTree = ""; }; D0C448191C034C3F00DC1C4B /* TopicSearchCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TopicSearchCell.h; sourceTree = ""; }; D0C4481A1C034C3F00DC1C4B /* TopicSearchCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TopicSearchCell.m; sourceTree = ""; }; - D0FE4DB51C103FA0006E5A76 /* git_icon_fork_old@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "git_icon_fork_old@2x.png"; sourceTree = ""; }; - D0FE4DB61C103FA0006E5A76 /* git_icon_star_old@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "git_icon_star_old@2x.png"; sourceTree = ""; }; - D0FE4DB71C103FA0006E5A76 /* git_icon_watch_old@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "git_icon_watch_old@2x.png"; sourceTree = ""; }; E7A0469E1A47279E00528C12 /* Helper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Helper.h; sourceTree = ""; }; E7A0469F1A47279E00528C12 /* Helper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Helper.m; sourceTree = ""; }; /* End PBXFileReference section */ @@ -2950,6 +5542,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + B19D4EFE1F724CDC00C598F3 /* CoreMotion.framework in Frameworks */, + 4EFF5A771E0AE54800683D03 /* libresolv.9.tbd in Frameworks */, 4EDBECEB1B709EB3003E87C3 /* AVFoundation.framework in Frameworks */, 0AB591AD1AB6D51C0076C454 /* MapKit.framework in Frameworks */, 0A6E6BBF1AB180CB004C0107 /* CoreLocation.framework in Frameworks */, @@ -2957,12 +5551,11 @@ 4EDD8F5A1A36F4FA00E9E232 /* Security.framework in Frameworks */, 4EDD8F581A36F4CA00E9E232 /* CoreTelephony.framework in Frameworks */, 4EDD8F561A36F4BD00E9E232 /* SystemConfiguration.framework in Frameworks */, + B19D4EFC1F7247BA00C598F3 /* AlipaySDK.framework in Frameworks */, 4EDD8F541A36F4AC00E9E232 /* CFNetwork.framework in Frameworks */, 4E96E7C81A1B46740037C098 /* QuickLook.framework in Frameworks */, 8E03D4A419F696970092F8C8 /* libz.dylib in Frameworks */, - 4EB5A9431BF1DB4600C23AC3 /* libWeiboSDK.a in Frameworks */, 8EF5E74519C68CC7009346D5 /* libicucore.dylib in Frameworks */, - 4EB5A9421BF1DB4600C23AC3 /* libSocialSinaSSO.a in Frameworks */, 4EDD8F511A36F42200E9E232 /* libXG-SDK.a in Frameworks */, 7EB02FE81B6D0F3E00D2166C /* libopencore-amrnb.a in Frameworks */, 8E61D27B19C028CC00C00414 /* AssetsLibrary.framework in Frameworks */, @@ -2974,7 +5567,41 @@ 8E477018198770E700997D05 /* UIKit.framework in Frameworks */, 8E477014198770E700997D05 /* Foundation.framework in Frameworks */, 4EF818241B09D8D8005F974B /* WebP.framework in Frameworks */, - 404ED88BE5253A2BE89DDC30 /* libPods-Coding_iOS.a in Frameworks */, + 7FD0104CFC28ED5705E0D5E8 /* libPods-Coding_iOS.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B1D5EE5A20BC06CB00983FB6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + B1D5EE5B20BC06CB00983FB6 /* CoreMotion.framework in Frameworks */, + B1D5EE5C20BC06CB00983FB6 /* libresolv.9.tbd in Frameworks */, + B1D5EE5D20BC06CB00983FB6 /* AVFoundation.framework in Frameworks */, + B1D5EE5E20BC06CB00983FB6 /* MapKit.framework in Frameworks */, + B1D5EE5F20BC06CB00983FB6 /* CoreLocation.framework in Frameworks */, + B1D5EE6020BC06CB00983FB6 /* libsqlite3.0.dylib in Frameworks */, + B1D5EE6120BC06CB00983FB6 /* Security.framework in Frameworks */, + B1D5EE6220BC06CB00983FB6 /* CoreTelephony.framework in Frameworks */, + B1D5EE6320BC06CB00983FB6 /* SystemConfiguration.framework in Frameworks */, + B1D5EE6420BC06CB00983FB6 /* AlipaySDK.framework in Frameworks */, + B1D5EE6520BC06CB00983FB6 /* CFNetwork.framework in Frameworks */, + B1D5EE6620BC06CB00983FB6 /* QuickLook.framework in Frameworks */, + B1D5EE6720BC06CB00983FB6 /* libz.dylib in Frameworks */, + B1D5EE6820BC06CB00983FB6 /* libicucore.dylib in Frameworks */, + B1D5EE6920BC06CB00983FB6 /* libXG-SDK.a in Frameworks */, + B1D5EE6A20BC06CB00983FB6 /* libopencore-amrnb.a in Frameworks */, + B1D5EE6B20BC06CB00983FB6 /* AssetsLibrary.framework in Frameworks */, + B1D5EE6C20BC06CB00983FB6 /* libxml2.2.dylib in Frameworks */, + B1D5EE6D20BC06CB00983FB6 /* CoreText.framework in Frameworks */, + B1D5EE6E20BC06CB00983FB6 /* CoreGraphics.framework in Frameworks */, + B1D5EE6F20BC06CB00983FB6 /* libopencore-amrwb.a in Frameworks */, + B1D5EE7020BC06CB00983FB6 /* CoreData.framework in Frameworks */, + B1D5EE7120BC06CB00983FB6 /* UIKit.framework in Frameworks */, + B1D5EE7220BC06CB00983FB6 /* Foundation.framework in Frameworks */, + B1D5EE7320BC06CB00983FB6 /* WebP.framework in Frameworks */, + B1D5EE7420BC06CB00983FB6 /* libPods-Coding_iOS.a in Frameworks */, + 74BCC5B7B071C6418DBC18C7 /* libPods-Coding_iOS-Coding_Enterprise_iOS.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3037,6 +5664,8 @@ 13FB5CD21CA17A0B00EE127C /* pullRequest */ = { isa = PBXGroup; children = ( + 4EAAD0A31E5D8D90008AA957 /* PR_plus@2x.png */, + 4EAAD0A41E5D8D90008AA957 /* PR_plus@3x.png */, 133DAA621CC13A30004D8501 /* PR_update_title@2x.png */, 133DAA631CC13A30004D8501 /* PR_update_title@3x.png */, 134116F61CB55E69005E6550 /* PR_update@2x.png */, @@ -3056,9 +5685,6 @@ 13FB5D1A1CA17A6400EE127C /* PR_push@3x.png */, 13FB5D1B1CA17A6400EE127C /* PR_update_content@2x.png */, 13FB5D1C1CA17A6400EE127C /* PR_update_content@3x.png */, - 13FB5D1D1CA17A6400EE127C /* EPointLikeHead@1x.png */, - 13FB5D1E1CA17A6400EE127C /* EPointLikeHead@2x.png */, - 13FB5D1F1CA17A6400EE127C /* EPointLikeHead@3x.png */, 13FB5D201CA17A6400EE127C /* PR_refuse@2x.png */, 13FB5D211CA17A6400EE127C /* PR_refuse@3x.png */, 13FB5D221CA17A6400EE127C /* PR_grant_undo@2x.png */, @@ -3067,12 +5693,10 @@ 13FB5D251CA17A6400EE127C /* merge-request coding@3x.png */, 13FB5D261CA17A6400EE127C /* PR_mergeChanges@2x.png */, 13FB5D271CA17A6400EE127C /* PR_mergeChanges@3x.png */, - 13FB5D281CA17A6400EE127C /* PointLikeHead@1x.png */, 13FB5D291CA17A6400EE127C /* PointLikeHead@2x.png */, 13FB5D2A1CA17A6400EE127C /* PointLikeHead@3x.png */, 13FB5D2B1CA17A6400EE127C /* PR_review@2x.png */, 13FB5D2C1CA17A6400EE127C /* PR_review@3x.png */, - 13FB5D2D1CA17A6400EE127C /* PRReviewer@1x.png */, 13FB5D2E1CA17A6400EE127C /* PRReviewer@2x.png */, 13FB5D2F1CA17A6400EE127C /* PRReviewer@3x.png */, 13FB5D301CA17A6400EE127C /* PR_review_undo@2x.png */, @@ -3103,29 +5727,6 @@ path = EAIntroView; sourceTree = ""; }; - 4E0022A11B7362EF005308DE /* intro_pages */ = { - isa = PBXGroup; - children = ( - 4E095A111D9534CB00E63D9E /* intro_page_selected@2x.png */, - 4E095A121D9534CB00E63D9E /* intro_page_selected@3x.png */, - 4E095A131D9534CB00E63D9E /* intro_page_unselected@2x.png */, - 4E095A141D9534CB00E63D9E /* intro_page_unselected@3x.png */, - 4E0022A21B7362EF005308DE /* intro_page0_ip4@2x.png */, - 4E0022A31B7362EF005308DE /* intro_page0_ip5@2x.png */, - 4E0022A41B7362EF005308DE /* intro_page0_ip6+@3x.png */, - 4E0022A51B7362EF005308DE /* intro_page0_ip6@2x.png */, - 4E6B070D1BA3D9B5007D6027 /* intro_page1_ip4@2x.png */, - 4E6B070E1BA3D9B5007D6027 /* intro_page1_ip5@2x.png */, - 4E6B070F1BA3D9B5007D6027 /* intro_page1_ip6@2x.png */, - 4E6B07101BA3D9B5007D6027 /* intro_page1_ip6+@3x.png */, - 4EB119F41D953AE200A36341 /* intro_page2_ip4@2x.png */, - 4EB119F51D953AE200A36341 /* intro_page2_ip5@2x.png */, - 4EB119F61D953AE200A36341 /* intro_page2_ip6@2x.png */, - 4EB119F71D953AE200A36341 /* intro_page2_ip6+@3x.png */, - ); - path = intro_pages; - sourceTree = ""; - }; 4E095A5D1B6909F9008DC439 /* AutoSlideScrollView */ = { isa = PBXGroup; children = ( @@ -3149,11 +5750,16 @@ 4E095A751B6B1E40008DC439 /* deadline_calendar */ = { isa = PBXGroup; children = ( - 4E095A761B6B1E40008DC439 /* calendar_0x95B763@2x.png */, - 4E095A771B6B1E40008DC439 /* calendar_0x9AAFC2@2x.png */, - 4E095A781B6B1E40008DC439 /* calendar_0xB5B5B5@2x.png */, - 4E095A791B6B1E40008DC439 /* calendar_0xF24B4B@2x.png */, - 4E095A7A1B6B1E40008DC439 /* calendar_0xF5A523@2x.png */, + B1C871731EB18599003DACF0 /* calendar_0x59A2FF@2x.png */, + B1C871741EB18599003DACF0 /* calendar_0x59A2FF@3x.png */, + B1C871751EB18599003DACF0 /* calendar_0xA1CF64@2x.png */, + B1C871761EB18599003DACF0 /* calendar_0xA1CF64@3x.png */, + B1C871771EB18599003DACF0 /* calendar_0xA9B3BE@2x.png */, + B1C871781EB18599003DACF0 /* calendar_0xA9B3BE@3x.png */, + B1C871791EB18599003DACF0 /* calendar_0xF56061@2x.png */, + B1C8717A1EB18599003DACF0 /* calendar_0xF56061@3x.png */, + B1C8717B1EB18599003DACF0 /* calendar_0xF68435@2x.png */, + B1C8717C1EB18599003DACF0 /* calendar_0xF68435@3x.png */, ); path = deadline_calendar; sourceTree = ""; @@ -3218,9 +5824,6 @@ 4E1A228C1AB19D1F00CFC14F /* git_btn_icons */ = { isa = PBXGroup; children = ( - D0FE4DB51C103FA0006E5A76 /* git_icon_fork_old@2x.png */, - D0FE4DB61C103FA0006E5A76 /* git_icon_star_old@2x.png */, - D0FE4DB71C103FA0006E5A76 /* git_icon_watch_old@2x.png */, D09E6AC51BF84AF9009D37F8 /* git_icon_fork@2x.png */, D09E6AC31BF84AE5009D37F8 /* git_icon_watch@2x.png */, D09E6AC11BF84AC5009D37F8 /* git_icon_star@2x.png */, @@ -3350,6 +5953,43 @@ path = member_type; sourceTree = ""; }; + 4E3068261E0B781A00AEE0CE /* EADeviceToServerLog */ = { + isa = PBXGroup; + children = ( + 4E3068271E0B781A00AEE0CE /* EADeviceToServerLog.h */, + 4E3068281E0B781A00AEE0CE /* EADeviceToServerLog.m */, + 4E3068291E0B781A00AEE0CE /* EANetTraceRoute.h */, + 4E30682A1E0B781A00AEE0CE /* EANetTraceRoute.m */, + 4E30682B1E0B781A00AEE0CE /* LDNetDiagnoService */, + 4E30683B1E0B781A00AEE0CE /* NSData+gzip.h */, + 4E30683C1E0B781A00AEE0CE /* NSData+gzip.m */, + ); + path = EADeviceToServerLog; + sourceTree = ""; + }; + 4E30682B1E0B781A00AEE0CE /* LDNetDiagnoService */ = { + isa = PBXGroup; + children = ( + 4E30682C1E0B781A00AEE0CE /* LDNetConnect.h */, + 4E30682D1E0B781A00AEE0CE /* LDNetConnect.m */, + 4E30682E1E0B781A00AEE0CE /* LDNetDiagnoService.h */, + 4E30682F1E0B781A00AEE0CE /* LDNetDiagnoService.m */, + 4E3068301E0B781A00AEE0CE /* LDNetGetAddress.h */, + 4E3068311E0B781A00AEE0CE /* LDNetGetAddress.m */, + 4E3068321E0B781A00AEE0CE /* LDNetPing.h */, + 4E3068331E0B781A00AEE0CE /* LDNetPing.m */, + 4E3068341E0B781A00AEE0CE /* LDNetTimer.h */, + 4E3068351E0B781A00AEE0CE /* LDNetTimer.m */, + 4E3068361E0B781A00AEE0CE /* LDNetTraceRoute.h */, + 4E3068371E0B781A00AEE0CE /* LDNetTraceRoute.m */, + 4E3068381E0B781A00AEE0CE /* LDSimplePing.h */, + 4E3068391E0B781A00AEE0CE /* LDSimplePing.m */, + 4E30683A1E0B781A00AEE0CE /* Route.h */, + B1B2BDB01F79E74000645EAD /* net_route.h */, + ); + path = LDNetDiagnoService; + sourceTree = ""; + }; 4E4972E51BB5446900F3AC15 /* tips_menu */ = { isa = PBXGroup; children = ( @@ -3382,6 +6022,21 @@ 4E6383991B3262D300D98648 /* task */ = { isa = PBXGroup; children = ( + B1C871591EB182C7003DACF0 /* checkbox_checked@3x.png */, + B1C8715A1EB182C7003DACF0 /* checkbox_unchecked@3x.png */, + B1C8715B1EB182C7003DACF0 /* taskPriority0_small@3x.png */, + B1C8715C1EB182C7003DACF0 /* taskPriority0@3x.png */, + B1C8715D1EB182C7003DACF0 /* taskPriority1_small@3x.png */, + B1C8715E1EB182C7003DACF0 /* taskPriority1@3x.png */, + B1C8715F1EB182C7003DACF0 /* taskPriority2_small@3x.png */, + B1C871601EB182C7003DACF0 /* taskPriority2@3x.png */, + B1C871611EB182C7003DACF0 /* taskPriority3_small@3x.png */, + B1C871621EB182C7003DACF0 /* taskPriority3@3x.png */, + B1C8713E1EADF1C1003DACF0 /* taskDeadline@3x.png */, + B1C8713F1EADF1C1003DACF0 /* taskOwner@3x.png */, + B1C871401EADF1C1003DACF0 /* taskPriority@3x.png */, + B1C871411EADF1C1003DACF0 /* taskProgress@3x.png */, + B1C871421EADF1C1003DACF0 /* taskProject@3x.png */, 4EB52F391C7C45E700B5EBEA /* taskResourceReference@2x.png */, 4EB52F3A1C7C45E700B5EBEA /* taskResourceReference@3x.png */, 4E6383E71B32791600D98648 /* checkbox_checked@2x.png */, @@ -3398,10 +6053,15 @@ 4E6383A11B3262D300D98648 /* taskPriority3@2x.png */, 4E6383A21B3262D300D98648 /* taskPriority3_small@2x.png */, 4E63840E1B34124000D98648 /* task_icon_arrow@2x.png */, + B1C871BD1EB33B37003DACF0 /* task_icon_arrow@3x.png */, 4EED9DCA1B539366000E5827 /* taskOwner@2x.png */, 4EED9DCB1B539366000E5827 /* taskProject@2x.png */, 4ED618221C3CB1AF0017946C /* taskWatchers@2x.png */, 4ED618231C3CB1AF0017946C /* taskWatchers@3x.png */, + B152ED7F209453E7004A6E8A /* taskboard_blankpage@2x.png */, + B152ED81209453E8004A6E8A /* taskboard_blankpage@3x.png */, + B152ED80209453E7004A6E8A /* taskBoardList@2x.png */, + B152ED7E209453E6004A6E8A /* taskBoardList@3x.png */, ); path = task; sourceTree = ""; @@ -3409,6 +6069,10 @@ 4E6383B01B32640900D98648 /* message */ = { isa = PBXGroup; children = ( + B1C871141EADF0B1003DACF0 /* messageAT@3x.png */, + B1C871151EADF0B1003DACF0 /* messageComment@3x.png */, + B1C871161EADF0B1003DACF0 /* messageProjectFollows@3x.png */, + B1C871171EADF0B1003DACF0 /* messageSystem@3x.png */, 4E6CBE561D8FBDF500644086 /* messageProjectFans@2x.png */, 4E6CBE571D8FBDF500644086 /* messageProjectFollows@2x.png */, 4E6383B11B32640900D98648 /* messageAT@2x.png */, @@ -3426,8 +6090,10 @@ 4E6383BD1B3265DC00D98648 /* mrpr */ = { isa = PBXGroup; children = ( + B1C8714C1EADF3AC003DACF0 /* mrpr_icon_fileChange@3x.png */, + 4EAAD09B1E5D8558008AA957 /* mrpr_icon_arrow@2x.png */, + 4EAAD09C1E5D8558008AA957 /* mrpr_icon_arrow@3x.png */, 4E6383BE1B3265DC00D98648 /* mrpr_icon_accepted@2x.png */, - 4E6383BF1B3265DC00D98648 /* mrpr_icon_arrow@2x.png */, 4E6383C21B3265DC00D98648 /* mrpr_icon_refaused@2x.png */, 4E6383D91B3266C200D98648 /* mrpr_icon_commit@2x.png */, 4E6383DA1B3266C200D98648 /* mrpr_icon_fileChange@2x.png */, @@ -3438,6 +6104,17 @@ 4E6383C81B32665700D98648 /* nproject_item */ = { isa = PBXGroup; children = ( + B131E2102074D2EE00D84FAA /* project_item_reading@2x.png */, + B131E20F2074D2ED00D84FAA /* project_item_reading@3x.png */, + B1C8712C1EADF155003DACF0 /* project_item_activity@3x.png */, + B1C8712D1EADF155003DACF0 /* project_item_code@3x.png */, + B1C8712E1EADF155003DACF0 /* project_item_file@3x.png */, + B1C8712F1EADF155003DACF0 /* project_item_member@3x.png */, + B1C871301EADF155003DACF0 /* project_item_mr_pr@3x.png */, + B1C871311EADF155003DACF0 /* project_item_readme@3x.png */, + B1C871321EADF155003DACF0 /* project_item_task@3x.png */, + B1C871331EADF155003DACF0 /* project_item_wiki@2x.png */, + B1C871341EADF155003DACF0 /* project_item_wiki@3x.png */, 4E6383EB1B32A2C300D98648 /* project_item_file@2x.png */, 4E6383C91B32665700D98648 /* project_item_activity@2x.png */, 4E6383CA1B32665700D98648 /* project_item_code@2x.png */, @@ -3446,6 +6123,13 @@ 4E6383CE1B32665700D98648 /* project_item_readme@2x.png */, 4E6383CF1B32665700D98648 /* project_item_task@2x.png */, 4E6383D01B32665700D98648 /* project_item_topic@2x.png */, + B1C871551EAE003A003DACF0 /* project_item_topic@3x.png */, + B1817EF32069186C00E9BAD1 /* project_item_branch@2x.png */, + B1817EF42069186D00E9BAD1 /* project_item_branch@3x.png */, + B1817EF22069186C00E9BAD1 /* project_item_tag@2x.png */, + B1817EF52069186E00E9BAD1 /* project_item_tag@3x.png */, + B152ED7A20945377004A6E8A /* project_item_taskboard@2x.png */, + B152ED7B20945377004A6E8A /* project_item_taskboard@3x.png */, ); path = nproject_item; sourceTree = ""; @@ -3453,6 +6137,23 @@ 4E6383F31B33C18700D98648 /* task_activity_icon */ = { isa = PBXGroup; children = ( + B1BFC4C020B2B24E009427FC /* task_activity_icon_add_milestone@2x.png */, + B1BFC4C120B2B24E009427FC /* task_activity_icon_add_milestone@3x.png */, + B1BFC4C320B2B250009427FC /* task_activity_icon_remove_milestone@2x.png */, + B1BFC4C220B2B24F009427FC /* task_activity_icon_remove_milestone@3x.png */, + B1C871931EB2D9E6003DACF0 /* task_activity_icon_add_watcher@3x.png */, + B1C871941EB2D9E6003DACF0 /* task_activity_icon_commit_refer@3x.png */, + B1C871951EB2D9E6003DACF0 /* task_activity_icon_create@3x.png */, + B1C871961EB2D9E6003DACF0 /* task_activity_icon_finish@3x.png */, + B1C871971EB2D9E6003DACF0 /* task_activity_icon_MergeRequestBean@3x.png */, + B1C871981EB2D9E6003DACF0 /* task_activity_icon_reassign@3x.png */, + B1C871991EB2D9E6003DACF0 /* task_activity_icon_remove_watcher@3x.png */, + B1C8719A1EB2D9E6003DACF0 /* task_activity_icon_restore@3x.png */, + B1C8719B1EB2D9E6003DACF0 /* task_activity_icon_update_deadline@3x.png */, + B1C8719C1EB2D9E6003DACF0 /* task_activity_icon_update_description@3x.png */, + B1C8719D1EB2D9E6003DACF0 /* task_activity_icon_update_label@3x.png */, + B1C8719E1EB2D9E6003DACF0 /* task_activity_icon_update_priority@3x.png */, + B1C8719F1EB2D9E6003DACF0 /* task_activity_icon_update@3x.png */, 4ED618201C3BD79B0017946C /* task_activity_icon_remove_watcher@2x.png */, 4E3DB53A1BFDD0F40062BA52 /* task_activity_icon_add_watcher@2x.png */, 4E3DB53B1BFDD0F40062BA52 /* task_activity_icon_MergeRequestBean@2x.png */, @@ -3473,7 +6174,17 @@ 4E66EE201A28226000DA1B3E /* button_file_manage */ = { isa = PBXGroup; children = ( - 4EAE06C41B7B587200179F4B /* button_file_comment@2x.png */, + B1AB5CAB202D7D4F0075A669 /* button_file_activity@3x.png */, + B1AB5CA6202D7D4D0075A669 /* button_file_createFolder_enable@3x.png */, + B1AB5CB0202D7D500075A669 /* button_file_createFolder_unable@3x.png */, + B1AB5CA7202D7D4E0075A669 /* button_file_denete_enable@3x.png */, + B1AB5CAC202D7D4F0075A669 /* button_file_denete_unable@3x.png */, + B1AB5CA8202D7D4E0075A669 /* button_file_download_enable@3x.png */, + B1AB5CAD202D7D4F0075A669 /* button_file_download_unable@3x.png */, + B1AB5CAA202D7D4E0075A669 /* button_file_history@3x.png */, + B1AB5CAE202D7D4F0075A669 /* button_file_move_enable@3x.png */, + B1AB5CAF202D7D4F0075A669 /* button_file_move_unable@3x.png */, + B1AB5CA9202D7D4E0075A669 /* button_file_upload_enable@3x.png */, 4E66EE211A28226000DA1B3E /* button_file_createFolder_enable@2x.png */, 4E66EE221A28226000DA1B3E /* button_file_denete_enable@2x.png */, 4E66EE231A28226000DA1B3E /* button_file_denete_unable@2x.png */, @@ -3602,6 +6313,42 @@ path = YLGIFImage; sourceTree = ""; }; + 4E80E9261DFFF06E00DE1BC6 /* shortcut */ = { + isa = PBXGroup; + children = ( + 4E80E9271DFFF06E00DE1BC6 /* shortcut_2FA@2x.png */, + 4E80E9281DFFF06E00DE1BC6 /* shortcut_2FA@3x.png */, + 4E80E9291DFFF06E00DE1BC6 /* shortcut_task@2x.png */, + 4E80E92A1DFFF06E00DE1BC6 /* shortcut_task@3x.png */, + 4E80E92B1DFFF06E00DE1BC6 /* shortcut_tweet@2x.png */, + 4E80E92C1DFFF06E00DE1BC6 /* shortcut_tweet@3x.png */, + ); + path = shortcut; + sourceTree = ""; + }; + 4E80E93D1E02911E00DE1BC6 /* search_icon */ = { + isa = PBXGroup; + children = ( + 4E80E93E1E02911E00DE1BC6 /* search_icon_tweet@2x.png */, + 4E80E93F1E02911E00DE1BC6 /* search_icon_tweet@3x.png */, + 4E80E9401E02911E00DE1BC6 /* search_icon_topic@2x.png */, + 4E80E9411E02911E00DE1BC6 /* search_icon_topic@3x.png */, + 4E80E9421E02911E00DE1BC6 /* search_icon_file@2x.png */, + 4E80E9431E02911E00DE1BC6 /* search_icon_file@3x.png */, + 4E80E9441E02911E00DE1BC6 /* search_icon_mr@2x.png */, + 4E80E9451E02911E00DE1BC6 /* search_icon_mr@3x.png */, + 4E80E9461E02911E00DE1BC6 /* search_icon_user@2x.png */, + 4E80E9471E02911E00DE1BC6 /* search_icon_user@3x.png */, + 4E80E9481E02911E00DE1BC6 /* search_icon_pr@2x.png */, + 4E80E9491E02911E00DE1BC6 /* search_icon_pr@3x.png */, + 4E80E94A1E02911E00DE1BC6 /* search_icon_project@2x.png */, + 4E80E94B1E02911E00DE1BC6 /* search_icon_project@3x.png */, + 4E80E94C1E02911E00DE1BC6 /* search_icon_task@2x.png */, + 4E80E94D1E02911E00DE1BC6 /* search_icon_task@3x.png */, + ); + path = search_icon; + sourceTree = ""; + }; 4E8765581A22E5B40090CFB9 /* SWTableViewCell */ = { isa = PBXGroup; children = ( @@ -3718,17 +6465,6 @@ path = ASProgressPopUpView; sourceTree = ""; }; - 4E9113A41A1CB19900AC9431 /* icon_file_state */ = { - isa = PBXGroup; - children = ( - 4E9113A51A1CB19900AC9431 /* icon_file_state_download@2x.png */, - 4E9113A61A1CB19900AC9431 /* icon_file_state_goon@2x.png */, - 4E9113A71A1CB19900AC9431 /* icon_file_state_look@2x.png */, - 4E9113A81A1CB19900AC9431 /* icon_file_state_pause@2x.png */, - ); - path = icon_file_state; - sourceTree = ""; - }; 4E93F2301B84243D00017916 /* KxMenu */ = { isa = PBXGroup; children = ( @@ -3809,7 +6545,21 @@ 4E96E7D41A1B537E0037C098 /* icon_file_psd@2x.png */, 4E96E7D51A1B537E0037C098 /* icon_file_txt@2x.png */, 4E96E7D61A1B537E0037C098 /* icon_file_xls@2x.png */, + B1BCB88A1FCD0A6D0098B87B /* icon_file_xls_big@2x.png */, 4E96E7D71A1B537E0037C098 /* icon_file_zip@2x.png */, + B1BCB87B1FCD006C0098B87B /* icon_file_ai_big@2x.png */, + B1BCB8771FCD006B0098B87B /* icon_file_apk_big@2x.png */, + B1BCB8781FCD006C0098B87B /* icon_file_code_big@2x.png */, + B1BCB8701FCD006A0098B87B /* icon_file_doc_big@2x.png */, + B1BCB8761FCD006B0098B87B /* icon_file_md_big@2x.png */, + B1BCB8751FCD006B0098B87B /* icon_file_movie_big@2x.png */, + B1BCB87A1FCD006C0098B87B /* icon_file_music_big@2x.png */, + B1BCB8721FCD006B0098B87B /* icon_file_pdf_big@2x.png */, + B1BCB87C1FCD006C0098B87B /* icon_file_ppt_big@2x.png */, + B1BCB8731FCD006B0098B87B /* icon_file_psd_big@2x.png */, + B1BCB8791FCD006C0098B87B /* icon_file_txt_big@2x.png */, + B1BCB8741FCD006B0098B87B /* icon_file_unknown_big@2x.png */, + B1BCB8711FCD006B0098B87B /* icon_file_zip_big@2x.png */, ); path = icon_file; sourceTree = ""; @@ -3817,6 +6567,8 @@ 4E996BC11ABA754600C704F1 /* JDStatusBarNotification */ = { isa = PBXGroup; children = ( + B12B641A1FF0F5E300ACFDCC /* JDStatusBarLayoutMarginHelper.h */, + B12B641B1FF0F5E300ACFDCC /* JDStatusBarLayoutMarginHelper.m */, 4E996BC21ABA754600C704F1 /* JDStatusBarNotification.h */, 4E996BC31ABA754600C704F1 /* JDStatusBarNotification.m */, 4E996BC41ABA754600C704F1 /* JDStatusBarStyle.h */, @@ -3830,6 +6582,10 @@ 4E996BF91ABBF56A00C704F1 /* userInfo */ = { isa = PBXGroup; children = ( + B19D4EF41F7210C300C598F3 /* user_info_shop@2x.png */, + B19D4EF51F7210C300C598F3 /* user_info_shop@3x.png */, + B1C871481EADF217003DACF0 /* user_info_company@2x.png */, + B1C871491EADF217003DACF0 /* user_info_company@3x.png */, 4E996BFA1ABBF56A00C704F1 /* n_btn_followed_both@2x.png */, 4E996BFB1ABBF56A00C704F1 /* n_btn_followed_not@2x.png */, 4E996BFC1ABBF56A00C704F1 /* n_btn_followed_yes@2x.png */, @@ -3905,6 +6661,40 @@ path = ODRefreshControl; sourceTree = ""; }; + 4EAAD0181E540551008AA957 /* mrpr_icon_status */ = { + isa = PBXGroup; + children = ( + 4EAAD0191E540551008AA957 /* mrpr_icon_status_accepted@2x.png */, + 4EAAD01A1E540551008AA957 /* mrpr_icon_status_accepted@3x.png */, + 4EAAD01B1E540551008AA957 /* mrpr_icon_status_canmerge@2x.png */, + 4EAAD01C1E540551008AA957 /* mrpr_icon_status_canmerge@3x.png */, + 4EAAD01D1E540551008AA957 /* mrpr_icon_status_cannotmerge@2x.png */, + 4EAAD01E1E540551008AA957 /* mrpr_icon_status_cannotmerge@3x.png */, + 4EAAD01F1E540551008AA957 /* mrpr_icon_status_refused@2x.png */, + 4EAAD0201E540551008AA957 /* mrpr_icon_status_refused@3x.png */, + 4EAAD0291E5405B4008AA957 /* mrpr_icon_status_cancel@2x.png */, + 4EAAD02A1E5405B4008AA957 /* mrpr_icon_status_cancel@3x.png */, + ); + path = mrpr_icon_status; + sourceTree = ""; + }; + 4EAAD0481E542B2D008AA957 /* icon_code */ = { + isa = PBXGroup; + children = ( + 4EAAD0491E542B2D008AA957 /* icon_code_executable@2x.png */, + 4EAAD04A1E542B2D008AA957 /* icon_code_executable@3x.png */, + 4EAAD04B1E542B2D008AA957 /* icon_code_tree@2x.png */, + 4EAAD04C1E542B2D008AA957 /* icon_code_tree@3x.png */, + 4EAAD04D1E542B2D008AA957 /* icon_code_file@2x.png */, + 4EAAD04E1E542B2D008AA957 /* icon_code_file@3x.png */, + 4EAAD04F1E542B2D008AA957 /* icon_code_git_link@2x.png */, + 4EAAD0501E542B2D008AA957 /* icon_code_git_link@3x.png */, + 4EAAD0801E55AC6E008AA957 /* icon_code_image@2x.png */, + 4EAAD0811E55AC6E008AA957 /* icon_code_image@3x.png */, + ); + path = icon_code; + sourceTree = ""; + }; 4EABD2511AD3CA7E005E515F /* UIMessageInputView */ = { isa = PBXGroup; children = ( @@ -3925,6 +6715,13 @@ 4EAE06BB1B7B51AF00179F4B /* file_activity_icon */ = { isa = PBXGroup; children = ( + B19D4EDF1F690F5E00C598F3 /* file_activity_icon_rename@2x.png */, + B19D4EE01F690F5E00C598F3 /* file_activity_icon_rename@3x.png */, + B1C871AD1EB2D9F0003DACF0 /* file_activity_icon_create@3x.png */, + B1C871AE1EB2D9F0003DACF0 /* file_activity_icon_delete_history@3x.png */, + B1C871AF1EB2D9F0003DACF0 /* file_activity_icon_move_file@3x.png */, + B1C871B01EB2D9F0003DACF0 /* file_activity_icon_update_file@3x.png */, + B1C871B11EB2D9F0003DACF0 /* file_activity_icon_upload_file@3x.png */, 4EAE06BC1B7B51AF00179F4B /* file_activity_icon_create@2x.png */, 4EAE06BD1B7B51AF00179F4B /* file_activity_icon_move_file@2x.png */, 4EAE06BE1B7B51AF00179F4B /* file_activity_icon_update_file@2x.png */, @@ -3986,27 +6783,6 @@ path = task_resource_reference; sourceTree = ""; }; - 4EB5A9331BF1DB4600C23AC3 /* SinaSSO */ = { - isa = PBXGroup; - children = ( - 4EB5A9341BF1DB4600C23AC3 /* libSocialSinaSSO.a */, - 4EB5A9351BF1DB4600C23AC3 /* libWeiboSDK.a */, - 4EB5A9361BF1DB4600C23AC3 /* UMSocialSinaSSOHandler.h */, - 4EB5A9371BF1DB4600C23AC3 /* WBHttpRequest+WeiboGame.h */, - 4EB5A9381BF1DB4600C23AC3 /* WBHttpRequest+WeiboShare.h */, - 4EB5A9391BF1DB4600C23AC3 /* WBHttpRequest+WeiboToken.h */, - 4EB5A93A1BF1DB4600C23AC3 /* WBHttpRequest+WeiboUser.h */, - 4EB5A93B1BF1DB4600C23AC3 /* WBHttpRequest.h */, - 4EB5A93C1BF1DB4600C23AC3 /* WBSDKBasicButton.h */, - 4EB5A93D1BF1DB4600C23AC3 /* WBSDKCommentButton.h */, - 4EB5A93E1BF1DB4600C23AC3 /* WBSDKRelationshipButton.h */, - 4EB5A93F1BF1DB4600C23AC3 /* WeiboSDK.bundle */, - 4EB5A9401BF1DB4600C23AC3 /* WeiboSDK.h */, - 4EB5A9411BF1DB4600C23AC3 /* WeiboUser.h */, - ); - path = SinaSSO; - sourceTree = ""; - }; 4EBB62471A6F526C0045DAEF /* NJKWebViewProgress */ = { isa = PBXGroup; children = ( @@ -4021,6 +6797,11 @@ 4EC461AE1B39360F00D08970 /* file_changeType */ = { isa = PBXGroup; children = ( + B1280CE9200EFDC600DEDF78 /* file_changeType_ADD@3x.png */, + B1280CEA200EFDC600DEDF78 /* file_changeType_COPY@3x.png */, + B1280CEB200EFDC600DEDF78 /* file_changeType_DELETE@3x.png */, + B1280CEC200EFDC600DEDF78 /* file_changeType_MODIFY@3x.png */, + B1280CE8200EFDC600DEDF78 /* file_changeType_RENAME@3x.png */, 4EC461AF1B39360F00D08970 /* file_changeType_ADD@2x.png */, 4EC461B01B39360F00D08970 /* file_changeType_DELETE@2x.png */, 4EC461B11B39360F00D08970 /* file_changeType_MODIFY@2x.png */, @@ -4070,14 +6851,12 @@ 4ECE8AD01A3943E80021E29C /* UILabel+Common.m */, 4ECE8AD11A3943E80021E29C /* UITableView+Common.h */, 4ECE8AD21A3943E80021E29C /* UITableView+Common.m */, + B1C871521EADF4D4003DACF0 /* UITableViewCell+Common.h */, + B1C871531EADF4D4003DACF0 /* UITableViewCell+Common.m */, 4ECE8AD31A3943E80021E29C /* UIView+Common.h */, 4ECE8AD41A3943E80021E29C /* UIView+Common.m */, 4ECE8AD51A3943E80021E29C /* UIViewController+Swizzle.h */, 4ECE8AD61A3943E80021E29C /* UIViewController+Swizzle.m */, - 4EBDA87A1A6640340035ED96 /* UIActionSheet+Common.h */, - 4EBDA87B1A6640340035ED96 /* UIActionSheet+Common.m */, - 4E19E7051BCE03CD00C66DC6 /* UIActionSheet+Front.h */, - 4E19E7061BCE03CD00C66DC6 /* UIActionSheet+Front.m */, 4EB0C1FE1A807ED00042FC4F /* NSURL+Common.h */, 4EB0C1FF1A807ED00042FC4F /* NSURL+Common.m */, 4EE5481C1AE7B7CA00A92306 /* UISearchBar+Common.h */, @@ -4094,6 +6873,14 @@ D09AA5BF1BFDEDD1008CA9EB /* NSString+Attribute.m */, 4E2527181C327FAE0032A7F4 /* UIViewController+BackButtonHandler.h */, 4E2527191C327FAE0032A7F4 /* UIViewController+BackButtonHandler.m */, + B1D5F20C20BD3BF300983FB6 /* UINavigationController+FullscreenPopGesture.h */, + B1D5F20D20BD3BF300983FB6 /* UINavigationController+FullscreenPopGesture.m */, + B12B64801FFC73A900ACFDCC /* PHAsset+Common.h */, + B12B64811FFC73A900ACFDCC /* PHAsset+Common.m */, + B1890C4C2019B29800F52ABA /* UINavigationBar+Common.h */, + B1890C4B2019B29800F52ABA /* UINavigationBar+Common.m */, + B186AEAE20F462F600A6AF35 /* UIAlertController+Common.h */, + B186AEAF20F462F600A6AF35 /* UIAlertController+Common.m */, ); path = OC_Category; sourceTree = ""; @@ -4140,6 +6927,10 @@ 4E00229F1B7360B1005308DE /* FunctionIntroManager.m */, 4E5D13131C0EDFE700985AEB /* SendRewardManager.h */, 4E5D13141C0EDFE700985AEB /* SendRewardManager.m */, + 4E80E9331E011D6000DE1BC6 /* RewardTipManager.h */, + 4E80E9341E011D6000DE1BC6 /* RewardTipManager.m */, + B12B641D1FF2835800ACFDCC /* CodingVipTipManager.h */, + B12B641E1FF2835800ACFDCC /* CodingVipTipManager.m */, ); path = Manager; sourceTree = ""; @@ -4166,17 +6957,6 @@ path = XGPush; sourceTree = ""; }; - 4EE083DD1ADB739300CA342E /* modules */ = { - isa = PBXGroup; - children = ( - 4E90F8971AF709C100B44F03 /* bubble.html */, - 4E90F8981AF709C100B44F03 /* code.html */, - 4E90F8991AF709C100B44F03 /* markdown.html */, - 4E90F89A1AF709C100B44F03 /* topic-ios.html */, - ); - name = modules; - sourceTree = ""; - }; 4EE1A2181B5D02CA004284F1 /* TableListView */ = { isa = PBXGroup; children = ( @@ -4186,8 +6966,8 @@ 4EE1A21C1B5D02CA004284F1 /* ProjectActivityListView.m */, 4EE1A21D1B5D02CA004284F1 /* ProjectCodeListView.h */, 4EE1A21E1B5D02CA004284F1 /* ProjectCodeListView.m */, - 4EE1A21F1B5D02CA004284F1 /* ProjectFolderListView.h */, - 4EE1A2201B5D02CA004284F1 /* ProjectFolderListView.m */, + B1C60C7820BFA2150073D3CA /* NProjectFileListView.h */, + B1C60C7920BFA2150073D3CA /* NProjectFileListView.m */, 4EE1A2211B5D02CA004284F1 /* ProjectListView.h */, 4EE1A2221B5D02CA004284F1 /* ProjectListView.m */, 4EE1A2231B5D02CA004284F1 /* ProjectTaskListView.h */, @@ -4202,66 +6982,19 @@ 4E6318A11BDA261100EFED97 /* MRListView.m */, 926C043C1C01A212004937D8 /* ShopOrderListView.h */, 926C043D1C01A212004937D8 /* ShopOrderListView.m */, + 4E80E93A1E02353900DE1BC6 /* CodingSearchDisplayView.h */, + 4E80E93B1E02353900DE1BC6 /* CodingSearchDisplayView.m */, + B1890C372015D89A00F52ABA /* WikiMenuListView.h */, + B1890C362015D89A00F52ABA /* WikiMenuListView.m */, + B152ED5E2093018A004A6E8A /* EABoardTaskListView.h */, + B152ED5F2093018A004A6E8A /* EABoardTaskListView.m */, + B152ED6120935524004A6E8A /* EABoardTaskListBlankView.h */, + B152ED6220935524004A6E8A /* EABoardTaskListBlankView.m */, + B152ED6420935594004A6E8A /* EABoardTaskListBlankView.xib */, ); path = TableListView; sourceTree = ""; }; - 4EE956521B9C1C500009EDA9 /* UMSocial_Sdk_4.3.0_Extra */ = { - isa = PBXGroup; - children = ( - 4EB5A9331BF1DB4600C23AC3 /* SinaSSO */, - ); - path = UMSocial_Sdk_4.3.0_Extra; - sourceTree = ""; - }; - 4EF17E761B3BF320003CDD2D /* introduction */ = { - isa = PBXGroup; - children = ( - 4EF17EAD1B3C3112003CDD2D /* intro_dot_selected@2x.png */, - 4EF17EAE1B3C3112003CDD2D /* intro_dot_selected@3x.png */, - 4EF17EAF1B3C3112003CDD2D /* intro_dot_unselected@2x.png */, - 4EF17EB01B3C3112003CDD2D /* intro_dot_unselected@3x.png */, - 4EF17EB11B3C3112003CDD2D /* intro_icon_0@2x.png */, - 4EF17EB21B3C3112003CDD2D /* intro_icon_0@3x.png */, - 4EF17EB31B3C3112003CDD2D /* intro_icon_1@2x.png */, - 4EF17EB41B3C3112003CDD2D /* intro_icon_1@3x.png */, - 4EF17EB51B3C3112003CDD2D /* intro_icon_2@2x.png */, - 4EF17EB61B3C3112003CDD2D /* intro_icon_2@3x.png */, - 4EF17EB71B3C3112003CDD2D /* intro_icon_3@2x.png */, - 4EF17EB81B3C3112003CDD2D /* intro_icon_3@3x.png */, - 4EF17EB91B3C3112003CDD2D /* intro_icon_4@2x.png */, - 4EF17EBA1B3C3112003CDD2D /* intro_icon_4@3x.png */, - 4EF17EBB1B3C3112003CDD2D /* intro_icon_5@2x.png */, - 4EF17EBC1B3C3112003CDD2D /* intro_icon_5@3x.png */, - 4EF17ECA1B3C3112003CDD2D /* intro_icon_6@2x.png */, - 4EF17EBD1B3C3112003CDD2D /* intro_icon_6@3x.png */, - 4EF17EBE1B3C3112003CDD2D /* intro_tip_0@2x.png */, - 4EF17EBF1B3C3112003CDD2D /* intro_tip_0@3x.png */, - 4EF17EC01B3C3112003CDD2D /* intro_tip_1@2x.png */, - 4EF17EC11B3C3112003CDD2D /* intro_tip_1@3x.png */, - 4EF17EC21B3C3112003CDD2D /* intro_tip_2@2x.png */, - 4EF17EC31B3C3112003CDD2D /* intro_tip_2@3x.png */, - 4EF17EC41B3C3112003CDD2D /* intro_tip_3@2x.png */, - 4EF17EC51B3C3112003CDD2D /* intro_tip_3@3x.png */, - 4EF17EC61B3C3112003CDD2D /* intro_tip_4@2x.png */, - 4EF17EC71B3C3112003CDD2D /* intro_tip_4@3x.png */, - 4EF17EC81B3C3112003CDD2D /* intro_tip_5@2x.png */, - 4EF17EC91B3C3112003CDD2D /* intro_tip_5@3x.png */, - ); - path = introduction; - sourceTree = ""; - }; - 677C285895EC30898E811622 /* Pods */ = { - isa = PBXGroup; - children = ( - 8B18B0211092D3903D031B13 /* Pods.debug.xcconfig */, - C613B8719C3D38FED828A1E2 /* Pods.release.xcconfig */, - A64F1BDEE7EF5AF0AEA5F032 /* Pods-Coding_iOS.debug.xcconfig */, - 1F50C85531CF9D72938EE577 /* Pods-Coding_iOS.release.xcconfig */, - ); - name = Pods; - sourceTree = ""; - }; 7E8E59781B6F91C40083CA02 /* bubble */ = { isa = PBXGroup; children = ( @@ -4392,6 +7125,8 @@ 8E1C3E0519E8DFE300EF3032 /* SettingViewController.m */, 8EF83F8819E92AA500E86DE7 /* SettingTagsViewController.h */, 8EF83F8919E92AA500E86DE7 /* SettingTagsViewController.m */, + B12B64101FF0D54800ACFDCC /* SettingSkillsViewController.h */, + B12B64111FF0D54800ACFDCC /* SettingSkillsViewController.m */, 8EF83F9219EB78CC00E86DE7 /* SettingTextViewController.h */, 8EF83F9319EB78CC00E86DE7 /* SettingTextViewController.m */, ); @@ -4404,7 +7139,7 @@ 8EA6CF1319E240C40076D59C /* Coding_iOS */, 8E477012198770E700997D05 /* Frameworks */, 8E477011198770E700997D05 /* Products */, - 677C285895EC30898E811622 /* Pods */, + C2A35A9B71AB7D9C11F8394B /* Pods */, ); indentWidth = 4; sourceTree = ""; @@ -4414,6 +7149,7 @@ isa = PBXGroup; children = ( 8E477010198770E700997D05 /* Coding_iOS.app */, + B1D5F20220BC06CB00983FB6 /* Coding_Enterprise_iOS.app */, ); name = Products; sourceTree = ""; @@ -4421,6 +7157,8 @@ 8E477012198770E700997D05 /* Frameworks */ = { isa = PBXGroup; children = ( + B19D4EFD1F724CDC00C598F3 /* CoreMotion.framework */, + 4EFF5A761E0AE54800683D03 /* libresolv.9.tbd */, 4EDBECEA1B709EB3003E87C3 /* AVFoundation.framework */, 4EF818231B09D8D8005F974B /* WebP.framework */, 0A6E6BBE1AB180CB004C0107 /* CoreLocation.framework */, @@ -4443,8 +7181,8 @@ 8E477017198770E700997D05 /* UIKit.framework */, 8E477019198770E700997D05 /* CoreData.framework */, 8E477031198770E700997D05 /* XCTest.framework */, - 3B024F2227BD4152BC7C9A7A /* libPods.a */, - C664C272FECA8523C17A4109 /* libPods-Coding_iOS.a */, + 645969FE6A8616A74543C249 /* libPods-Coding_iOS.a */, + 627CA7E44F0D5A025A49E2F0 /* libPods-Coding_iOS-Coding_Enterprise_iOS.a */, ); name = Frameworks; sourceTree = ""; @@ -4452,10 +7190,34 @@ 8E525C8119F7E3F800496B34 /* blankpage */ = { isa = PBXGroup; children = ( - 8E525C8219F7E3F800496B34 /* blankpage_button_reload@2x.png */, - 8E525C8319F7E3F800496B34 /* blankpage_image_loadFail@2x.png */, - 8E525C8619F7E3F800496B34 /* blankpage_image_Sleep@2x.png */, - 4E743E6E1A88ABF700DADDE5 /* blankpage_image_Hi@2x.png */, + 4E9423BE1E69401B0095F1CD /* blankpage_image_Activity@2x.png */, + 4E9423BF1E69401B0095F1CD /* blankpage_image_Activity@3x.png */, + 4E9423C01E69401B0095F1CD /* blankpage_image_Default@2x.png */, + 4E9423C11E69401B0095F1CD /* blankpage_image_Default@3x.png */, + 4E9423C21E69401B0095F1CD /* blankpage_image_File@2x.png */, + 4E9423C31E69401B0095F1CD /* blankpage_image_File@3x.png */, + 4E9423C41E69401B0095F1CD /* blankpage_image_LoadFail@2x.png */, + 4E9423C51E69401B0095F1CD /* blankpage_image_LoadFail@3x.png */, + 4E9423C61E69401B0095F1CD /* blankpage_image_MessageList@2x.png */, + 4E9423C71E69401B0095F1CD /* blankpage_image_MessageList@3x.png */, + 4E9423C81E69401B0095F1CD /* blankpage_image_Notice@2x.png */, + 4E9423C91E69401B0095F1CD /* blankpage_image_Notice@3x.png */, + 4E9423CA1E69401B0095F1CD /* blankpage_image_Project@2x.png */, + 4E9423CB1E69401B0095F1CD /* blankpage_image_Project@3x.png */, + 4E9423CC1E69401B0095F1CD /* blankpage_image_ShopOrder@2x.png */, + 4E9423CD1E69401B0095F1CD /* blankpage_image_ShopOrder@3x.png */, + 4E9423CE1E69401B0095F1CD /* blankpage_image_Task@2x.png */, + 4E9423CF1E69401B0095F1CD /* blankpage_image_Task@3x.png */, + 4E9423D01E69401B0095F1CD /* blankpage_image_Team@2x.png */, + 4E9423D11E69401B0095F1CD /* blankpage_image_Team@3x.png */, + 4E9423D21E69401B0095F1CD /* blankpage_image_Tip@2x.png */, + 4E9423D31E69401B0095F1CD /* blankpage_image_Tip@3x.png */, + 4E9423D41E69401B0095F1CD /* blankpage_image_Topic@2x.png */, + 4E9423D51E69401B0095F1CD /* blankpage_image_Topic@3x.png */, + 4E9423D61E69401B0095F1CD /* blankpage_image_Tweet@2x.png */, + 4E9423D71E69401B0095F1CD /* blankpage_image_Tweet@3x.png */, + 4E9423D81E69401B0095F1CD /* blankpage_image_Wiki@2x.png */, + 4E9423D91E69401B0095F1CD /* blankpage_image_Wiki@3x.png */, ); path = blankpage; sourceTree = ""; @@ -4472,34 +7234,6 @@ path = SVPullToRefresh; sourceTree = ""; }; - 8E64ED6519ED0CE3006E99DA /* QBImagePickerController */ = { - isa = PBXGroup; - children = ( - 8E64ED6619ED0CE3006E99DA /* QBAssetsCollectionCheckmarkView.h */, - 8E64ED6719ED0CE3006E99DA /* QBAssetsCollectionCheckmarkView.m */, - 8E64ED6819ED0CE3006E99DA /* QBAssetsCollectionFooterView.h */, - 8E64ED6919ED0CE3006E99DA /* QBAssetsCollectionFooterView.m */, - 8E64ED6A19ED0CE3006E99DA /* QBAssetsCollectionOverlayView.h */, - 8E64ED6B19ED0CE3006E99DA /* QBAssetsCollectionOverlayView.m */, - 8E64ED6C19ED0CE3006E99DA /* QBAssetsCollectionVideoIndicatorView.h */, - 8E64ED6D19ED0CE3006E99DA /* QBAssetsCollectionVideoIndicatorView.m */, - 8E64ED6E19ED0CE3006E99DA /* QBAssetsCollectionViewCell.h */, - 8E64ED6F19ED0CE3006E99DA /* QBAssetsCollectionViewCell.m */, - 8E64ED7019ED0CE3006E99DA /* QBAssetsCollectionViewController.h */, - 8E64ED7119ED0CE3006E99DA /* QBAssetsCollectionViewController.m */, - 8E64ED7219ED0CE3006E99DA /* QBAssetsCollectionViewLayout.h */, - 8E64ED7319ED0CE3006E99DA /* QBAssetsCollectionViewLayout.m */, - 8E64ED7419ED0CE3006E99DA /* QBImagePickerController.h */, - 8E64ED7519ED0CE3006E99DA /* QBImagePickerController.m */, - 8E64ED7619ED0CE3006E99DA /* QBImagePickerController.strings */, - 8E64ED7719ED0CE3006E99DA /* QBImagePickerGroupCell.h */, - 8E64ED7819ED0CE3006E99DA /* QBImagePickerGroupCell.m */, - 8E64ED7919ED0CE3006E99DA /* QBImagePickerThumbnailView.h */, - 8E64ED7A19ED0CE3006E99DA /* QBImagePickerThumbnailView.m */, - ); - path = QBImagePickerController; - sourceTree = ""; - }; 8E64ED8619EE484A006E99DA /* NSDate+Helper */ = { isa = PBXGroup; children = ( @@ -4513,13 +7247,19 @@ 8E8F7B2119EF6306006BA8BD /* cell_right_plain_btn_image */ = { isa = PBXGroup; children = ( + B1DFD09F20C67D3E00F75F2F /* btn_followed_both@3x.png */, + B1DFD09E20C67D3E00F75F2F /* btn_followed_not@3x.png */, + B1DFD09D20C67D3D00F75F2F /* btn_followed_yes@3x.png */, + B1DFD0A020C67D3E00F75F2F /* btn_privateMsg_friend@3x.png */, + B16E6CBB20C13F5E0076026D /* btn_privateMsg_stranger@3x.png */, + B16E6CB820C13F5E0076026D /* btn_project_add@3x.png */, + B16E6CB920C13F5E0076026D /* btn_project_added@3x.png */, + B16E6CBA20C13F5E0076026D /* btn_project_quit@3x.png */, 8E8F7B2219EF6306006BA8BD /* btn_followed_both@2x.png */, 8E8F7B2319EF6306006BA8BD /* btn_followed_not@2x.png */, 8E8F7B2419EF6306006BA8BD /* btn_followed_yes@2x.png */, - 8E8F7B2519EF6306006BA8BD /* btn_privateMsg_black@2x.png */, 8E8F7B2619EF6306006BA8BD /* btn_privateMsg_friend@2x.png */, 8E8F7B2719EF6306006BA8BD /* btn_privateMsg_stranger@2x.png */, - 8E8F7B2819EF6306006BA8BD /* btn_privateMsg_white@2x.png */, 8E8F7B2919EF6306006BA8BD /* btn_project_add@2x.png */, 8E8F7B2A19EF6306006BA8BD /* btn_project_added@2x.png */, 8E8F7B2B19EF6306006BA8BD /* btn_project_quit@2x.png */, @@ -4543,6 +7283,18 @@ 8E97CE4B1A0A3410006F9AD7 /* nav_button */ = { isa = PBXGroup; children = ( + B16E6CC620C144910076026D /* done_Nav@2x.png */, + B16E6CC720C144920076026D /* done_Nav@3x.png */, + B16E6CC820C144920076026D /* done_un_Nav@2x.png */, + B16E6CC920C144920076026D /* done_un_Nav@3x.png */, + B1C8711C1EADF0FF003DACF0 /* addBtn_Artboard@2x.png */, + B1C8711D1EADF0FF003DACF0 /* addBtn_Artboard@3x.png */, + B1C8711E1EADF0FF003DACF0 /* back_green_Nav@2x.png */, + B1C8711F1EADF0FF003DACF0 /* back_green_Nav@3x.png */, + B1C871201EADF0FF003DACF0 /* back_T_Nav@2x.png */, + B1C871211EADF0FF003DACF0 /* back_T_Nav@3x.png */, + B1C871221EADF0FF003DACF0 /* settingBtn_Nav@2x.png */, + B1C871231EADF0FF003DACF0 /* settingBtn_Nav@3x.png */, 4E59D3291D3E106D008C914B /* tweetsBtn_Nav@2x.png */, 4E59D32A1D3E106D008C914B /* tweetsBtn_Nav@3x.png */, 4ECEF9F81D1D0B3D002A27D3 /* tip_normal_Nav@2x.png */, @@ -4574,6 +7326,7 @@ 8E97CE561A0A3424006F9AD7 /* keyboard */ = { isa = PBXGroup; children = ( + 4E9DEEC51E30CA3C001B8D1B /* keyboard_emotion_emoji_code@2x.png */, 4E5F39061ACBFDCD0010515D /* keyboard_photo@2x.png */, 8E97CE6B1A0B243B006F9AD7 /* keyboard_add@2x.png */, 8E97CE571A0A3424006F9AD7 /* keyboard_add_photo@2x.png */, @@ -4657,12 +7410,16 @@ isa = PBXGroup; children = ( 4EBED55A1D93C9F700E3684E /* Coding_iOS.entitlements */, + B16E6CA220C0FFFF0076026D /* Coding_Enterprise_iOS.entitlements */, 8EA6CFC619E240C40076D59C /* main.m */, - 8EA6CF1519E240C40076D59C /* AppDelegate.h */, 8EA6CF1619E240C40076D59C /* AppDelegate.m */, + 8EA6CF1519E240C40076D59C /* AppDelegate.h */, 4EFE8DB81B3A5727004B7559 /* Launch Screen.xib */, + B1C60CAA20C0FC750073D3CA /* Launch Screen_E.xib */, 8EA6CF1719E240C40076D59C /* Coding_iOS-Info.plist */, + B1D5F20620BCF5F800983FB6 /* Coding_Enterprise_iOS-Info.plist */, 4E8C51AE1AC0177600B4C51F /* Coding_iOS-Prefix.pch */, + B1D5F20B20BCF72300983FB6 /* Coding_Enterprise_iOS-Prefix.pch */, 8EA6CF1919E240C40076D59C /* Coding_iOS.xcdatamodeld */, 8EA6CFC519E240C40076D59C /* Images.xcassets */, 8EA6CF5B19E240C40076D59C /* InfoPlist.strings */, @@ -4671,6 +7428,7 @@ 8EA6CF1B19E240C40076D59C /* Controllers */, 8EA6CFFC19E240C40076D59C /* Util */, 8EA6CF5D19E240C40076D59C /* Images */, + B16E6D1D20C148E50076026D /* images_diff */, 8EA6CFFA19E240C40076D59C /* Resources */, 8EA6D03E19E240C40076D59C /* Vendor */, 4E8D5D3D1B451E9100B70936 /* Ease_2FA */, @@ -4747,8 +7505,6 @@ 8E59F10C1A02188D009A905F /* CodeViewController.m */, 4E2F6A551C437D1D00A25502 /* EditCodeViewController.h */, 4E2F6A561C437D1D00A25502 /* EditCodeViewController.m */, - 4EA6791E1A15AB9F001A0324 /* FileListViewController.h */, - 4EA6791F1A15AB9F001A0324 /* FileListViewController.m */, 4E15C7CE1A26D2F000FB8DAD /* FolderToMoveViewController.h */, 4E15C7CF1A26D2F000FB8DAD /* FolderToMoveViewController.m */, 4E35A99D1A3EC47E00CE35F1 /* FileViewController.h */, @@ -4765,10 +7521,8 @@ 4E996BDB1ABA79AB00C704F1 /* UserInfoDetailViewController.m */, 4E996BE01ABA957B00C704F1 /* ProjectListViewController.h */, 4E996BE11ABA957B00C704F1 /* ProjectListViewController.m */, - 4ECF70411B18514F000280FF /* PRListViewController.h */, - 4ECF70421B18514F000280FF /* PRListViewController.m */, - 4E63189A1BDA198000EFED97 /* MRListViewController.h */, - 4E63189B1BDA198000EFED97 /* MRListViewController.m */, + 4EAAD0121E5306F3008AA957 /* MRPRListViewController.h */, + 4EAAD0131E5306F3008AA957 /* MRPRListViewController.m */, 4E4D6A5F1B1C65C100FD2E49 /* MRPRCommitsViewController.h */, 4E4D6A601B1C65C100FD2E49 /* MRPRCommitsViewController.m */, 4E4D6A621B1C65F700FD2E49 /* MRPRFilesViewController.h */, @@ -4787,6 +7541,9 @@ 4E24B2671B43D33F004D7989 /* ProjectToChooseListViewController.m */, 4E0022871B721516005308DE /* PointRecordsViewController.h */, 4E0022881B721516005308DE /* PointRecordsViewController.m */, + B19D4EE71F6FAA6000C598F3 /* AboutPointViewController.h */, + B19D4EE81F6FAA6000C598F3 /* AboutPointViewController.m */, + B19D4EE91F6FAA6000C598F3 /* AboutPointViewController.xib */, 4EAE06A91B7B23EA00179F4B /* FileActivitiesViewController.h */, 4EAE06AA1B7B23EA00179F4B /* FileActivitiesViewController.m */, 4EAE06AC1B7B241A00179F4B /* FileVersionsViewController.h */, @@ -4828,6 +7585,46 @@ 4E6CBE501D8E962300644086 /* TopicAnswerDetailViewController.m */, 4E9E3B731DCC2DB10005FD79 /* HtmlMediaViewController.h */, 4E9E3B741DCC2DB10005FD79 /* HtmlMediaViewController.m */, + B1BCB88C1FCE61D60098B87B /* EAPayViewController.h */, + B1BCB88D1FCE61D60098B87B /* EAPayViewController.m */, + B1BCB88E1FCE61D60098B87B /* EAPayViewController.xib */, + B1890C462015D92600F52ABA /* WikiEditViewController.h */, + B1890C432015D92500F52ABA /* WikiEditViewController.m */, + B1890C422015D92500F52ABA /* WikiHistoryListViewController.h */, + B1890C442015D92500F52ABA /* WikiHistoryListViewController.m */, + B1890C452015D92600F52ABA /* WikiViewController.h */, + B1890C472015D92600F52ABA /* WikiViewController.m */, + B1816061202063440022B4C6 /* EATerminalViewController.h */, + B1816062202063440022B4C6 /* EATerminalViewController.m */, + B1817EB42063899400E9BAD1 /* EACodeBranchListViewController.h */, + B1817EB52063899400E9BAD1 /* EACodeBranchListViewController.m */, + B1817EB7206389F500E9BAD1 /* EACodeReleaseListViewController.h */, + B1817EB8206389F500E9BAD1 /* EACodeReleaseListViewController.m */, + B1817EE22064F92C00E9BAD1 /* EACodeReleaseViewController.h */, + B1817EE32064F92C00E9BAD1 /* EACodeReleaseViewController.m */, + B1817F042069F67700E9BAD1 /* EAEditCodeReleaseViewController.h */, + B1817F052069F67700E9BAD1 /* EAEditCodeReleaseViewController.m */, + B1944142206BB87F00147158 /* EALocalCodeListViewController.h */, + B1944143206BB87F00147158 /* EALocalCodeListViewController.m */, + B1944145206BB89100147158 /* EALocalCodeViewController.h */, + B1944146206BB89100147158 /* EALocalCodeViewController.m */, + B16EEF11209080D7005ABFD5 /* TaskBoardsViewController.h */, + B16EEF12209080D7005ABFD5 /* TaskBoardsViewController.m */, + B152ED66209420CD004A6E8A /* RATaskBoardListListViewController.h */, + B152ED67209420CD004A6E8A /* RATaskBoardListListViewController.m */, + B1C60C7C20BFCDBD0073D3CA /* EditMemberTypeProjectListViewController.h */, + B1C60C7D20BFCDBD0073D3CA /* EditMemberTypeProjectListViewController.m */, + B1C60C8120BFCEFD0073D3CA /* NFileListViewController.h */, + B1C60C8020BFCEFD0073D3CA /* NFileListViewController.m */, + B1C60C8C20BFF7950073D3CA /* ProjectTypeExplanationViewController.h */, + B1C60C8D20BFF7950073D3CA /* ProjectTypeExplanationViewController.m */, + B1C60C8B20BFF7940073D3CA /* ProjectTypeExplanationViewController.xib */, + B1C60C9F20C0DDF40073D3CA /* TeamPurchaseViewController.h */, + B1C60CA120C0DDF40073D3CA /* TeamPurchaseViewController.m */, + B1C60C9E20C0DDF30073D3CA /* TeamSettingViewController.h */, + B1C60CA020C0DDF40073D3CA /* TeamSettingViewController.m */, + B1C60CA220C0DDF50073D3CA /* TeamSupportViewController.h */, + B1C60CA320C0DDF50073D3CA /* TeamSupportViewController.m */, ); path = Controllers; sourceTree = ""; @@ -4879,6 +7676,23 @@ 8EA6CF5D19E240C40076D59C /* Images */ = { isa = PBXGroup; children = ( + B16E6CFA20C147760076026D /* team_cell_edit */, + B16E6CF120C147760076026D /* team_info */, + B16E6CD220C145BE0076026D /* quick_menu_icon */, + B16E6CAA20C13BF40076026D /* btn_next */, + B152ED86209453F2004A6E8A /* taskboard_page */, + B17CC31620731FF10077C956 /* code_release_resource_icon */, + B1AB5C8F202953E40075A669 /* terminal_icon */, + B1890C1D2015D82600F52ABA /* wiki */, + B1890C262015D82600F52ABA /* wiki_menu_icon */, + B1280CF2200EFEA400DEDF78 /* PR_Activity */, + B12B640B1FECB58F00ACFDCC /* login */, + B1BCB8941FCE93830098B87B /* pay */, + B14689A31EE100B200B01371 /* vip */, + 4EAAD0481E542B2D008AA957 /* icon_code */, + 4EAAD0181E540551008AA957 /* mrpr_icon_status */, + 4E80E93D1E02911E00DE1BC6 /* search_icon */, + 4E80E9261DFFF06E00DE1BC6 /* shortcut */, 13FB5CD21CA17A0B00EE127C /* pullRequest */, 4EB52F431C7C4C0B00B5EBEA /* task_resource_reference */, 4EB52F161C76BA3B00B5EBEA /* tag_button */, @@ -4891,11 +7705,9 @@ 4E2BF3BD1B95B97A00A5A0A8 /* tweet_btn */, 4E93F2341B84356500017916 /* file_menu_icon */, 4EAE06BB1B7B51AF00179F4B /* file_activity_icon */, - 4E0022A11B7362EF005308DE /* intro_pages */, 4E095A751B6B1E40008DC439 /* deadline_calendar */, 4E095A6A1B69F920008DC439 /* banner */, 4E94C5021B4D334B00EB668A /* pop_icon */, - 4EF17E761B3BF320003CDD2D /* introduction */, 4EC461AE1B39360F00D08970 /* file_changeType */, 4E6383F31B33C18700D98648 /* task_activity_icon */, 4E6383C81B32665700D98648 /* nproject_item */, @@ -4905,7 +7717,6 @@ 4E996BF91ABBF56A00C704F1 /* userInfo */, 4E66EE201A28226000DA1B3E /* button_file_manage */, 4EC5AD8E1A258DF8006FA97C /* icon_file_cell_edit */, - 4E9113A41A1CB19900AC9431 /* icon_file_state */, 4E96E7C91A1B537E0037C098 /* icon_file */, 8E97CE731A0C7E26006F9AD7 /* emotion_monkey */, 4E2DB33B1BA6A1FC002F27C4 /* emotion_monkey_gif */, @@ -4922,6 +7733,14 @@ 4E1A228C1AB19D1F00CFC14F /* git_btn_icons */, 7E8E59781B6F91C40083CA02 /* bubble */, 8EA6CF5F19E240C40076D59C /* btn_delete_tweetimage@2x.png */, + B184166720513CA000207666 /* topic_add_watcher_btn@3x.png */, + B184166820513CA000207666 /* tweet_comment_btn@3x.png */, + B1C871871EB1E608003DACF0 /* btn_setFrequent@3x.png */, + B1C871881EB1E608003DACF0 /* cell_checkmark@3x.png */, + B1C871891EB1E608003DACF0 /* icon_add_comment@3x.png */, + B1C8718A1EB1E608003DACF0 /* nav_page_selected@3x.png */, + B1C8718B1EB1E608003DACF0 /* nav_page_unselected@3x.png */, + B1C8718C1EB1E608003DACF0 /* tasks_all@3x.png */, 8B3516541B6CF69E0049BC45 /* icon_search_clock@2x.png */, D0C448121C02F76600DC1C4B /* icon_search_searchbar@2x.png */, D0C448131C02F76600DC1C4B /* icon_search_searchbar@3x.png */, @@ -4932,6 +7751,9 @@ 8EA6CF6319E240C40076D59C /* commentOrLikeBeginImg@2x.png */, 8B35164A1B6CE9460049BC45 /* icon_arrow_searchHistory@2x.png */, 8B35164B1B6CE9460049BC45 /* icon_topic_hotTop@2x.png */, + B1C8716D1EB1832B003DACF0 /* task_description_icon@3x.png */, + B1C8716E1EB1832B003DACF0 /* topic_comment_icon@3x.png */, + B1C8716F1EB1832B003DACF0 /* time_clock_icon@3x.png */, 8B35164C1B6CE9460049BC45 /* search_tweet_colck@2x.png */, 8EA6CF7119E240C40076D59C /* login_email@2x.png */, 8EA6CF7319E240C40076D59C /* login_suffix@2x.png */, @@ -4947,28 +7769,23 @@ 8EA6CFC419E240C40076D59C /* xtsegment_bordor_right@2x.png */, 8ED2AAF819F60D5200607A1D /* loading_loop@2x.png */, 8ED2AAF919F60D5200607A1D /* loading_monkey@2x.png */, + B1C871121EADAEE1003DACF0 /* loading_monkey@2x.gif */, 8EF6433B19FE696B00F7EEB0 /* cell_checkmark@2x.png */, 8EF6434F19FF4E1600F7EEB0 /* comment_count_top_line@2x.png */, - 4E4D6ABF1B252CD400FD2E49 /* icon_code_file@2x.png */, - 4E4D6AC01B252CD400FD2E49 /* icon_code_tree@2x.png */, 4EA679171A14BFA0001A0324 /* icon_file_folder_default@2x.png */, 4EA679181A14BFA0001A0324 /* icon_file_folder_normal@2x.png */, 4E1D99121DCAE67D00BAE585 /* icon_file_folder_out@2x.png */, - 4E1D99131DCAE67D00BAE585 /* icon_file_folder_out@3x.png */, 4E1D99141DCAE67D00BAE585 /* icon_file_folder_share@2x.png */, - 4E1D99151DCAE67D00BAE585 /* icon_file_folder_share@3x.png */, 4E1D991A1DCAE69600BAE585 /* icon_file_share_logo@2x.png */, 4E1D991B1DCAE69600BAE585 /* icon_file_share_logo@3x.png */, 4E07D30B1A4A9F45009EDDF2 /* btn_file_cancel@2x.png */, 4E07D30C1A4A9F45009EDDF2 /* btn_file_reDo@2x.png */, - 4E07D3121A4D3CA6009EDDF2 /* icon_user_monkey@2x.png */, - 4E07D3131A4D3CA6009EDDF2 /* logo_coding@2x.png */, 4EFE8DAE1B3960E6004B7559 /* logo_coding_top@2x.png */, + B16E6C9F20C0FDB50076026D /* logo_coding_top@3x.png */, 4E76D4DD1A5A7B4A0094A35E /* text_clear_btn@2x.png */, 4E03AC991A5BDDF9002B000B /* STARTIMAGE.jpg */, 4E6B07151BA4045E007D6027 /* MIDAUTUMNIMAGE.jpg */, D09E6AB91BF829A1009D37F8 /* icon_project_private@2x.png */, - 4E38CF631A7B8DD4005536C0 /* icon_triangle@2x.png */, 4EBFBD171AA85B8500E4B10E /* add_user_icon@2x.png */, 4E2719C61AB07ED6006AE214 /* dot_line@2x.png */, 0A06C2521AB9E57900AB3B03 /* map_annotation@2x.png */, @@ -4989,8 +7806,6 @@ 4EE1A23B1B5F3834004284F1 /* project_tag_btn@2x.png */, 4EE1A23C1B5F3834004284F1 /* project_tag_icon@2x.png */, 8EA6CF7419E240C40076D59C /* logo_about@2x.png */, - 4E8F92DB1B67BE3C00033D8F /* icon_user_monkey_i6@2x.png */, - 4E8F92DC1B67BE3C00033D8F /* icon_user_monkey_i6p@3x.png */, 4E095A801B6B24DE008DC439 /* task_description_icon@2x.png */, 4E095A811B6B24DE008DC439 /* time_clock_icon@2x.png */, 4E095A821B6B24DE008DC439 /* topic_comment_icon@2x.png */, @@ -4998,6 +7813,7 @@ 4EAE068F1B784E9200179F4B /* store_icon@2x.png */, 4EAE06911B7880BA00179F4B /* me_info_arrow_left@2x.png */, 4EAC8B691BA01F190060B0FC /* little_phone_icon@2x.png */, + B1C871571EB0884A003DACF0 /* little_phone_icon@3x.png */, 4E5D13161C0EF48200985AEB /* button_close@2x.png */, 4E5D13171C0EF48200985AEB /* button_close@3x.png */, 4EC4800D1C2A909D005F1772 /* register_step_ed@2x.png */, @@ -5006,12 +7822,48 @@ 4EC480101C2A909D005F1772 /* register_step_un@3x.png */, 4ED6181E1C3A732F0017946C /* button_arrow_left@2x.png */, 4EB52F2C1C77138A00B5EBEA /* button_scan@2x.png */, - 4EB52F2D1C77138A00B5EBEA /* button_scan@3x.png */, 4ECEFA001D1D0B4B002A27D3 /* tip_bg@2x.png */, 4ECEFA011D1D0B4B002A27D3 /* tip_bg@3x.png */, 4E59D3301D409C8C008C914B /* topic_add_watcher_btn@2x.png */, 4E6CBE521D8EA9D100644086 /* icon_best_answer@2x.png */, 4E6CBE531D8EA9D100644086 /* icon_best_answer@3x.png */, + 4E80E9361E01218300DE1BC6 /* reward_tip_logo@2x.png */, + 4E80E9371E01218300DE1BC6 /* reward_tip_logo@3x.png */, + 4EAAD0591E544006008AA957 /* icon_triangle@2x.png */, + 4EAAD05A1E544006008AA957 /* icon_triangle@3x.png */, + B1C8714E1EADF48B003DACF0 /* cell_arrow_left@2x.png */, + B1C8714F1EADF48B003DACF0 /* cell_arrow_left@3x.png */, + B1C871B71EB338FD003DACF0 /* comment_bg@3x.png */, + B1C871B81EB338FD003DACF0 /* project_tag_btn@3x.png */, + B1C871B91EB338FD003DACF0 /* project_tag_icon@3x.png */, + B12B64161FF0E4CA00ACFDCC /* skill_delete@2x.png */, + B12B64171FF0E4CA00ACFDCC /* skill_delete@3x.png */, + B12B64211FF33DFF00ACFDCC /* button_red_close@2x.png */, + B12B64201FF33DFE00ACFDCC /* button_red_close@3x.png */, + B12B64251FF33E0000ACFDCC /* button_tip_close@2x.png */, + B12B64221FF33DFF00ACFDCC /* button_tip_close@3x.png */, + B1CB8DD02047F1D000872197 /* button_tip_notice@2x.png */, + B1CB8DD12047F1D100872197 /* button_tip_notice@3x.png */, + B12B64231FF33DFF00ACFDCC /* upgrade_success@2x.png */, + B12B64241FF33E0000ACFDCC /* upgrade_success@3x.png */, + B11DC7BE20245727004E76A9 /* button_terminal@2x.png */, + B11DC7BF20245728004E76A9 /* button_terminal@3x.png */, + B10341272024633800853447 /* logo_coding@2x.png */, + B10341282024633900853447 /* logo_coding@3x.png */, + B1817EFB206918D200E9BAD1 /* icon_branch_protected@2x.png */, + B1817EFA206918D100E9BAD1 /* icon_branch_protected@3x.png */, + B1817EFF2069197C00E9BAD1 /* icon_release_tag@2x.png */, + B1817EFE2069197C00E9BAD1 /* icon_release_tag@3x.png */, + B17CC31320731E910077C956 /* icon_release_tag_blue@2x.png */, + B17CC31220731E900077C956 /* icon_release_tag_blue@3x.png */, + B1BFC4B520B2ACEE009427FC /* editBoardList@2x.png */, + B1BFC4B420B2ACED009427FC /* editBoardList@3x.png */, + B16E6CA520C13BA10076026D /* btn_dismiss@2x.png */, + B16E6CA420C13BA10076026D /* btn_dismiss@3x.png */, + B16E6CEC20C147490076026D /* team_bg@2x.png */, + B16E6CEB20C147480076026D /* team_bg@3x.png */, + B15C98AE20D39CA100DDA425 /* project_icon_edit@2x.png */, + B15C98AF20D39CA200DDA425 /* project_icon_edit@3x.png */, ); path = Images; sourceTree = ""; @@ -5089,6 +7941,8 @@ children = ( 8EA6CFAB19E240C40076D59C /* timeline_icon_read@2x.png */, 8EA6CFAC19E240C40076D59C /* timeline_icon_unread@2x.png */, + B16EEF06208DDBB5005ABFD5 /* timeline_icon_read@3x.png */, + B16EEF07208DDBB6005ABFD5 /* timeline_icon_unread@3x.png */, 8EA6CFAD19E240C40076D59C /* timeline_line_read@2x.png */, 8EA6CFAE19E240C40076D59C /* timeline_line_unread@2x.png */, ); @@ -5133,6 +7987,8 @@ 13C8FE6F1CA77E26001E30FA /* MergeRequest */, 134E1BA41CA41671002A3E0D /* DemoModel.h */, 134E1BA51CA41671002A3E0D /* DemoModel.m */, + 09A0587E1E0AA97000C1CA3F /* ActivenessModel.h */, + 09A0587F1E0AA97000C1CA3F /* ActivenessModel.m */, 4E96E7B91A1B25D40037C098 /* DirectoryWatcher.h */, 4E96E7BA1A1B25D40037C098 /* DirectoryWatcher.m */, 8EA6CFCC19E240C40076D59C /* CodingTip.h */, @@ -5217,6 +8073,14 @@ 4E49693F1DCB0BCE0065028E /* FileShare.m */, 4E38CF601A7B7C99005536C0 /* CodeBranchOrTag.h */, 4E38CF611A7B7C99005536C0 /* CodeBranchOrTag.m */, + B1817EBD2063951000E9BAD1 /* EABasePageModel.h */, + B1817EBE2063951000E9BAD1 /* EABasePageModel.m */, + B1817EBA2063936100E9BAD1 /* EACodeBranches.h */, + B1817EBB2063936100E9BAD1 /* EACodeBranches.m */, + B1817EC2206397E000E9BAD1 /* EACodeRelease.h */, + B1817EC3206397E000E9BAD1 /* EACodeRelease.m */, + B1817EC5206397F500E9BAD1 /* EACodeReleases.h */, + B1817EC6206397F500E9BAD1 /* EACodeReleases.m */, 0A6E6BAB1AB08540004C0107 /* TweetSendLocation.h */, 0A6E6BAC1AB08540004C0107 /* TweetSendLocation.m */, 4ECF70441B18557E000280FF /* MRPRS.h */, @@ -5269,6 +8133,22 @@ 4E6CBE5B1D8FC7A500644086 /* ProjectServiceInfo.m */, 4ED4B4951D82939700EED8C6 /* Team.h */, 4ED4B4961D82939700EED8C6 /* Team.m */, + B1D5F21420BD485C00983FB6 /* TeamPurchaseBilling.h */, + B1D5F21320BD485B00983FB6 /* TeamPurchaseBilling.m */, + B1D5F21120BD485A00983FB6 /* TeamPurchaseBillingDetail.h */, + B1D5F21520BD485C00983FB6 /* TeamPurchaseBillingDetail.m */, + B1D5F21020BD485A00983FB6 /* TeamPurchaseOrder.h */, + B1D5F21220BD485B00983FB6 /* TeamPurchaseOrder.m */, + B19D4EEC1F6FCEAC00C598F3 /* CodingSkill.h */, + B19D4EED1F6FCEAC00C598F3 /* CodingSkill.m */, + B1890C332015D87800F52ABA /* EAWiki.h */, + B1890C342015D87800F52ABA /* EAWiki.m */, + B152ED582092BF46004A6E8A /* EABoardTaskList.h */, + B152ED592092BF46004A6E8A /* EABoardTaskList.m */, + B1ACFE0B20A975E2000BC41E /* EAMilestone.h */, + B1ACFE0C20A975E2000BC41E /* EAMilestone.m */, + B1D5F21C20BD50D000983FB6 /* ProjectRole.h */, + B1D5F21D20BD50D000983FB6 /* ProjectRole.m */, ); path = Models; sourceTree = ""; @@ -5276,10 +8156,11 @@ 8EA6CFFA19E240C40076D59C /* Resources */ = { isa = PBXGroup; children = ( - 4EE083DD1ADB739300CA342E /* modules */, + B177F5BF2060E6B1006709C2 /* modules */, 4EE083DB1ADB736800CA342E /* service_terms.html */, 4ECEF9F61D1BB7FB002A27D3 /* diff-ios.html */, 4EBD7FB01CE482A400B3AF49 /* country_code.plist */, + B1944153206CBE8C00147158 /* code_lang.plist */, 8E1C3DF519E7F4CA00EF3032 /* address.json */, ); path = Resources; @@ -5288,6 +8169,7 @@ 8EA6CFFC19E240C40076D59C /* Util */ = { isa = PBXGroup; children = ( + 4E3068261E0B781A00AEE0CE /* EADeviceToServerLog */, 4ECE8AEA1A3946C10021E29C /* Manager */, 8EA6CFFD19E240C40076D59C /* Common */, 8EA6D01019E240C40076D59C /* ObjcRuntime */, @@ -5344,9 +8226,13 @@ 8EA6D03E19E240C40076D59C /* Vendor */ = { isa = PBXGroup; children = ( + B14DE6DB20C914E60072ECEA /* AnimatedGIFImageSerialization */, + B12B64561FFB61AD00ACFDCC /* QBImagePickerController */, + B12B63FA1FE900D400ACFDCC /* AMPopTip */, + B12B63F41FE8A77200ACFDCC /* SinaSDK */, + B19D4EF81F7247BA00C598F3 /* AlipaySDK */, D031F5D81BFAD6690008E964 /* FRDLivelyButton */, 4E5D12FB1C0C5EE600985AEB /* RRFPSBar */, - 4EE956521B9C1C500009EDA9 /* UMSocial_Sdk_4.3.0_Extra */, 4E93F2301B84243D00017916 /* KxMenu */, 4E0022971B735075005308DE /* EAIntroView */, 4E0022931B73506A005308DE /* EARestrictedScrollView */, @@ -5370,7 +8256,6 @@ 8E59F0DC1A0098BA009A905F /* SVPullToRefresh */, 8ED0D87119FBA6EA00FBA818 /* NSStringEmojize */, 8E64ED8619EE484A006E99DA /* NSDate+Helper */, - 8E64ED6519ED0CE3006E99DA /* QBImagePickerController */, 8E1C3DD819E7D58A00EF3032 /* ActionSheetPicker */, 8ED4611D19E4DC470059B3BE /* iCarousel */, 8EA6D06819E240C40076D59C /* MJPhotoBrowser */, @@ -5441,6 +8326,8 @@ 3A38784B1AE36EF00078D5DE /* TopicListView.m */, 3A3878471AE36ED70078D5DE /* TopicListButton.h */, 3A3878481AE36ED70078D5DE /* TopicListButton.m */, + 09A0589F1E0AAACA00C1CA3F /* TagsScrollView.h */, + 09A058A01E0AAACA00C1CA3F /* TagsScrollView.m */, 4E6FB0561B58DB0A00B0A17B /* ProjectTagsView.h */, 4E6FB0571B58DB0A00B0A17B /* ProjectTagsView.m */, 4E2906A01A403B7D008A5B97 /* FileDownloadView.h */, @@ -5473,8 +8360,26 @@ 923399711C00A9EF00F29E04 /* DashesLineView.m */, D0A32BF11BF19EF100336C52 /* PopFliterMenu.h */, D0A32BF21BF19EF100336C52 /* PopFliterMenu.m */, + 4EAAD0151E53EFF2008AA957 /* EAFliterMenu.h */, + 4EAAD0161E53EFF2008AA957 /* EAFliterMenu.m */, 4EC4800A1C2936DA005F1772 /* PhoneCodeButton.h */, 4EC4800B1C2936DA005F1772 /* PhoneCodeButton.m */, + 09A058811E0AA9AE00C1CA3F /* ActivityMonScrollView.h */, + 09A058821E0AA9AE00C1CA3F /* ActivityMonScrollView.m */, + 09A058831E0AA9AE00C1CA3F /* ActivityView.h */, + 09A058841E0AA9AE00C1CA3F /* ActivityView.m */, + 09A058871E0AA9AE00C1CA3F /* UserActiveStatusView.h */, + 09A058881E0AA9AE00C1CA3F /* UserActiveStatusView.m */, + 09A058931E0AAA2F00C1CA3F /* TaskSelectionView.h */, + 09A058941E0AAA2F00C1CA3F /* TaskSelectionView.m */, + 09A058961E0AAA5300C1CA3F /* ScreenView.h */, + 09A058971E0AAA5300C1CA3F /* ScreenView.m */, + B1BCB8921FCE662A0098B87B /* NSLayoutConstraintLine.h */, + B1BCB8911FCE662A0098B87B /* NSLayoutConstraintLine.m */, + B12B63F71FE8FF0300ACFDCC /* MartFunctionTipView.h */, + B12B63F81FE8FF0300ACFDCC /* MartFunctionTipView.m */, + B1890C3F2015D8F700F52ABA /* WikiHeaderView.h */, + B1890C402015D8F700F52ABA /* WikiHeaderView.m */, ); path = Views; sourceTree = ""; @@ -5523,6 +8428,8 @@ 927AFF3D1BFF608700AAE593 /* ShopGoodsCCell.m */, 927AFF421BFF61FF00AAE593 /* BaseCollectionCell.h */, 927AFF431BFF61FF00AAE593 /* BaseCollectionCell.m */, + B12B64131FF0DE4800ACFDCC /* SkillCCell.h */, + B12B64141FF0DE4800ACFDCC /* SkillCCell.m */, ); path = CCell; sourceTree = ""; @@ -5623,6 +8530,8 @@ 8EF643A819FF7E2900F7EEB0 /* ValueListCell.m */, 8E59F0F21A00F3B9009A905F /* ProjectCodeListCell.h */, 8E59F0F31A00F3B9009A905F /* ProjectCodeListCell.m */, + 4EAAD05D1E545516008AA957 /* ProjectCodeListSearchCell.h */, + 4EAAD05E1E545516008AA957 /* ProjectCodeListSearchCell.m */, 8E59F0F51A00F3E2009A905F /* ProjectFolderListCell.h */, 8E59F0F61A00F3E2009A905F /* ProjectFolderListCell.m */, 4EA6791B1A15A943001A0324 /* FileListFolderCell.h */, @@ -5736,6 +8645,48 @@ 4ED4B4A51D82990600EED8C6 /* TeamTopCell.m */, 4ED4B4AA1D829E1200EED8C6 /* TeamMemberCell.h */, 4ED4B4AB1D829E1200EED8C6 /* TeamMemberCell.m */, + 09A058901E0AA9FB00C1CA3F /* EaseUserInfoCell.h */, + 09A058911E0AA9FB00C1CA3F /* EaseUserInfoCell.m */, + 09A0588D1E0AA9D600C1CA3F /* UserActiveGraphCell.h */, + 09A0588E1E0AA9D600C1CA3F /* UserActiveGraphCell.m */, + 09A058991E0AAA7200C1CA3F /* ScreenCell.h */, + 09A0589A1E0AAA7200C1CA3F /* ScreenCell.m */, + 09A0589C1E0AAA8800C1CA3F /* TaskSelectionCell.h */, + 09A0589D1E0AAA8800C1CA3F /* TaskSelectionCell.m */, + B19D4EEF1F710EF900C598F3 /* ShopSwitchCell.h */, + B19D4EF01F710EF900C598F3 /* ShopSwitchCell.m */, + B19D4EF11F710EF900C598F3 /* ShopSwitchCell.xib */, + B1890C3C2015D8C800F52ABA /* WikiHistoryCell.h */, + B1890C3B2015D8C800F52ABA /* WikiHistoryCell.m */, + B1890C392015D8C800F52ABA /* WikiMenuListCell.h */, + B1890C3A2015D8C800F52ABA /* WikiMenuListCell.m */, + B1817ECB20639F0A00E9BAD1 /* EACodeBranchListCell.h */, + B1817ECC20639F0A00E9BAD1 /* EACodeBranchListCell.m */, + B1817EEE2068C7A100E9BAD1 /* EACodeBranchListCell.xib */, + B1817EC820639E9500E9BAD1 /* EACodeReleaseListCell.h */, + B1817EC920639E9500E9BAD1 /* EACodeReleaseListCell.m */, + B1817EF02068F4B400E9BAD1 /* EACodeReleaseListCell.xib */, + B1817EE52064FC6100E9BAD1 /* EACodeReleaseTopCell.h */, + B1817EE62064FC6100E9BAD1 /* EACodeReleaseTopCell.m */, + B1817F0220691B2700E9BAD1 /* EACodeReleaseTopCell.xib */, + B1817EE82064FC7300E9BAD1 /* EACodeReleaseBodyCell.h */, + B1817EE92064FC7300E9BAD1 /* EACodeReleaseBodyCell.m */, + B1817EEB2064FD9400E9BAD1 /* EACodeReleaseAttachmentsOrReferencesCell.h */, + B1817EEC2064FD9400E9BAD1 /* EACodeReleaseAttachmentsOrReferencesCell.m */, + B1944148206BB8BB00147158 /* EALocalCodeListCell.h */, + B1944149206BB8BB00147158 /* EALocalCodeListCell.m */, + B152ED5B2092D51E004A6E8A /* EATaskBoardListTaskCell.h */, + B152ED5C2092D51E004A6E8A /* EATaskBoardListTaskCell.m */, + B1D5F22020BEA37500983FB6 /* MeRootCompanyCell.h */, + B1D5F22120BEA37500983FB6 /* MeRootCompanyCell.m */, + B1C60C9220C004C70073D3CA /* TeamPurchaseBillingCell.h */, + B1C60C9420C004C70073D3CA /* TeamPurchaseBillingCell.m */, + B1C60C9520C004C80073D3CA /* TeamPurchaseOrderCell.h */, + B1C60C9620C004C80073D3CA /* TeamPurchaseOrderCell.m */, + B1C60C9720C004C80073D3CA /* TeamPurchaseTopCell.h */, + B1C60C9320C004C70073D3CA /* TeamPurchaseTopCell.m */, + B1D5F23120BEADD200983FB6 /* TeamSupportCell.h */, + B1D5F23020BEADD100983FB6 /* TeamSupportCell.m */, ); path = Cell; sourceTree = ""; @@ -5764,12 +8715,457 @@ 927AFF491BFF6DAD00AAE593 /* shop_exchange_icon@3x.png */, 927AFF4A1BFF6DAD00AAE593 /* shop_nar_history_icon@2x.png */, 927AFF4B1BFF6DAD00AAE593 /* shop_nar_history_icon@3x.png */, - 927AFF4C1BFF6DAD00AAE593 /* shop_unexchange_icon@2x.png */, - 927AFF4D1BFF6DAD00AAE593 /* shop_unexchange_icon@3x.png */, ); path = shop; sourceTree = ""; }; + B1280CF2200EFEA400DEDF78 /* PR_Activity */ = { + isa = PBXGroup; + children = ( + B1280CF3200EFEA400DEDF78 /* PR_add_label@3x.png */, + B1280CF4200EFEA400DEDF78 /* PR_add_watcher@2x.png */, + B1280CF5200EFEA400DEDF78 /* PR_del_label@3x.png */, + B1280CF6200EFEA400DEDF78 /* PR_del_watcher@2x.png */, + B1280CF7200EFEA400DEDF78 /* PR_add_reviewer@3x.png */, + B1280CF8200EFEA400DEDF78 /* PR_add_reviewer@2x.png */, + B1280CF9200EFEA400DEDF78 /* PR_del_watcher@3x.png */, + B1280CFA200EFEA400DEDF78 /* PR_del_label@2x.png */, + B1280CFB200EFEA400DEDF78 /* PR_add_watcher@3x.png */, + B1280CFC200EFEA400DEDF78 /* PR_add_label@2x.png */, + B1280CFD200EFEA400DEDF78 /* PR_del_reviewer@2x.png */, + B1280CFE200EFEA400DEDF78 /* PR_del_reviewer@3x.png */, + ); + path = PR_Activity; + sourceTree = ""; + }; + B12B63F41FE8A77200ACFDCC /* SinaSDK */ = { + isa = PBXGroup; + children = ( + B12B63F51FE8A77200ACFDCC /* WeiboSDK.bundle */, + ); + path = SinaSDK; + sourceTree = ""; + }; + B12B63FA1FE900D400ACFDCC /* AMPopTip */ = { + isa = PBXGroup; + children = ( + B12B63FB1FE900D400ACFDCC /* AMPopTip+Animation.m */, + B12B63FC1FE900D400ACFDCC /* AMPopTip+Entrance.h */, + B12B63FD1FE900D400ACFDCC /* AMPopTip.m */, + B12B63FE1FE900D400ACFDCC /* AMPopTipDefaults.h */, + B12B63FF1FE900D400ACFDCC /* AMPopTip+Draw.h */, + B12B64001FE900D400ACFDCC /* AMPopTip+Exit.h */, + B12B64011FE900D400ACFDCC /* AMPopTip+Animation.h */, + B12B64021FE900D400ACFDCC /* AMPopTip+Entrance.m */, + B12B64031FE900D400ACFDCC /* AMPopTip+Draw.m */, + B12B64041FE900D400ACFDCC /* AMPopTip.h */, + B12B64051FE900D400ACFDCC /* AMPopTip+Exit.m */, + ); + path = AMPopTip; + sourceTree = ""; + }; + B12B640B1FECB58F00ACFDCC /* login */ = { + isa = PBXGroup; + children = ( + B12B640C1FECB58F00ACFDCC /* login_wechat@3x.png */, + B12B640D1FECB58F00ACFDCC /* login_wechat@2x.png */, + ); + path = login; + sourceTree = ""; + }; + B12B64561FFB61AD00ACFDCC /* QBImagePickerController */ = { + isa = PBXGroup; + children = ( + B12B64591FFB61AD00ACFDCC /* QBImagePicker */, + B12B64571FFB61AD00ACFDCC /* LICENSE */, + B12B64581FFB61AD00ACFDCC /* README.md */, + ); + path = QBImagePickerController; + sourceTree = ""; + }; + B12B64591FFB61AD00ACFDCC /* QBImagePicker */ = { + isa = PBXGroup; + children = ( + B12B645A1FFB61AD00ACFDCC /* QBImagePicker.strings */, + B12B645C1FFB61AD00ACFDCC /* QBImagePickerController.h */, + B12B645F1FFB61AD00ACFDCC /* QBAssetsViewController.h */, + B12B64601FFB61AD00ACFDCC /* QBAlbumsViewController.h */, + B12B64611FFB61AD00ACFDCC /* QBVideoIconView.m */, + B12B64621FFB61AD00ACFDCC /* QBVideoIndicatorView.m */, + B12B64651FFB61AD00ACFDCC /* QBCheckmarkView.h */, + B12B64661FFB61AD00ACFDCC /* QBAssetCell.h */, + B12B64671FFB61AD00ACFDCC /* QBSlomoIconView.h */, + B12B64681FFB61AD00ACFDCC /* QBAlbumCell.m */, + B12B64691FFB61AD00ACFDCC /* QBImagePicker.storyboard */, + B12B646A1FFB61AD00ACFDCC /* QBVideoIndicatorView.h */, + B12B646B1FFB61AD00ACFDCC /* QBAlbumsViewController.m */, + B12B646C1FFB61AD00ACFDCC /* QBVideoIconView.h */, + B12B646D1FFB61AD00ACFDCC /* QBAssetsViewController.m */, + B12B646E1FFB61AD00ACFDCC /* QBImagePickerController.m */, + B12B646F1FFB61AD00ACFDCC /* QBCheckmarkView.m */, + B12B64701FFB61AD00ACFDCC /* QBAlbumCell.h */, + B12B64711FFB61AD00ACFDCC /* QBSlomoIconView.m */, + B12B64721FFB61AD00ACFDCC /* QBAssetCell.m */, + ); + path = QBImagePicker; + sourceTree = ""; + }; + B14689A31EE100B200B01371 /* vip */ = { + isa = PBXGroup; + children = ( + B14689A41EE100B200B01371 /* vip_3_30@2x.png */, + B14689A51EE100B200B01371 /* vip_3_30@3x.png */, + B14689A61EE100B200B01371 /* vip_3_40@2x.png */, + B14689A71EE100B200B01371 /* vip_3_40@3x.png */, + B14689A81EE100B200B01371 /* vip_3_45@2x.png */, + B14689A91EE100B200B01371 /* vip_3_45@3x.png */, + B14689AA1EE100B200B01371 /* vip_3_75@2x.png */, + B14689AB1EE100B200B01371 /* vip_3_75@3x.png */, + B14689AC1EE100B200B01371 /* vip_4_30@2x.png */, + B14689AD1EE100B200B01371 /* vip_4_30@3x.png */, + B14689AE1EE100B200B01371 /* vip_4_40@2x.png */, + B14689AF1EE100B200B01371 /* vip_4_40@3x.png */, + B14689B01EE100B200B01371 /* vip_4_45@2x.png */, + B14689B11EE100B200B01371 /* vip_4_45@3x.png */, + B14689B21EE100B200B01371 /* vip_4_75@2x.png */, + B14689B31EE100B200B01371 /* vip_4_75@3x.png */, + ); + path = vip; + sourceTree = ""; + }; + B14DE6DB20C914E60072ECEA /* AnimatedGIFImageSerialization */ = { + isa = PBXGroup; + children = ( + B14DE6DC20C914E60072ECEA /* AnimatedGIFImageSerialization.h */, + B14DE6DD20C914E60072ECEA /* AnimatedGIFImageSerialization.m */, + ); + path = AnimatedGIFImageSerialization; + sourceTree = ""; + }; + B152ED86209453F2004A6E8A /* taskboard_page */ = { + isa = PBXGroup; + children = ( + B152ED87209453F2004A6E8A /* taskboard_normal_page_selected@3x.png */, + B152ED88209453F2004A6E8A /* taskboard_normal_page_selected@2x.png */, + B152ED89209453F2004A6E8A /* taskboard_add_page_unselected@2x.png */, + B152ED8A209453F2004A6E8A /* taskboard_add_page_selected@2x.png */, + B152ED8B209453F2004A6E8A /* taskboard_add_page_selected@3x.png */, + B152ED8C209453F2004A6E8A /* taskboard_add_page_unselected@3x.png */, + B152ED8D209453F2004A6E8A /* taskboard_normal_page_unselected@3x.png */, + B152ED8E209453F2004A6E8A /* taskboard_normal_page_unselected@2x.png */, + ); + path = taskboard_page; + sourceTree = ""; + }; + B16E6CAA20C13BF40076026D /* btn_next */ = { + isa = PBXGroup; + children = ( + B16E6CAB20C13BF40076026D /* btn_next_unable@2x.png */, + B16E6CAC20C13BF40076026D /* btn_next_unable@3x.png */, + B16E6CAD20C13BF40076026D /* btn_next_enable@2x.png */, + B16E6CAE20C13BF40076026D /* btn_next_enable@3x.png */, + ); + path = btn_next; + sourceTree = ""; + }; + B16E6CD220C145BE0076026D /* quick_menu_icon */ = { + isa = PBXGroup; + children = ( + B16E6CD320C145BE0076026D /* quick_menu_icon_message@2x.png */, + B16E6CD420C145BE0076026D /* quick_menu_icon_message@3x.png */, + B16E6CD520C145BE0076026D /* quick_menu_icon_task@3x.png */, + B16E6CD620C145BE0076026D /* quick_menu_icon_task@2x.png */, + B16E6CD720C145BE0076026D /* quick_menu_icon_project@3x.png */, + B16E6CD820C145BE0076026D /* quick_menu_icon_2fa@3x.png */, + B16E6CD920C145BE0076026D /* quick_menu_icon_2fa@2x.png */, + B16E6CDA20C145BE0076026D /* quick_menu_icon_project@2x.png */, + ); + path = quick_menu_icon; + sourceTree = ""; + }; + B16E6CF120C147760076026D /* team_info */ = { + isa = PBXGroup; + children = ( + B16E6CF220C147760076026D /* team_info_pro@3x.png */, + B16E6CF320C147760076026D /* team_info_pro@2x.png */, + B16E6CF420C147760076026D /* team_info_order@2x.png */, + B16E6CF520C147760076026D /* team_info_order@3x.png */, + B16E6CF620C147760076026D /* team_info_sup@2x.png */, + B16E6CF720C147760076026D /* team_info_mem@3x.png */, + B16E6CF820C147760076026D /* team_info_mem@2x.png */, + B16E6CF920C147760076026D /* team_info_sup@3x.png */, + ); + path = team_info; + sourceTree = ""; + }; + B16E6CFA20C147760076026D /* team_cell_edit */ = { + isa = PBXGroup; + children = ( + B16E6CFB20C147760076026D /* team_cell_edit_team@3x.png */, + B16E6CFC20C147760076026D /* team_cell_edit_team@2x.png */, + B16E6CFD20C147760076026D /* team_cell_edit_delete@3x.png */, + B16E6CFE20C147760076026D /* team_cell_edit_delete@2x.png */, + B16E6CFF20C147760076026D /* team_cell_edit_pro@3x.png */, + B16E6D0020C147760076026D /* team_cell_edit_pro@2x.png */, + ); + path = team_cell_edit; + sourceTree = ""; + }; + B16E6D1D20C148E50076026D /* images_diff */ = { + isa = PBXGroup; + children = ( + B16E6D1E20C148E50076026D /* personal */, + B16E6D4C20C148E50076026D /* enterprise */, + ); + path = images_diff; + sourceTree = ""; + }; + B16E6D1E20C148E50076026D /* personal */ = { + isa = PBXGroup; + children = ( + B16E6D1F20C148E50076026D /* introduction */, + B16E6D3E20C148E50076026D /* intro_pages */, + B16E6D4820C148E50076026D /* icon_user_monkey */, + ); + path = personal; + sourceTree = ""; + }; + B16E6D1F20C148E50076026D /* introduction */ = { + isa = PBXGroup; + children = ( + B16E6D2020C148E50076026D /* intro_icon_4@3x.png */, + B16E6D2120C148E50076026D /* intro_tip_2@3x.png */, + B16E6D2220C148E50076026D /* intro_icon_6@2x.png */, + B16E6D2320C148E50076026D /* intro_tip_0@2x.png */, + B16E6D2420C148E50076026D /* intro_tip_0@3x.png */, + B16E6D2520C148E50076026D /* intro_icon_6@3x.png */, + B16E6D2620C148E50076026D /* intro_tip_2@2x.png */, + B16E6D2720C148E50076026D /* intro_icon_4@2x.png */, + B16E6D2820C148E50076026D /* intro_icon_0@2x.png */, + B16E6D2920C148E50076026D /* intro_icon_2@3x.png */, + B16E6D2A20C148E50076026D /* intro_tip_4@3x.png */, + B16E6D2B20C148E50076026D /* intro_tip_4@2x.png */, + B16E6D2C20C148E50076026D /* intro_icon_2@2x.png */, + B16E6D2D20C148E50076026D /* intro_icon_0@3x.png */, + B16E6D2E20C148E50076026D /* intro_tip_1@2x.png */, + B16E6D2F20C148E50076026D /* intro_icon_5@3x.png */, + B16E6D3020C148E50076026D /* intro_dot_unselected@2x.png */, + B16E6D3120C148E50076026D /* intro_tip_3@3x.png */, + B16E6D3220C148E50076026D /* intro_tip_3@2x.png */, + B16E6D3320C148E50076026D /* intro_icon_5@2x.png */, + B16E6D3420C148E50076026D /* intro_dot_unselected@3x.png */, + B16E6D3520C148E50076026D /* intro_tip_1@3x.png */, + B16E6D3620C148E50076026D /* intro_icon_3@3x.png */, + B16E6D3720C148E50076026D /* intro_tip_5@3x.png */, + B16E6D3820C148E50076026D /* intro_icon_1@2x.png */, + B16E6D3920C148E50076026D /* intro_dot_selected@2x.png */, + B16E6D3A20C148E50076026D /* intro_dot_selected@3x.png */, + B16E6D3B20C148E50076026D /* intro_icon_1@3x.png */, + B16E6D3C20C148E50076026D /* intro_tip_5@2x.png */, + B16E6D3D20C148E50076026D /* intro_icon_3@2x.png */, + ); + path = introduction; + sourceTree = ""; + }; + B16E6D3E20C148E50076026D /* intro_pages */ = { + isa = PBXGroup; + children = ( + B16E6D3F20C148E50076026D /* intro_page0_ip5@2x.png */, + B16E6D4020C148E50076026D /* intro_page_selected@2x.png */, + B16E6D4120C148E50076026D /* intro_page_unselected@2x.png */, + B16E6D4220C148E50076026D /* intro_page0_ip4@2x.png */, + B16E6D4320C148E50076026D /* intro_page_unselected@3x.png */, + B16E6D4420C148E50076026D /* intro_page_selected@3x.png */, + B16E6D4520C148E50076026D /* intro_page0_ip6@2x.png */, + B16E6D4620C148E50076026D /* intro_page0_ip6+@3x.png */, + B16E6D4720C148E50076026D /* intro_page0_ipX@3x.png */, + ); + path = intro_pages; + sourceTree = ""; + }; + B16E6D4820C148E50076026D /* icon_user_monkey */ = { + isa = PBXGroup; + children = ( + B16E6D4920C148E50076026D /* icon_user_monkey_i6p@3x.png */, + B16E6D4A20C148E50076026D /* icon_user_monkey_i6@2x.png */, + B16E6D4B20C148E50076026D /* icon_user_monkey@2x.png */, + ); + path = icon_user_monkey; + sourceTree = ""; + }; + B16E6D4C20C148E50076026D /* enterprise */ = { + isa = PBXGroup; + children = ( + B16E6D4D20C148E50076026D /* introduction */, + B16E6D6020C148E50076026D /* intro_pages */, + B16E6D7120C148E50076026D /* icon_user_monkey */, + ); + path = enterprise; + sourceTree = ""; + }; + B16E6D4D20C148E50076026D /* introduction */ = { + isa = PBXGroup; + children = ( + B16E6D5420C148E50076026D /* dot_dark */, + B16E6D4E20C148E50076026D /* dot_light */, + B16E6D5320C148E50076026D /* intro_icon_wiki_down.gif */, + B16E6D5920C148E50076026D /* intro_icon_wiki_up.gif */, + B16E6D5A20C148E50076026D /* intro_icon_file_up.gif */, + B16E6D5B20C148E50076026D /* intro_icon_code_up.gif */, + B16E6D5C20C148E50076026D /* intro_icon_task_up.gif */, + B16E6D5D20C148E50076026D /* intro_icon_file_down.gif */, + B16E6D5E20C148E50076026D /* intro_icon_task_down.gif */, + B16E6D5F20C148E50076026D /* intro_icon_code_down.gif */, + ); + path = introduction; + sourceTree = ""; + }; + B16E6D4E20C148E50076026D /* dot_light */ = { + isa = PBXGroup; + children = ( + B16E6D4F20C148E50076026D /* intro_dot_light_unselected@2x.png */, + B16E6D5020C148E50076026D /* intro_dot_light_unselected@3x.png */, + B16E6D5120C148E50076026D /* intro_dot_light_selected@3x.png */, + B16E6D5220C148E50076026D /* intro_dot_light_selected@2x.png */, + ); + path = dot_light; + sourceTree = ""; + }; + B16E6D5420C148E50076026D /* dot_dark */ = { + isa = PBXGroup; + children = ( + B16E6D5520C148E50076026D /* intro_dot_dark_unselected@3x.png */, + B16E6D5620C148E50076026D /* intro_dot_dark_selected@3x.png */, + B16E6D5720C148E50076026D /* intro_dot_dark_selected@2x.png */, + B16E6D5820C148E50076026D /* intro_dot_dark_unselected@2x.png */, + ); + path = dot_dark; + sourceTree = ""; + }; + B16E6D6020C148E50076026D /* intro_pages */ = { + isa = PBXGroup; + children = ( + B16E6D6120C148E50076026D /* intro_page0_ip5@2x.png */, + B16E6D6220C148E50076026D /* intro_page2_ip6+@3x.png */, + B16E6D6320C148E50076026D /* intro_page1_ip6@2x.png */, + B16E6D6420C148E50076026D /* intro_page1_ip4@2x.png */, + B16E6D6520C148E50076026D /* intro_page2_ip5@2x.png */, + B16E6D6620C148E50076026D /* intro_page1_ip6+@3x.png */, + B16E6D6720C148E50076026D /* intro_page_selected@2x.png */, + B16E6D6820C148E50076026D /* intro_page_unselected@2x.png */, + B16E6D6920C148E50076026D /* intro_page0_ip4@2x.png */, + B16E6D6A20C148E50076026D /* intro_page1_ip5@2x.png */, + B16E6D6B20C148E50076026D /* intro_page_unselected@3x.png */, + B16E6D6C20C148E50076026D /* intro_page_selected@3x.png */, + B16E6D6D20C148E50076026D /* intro_page0_ip6@2x.png */, + B16E6D6E20C148E50076026D /* intro_page2_ip4@2x.png */, + B16E6D6F20C148E50076026D /* intro_page0_ip6+@3x.png */, + B16E6D7020C148E50076026D /* intro_page2_ip6@2x.png */, + ); + path = intro_pages; + sourceTree = ""; + }; + B16E6D7120C148E50076026D /* icon_user_monkey */ = { + isa = PBXGroup; + children = ( + B16E6D7220C148E50076026D /* icon_user_monkey@2x.png */, + B16E6D7320C148E50076026D /* icon_user_monkey@3x.png */, + ); + path = icon_user_monkey; + sourceTree = ""; + }; + B177F5BF2060E6B1006709C2 /* modules */ = { + isa = PBXGroup; + children = ( + B177F5C02060E6B1006709C2 /* wiki.html */, + B177F5C12060E6B1006709C2 /* bubble.html */, + B177F5C22060E6B1006709C2 /* markdown.html */, + B177F5C32060E6B1006709C2 /* topic-ios.html */, + B177F5C42060E6B1006709C2 /* code.html */, + ); + path = modules; + sourceTree = ""; + }; + B17CC31620731FF10077C956 /* code_release_resource_icon */ = { + isa = PBXGroup; + children = ( + B17CC31720731FF10077C956 /* code_release_resource_Zip@2x.png */, + B17CC31820731FF10077C956 /* code_release_resource_Zip@3x.png */, + B17CC31920731FF10077C956 /* code_release_resource_Default@3x.png */, + B17CC31A20731FF10077C956 /* code_release_resource__Default@2x.png */, + B17CC31B20731FF10077C956 /* code_release_resource_Task@2x.png */, + B17CC31C20731FF10077C956 /* code_release_resource_Task@3x.png */, + B17CC3272073212E0077C956 /* code_release_resource_MergeRequestBean@2x.png */, + B17CC3242073212D0077C956 /* code_release_resource_MergeRequestBean@3x.png */, + B17CC3252073212D0077C956 /* code_release_resource_ProjectFile@2x.png */, + B17CC3232073212D0077C956 /* code_release_resource_ProjectFile@3x.png */, + B17CC3282073212E0077C956 /* code_release_resource_ProjectTopic@2x.png */, + B17CC3262073212D0077C956 /* code_release_resource_ProjectTopic@3x.png */, + ); + path = code_release_resource_icon; + sourceTree = ""; + }; + B1890C1D2015D82600F52ABA /* wiki */ = { + isa = PBXGroup; + children = ( + B1890C1E2015D82600F52ABA /* wiki_menu_0@2x.png */, + B1890C1F2015D82600F52ABA /* wiki_menu_2@3x.png */, + B1890C202015D82600F52ABA /* wiki_menu_2@2x.png */, + B1890C212015D82600F52ABA /* wiki_menu_0@3x.png */, + B1890C222015D82600F52ABA /* wiki_revert@3x.png */, + B1890C232015D82600F52ABA /* wiki_revert@2x.png */, + B1890C242015D82600F52ABA /* wiki_menu_1@2x.png */, + B1890C252015D82600F52ABA /* wiki_menu_1@3x.png */, + ); + path = wiki; + sourceTree = ""; + }; + B1890C262015D82600F52ABA /* wiki_menu_icon */ = { + isa = PBXGroup; + children = ( + B1890C272015D82600F52ABA /* wiki_menu_icon_share@2x.png */, + B1890C282015D82600F52ABA /* wiki_menu_icon_delete@2x.png */, + ); + path = wiki_menu_icon; + sourceTree = ""; + }; + B19D4EF81F7247BA00C598F3 /* AlipaySDK */ = { + isa = PBXGroup; + children = ( + B19D4EF91F7247BA00C598F3 /* AlipaySDK.bundle */, + B19D4EFA1F7247BA00C598F3 /* AlipaySDK.framework */, + ); + path = AlipaySDK; + sourceTree = ""; + }; + B1AB5C8F202953E40075A669 /* terminal_icon */ = { + isa = PBXGroup; + children = ( + B1AB5C90202953E40075A669 /* terminal_tail@2x.png */, + B1AB5C91202953E40075A669 /* terminal_box_unselected@2x.png */, + B1AB5C92202953E40075A669 /* terminal_box_unselected@3x.png */, + B1AB5C93202953E40075A669 /* terminal_tail@3x.png */, + B1AB5C94202953E40075A669 /* terminal_more@3x.png */, + B1AB5C95202953E40075A669 /* terminal_more@2x.png */, + B1AB5C96202953E40075A669 /* terminal_triangle@3x.png */, + B1AB5C97202953E40075A669 /* terminal_box_selected@3x.png */, + B1AB5C98202953E40075A669 /* terminal_triangle@2x.png */, + B1AB5C99202953E40075A669 /* terminal_box_selected@2x.png */, + ); + path = terminal_icon; + sourceTree = ""; + }; + B1BCB8941FCE93830098B87B /* pay */ = { + isa = PBXGroup; + children = ( + B1BCB8951FCE93830098B87B /* alipay@2x.png */, + B1BCB8961FCE93830098B87B /* alipay@3x.png */, + B1BCB8971FCE93830098B87B /* wechat@2x.png */, + B1BCB8981FCE93830098B87B /* wechat@3x.png */, + ); + path = pay; + sourceTree = ""; + }; B94C1B661AC945C60000C271 /* NewProject */ = { isa = PBXGroup; children = ( @@ -5786,6 +9182,10 @@ isa = PBXGroup; children = ( B9A00D7E1ACA3A05008BA008 /* ProjectSetting.storyboard */, + B152ED522091B7CB004A6E8A /* ProjectArchiveViewController.h */, + B152ED532091B7CB004A6E8A /* ProjectArchiveViewController.m */, + B152ED4C2090B223004A6E8A /* ProjectSettingEntranceController.h */, + B152ED4D2090B223004A6E8A /* ProjectSettingEntranceController.m */, B9A00D801ACA3A17008BA008 /* ProjectSettingViewController.h */, B9A00D811ACA3A17008BA008 /* ProjectSettingViewController.m */, B9A00D831ACA3A55008BA008 /* ProjectAdvancedSettingViewController.h */, @@ -5798,6 +9198,19 @@ path = ProjectSetting; sourceTree = ""; }; + C2A35A9B71AB7D9C11F8394B /* Pods */ = { + isa = PBXGroup; + children = ( + 34E37865A7DAAE68AEF68258 /* Pods-Coding_iOS.debug.xcconfig */, + 2FD5D8DD0689696D28A6D49E /* Pods-Coding_iOS.release.xcconfig */, + 344214A4A1281EB0C9B3DE71 /* Pods-Coding_iOS-CodingEnterprise_iOS.debug.xcconfig */, + BA1AE837BA26B375F43A9343 /* Pods-Coding_iOS-CodingEnterprise_iOS.release.xcconfig */, + 59EA81AF0F8C7610F675E1EB /* Pods-Coding_iOS-Coding_Enterprise_iOS.debug.xcconfig */, + 22A08D8B77355DB8A773B8E2 /* Pods-Coding_iOS-Coding_Enterprise_iOS.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; D031F5D81BFAD6690008E964 /* FRDLivelyButton */ = { isa = PBXGroup; children = ( @@ -5814,12 +9227,13 @@ isa = PBXNativeTarget; buildConfigurationList = 8E477042198770E700997D05 /* Build configuration list for PBXNativeTarget "Coding_iOS" */; buildPhases = ( - 23542360C260462A83BCBCAD /* Check Pods Manifest.lock */, + B7F20F3BC924F718A926E931 /* [CP] Check Pods Manifest.lock */, 8E47700C198770E700997D05 /* Sources */, 8E47700D198770E700997D05 /* Frameworks */, 8E47700E198770E700997D05 /* Resources */, - 96A9263FF11A4AA8B5F6BB6B /* Copy Pods Resources */, - 2BE7A354A6FF9E5410B304BF /* Embed Pods Frameworks */, + B7C390DEFD2073480C56FD88 /* [CP] Copy Pods Resources */, + 4E3068251E0B77DF00AEE0CE /* Embed Frameworks */, + 4E9EC23F1E0B78F00098C761 /* ShellScript */, ); buildRules = ( ); @@ -5830,17 +9244,39 @@ productReference = 8E477010198770E700997D05 /* Coding_iOS.app */; productType = "com.apple.product-type.application"; }; + B1D5EBF120BC06CB00983FB6 /* Coding_Enterprise_iOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = B1D5F1FF20BC06CB00983FB6 /* Build configuration list for PBXNativeTarget "Coding_Enterprise_iOS" */; + buildPhases = ( + B1D5EBF220BC06CB00983FB6 /* [CP] Check Pods Manifest.lock */, + B1D5EBF320BC06CB00983FB6 /* Sources */, + B1D5EE5A20BC06CB00983FB6 /* Frameworks */, + B1D5EE7520BC06CB00983FB6 /* Resources */, + B1D5F1FC20BC06CB00983FB6 /* [CP] Copy Pods Resources */, + B1D5F1FD20BC06CB00983FB6 /* Embed Frameworks */, + B1D5F1FE20BC06CB00983FB6 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Coding_Enterprise_iOS; + productName = CodiOS; + productReference = B1D5F20220BC06CB00983FB6 /* Coding_Enterprise_iOS.app */; + productType = "com.apple.product-type.application"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 8E477008198770E700997D05 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0700; + LastUpgradeCheck = 0940; ORGANIZATIONNAME = Coding; TargetAttributes = { 8E47700F198770E700997D05 = { DevelopmentTeam = QN5Z87S3LH; + ProvisioningStyle = Automatic; SystemCapabilities = { com.apple.BackgroundModes = { enabled = 0; @@ -5848,6 +9284,17 @@ com.apple.Push = { enabled = 1; }; + com.apple.SafariKeychain = { + enabled = 1; + }; + }; + }; + B1D5EBF120BC06CB00983FB6 = { + DevelopmentTeam = QN5Z87S3LH; + SystemCapabilities = { + com.apple.SafariKeychain = { + enabled = 0; + }; }; }; }; @@ -5859,6 +9306,9 @@ knownRegions = ( en, "zh-Hans", + de, + ja, + es, ); mainGroup = 8E477007198770E700997D05; productRefGroup = 8E477011198770E700997D05 /* Products */; @@ -5866,6 +9316,7 @@ projectRoot = ""; targets = ( 8E47700F198770E700997D05 /* Coding_iOS */, + B1D5EBF120BC06CB00983FB6 /* Coding_Enterprise_iOS */, ); }; /* End PBXProject section */ @@ -5881,106 +9332,150 @@ 4E6383FD1B33C18700D98648 /* task_activity_icon_restore@2x.png in Resources */, 4E9F5D201C03051D007CCDCC /* tipIcon_tweetReward@2x.png in Resources */, 4EA6791A1A14BFA0001A0324 /* icon_file_folder_normal@2x.png in Resources */, + B152ED92209453F3004A6E8A /* taskboard_add_page_selected@2x.png in Resources */, + B1C871721EB1832B003DACF0 /* time_clock_icon@3x.png in Resources */, + B1C871A01EB2D9E6003DACF0 /* task_activity_icon_add_watcher@3x.png in Resources */, 8EA6D19919E240C40076D59C /* tipIcon_ProjectTopic@2x.png in Resources */, 4ED673261A8E127100DF2D1A /* SVWebViewControllerActivityReport@2x.png in Resources */, - 4EB119FB1D953AE200A36341 /* intro_page2_ip6+@3x.png in Resources */, + B1890C312015D82600F52ABA /* wiki_menu_icon_share@2x.png in Resources */, 8EA6D14A19E240C40076D59C /* InfoPlist.strings in Resources */, 4E6383C31B3265DC00D98648 /* mrpr_icon_accepted@2x.png in Resources */, + B1DFD0A720C67D3F00F75F2F /* btn_privateMsg_friend@3x.png in Resources */, + 4EAAD0271E540551008AA957 /* mrpr_icon_status_refused@2x.png in Resources */, D0C447DE1C02DB8900DC1C4B /* privatemessage_normal@3x.png in Resources */, 8E8F7B3419EF6306006BA8BD /* btn_project_added@2x.png in Resources */, 8EA6D16B19E240C40076D59C /* nav_tweet_all@2x.png in Resources */, 4EACB43F1A2C448F0097ABB3 /* button_file_createFolder_unable@2x.png in Resources */, + B1AB5CB7202D7D500075A669 /* button_file_denete_unable@3x.png in Resources */, + B1C871B61EB2D9F0003DACF0 /* file_activity_icon_upload_file@3x.png in Resources */, + B12B64791FFB61AD00ACFDCC /* QBImagePicker.storyboard in Resources */, 4EED9DCD1B539366000E5827 /* taskProject@2x.png in Resources */, - 4EF17ED91B3C3112003CDD2D /* intro_icon_5@2x.png in Resources */, + B1AB5CB4202D7D500075A669 /* button_file_upload_enable@3x.png in Resources */, 4EB52F221C76BA3B00B5EBEA /* tag_button_randomColor@3x.png in Resources */, + B16E6D7420C148E50076026D /* intro_icon_4@3x.png in Resources */, + B16E6D8A20C148E50076026D /* intro_icon_3@3x.png in Resources */, 4ED4B48A1D82646100EED8C6 /* user_info_help@3x.png in Resources */, 4E6383B81B32640900D98648 /* messageComment@2x.png in Resources */, + B12B642A1FF33E0100ACFDCC /* upgrade_success@3x.png in Resources */, 8EA6D1A319E240C40076D59C /* tweet_comment_btn@2x.png in Resources */, D09E6ACE1BF9CCCF009D37F8 /* fliter_square@2x.png in Resources */, 1319D1081CA7FE6E00729F82 /* PR_create@2x.png in Resources */, 4ED4B4941D82646100EED8C6 /* user_info_tweet@3x.png in Resources */, 4E6383AB1B3262D300D98648 /* taskPriority2_small@2x.png in Resources */, - D0FE4DB91C103FA0006E5A76 /* git_icon_star_old@2x.png in Resources */, D0C447CC1C02DB6700DC1C4B /* pop_2FA@3x.png in Resources */, + B17CC31D20731FF10077C956 /* code_release_resource_Zip@2x.png in Resources */, 4E59D3311D409C8C008C914B /* topic_add_watcher_btn@2x.png in Resources */, + B16E6D1120C147770076026D /* team_cell_edit_team@3x.png in Resources */, 7E8E59831B6F91C40083CA02 /* bubble_right_play_1@2x.png in Resources */, + B16E6D0520C147770076026D /* team_info_order@2x.png in Resources */, 8B3516511B6CE9460049BC45 /* search_tweet_colck@2x.png in Resources */, 8E97CE6A1A0A3424006F9AD7 /* keyboard_page_unselected@2x.png in Resources */, - 4E095A161D9534CB00E63D9E /* intro_page_selected@3x.png in Resources */, + 4E9423E61E69401B0095F1CD /* blankpage_image_Project@2x.png in Resources */, 134116F01CB529E1005E6550 /* PR_more@2x.png in Resources */, 4E54C24C1D8FE19100A61023 /* user_info_edit@3x.png in Resources */, - 4E07D3161A4D3CA6009EDDF2 /* logo_coding@2x.png in Resources */, + B1280CF1200EFDC600DEDF78 /* file_changeType_MODIFY@3x.png in Resources */, 4E96E7D91A1B537E0037C098 /* icon_file_apk@2x.png in Resources */, 4E996C021ABBF56A00C704F1 /* n_btn_followed_both@2x.png in Resources */, 4E6383BB1B32640900D98648 /* messageSystem@2x.png in Resources */, + B1280D02200EFEA400DEDF78 /* PR_del_watcher@2x.png in Resources */, 4ED618251C3CB1AF0017946C /* taskWatchers@3x.png in Resources */, + B16E6D8220C148E50076026D /* intro_tip_1@2x.png in Resources */, + 4EAAD0241E540551008AA957 /* mrpr_icon_status_canmerge@3x.png in Resources */, + B16E6CBE20C13F5F0076026D /* btn_project_add@3x.png in Resources */, 4E095A851B6B24DE008DC439 /* topic_comment_icon@2x.png in Resources */, + B1C871351EADF155003DACF0 /* project_item_activity@3x.png in Resources */, 4E2F6A6F1C43CA4B00A25502 /* member_type_75@3x.png in Resources */, + B16E6D8E20C148E50076026D /* intro_dot_selected@3x.png in Resources */, 7E8E59841B6F91C40083CA02 /* bubble_right_play_2@2x.png in Resources */, 4E2BF3CF1B96CDF800A5A0A8 /* share_btn_coding@2x.png in Resources */, 8EA6D15019E240C40076D59C /* commentOrLikeBeginImg@2x.png in Resources */, + B16E6CED20C147490076026D /* team_bg@3x.png in Resources */, 4EB52F5F1C7C5C4F00B5EBEA /* task_resource_reference_ProjectFile@3x.png in Resources */, 13FB5D481CA17A6400EE127C /* PR_mergeChanges@3x.png in Resources */, + B19D4EF61F7210C300C598F3 /* user_info_shop@2x.png in Resources */, + B16E6CA020C0FDB50076026D /* logo_coding_top@3x.png in Resources */, 134E1B9B1CA41217002A3E0D /* ReviewCell.xib in Resources */, 8EA6D15E19E240C40076D59C /* login_suffix@2x.png in Resources */, + B16E6D9A20C148E50076026D /* intro_page0_ipX@3x.png in Resources */, 4EB52F101C74691B00B5EBEA /* password_look@3x.png in Resources */, + B16E6CDB20C145BF0076026D /* quick_menu_icon_message@2x.png in Resources */, 8E97CE721A0B8C6C006F9AD7 /* emotion_list.plist in Resources */, + B1890C302015D82600F52ABA /* wiki_menu_1@3x.png in Resources */, 4EC461B21B39360F00D08970 /* file_changeType_ADD@2x.png in Resources */, - 13FB5D3E1CA17A6400EE127C /* EPointLikeHead@1x.png in Resources */, 4E6CBE541D8EA9D100644086 /* icon_best_answer@2x.png in Resources */, 4E4D6ACC1B2571B100FD2E49 /* git_icon_watched@2x.png in Resources */, 8E97CEB11A0C7E26006F9AD7 /* coding_emoji_26@2x.png in Resources */, 8E97CEBA1A0C7E26006F9AD7 /* coding_emoji_35@2x.png in Resources */, + B1C871A91EB2D9E6003DACF0 /* task_activity_icon_update_description@3x.png in Resources */, + B14689BF1EE100B200B01371 /* vip_4_40@3x.png in Resources */, 8E97CE681A0A3424006F9AD7 /* keyboard_keyboard@2x.png in Resources */, + B1817F012069197D00E9BAD1 /* icon_release_tag@2x.png in Resources */, 8EA6D17919E240C40076D59C /* placeholder_monkey_round_48@2x.png in Resources */, + B1C60C8620BFE8220073D3CA /* NewProject.storyboard in Resources */, + 4EAAD0A51E5D8D90008AA957 /* PR_plus@2x.png in Resources */, 8EA6D1A819E240C40076D59C /* xtsegment_bordor_left@2x.png in Resources */, 4EB52F5C1C7C5C4F00B5EBEA /* task_resource_reference_MergeRequestBean@2x.png in Resources */, - 8E525C8A19F7E3F800496B34 /* blankpage_image_loadFail@2x.png in Resources */, 4E1D99161DCAE67D00BAE585 /* icon_file_folder_out@2x.png in Resources */, 4E6CBE591D8FBDF500644086 /* messageProjectFollows@2x.png in Resources */, - 4E095A7E1B6B1E40008DC439 /* calendar_0xF24B4B@2x.png in Resources */, 4E5D13091C0ECB3400985AEB /* tweet_btn_comment@2x.png in Resources */, + 4E9423E91E69401B0095F1CD /* blankpage_image_ShopOrder@3x.png in Resources */, 4E095A6E1B69F920008DC439 /* banner__page_unselected@2x.png in Resources */, + 4EAAD0211E540551008AA957 /* mrpr_icon_status_accepted@2x.png in Resources */, 4E96E7D81A1B537E0037C098 /* icon_file_ai@2x.png in Resources */, + 4EAAD0A61E5D8D90008AA957 /* PR_plus@3x.png in Resources */, 4ED4B4931D82646100EED8C6 /* user_info_tweet@2x.png in Resources */, - 8E525C8919F7E3F800496B34 /* blankpage_button_reload@2x.png in Resources */, 8E97CEAC1A0C7E26006F9AD7 /* coding_emoji_21@2x.png in Resources */, 7E8E59811B6F91C40083CA02 /* bubble_left_play_2@2x.png in Resources */, 4EB52F631C7C5C4F00B5EBEA /* task_resource_reference_Task@3x.png in Resources */, + B1280D00200EFEA400DEDF78 /* PR_add_watcher@2x.png in Resources */, 4E93F23A1B84356500017916 /* file_menu_icon_delete@2x.png in Resources */, + B12B64261FF33E0100ACFDCC /* button_red_close@3x.png in Resources */, + B16E6D8F20C148E50076026D /* intro_icon_1@3x.png in Resources */, 1319D10C1CA81FE100729F82 /* PR_merge@3x.png in Resources */, - 4E4D6AC21B252CD400FD2E49 /* icon_code_tree@2x.png in Resources */, 8E97CEB01A0C7E26006F9AD7 /* coding_emoji_25@2x.png in Resources */, 7E335D9D1B6F5E94003D0F3D /* keyboard_arrow_down@2x.png in Resources */, 4EB52F3C1C7C45E700B5EBEA /* taskResourceReference@3x.png in Resources */, 4EB52F1D1C76BA3B00B5EBEA /* tag_button_add@2x.png in Resources */, 4E59D32C1D3E106D008C914B /* tweetsBtn_Nav@3x.png in Resources */, + B1817EFD206918D200E9BAD1 /* icon_branch_protected@2x.png in Resources */, + B152ED90209453F3004A6E8A /* taskboard_normal_page_selected@2x.png in Resources */, 4ED4B4851D82646100EED8C6 /* user_info_about@2x.png in Resources */, - 4EF17ED71B3C3112003CDD2D /* intro_icon_4@2x.png in Resources */, + B1817EFC206918D200E9BAD1 /* icon_branch_protected@3x.png in Resources */, 4E6384031B33C8E900D98648 /* task_activity_icon_create@2x.png in Resources */, 4EACB4401A2C448F0097ABB3 /* button_file_download_unable@2x.png in Resources */, D09E6AC01BF82DC6009D37F8 /* btn_setFrequent@2x.png in Resources */, + B1C871A61EB2D9E6003DACF0 /* task_activity_icon_remove_watcher@3x.png in Resources */, + B16E6D9920C148E50076026D /* intro_page0_ip6+@3x.png in Resources */, + B177F5C72060E6B1006709C2 /* markdown.html in Resources */, + B17CC32C2073212E0077C956 /* code_release_resource_ProjectTopic@3x.png in Resources */, 4ECEF9F71D1BB7FB002A27D3 /* diff-ios.html in Resources */, 4EAC8B6A1BA01F190060B0FC /* little_phone_icon@2x.png in Resources */, 4E2BF3D41B96CDF800A5A0A8 /* share_btn_sina@2x.png in Resources */, - 8E8F7B2F19EF6306006BA8BD /* btn_privateMsg_black@2x.png in Resources */, 4E96E7E01A1B537E0037C098 /* icon_file_pdf@2x.png in Resources */, 4E4972DC1BB52A8300F3AC15 /* tipIcon_TweetComment@2x.png in Resources */, + 4E9423E11E69401B0095F1CD /* blankpage_image_LoadFail@3x.png in Resources */, + B152ED91209453F3004A6E8A /* taskboard_add_page_unselected@2x.png in Resources */, 13FB5D431CA17A6400EE127C /* PR_grant_undo@2x.png in Resources */, + B1C871261EADF0FF003DACF0 /* back_green_Nav@2x.png in Resources */, 4EFE8DAC1B394A0D004B7559 /* file_changeType_COPY@2x.png in Resources */, + B16E6D7620C148E50076026D /* intro_icon_6@2x.png in Resources */, 927AFF501BFF6DAD00AAE593 /* shop_exchange_icon@2x.png in Resources */, D0C448101C02DCAC00DC1C4B /* timeBtn_Nav@3x.png in Resources */, + B16E6D7520C148E50076026D /* intro_tip_2@3x.png in Resources */, 13FB5D381CA17A6400EE127C /* close@2x.png in Resources */, 13FB5D3D1CA17A6400EE127C /* PR_update_content@3x.png in Resources */, 4E996C071ABBF56A00C704F1 /* user_info_detail@2x.png in Resources */, + B14689C01EE100B200B01371 /* vip_4_45@2x.png in Resources */, 4E8C51B01AC1081500B4C51F /* icon_recommended@2x.png in Resources */, 4E96E7DA1A1B537E0037C098 /* icon_file_doc@2x.png in Resources */, 4E09DCA61C156387001C9392 /* hot_topic_Nav@3x.png in Resources */, + B1817EF12068F4B400E9BAD1 /* EACodeReleaseListCell.xib in Resources */, 4ED4B4901D82646100EED8C6 /* user_info_setup@3x.png in Resources */, 4E4972DF1BB535B400F3AC15 /* tipIcon_ProjectTweet@2x.png in Resources */, 4E09DCA91C15662E001C9392 /* share_Nav@2x.png in Resources */, 8E62ADDA19E28DA800963870 /* tipIcon_User@2x.png in Resources */, 4E6383A71B3262D300D98648 /* taskPriority0_small@2x.png in Resources */, + B1280CEF200EFDC600DEDF78 /* file_changeType_COPY@3x.png in Resources */, 8E8F7B3519EF6306006BA8BD /* btn_project_quit@2x.png in Resources */, 4E2F6A6C1C43CA4B00A25502 /* member_type_100@2x.png in Resources */, 4ED558321B4FA68400FC10CB /* dismissBtn_Nav@2x.png in Resources */, @@ -5988,114 +9483,181 @@ 8E97CE661A0A3424006F9AD7 /* keyboard_emotion_emoji@2x.png in Resources */, 4EED9DCC1B539366000E5827 /* taskOwner@2x.png in Resources */, 4EC461B71B3939DC00D08970 /* task_activity_icon_commit_refer@2x.png in Resources */, + B1C871371EADF155003DACF0 /* project_item_file@3x.png in Resources */, 8E8F7B2E19EF6306006BA8BD /* btn_followed_yes@2x.png in Resources */, 8E8F7B3319EF6306006BA8BD /* btn_project_add@2x.png in Resources */, + B16E6D8920C148E50076026D /* intro_tip_1@3x.png in Resources */, 4E6383D11B32665700D98648 /* project_item_activity@2x.png in Resources */, 4E4972E91BB5446900F3AC15 /* tips_menu_icon_status@2x.png in Resources */, + B16E6D7B20C148E50076026D /* intro_icon_4@2x.png in Resources */, + B16E6D1920C147770076026D /* team_cell_edit_pro@3x.png in Resources */, D0C447AA1C02A3C700DC1C4B /* task_selected@2x.png in Resources */, - 4E9113AA1A1CB19900AC9431 /* icon_file_state_goon@2x.png in Resources */, + B1C871361EADF155003DACF0 /* project_item_code@3x.png in Resources */, + B1AB5C9A202953E50075A669 /* terminal_tail@2x.png in Resources */, + B1280D04200EFEA400DEDF78 /* PR_add_reviewer@2x.png in Resources */, 13FB5D3B1CA17A6400EE127C /* PR_push@3x.png in Resources */, 927AFF4F1BFF6DAD00AAE593 /* shop_coding_coin_icon@3x.png in Resources */, - 4EF17EDA1B3C3112003CDD2D /* intro_icon_5@3x.png in Resources */, + B1C871BC1EB338FD003DACF0 /* project_tag_icon@3x.png in Resources */, + B1944154206CBE8C00147158 /* code_lang.plist in Resources */, + B10341292024633900853447 /* logo_coding@2x.png in Resources */, 4ED4B48D1D82646100EED8C6 /* user_info_project@2x.png in Resources */, + B1AB5CBB202D7D500075A669 /* button_file_createFolder_unable@3x.png in Resources */, D09E6ABC1BF829F2009D37F8 /* icon_project_cell_setNormal@2x.png in Resources */, D0C4480E1C02DCAC00DC1C4B /* search_Nav@3x.png in Resources */, - 8E64ED8319ED0CE3006E99DA /* QBImagePickerController.strings in Resources */, 8E97CE671A0A3424006F9AD7 /* keyboard_emotion_monkey@2x.png in Resources */, + B1BCB8891FCD006C0098B87B /* icon_file_ppt_big@2x.png in Resources */, + B1C8717F1EB18599003DACF0 /* calendar_0xA1CF64@2x.png in Resources */, + B16E6D7820C148E50076026D /* intro_tip_0@3x.png in Resources */, + 4E9423DF1E69401B0095F1CD /* blankpage_image_File@3x.png in Resources */, 4E217F0F1A70EDC700F6DF88 /* SVWebViewControllerActivityChrome-iPad.png in Resources */, + B1C8712B1EADF0FF003DACF0 /* settingBtn_Nav@3x.png in Resources */, + B1280D05200EFEA400DEDF78 /* PR_del_watcher@3x.png in Resources */, 4E5D130A1C0ECB3400985AEB /* tweet_btn_comment@3x.png in Resources */, + B1C871A81EB2D9E6003DACF0 /* task_activity_icon_update_deadline@3x.png in Resources */, 13FB5D391CA17A6400EE127C /* close@3x.png in Resources */, 8E97CEA51A0C7E26006F9AD7 /* coding_emoji_14@2x.png in Resources */, + B152ED96209453F3004A6E8A /* taskboard_normal_page_unselected@2x.png in Resources */, + B1C871131EADAEE1003DACF0 /* loading_monkey@2x.gif in Resources */, + 4E80E9511E02911E00DE1BC6 /* search_icon_topic@3x.png in Resources */, + B16E6CB320C13BF50076026D /* btn_next_enable@2x.png in Resources */, D0C447D11C02DB6700DC1C4B /* pop_User@3x.png in Resources */, + B1C871691EB182C7003DACF0 /* taskPriority2_small@3x.png in Resources */, + B1C871BB1EB338FD003DACF0 /* project_tag_btn@3x.png in Resources */, 4EB52F621C7C5C4F00B5EBEA /* task_resource_reference_Task@2x.png in Resources */, 4E4972E81BB5446900F3AC15 /* tips_menu_icon_mkread@2x.png in Resources */, 8E97CEA61A0C7E26006F9AD7 /* coding_emoji_15@2x.png in Resources */, + B16E6D8420C148E50076026D /* intro_dot_unselected@2x.png in Resources */, + 4E80E92F1DFFF06E00DE1BC6 /* shortcut_task@2x.png in Resources */, + B1AB5CA2202953E50075A669 /* terminal_triangle@2x.png in Resources */, + B1C871711EB1832B003DACF0 /* topic_comment_icon@3x.png in Resources */, 8EA6D17819E240C40076D59C /* placeholder_monkey_round_40@2x.png in Resources */, 1319D10B1CA81FE100729F82 /* PR_merge@2x.png in Resources */, 4E5D130B1C0ECB3400985AEB /* tweet_btn_like@2x.png in Resources */, 134116F81CB55E69005E6550 /* PR_update@2x.png in Resources */, 8EA6D15C19E240C40076D59C /* login_email@2x.png in Resources */, D0C448111C02DCAC00DC1C4B /* tweetBtn_Nav@3x.png in Resources */, + 4EAAD0281E540551008AA957 /* mrpr_icon_status_refused@3x.png in Resources */, + B16E6D0D20C147770076026D /* team_info_mem@2x.png in Resources */, + B1DFD0A520C67D3F00F75F2F /* btn_followed_both@3x.png in Resources */, + B12B640E1FECB59000ACFDCC /* login_wechat@3x.png in Resources */, 4EDD8F521A36F42300E9E232 /* ReleaseNotes.txt in Resources */, - 13FB5D491CA17A6400EE127C /* PointLikeHead@1x.png in Resources */, 13FB5D3C1CA17A6400EE127C /* PR_update_content@2x.png in Resources */, 13972E291CA6157C00489EBA /* ReviewerListController.xib in Resources */, + B1C871B21EB2D9F0003DACF0 /* file_activity_icon_create@3x.png in Resources */, 8EA6D19619E240C40076D59C /* tipIcon_MergeRequestComment@2x.png in Resources */, 4E6383BC1B32640900D98648 /* private_message_send_fail@2x.png in Resources */, - 4E743E6F1A88ABF700DADDE5 /* blankpage_image_Hi@2x.png in Resources */, + B1AB5C9B202953E50075A669 /* terminal_box_unselected@2x.png in Resources */, 8E97CE631A0A3424006F9AD7 /* keyboard_at@2x.png in Resources */, 8E97CEA41A0C7E26006F9AD7 /* coding_emoji_13@2x.png in Resources */, + 4E9423F41E69401B0095F1CD /* blankpage_image_Wiki@2x.png in Resources */, 133DAA641CC13A30004D8501 /* PR_update_title@2x.png in Resources */, 4E6383D71B32665700D98648 /* project_item_task@2x.png in Resources */, + B1BCB8841FCD006C0098B87B /* icon_file_apk_big@2x.png in Resources */, 4E93F23E1B84356500017916 /* file_menu_icon_share@2x.png in Resources */, 8EA6D14C19E240C40076D59C /* btn_delete_tweetimage@2x.png in Resources */, + B1C871A11EB2D9E6003DACF0 /* task_activity_icon_commit_refer@3x.png in Resources */, + 4EAAD0521E542B2D008AA957 /* icon_code_executable@3x.png in Resources */, + B1C8717E1EB18599003DACF0 /* calendar_0x59A2FF@3x.png in Resources */, + B1C871A21EB2D9E6003DACF0 /* task_activity_icon_create@3x.png in Resources */, 4EC5AD931A258DF8006FA97C /* icon_file_cell_move@2x.png in Resources */, + 4EAAD0261E540551008AA957 /* mrpr_icon_status_cannotmerge@3x.png in Resources */, 4EAECBC31C44CB860096CA74 /* member_cell_edit_alias@3x.png in Resources */, + B16E6D1720C147770076026D /* team_cell_edit_delete@2x.png in Resources */, + B16E6D1520C147770076026D /* team_cell_edit_delete@3x.png in Resources */, 4EC5AD941A258DF8006FA97C /* icon_file_cell_rename@2x.png in Resources */, 13FB5D561CA17A6400EE127C /* PR_grant@3x.png in Resources */, 8E97CE9A1A0C7E26006F9AD7 /* coding_emoji_03@2x.png in Resources */, + B1C8718E1EB1E608003DACF0 /* cell_checkmark@3x.png in Resources */, 4ED618241C3CB1AF0017946C /* taskWatchers@2x.png in Resources */, 4E96E7E21A1B537E0037C098 /* icon_file_psd@2x.png in Resources */, 8EA6D18019E240C40076D59C /* sex_man_icon@2x.png in Resources */, 4EC461B31B39360F00D08970 /* file_changeType_DELETE@2x.png in Resources */, + B1AB5CBA202D7D500075A669 /* button_file_move_unable@3x.png in Resources */, + B1AB5CB5202D7D500075A669 /* button_file_history@3x.png in Resources */, + 4E80E92D1DFFF06E00DE1BC6 /* shortcut_2FA@2x.png in Resources */, + B1AB5CB3202D7D500075A669 /* button_file_download_enable@3x.png in Resources */, + B1BCB8881FCD006C0098B87B /* icon_file_ai_big@2x.png in Resources */, 4EBDC27B1BC501C00037EB66 /* tipIcon_ProjectPayment@2x.png in Resources */, 4E6B07161BA4045E007D6027 /* MIDAUTUMNIMAGE.jpg in Resources */, + B1C871811EB18599003DACF0 /* calendar_0xA9B3BE@2x.png in Resources */, + B1C871561EAE003A003DACF0 /* project_item_topic@3x.png in Resources */, + B16E6D0720C147770076026D /* team_info_order@3x.png in Resources */, 4EE083DC1ADB736800CA342E /* service_terms.html in Resources */, 4E6384011B33C18700D98648 /* task_activity_icon_update_priority@2x.png in Resources */, D0C448151C02F76600DC1C4B /* icon_search_searchbar@3x.png in Resources */, 7E335D9F1B6F5E94003D0F3D /* keyboard_voice@2x.png in Resources */, - 4E90F89B1AF709C100B44F03 /* bubble.html in Resources */, + 4E80E95B1E02911E00DE1BC6 /* search_icon_project@3x.png in Resources */, 4E5D13191C0EF48200985AEB /* button_close@3x.png in Resources */, 8E8F7B2D19EF6306006BA8BD /* btn_followed_not@2x.png in Resources */, - 4EF17EE11B3C3112003CDD2D /* intro_tip_2@3x.png in Resources */, 4E6383DC1B3266C200D98648 /* mrpr_icon_fileChange@2x.png in Resources */, 4E6383FB1B33C18700D98648 /* task_activity_icon_finish@2x.png in Resources */, + B14689BE1EE100B200B01371 /* vip_4_40@2x.png in Resources */, + B1C871431EADF1C1003DACF0 /* taskDeadline@3x.png in Resources */, 4ED6181F1C3A732F0017946C /* button_arrow_left@2x.png in Resources */, 4E6383E21B32676600D98648 /* taskProgress@2x.png in Resources */, D0C447FD1C02DCA200DC1C4B /* tweetBtn_Nav@2x.png in Resources */, 7E8E59801B6F91C40083CA02 /* bubble_left_play_1@2x.png in Resources */, 8EA6D17B19E240C40076D59C /* placeholder_monkey_round_54@2x.png in Resources */, 4E5D13121C0ECB3400985AEB /* tweet_btn_rewarded@3x.png in Resources */, + B14689C21EE100B200B01371 /* vip_4_75@2x.png in Resources */, 4E6383FF1B33C18700D98648 /* task_activity_icon_update_deadline@2x.png in Resources */, 0A0519E31ABA918100551B61 /* TweetSendDetailLoctionCell.xib in Resources */, + B1C8713A1EADF155003DACF0 /* project_item_readme@3x.png in Resources */, + B1BCB87D1FCD006C0098B87B /* icon_file_doc_big@2x.png in Resources */, 4EF91F631B00B62B0021C951 /* icon_locationed@2x.png in Resources */, 4ECEF9FD1D1D0B3D002A27D3 /* tip_normal_Nav@3x.png in Resources */, 4E5D130C1C0ECB3400985AEB /* tweet_btn_like@3x.png in Resources */, 4EE548281AE9166B00A92306 /* icon_project_cell_nopin@2x.png in Resources */, 4E0849811A918A7F00BD27F6 /* coding_emoji_39@2x.png in Resources */, - 4EF17EDD1B3C3112003CDD2D /* intro_tip_0@3x.png in Resources */, 8E97CE9F1A0C7E26006F9AD7 /* coding_emoji_08@2x.png in Resources */, 4E5D130D1C0ECB3400985AEB /* tweet_btn_liked@2x.png in Resources */, 4E93F2451B85C4C300017916 /* FileInfoViewController.xib in Resources */, 4EC480141C2A909D005F1772 /* register_step_un@3x.png in Resources */, + 4E9423EB1E69401B0095F1CD /* blankpage_image_Task@3x.png in Resources */, 0A782FDE1AB5B78B00E96661 /* TweetSendCreateLocationCell.xib in Resources */, - 8E8F7B3219EF6306006BA8BD /* btn_privateMsg_white@2x.png in Resources */, - 4EB119F81D953AE200A36341 /* intro_page2_ip4@2x.png in Resources */, + B16E6D8820C148E50076026D /* intro_dot_unselected@3x.png in Resources */, 8E97CEBB1A0C7E26006F9AD7 /* coding_emoji_36@2x.png in Resources */, 4E996C041ABBF56A00C704F1 /* n_btn_followed_yes@2x.png in Resources */, 4EAE06901B784E9200179F4B /* store_icon@2x.png in Resources */, + B14689C31EE100B200B01371 /* vip_4_75@3x.png in Resources */, + B1CB8DD22047F1D200872197 /* button_tip_notice@2x.png in Resources */, 4EF818161B049C89005F974B /* addPictureBgImage@2x.png in Resources */, + B16E6D0B20C147770076026D /* team_info_mem@3x.png in Resources */, 13FB5D501CA17A6400EE127C /* PRReviewer@3x.png in Resources */, + B1CB8DD32047F1D200872197 /* button_tip_notice@3x.png in Resources */, 4EB52F0F1C74691B00B5EBEA /* password_look@2x.png in Resources */, 4ED673281A8E12F900DF2D1A /* SVWebViewControllerActivityReport-iPad@2x.png in Resources */, 13FB5D4B1CA17A6400EE127C /* PointLikeHead@3x.png in Resources */, 4E07D30E1A4A9F45009EDDF2 /* btn_file_reDo@2x.png in Resources */, + B1DFD0A320C67D3F00F75F2F /* btn_followed_not@3x.png in Resources */, + B14689BC1EE100B200B01371 /* vip_4_30@2x.png in Resources */, + B1C8714D1EADF3AC003DACF0 /* mrpr_icon_fileChange@3x.png in Resources */, + B131E2112074D2EE00D84FAA /* project_item_reading@3x.png in Resources */, + 4EAAD0511E542B2D008AA957 /* icon_code_executable@2x.png in Resources */, + B1C8714B1EADF217003DACF0 /* user_info_company@3x.png in Resources */, + B12B64291FF33E0100ACFDCC /* upgrade_success@2x.png in Resources */, D0C447C41C02DB5400DC1C4B /* pop_Tweet@2x.png in Resources */, 4E6383A81B3262D300D98648 /* taskPriority1@2x.png in Resources */, + 4E80E9581E02911E00DE1BC6 /* search_icon_pr@2x.png in Resources */, 8EA6D15F19E240C40076D59C /* logo_about@2x.png in Resources */, + B16E6CA620C13BA20076026D /* btn_dismiss@3x.png in Resources */, 4E66EE2A1A28226000DA1B3E /* button_file_upload_enable@2x.png in Resources */, + B16E6CE720C145BF0076026D /* quick_menu_icon_2fa@2x.png in Resources */, 4E2BF3D21B96CDF800A5A0A8 /* share_btn_qq@2x.png in Resources */, + B16E6D0120C147770076026D /* team_info_pro@3x.png in Resources */, 13FB5D4C1CA17A6400EE127C /* PR_review@2x.png in Resources */, D0C447C11C02DB5400DC1C4B /* pop_Message@2x.png in Resources */, + B1AB5CA3202953E50075A669 /* terminal_box_selected@2x.png in Resources */, D09E6AC41BF84AE5009D37F8 /* git_icon_watch@2x.png in Resources */, - 4E07D3151A4D3CA6009EDDF2 /* icon_user_monkey@2x.png in Resources */, + B1BCB87F1FCD006C0098B87B /* icon_file_pdf_big@2x.png in Resources */, 8EA6D17519E240C40076D59C /* placeholder_coding_square_80@2x.png in Resources */, - B94C1B6B1AC945FB0000C271 /* NewProject.storyboard in Resources */, + 4EAAD0251E540551008AA957 /* mrpr_icon_status_cannotmerge@2x.png in Resources */, 8ED2AAFA19F60D5200607A1D /* loading_loop@2x.png in Resources */, - 4E6B07131BA3D9B5007D6027 /* intro_page1_ip6@2x.png in Resources */, + B17CC32220731FF10077C956 /* code_release_resource_Task@3x.png in Resources */, 13FB5D411CA17A6400EE127C /* PR_refuse@2x.png in Resources */, - D0FE4DBA1C103FA0006E5A76 /* git_icon_watch_old@2x.png in Resources */, + B16E6CCC20C144930076026D /* done_Nav@3x.png in Resources */, 8B3516501B6CE9460049BC45 /* icon_topic_hotTop@2x.png in Resources */, + B1890C2D2015D82600F52ABA /* wiki_revert@3x.png in Resources */, 4E2BF3D31B96CDF800A5A0A8 /* share_btn_qzone@2x.png in Resources */, 4EE1A23D1B5F3834004284F1 /* project_tag_btn@2x.png in Resources */, 4E5C06E81AC2B34800F427C5 /* tipIcon_BranchMember@2x.png in Resources */, @@ -6103,159 +9665,236 @@ 8EA6D19A19E240C40076D59C /* tipIcon_PullRequestBean@2x.png in Resources */, 8E8F7B3019EF6306006BA8BD /* btn_privateMsg_friend@2x.png in Resources */, 4E07D30D1A4A9F45009EDDF2 /* btn_file_cancel@2x.png in Resources */, + B1C871A71EB2D9E6003DACF0 /* task_activity_icon_restore@3x.png in Resources */, 4ED4B4881D82646100EED8C6 /* user_info_file@3x.png in Resources */, 927AFF4E1BFF6DAD00AAE593 /* shop_coding_coin_icon@2x.png in Resources */, - 4EF17ECD1B3C3112003CDD2D /* intro_dot_unselected@2x.png in Resources */, + 4E80E9301DFFF06E00DE1BC6 /* shortcut_task@3x.png in Resources */, + B1C871671EB182C7003DACF0 /* taskPriority1_small@3x.png in Resources */, + B1C871921EB1E608003DACF0 /* tasks_all@3x.png in Resources */, + B16E6CA820C13BA20076026D /* btn_dismiss@2x.png in Resources */, 8E97CEA01A0C7E26006F9AD7 /* coding_emoji_09@2x.png in Resources */, 0A06C2531AB9E57900AB3B03 /* map_annotation@2x.png in Resources */, + B17CC32D2073212E0077C956 /* code_release_resource_MergeRequestBean@2x.png in Resources */, 4EB52F601C7C5C4F00B5EBEA /* task_resource_reference_ProjectTopic@2x.png in Resources */, - 4E90F89C1AF709C100B44F03 /* code.html in Resources */, 4E6383FE1B33C18700D98648 /* task_activity_icon_update@2x.png in Resources */, + B1AB5CB6202D7D500075A669 /* button_file_activity@3x.png in Resources */, 4E0849831A918A7F00BD27F6 /* coding_emoji_41@2x.png in Resources */, + B1C8713B1EADF155003DACF0 /* project_item_task@3x.png in Resources */, + 4EAAD0821E55AC6E008AA957 /* icon_code_image@2x.png in Resources */, + B1BCB88B1FCD0A6D0098B87B /* icon_file_xls_big@2x.png in Resources */, 4ED4B4921D82646100EED8C6 /* user_info_topic@3x.png in Resources */, - 4EB119F91D953AE200A36341 /* intro_page2_ip5@2x.png in Resources */, 4ED618211C3BD79B0017946C /* task_activity_icon_remove_watcher@2x.png in Resources */, + B131E2122074D2EE00D84FAA /* project_item_reading@2x.png in Resources */, 927AFF521BFF6DAD00AAE593 /* shop_nar_history_icon@2x.png in Resources */, 4E6383AD1B3262D300D98648 /* taskPriority3_small@2x.png in Resources */, 8E97CEA91A0C7E26006F9AD7 /* coding_emoji_18@2x.png in Resources */, 4ED4B4861D82646100EED8C6 /* user_info_about@3x.png in Resources */, + B12B63F61FE8A77200ACFDCC /* WeiboSDK.bundle in Resources */, + B16E6D9B20C148E50076026D /* icon_user_monkey_i6p@3x.png in Resources */, + B1BCB8901FCE61D60098B87B /* EAPayViewController.xib in Resources */, + B16E6D0F20C147770076026D /* team_info_sup@3x.png in Resources */, + B1C871801EB18599003DACF0 /* calendar_0xA1CF64@3x.png in Resources */, 4ED4B4871D82646100EED8C6 /* user_info_file@2x.png in Resources */, + B19D4EF31F710EF900C598F3 /* ShopSwitchCell.xib in Resources */, + B1C871501EADF48B003DACF0 /* cell_arrow_left@2x.png in Resources */, + B12B64731FFB61AD00ACFDCC /* LICENSE in Resources */, 4E2F6A711C43CA4B00A25502 /* member_type_90@3x.png in Resources */, - 4EF17ECB1B3C3112003CDD2D /* intro_dot_selected@2x.png in Resources */, + B16E6D8D20C148E50076026D /* intro_dot_selected@2x.png in Resources */, 0A6E6BBB1AB168B0004C0107 /* location_checkmark@2x.png in Resources */, + 4EAAD0531E542B2D008AA957 /* icon_code_tree@2x.png in Resources */, 8EA6D16919E240C40076D59C /* nav_project_task@2x.png in Resources */, + B1C871851EB18599003DACF0 /* calendar_0xF68435@2x.png in Resources */, 4E2BF3D11B96CDF800A5A0A8 /* share_btn_evernote@2x.png in Resources */, + B1817EF72069186E00E9BAD1 /* project_item_branch@2x.png in Resources */, 13FB5D3A1CA17A6400EE127C /* PR_push@2x.png in Resources */, + B14689C11EE100B200B01371 /* vip_4_45@3x.png in Resources */, 4E54C24E1D90E05400A61023 /* tipIcon_ProjectTopicCommentVote@2x.png in Resources */, - 4EF17EE41B3C3112003CDD2D /* intro_tip_4@2x.png in Resources */, 4E1D991D1DCAE69600BAE585 /* icon_file_share_logo@3x.png in Resources */, + B1C871861EB18599003DACF0 /* calendar_0xF68435@3x.png in Resources */, 4EAE06C01B7B51AF00179F4B /* file_activity_icon_create@2x.png in Resources */, 8EA6D18F19E240C40076D59C /* tasks_all@2x.png in Resources */, + B1817F0320691B2700E9BAD1 /* EACodeReleaseTopCell.xib in Resources */, 13FB5D451CA17A6400EE127C /* merge-request coding@2x.png in Resources */, + B1280CEE200EFDC600DEDF78 /* file_changeType_ADD@3x.png in Resources */, + B1C871821EB18599003DACF0 /* calendar_0xA9B3BE@3x.png in Resources */, 7E774C251B870DC70026E5AB /* messageLeft_bg_highlight_img@2x.png in Resources */, 134116F91CB55E69005E6550 /* PR_update@3x.png in Resources */, 8EA6D16A19E240C40076D59C /* nav_project_topic@2x.png in Resources */, 4E2BF3D61B96CDF800A5A0A8 /* share_btn_wxtimeline@2x.png in Resources */, 4E96E7E51A1B537E0037C098 /* icon_file_zip@2x.png in Resources */, D0C447DC1C02DB8900DC1C4B /* me_normal@3x.png in Resources */, - 4E90F89E1AF709C100B44F03 /* topic-ios.html in Resources */, D0C447C21C02DB5400DC1C4B /* pop_Project@2x.png in Resources */, - 4EF17EDF1B3C3112003CDD2D /* intro_tip_1@3x.png in Resources */, 4EFE8DAF1B3960E6004B7559 /* logo_coding_top@2x.png in Resources */, 4E4972E01BB535B400F3AC15 /* tipIcon_ProjectTweetComment@2x.png in Resources */, 4E66EE261A28226000DA1B3E /* button_file_createFolder_enable@2x.png in Resources */, + B1890C2B2015D82600F52ABA /* wiki_menu_2@2x.png in Resources */, + B12B64181FF0E4CB00ACFDCC /* skill_delete@2x.png in Resources */, + B1C871831EB18599003DACF0 /* calendar_0xF56061@2x.png in Resources */, D0C447A81C02A3C700DC1C4B /* project_selected@2x.png in Resources */, - 4EB119FA1D953AE200A36341 /* intro_page2_ip6@2x.png in Resources */, 8EA6D19C19E240C40076D59C /* tipIcon_QcTask@2x.png in Resources */, 4E095A841B6B24DE008DC439 /* time_clock_icon@2x.png in Resources */, 4EB52F211C76BA3B00B5EBEA /* tag_button_randomColor@2x.png in Resources */, + 4E9423E51E69401B0095F1CD /* blankpage_image_Notice@3x.png in Resources */, + B16E6CC220C13F5F0076026D /* btn_project_quit@3x.png in Resources */, + B1C871391EADF155003DACF0 /* project_item_mr_pr@3x.png in Resources */, + B12B642B1FF33E0100ACFDCC /* button_tip_close@2x.png in Resources */, 4E6383FC1B33C18700D98648 /* task_activity_icon_reassign@2x.png in Resources */, 4EB52F5E1C7C5C4F00B5EBEA /* task_resource_reference_ProjectFile@2x.png in Resources */, 4E6383B71B32640900D98648 /* messageAT@2x.png in Resources */, D0C447AC1C02A3C700DC1C4B /* tweet_selected@2x.png in Resources */, 4E96E7DB1A1B537E0037C098 /* icon_file_code@2x.png in Resources */, - 4EF17ED51B3C3112003CDD2D /* intro_icon_3@2x.png in Resources */, + B1C871291EADF0FF003DACF0 /* back_T_Nav@3x.png in Resources */, D0C447A41C02A3C700DC1C4B /* me_selected@2x.png in Resources */, 8EA6D19B19E240C40076D59C /* tipIcon_PullRequestComment@2x.png in Resources */, + B16E6CC420C13F5F0076026D /* btn_privateMsg_stranger@3x.png in Resources */, 4E4972E41BB543A900F3AC15 /* tipIcon_Depot@2x.png in Resources */, 8EF6434119FE696B00F7EEB0 /* cell_checkmark@2x.png in Resources */, - 4EF17ED61B3C3112003CDD2D /* intro_icon_3@3x.png in Resources */, + B16E6D8020C148E50076026D /* intro_icon_2@2x.png in Resources */, + B1280D08200EFEA400DEDF78 /* PR_add_label@2x.png in Resources */, + B103412A2024633900853447 /* logo_coding@3x.png in Resources */, + B1280D09200EFEA400DEDF78 /* PR_del_reviewer@2x.png in Resources */, + B1C871A51EB2D9E6003DACF0 /* task_activity_icon_reassign@3x.png in Resources */, + B16E6D8B20C148E50076026D /* intro_tip_5@3x.png in Resources */, 8EA6D17319E240C40076D59C /* placeholder_coding_square_150@2x.png in Resources */, + B1C60C8E20BFF7950073D3CA /* ProjectTypeExplanationViewController.xib in Resources */, 4EAECBC41C44CB860096CA74 /* member_cell_edit_remove@2x.png in Resources */, - 4E095A181D9534CB00E63D9E /* intro_page_unselected@3x.png in Resources */, 134116F41CB54AF8005E6550 /* PR_TaskResource@2x.png in Resources */, 4E1D991C1DCAE69600BAE585 /* icon_file_share_logo@2x.png in Resources */, + B16E6D9620C148E50076026D /* intro_page_unselected@3x.png in Resources */, + 4E9423E41E69401B0095F1CD /* blankpage_image_Notice@2x.png in Resources */, 8EA6D17619E240C40076D59C /* placeholder_monkey_round_25@2x.png in Resources */, 4E2DB34A1BA6AEB4002F27C4 /* coding_emoji_gif_05@2x.png in Resources */, + B1C871251EADF0FF003DACF0 /* addBtn_Artboard@3x.png in Resources */, 8E97CEAD1A0C7E26006F9AD7 /* coding_emoji_22@2x.png in Resources */, 4E5D13111C0ECB3400985AEB /* tweet_btn_rewarded@2x.png in Resources */, 4E66EE291A28226000DA1B3E /* button_file_move_enable@2x.png in Resources */, + B1C8711B1EADF0B1003DACF0 /* messageSystem@3x.png in Resources */, + B12B64271FF33E0100ACFDCC /* button_red_close@2x.png in Resources */, + 4E9423F51E69401B0095F1CD /* blankpage_image_Wiki@3x.png in Resources */, 4EE1A23E1B5F3834004284F1 /* project_tag_icon@2x.png in Resources */, + B11DC7C120245728004E76A9 /* button_terminal@3x.png in Resources */, + B1890C2C2015D82600F52ABA /* wiki_menu_0@3x.png in Resources */, 133DAA651CC13A30004D8501 /* PR_update_title@3x.png in Resources */, + B177F5C52060E6B1006709C2 /* wiki.html in Resources */, + B1C871AC1EB2D9E6003DACF0 /* task_activity_icon_update@3x.png in Resources */, 8EA6D19319E240C40076D59C /* timeline_line_read@2x.png in Resources */, D09E6AC61BF84AF9009D37F8 /* git_icon_fork@2x.png in Resources */, 4EB52F1E1C76BA3B00B5EBEA /* tag_button_add@3x.png in Resources */, - 4EF17EE31B3C3112003CDD2D /* intro_tip_3@3x.png in Resources */, + B1C871461EADF1C1003DACF0 /* taskProgress@3x.png in Resources */, + B152ED85209453E8004A6E8A /* taskboard_blankpage@3x.png in Resources */, + 4E9423EA1E69401B0095F1CD /* blankpage_image_Task@2x.png in Resources */, + B1C871AA1EB2D9E6003DACF0 /* task_activity_icon_update_label@3x.png in Resources */, + 4E80E9551E02911E00DE1BC6 /* search_icon_mr@3x.png in Resources */, + 4E9423F31E69401B0095F1CD /* blankpage_image_Tweet@3x.png in Resources */, + B1C8714A1EADF217003DACF0 /* user_info_company@2x.png in Resources */, 4E94C4EF1B4B73BB00EB668A /* scan_line@2x.png in Resources */, + B12B64741FFB61AD00ACFDCC /* README.md in Resources */, 4E96E7DF1A1B537E0037C098 /* icon_file_unknown@2x.png in Resources */, - 8E525C8D19F7E3F800496B34 /* blankpage_image_Sleep@2x.png in Resources */, + 4E80E94E1E02911E00DE1BC6 /* search_icon_tweet@2x.png in Resources */, 4ECEFA021D1D0B4B002A27D3 /* tip_bg@2x.png in Resources */, 4E217F101A70EDC700F6DF88 /* SVWebViewControllerActivityChrome-iPad@2x.png in Resources */, 13FB5D551CA17A6400EE127C /* PR_grant@2x.png in Resources */, + B1C8712A1EADF0FF003DACF0 /* settingBtn_Nav@2x.png in Resources */, + B16E6D9220C148E50076026D /* intro_page0_ip5@2x.png in Resources */, 4ED4B4911D82646100EED8C6 /* user_info_topic@2x.png in Resources */, 4E6383EC1B32A2C300D98648 /* project_item_file@2x.png in Resources */, 8B35164F1B6CE9460049BC45 /* icon_arrow_searchHistory@2x.png in Resources */, + B1BCB8821FCD006C0098B87B /* icon_file_movie_big@2x.png in Resources */, + B1BCB8831FCD006C0098B87B /* icon_file_md_big@2x.png in Resources */, 8EA6D16819E240C40076D59C /* nav_project_member@2x.png in Resources */, - 4E9113A91A1CB19900AC9431 /* icon_file_state_download@2x.png in Resources */, + 4E9423E21E69401B0095F1CD /* blankpage_image_MessageList@2x.png in Resources */, 4EB52F121C74691B00B5EBEA /* password_unlook@3x.png in Resources */, - 4E9113AB1A1CB19900AC9431 /* icon_file_state_look@2x.png in Resources */, + B16EEF09208DDBB6005ABFD5 /* timeline_icon_unread@3x.png in Resources */, + B1BFC4C520B2B250009427FC /* task_activity_icon_add_milestone@3x.png in Resources */, + B16E6D8320C148E50076026D /* intro_icon_5@3x.png in Resources */, D0C447CD1C02DB6700DC1C4B /* pop_Message@3x.png in Resources */, + B152ED6520935594004A6E8A /* EABoardTaskListBlankView.xib in Resources */, 4E63840B1B33F9B400D98648 /* comment_bg@2x.png in Resources */, 4EB52F2E1C77138A00B5EBEA /* button_scan@2x.png in Resources */, + B1AB5CA0202953E50075A669 /* terminal_triangle@3x.png in Resources */, 4E59D32B1D3E106D008C914B /* tweetsBtn_Nav@2x.png in Resources */, 8E97CEA31A0C7E26006F9AD7 /* coding_emoji_12@2x.png in Resources */, - 4EF17EE81B3C3112003CDD2D /* intro_icon_6@2x.png in Resources */, - 4EF17ED11B3C3112003CDD2D /* intro_icon_1@2x.png in Resources */, + B1AB5C9C202953E50075A669 /* terminal_box_unselected@3x.png in Resources */, + B1AB5C9D202953E50075A669 /* terminal_tail@3x.png in Resources */, D0C447E21C02DB8900DC1C4B /* task_normal@3x.png in Resources */, + B14689BA1EE100B200B01371 /* vip_3_75@2x.png in Resources */, 4E0BD8841B6C7F0A0061CAA6 /* mock_hotTopiclist.geojson in Resources */, + B16E6D9D20C148E50076026D /* icon_user_monkey@2x.png in Resources */, 4EE548291AE9166B00A92306 /* icon_project_cell_pin@2x.png in Resources */, D0C447C01C02DB5400DC1C4B /* pop_2FA@2x.png in Resources */, + B1280D03200EFEA400DEDF78 /* PR_add_reviewer@3x.png in Resources */, 4EBD0C661A1F2011004B4284 /* nav_project_file@2x.png in Resources */, + B19D4EF71F7210C300C598F3 /* user_info_shop@3x.png in Resources */, D0C447C31C02DB5400DC1C4B /* pop_Task@2x.png in Resources */, 8EA6D17E19E240C40076D59C /* section_btn_close@2x.png in Resources */, 4EBD7FB11CE482A400B3AF49 /* country_code.plist in Resources */, 4E93F23C1B84356500017916 /* file_menu_icon_info@2x.png in Resources */, 8E97CE9E1A0C7E26006F9AD7 /* coding_emoji_07@2x.png in Resources */, + B152ED7D20945378004A6E8A /* project_item_taskboard@3x.png in Resources */, 13FB5D461CA17A6400EE127C /* merge-request coding@3x.png in Resources */, - 4EF17ECF1B3C3112003CDD2D /* intro_icon_0@2x.png in Resources */, + 4E9423ED1E69401B0095F1CD /* blankpage_image_Team@3x.png in Resources */, + 4EAAD0231E540551008AA957 /* mrpr_icon_status_canmerge@2x.png in Resources */, + 4E9423E31E69401B0095F1CD /* blankpage_image_MessageList@3x.png in Resources */, 4E6383A91B3262D300D98648 /* taskPriority1_small@2x.png in Resources */, D0C447DD1C02DB8900DC1C4B /* me_selected@3x.png in Resources */, + B16E6D7A20C148E50076026D /* intro_tip_2@2x.png in Resources */, D0C447FC1C02DCA200DC1C4B /* timeBtn_Nav@2x.png in Resources */, 7E8E59821B6F91C40083CA02 /* bubble_right_play_0@2x.png in Resources */, + B16E6D9420C148E50076026D /* intro_page_unselected@2x.png in Resources */, 4ED6181D1C3A72CF0017946C /* ShopMutileValueCell.xib in Resources */, + B1C871AB1EB2D9E6003DACF0 /* task_activity_icon_update_priority@3x.png in Resources */, + B16E6D9120C148E50076026D /* intro_icon_3@2x.png in Resources */, 4E96E7DD1A1B537E0037C098 /* icon_file_movie@2x.png in Resources */, 4E93F23D1B84356500017916 /* file_menu_icon_open@2x.png in Resources */, D0C447F41C02DCA200DC1C4B /* addBtn_Nav@2x.png in Resources */, - 4EF17EE51B3C3112003CDD2D /* intro_tip_4@3x.png in Resources */, + B16E6D7D20C148E50076026D /* intro_icon_2@3x.png in Resources */, + B1DFD0A120C67D3F00F75F2F /* btn_followed_yes@3x.png in Resources */, + B1C871181EADF0B1003DACF0 /* messageAT@3x.png in Resources */, + 4E80E9531E02911E00DE1BC6 /* search_icon_file@3x.png in Resources */, 13FB5D4D1CA17A6400EE127C /* PR_review@3x.png in Resources */, - 4E6B07121BA3D9B5007D6027 /* intro_page1_ip5@2x.png in Resources */, 4E2DB33F1BA6A2FE002F27C4 /* keyboard_emotion_monkey_gif@2x.png in Resources */, 8E97CEB41A0C7E26006F9AD7 /* coding_emoji_29@2x.png in Resources */, 4EAE06C11B7B51AF00179F4B /* file_activity_icon_move_file@2x.png in Resources */, - 13FB5D3F1CA17A6400EE127C /* EPointLikeHead@2x.png in Resources */, D0C448081C02DCAC00DC1C4B /* addBtn_Nav@3x.png in Resources */, + B16E6D1320C147770076026D /* team_cell_edit_team@2x.png in Resources */, + B14689BB1EE100B200B01371 /* vip_3_75@3x.png in Resources */, D0C4480C1C02DCAC00DC1C4B /* info_Nav@3x.png in Resources */, - 13FB5D4E1CA17A6400EE127C /* PRReviewer@1x.png in Resources */, + B1AB5C9F202953E50075A669 /* terminal_more@2x.png in Resources */, D0C447E31C02DB8900DC1C4B /* task_selected@3x.png in Resources */, + 4E9423E71E69401B0095F1CD /* blankpage_image_Project@3x.png in Resources */, 8E97CE641A0A3424006F9AD7 /* keyboard_emotion@2x.png in Resources */, 4EAE06A81B7B1AE100179F4B /* button_file_history@2x.png in Resources */, + B1BCB89B1FCE93830098B87B /* wechat@2x.png in Resources */, 4E0849851A918A7F00BD27F6 /* coding_emoji_43@2x.png in Resources */, 4E5D130E1C0ECB3400985AEB /* tweet_btn_liked@3x.png in Resources */, 4E96E7DE1A1B537E0037C098 /* icon_file_music@2x.png in Resources */, - 927AFF541BFF6DAD00AAE593 /* shop_unexchange_icon@2x.png in Resources */, 8EA6D1A119E240C40076D59C /* tipIcon_UserFollow@2x.png in Resources */, + 4EAAD0581E542B2D008AA957 /* icon_code_git_link@3x.png in Resources */, + B1280CED200EFDC600DEDF78 /* file_changeType_RENAME@3x.png in Resources */, 4E2F6A6D1C43CA4B00A25502 /* member_type_100@3x.png in Resources */, - 4E095A7F1B6B1E40008DC439 /* calendar_0xF5A523@2x.png in Resources */, + B17CC32020731FF10077C956 /* code_release_resource__Default@2x.png in Resources */, 4E5D13181C0EF48200985AEB /* button_close@2x.png in Resources */, 134116F51CB54AF8005E6550 /* PR_TaskResource@3x.png in Resources */, - 4EF17EDC1B3C3112003CDD2D /* intro_tip_0@2x.png in Resources */, 8EA6D19719E240C40076D59C /* tipIcon_Project@2x.png in Resources */, + 4EAAD0541E542B2D008AA957 /* icon_code_tree@3x.png in Resources */, D0C447CF1C02DB6700DC1C4B /* pop_Task@3x.png in Resources */, 4EB52F1F1C76BA3B00B5EBEA /* tag_button_editColor@2x.png in Resources */, 4E6CBE551D8EA9D100644086 /* icon_best_answer@3x.png in Resources */, - 4EF17ED31B3C3112003CDD2D /* intro_icon_2@2x.png in Resources */, + B16E6CB520C13BF50076026D /* btn_next_enable@3x.png in Resources */, 4ECEFA031D1D0B4B002A27D3 /* tip_bg@3x.png in Resources */, D0C448091C02DCAC00DC1C4B /* addUserBtn_Nav@3x.png in Resources */, + B1C871441EADF1C1003DACF0 /* taskOwner@3x.png in Resources */, D0C447F51C02DCA200DC1C4B /* addUserBtn_Nav@2x.png in Resources */, - 4E4D6AC11B252CD400FD2E49 /* icon_code_file@2x.png in Resources */, + 4EAAD0221E540551008AA957 /* mrpr_icon_status_accepted@3x.png in Resources */, 4E5D13101C0ECB3400985AEB /* tweet_btn_reward@3x.png in Resources */, 4EAECBC51C44CB860096CA74 /* member_cell_edit_remove@3x.png in Resources */, - 4EF17EE71B3C3112003CDD2D /* intro_tip_5@3x.png in Resources */, + B16E6D9320C148E50076026D /* intro_page_selected@2x.png in Resources */, + 4E80E9321DFFF06E00DE1BC6 /* shortcut_tweet@3x.png in Resources */, 8E97CEB91A0C7E26006F9AD7 /* coding_emoji_34@2x.png in Resources */, - 4EF17ED81B3C3112003CDD2D /* intro_icon_4@3x.png in Resources */, + B1C871701EB1832B003DACF0 /* task_description_icon@3x.png in Resources */, 4EAE06921B7880BA00179F4B /* me_info_arrow_left@2x.png in Resources */, 4E5F39071ACBFDCD0010515D /* keyboard_photo@2x.png in Resources */, - 4E0022A91B7362EF005308DE /* intro_page0_ip6@2x.png in Resources */, + B1BCB89C1FCE93830098B87B /* wechat@3x.png in Resources */, 4E76D4DE1A5A7B4A0094A35E /* text_clear_btn@2x.png in Resources */, D0C447A91C02A3C700DC1C4B /* task_normal@2x.png in Resources */, 4E96E7E41A1B537E0037C098 /* icon_file_xls@2x.png in Resources */, @@ -6264,148 +9903,258 @@ 927AFF531BFF6DAD00AAE593 /* shop_nar_history_icon@3x.png in Resources */, 4EC461B41B39360F00D08970 /* file_changeType_MODIFY@2x.png in Resources */, D0C447A71C02A3C700DC1C4B /* project_normal@2x.png in Resources */, + B16E6D7E20C148E50076026D /* intro_tip_4@3x.png in Resources */, + 4E80E9381E01218300DE1BC6 /* reward_tip_logo@2x.png in Resources */, + B16E6CDF20C145BF0076026D /* quick_menu_icon_task@3x.png in Resources */, + B1C871471EADF1C1003DACF0 /* taskProject@3x.png in Resources */, 4ED4B48C1D82646100EED8C6 /* user_info_point@3x.png in Resources */, 4EA679191A14BFA0001A0324 /* icon_file_folder_default@2x.png in Resources */, + 4EAAD0561E542B2D008AA957 /* icon_code_file@3x.png in Resources */, 4E6383D61B32665700D98648 /* project_item_readme@2x.png in Resources */, + B1817EEF2068C7A100E9BAD1 /* EACodeBranchListCell.xib in Resources */, + B17CC31F20731FF10077C956 /* code_release_resource_Default@3x.png in Resources */, D0C447F81C02DCA200DC1C4B /* info_Nav@2x.png in Resources */, - 4EF17ECE1B3C3112003CDD2D /* intro_dot_unselected@3x.png in Resources */, + B1C871B51EB2D9F0003DACF0 /* file_activity_icon_update_file@3x.png in Resources */, + B177F5C62060E6B1006709C2 /* bubble.html in Resources */, 4E2DB34B1BA6AEB4002F27C4 /* coding_emoji_gif_06@2x.png in Resources */, - 4EF17EDB1B3C3112003CDD2D /* intro_icon_6@3x.png in Resources */, + B16E6CCA20C144930076026D /* done_Nav@2x.png in Resources */, 4E6383D41B32665700D98648 /* project_item_member@2x.png in Resources */, 8EA6D19E19E240C40076D59C /* tipIcon_Tweet@2x.png in Resources */, + B16E6CD020C144930076026D /* done_un_Nav@3x.png in Resources */, 8E97CE9B1A0C7E26006F9AD7 /* coding_emoji_04@2x.png in Resources */, 8EA6D16D19E240C40076D59C /* nav_tweet_hot@2x.png in Resources */, 4E6383D81B32665700D98648 /* project_item_topic@2x.png in Resources */, + B1890C2F2015D82600F52ABA /* wiki_menu_1@2x.png in Resources */, + B1C871B41EB2D9F0003DACF0 /* file_activity_icon_move_file@3x.png in Resources */, 4E96E7DC1A1B537E0037C098 /* icon_file_md@2x.png in Resources */, D0C447AB1C02A3C700DC1C4B /* tweet_normal@2x.png in Resources */, 13FB5D511CA17A6400EE127C /* PR_review_undo@2x.png in Resources */, + 4E9423F21E69401B0095F1CD /* blankpage_image_Tweet@2x.png in Resources */, + B152ED82209453E8004A6E8A /* taskBoardList@3x.png in Resources */, 4E62410B1B74D65400E1533C /* search_tweet_like@2x.png in Resources */, 4E94C4ED1B4A867A00EB668A /* scan_bg@2x.png in Resources */, + B1C871BE1EB33B37003DACF0 /* task_icon_arrow@3x.png in Resources */, 4E996C031ABBF56A00C704F1 /* n_btn_followed_not@2x.png in Resources */, 8EA6D17F19E240C40076D59C /* section_btn_open@2x.png in Resources */, - 4E095A151D9534CB00E63D9E /* intro_page_selected@2x.png in Resources */, 4EB52F611C7C5C4F00B5EBEA /* task_resource_reference_ProjectTopic@3x.png in Resources */, + B12B64191FF0E4CB00ACFDCC /* skill_delete@3x.png in Resources */, 4EACB4411A2C448F0097ABB3 /* button_file_move_unable@2x.png in Resources */, 4E0BD8851B6C7F0A0061CAA6 /* mock_topicAdlist.geojson in Resources */, 8EA6D17419E240C40076D59C /* placeholder_coding_square_55@2x.png in Resources */, D0C447CE1C02DB6700DC1C4B /* pop_Project@3x.png in Resources */, + B1BFC4C620B2B250009427FC /* task_activity_icon_remove_milestone@3x.png in Resources */, + B16E6CA320C102B60076026D /* Images.xcassets in Resources */, + B1AB5CB8202D7D500075A669 /* button_file_download_unable@3x.png in Resources */, + 4E80E95C1E02911E00DE1BC6 /* search_icon_task@2x.png in Resources */, + B17CC32120731FF10077C956 /* code_release_resource_Task@2x.png in Resources */, D0C4480D1C02DCAC00DC1C4B /* moreBtn_Nav@3x.png in Resources */, + B184166A20513CA100207666 /* tweet_comment_btn@3x.png in Resources */, + B16E6D7920C148E50076026D /* intro_icon_6@3x.png in Resources */, + B14689B41EE100B200B01371 /* vip_3_30@2x.png in Resources */, + B1280D01200EFEA400DEDF78 /* PR_del_label@3x.png in Resources */, + 4E9423EC1E69401B0095F1CD /* blankpage_image_Team@2x.png in Resources */, + B15C98B220D39CA200DDA425 /* project_icon_edit@3x.png in Resources */, + B16E6D8520C148E50076026D /* intro_tip_3@3x.png in Resources */, + B16E6D0920C147770076026D /* team_info_sup@2x.png in Resources */, + B17CC31520731E950077C956 /* icon_release_tag_blue@2x.png in Resources */, 8E8F7B3119EF6306006BA8BD /* btn_privateMsg_stranger@2x.png in Resources */, + B1C8713D1EADF155003DACF0 /* project_item_wiki@3x.png in Resources */, 4E03AC9A1A5BDDF9002B000B /* STARTIMAGE.jpg in Resources */, + B1C871191EADF0B1003DACF0 /* messageComment@3x.png in Resources */, 8E97CE991A0C7E26006F9AD7 /* coding_emoji_02@2x.png in Resources */, 4E6383E91B32791600D98648 /* checkbox_checked@2x.png in Resources */, + B152ED83209453E8004A6E8A /* taskboard_blankpage@2x.png in Resources */, 4EAECBC71C44CB860096CA74 /* member_cell_edit_type@3x.png in Resources */, + B1280D06200EFEA400DEDF78 /* PR_del_label@2x.png in Resources */, 4E217F1A1A71007800F6DF88 /* SVWebViewController.strings in Resources */, - 4EF17ED01B3C3112003CDD2D /* intro_icon_0@3x.png in Resources */, + 4E9423F11E69401B0095F1CD /* blankpage_image_Topic@3x.png in Resources */, 8EA6D17719E240C40076D59C /* placeholder_monkey_round_33@2x.png in Resources */, 8E97CEB51A0C7E26006F9AD7 /* coding_emoji_30@2x.png in Resources */, 4E6383D21B32665700D98648 /* project_item_code@2x.png in Resources */, - 4EF17ED21B3C3112003CDD2D /* intro_icon_1@3x.png in Resources */, + 4E80E9571E02911E00DE1BC6 /* search_icon_user@3x.png in Resources */, + B17CC32A2073212E0077C956 /* code_release_resource_MergeRequestBean@3x.png in Resources */, + 4E9423DC1E69401B0095F1CD /* blankpage_image_Default@2x.png in Resources */, + B1817EF62069186E00E9BAD1 /* project_item_tag@2x.png in Resources */, 13FB5D4F1CA17A6400EE127C /* PRReviewer@2x.png in Resources */, - 4E0022A61B7362EF005308DE /* intro_page0_ip4@2x.png in Resources */, + B12B640F1FECB59000ACFDCC /* login_wechat@2x.png in Resources */, + B1C871A31EB2D9E6003DACF0 /* task_activity_icon_finish@3x.png in Resources */, + B152ED95209453F3004A6E8A /* taskboard_normal_page_unselected@3x.png in Resources */, 4E53EB591AFB090E0034FE1C /* nav_page_selected@2x.png in Resources */, - 4E1D99171DCAE67D00BAE585 /* icon_file_folder_out@3x.png in Resources */, + B16E6CCE20C144930076026D /* done_un_Nav@2x.png in Resources */, + B16E6CE520C145BF0076026D /* quick_menu_icon_2fa@3x.png in Resources */, 8E97CEB31A0C7E26006F9AD7 /* coding_emoji_28@2x.png in Resources */, - 4EF17EE61B3C3112003CDD2D /* intro_tip_5@2x.png in Resources */, 8EA6D17A19E240C40076D59C /* placeholder_monkey_round_50@2x.png in Resources */, + B14689B81EE100B200B01371 /* vip_3_45@2x.png in Resources */, 4E996C051ABBF56A00C704F1 /* n_sex_man_icon@2x.png in Resources */, 8EA6D15919E240C40076D59C /* AppIcon120x120.png in Resources */, D0C447A61C02A3C700DC1C4B /* privatemessage_selected@2x.png in Resources */, 4E2DB34C1BA6AEB4002F27C4 /* coding_emoji_gif_07@2x.png in Resources */, + B1C8717D1EB18599003DACF0 /* calendar_0x59A2FF@2x.png in Resources */, + B19D4EE21F690F5E00C598F3 /* file_activity_icon_rename@3x.png in Resources */, + B1AB5CB2202D7D500075A669 /* button_file_denete_enable@3x.png in Resources */, 8E97CEB71A0C7E26006F9AD7 /* coding_emoji_32@2x.png in Resources */, 8E97CEA71A0C7E26006F9AD7 /* coding_emoji_16@2x.png in Resources */, - 4E0022A81B7362EF005308DE /* intro_page0_ip6+@3x.png in Resources */, + 4EAAD05C1E544006008AA957 /* icon_triangle@3x.png in Resources */, + 4EAAD09E1E5D8558008AA957 /* mrpr_icon_arrow@3x.png in Resources */, + B16E6CEF20C147490076026D /* team_bg@2x.png in Resources */, + B1C871BA1EB338FD003DACF0 /* comment_bg@3x.png in Resources */, 8E8F7B2C19EF6306006BA8BD /* btn_followed_both@2x.png in Resources */, 13FB5D421CA17A6400EE127C /* PR_refuse@3x.png in Resources */, + 4E80E9311DFFF06E00DE1BC6 /* shortcut_tweet@2x.png in Resources */, + B14689B51EE100B200B01371 /* vip_3_30@3x.png in Resources */, 4E0849841A918A7F00BD27F6 /* coding_emoji_42@2x.png in Resources */, 8E97CEB61A0C7E26006F9AD7 /* coding_emoji_31@2x.png in Resources */, - 4E095A7D1B6B1E40008DC439 /* calendar_0xB5B5B5@2x.png in Resources */, 4ED4B48F1D82646100EED8C6 /* user_info_setup@2x.png in Resources */, + B1C871841EB18599003DACF0 /* calendar_0xF56061@3x.png in Resources */, + 4E9423DE1E69401B0095F1CD /* blankpage_image_File@2x.png in Resources */, + B16E6D9C20C148E50076026D /* icon_user_monkey_i6@2x.png in Resources */, + B16E6D8C20C148E50076026D /* intro_icon_1@2x.png in Resources */, + B1C8718F1EB1E608003DACF0 /* icon_add_comment@3x.png in Resources */, 4EACB4431A2C45300097ABB3 /* button_file_download_enable@2x.png in Resources */, - D0FE4DB81C103FA0006E5A76 /* git_icon_fork_old@2x.png in Resources */, 8E97CE691A0A3424006F9AD7 /* keyboard_page_selected@2x.png in Resources */, + B15C98B020D39CA200DDA425 /* project_icon_edit@2x.png in Resources */, + B1C8716C1EB182C7003DACF0 /* taskPriority3@3x.png in Resources */, + B177F5C92060E6B1006709C2 /* code.html in Resources */, + B16EEF08208DDBB6005ABFD5 /* timeline_icon_read@3x.png in Resources */, + B1C871B31EB2D9F0003DACF0 /* file_activity_icon_delete_history@3x.png in Resources */, 4E6383DB1B3266C200D98648 /* mrpr_icon_commit@2x.png in Resources */, + B1BFC4B720B2ACEE009427FC /* editBoardList@2x.png in Resources */, + B16E6D8720C148E50076026D /* intro_icon_5@2x.png in Resources */, D0C447C51C02DB5400DC1C4B /* pop_User@2x.png in Resources */, 8E97CE611A0A3424006F9AD7 /* keyboard_add_photo@2x.png in Resources */, 4EAECBC61C44CB860096CA74 /* member_cell_edit_type@2x.png in Resources */, + B1890C322015D82600F52ABA /* wiki_menu_icon_delete@2x.png in Resources */, 4E93F23B1B84356500017916 /* file_menu_icon_edit@2x.png in Resources */, + B19D4EEB1F6FAA6000C598F3 /* AboutPointViewController.xib in Resources */, 8E1C3DF619E7F4CA00EF3032 /* address.json in Resources */, + 4E80E9391E01218300DE1BC6 /* reward_tip_logo@3x.png in Resources */, + B17CC32B2073212E0077C956 /* code_release_resource_ProjectFile@2x.png in Resources */, 4E09DCAA1C15662E001C9392 /* share_Nav@3x.png in Resources */, + B16E6D9520C148E50076026D /* intro_page0_ip4@2x.png in Resources */, + B1BFC4C420B2B250009427FC /* task_activity_icon_add_milestone@2x.png in Resources */, 4E2BF3D01B96CDF800A5A0A8 /* share_btn_copylink@2x.png in Resources */, - 4EF17ED41B3C3112003CDD2D /* intro_icon_2@3x.png in Resources */, + B1817EF82069186E00E9BAD1 /* project_item_branch@3x.png in Resources */, 7E8E597F1B6F91C40083CA02 /* bubble_left_play_0@2x.png in Resources */, + B1C871581EB0884A003DACF0 /* little_phone_icon@3x.png in Resources */, + B16E6D9720C148E50076026D /* intro_page_selected@3x.png in Resources */, + B16E6D7720C148E50076026D /* intro_tip_0@2x.png in Resources */, 4E96E7E11A1B537E0037C098 /* icon_file_ppt@2x.png in Resources */, 4E2F6A6E1C43CA4B00A25502 /* member_type_75@2x.png in Resources */, D0C448141C02F76600DC1C4B /* icon_search_searchbar@2x.png in Resources */, + B16E6CE920C145BF0076026D /* quick_menu_icon_project@2x.png in Resources */, 4EC480111C2A909D005F1772 /* register_step_ed@2x.png in Resources */, D0C447E01C02DB8900DC1C4B /* project_normal@3x.png in Resources */, + B11DC7C020245728004E76A9 /* button_terminal@2x.png in Resources */, D0C447A51C02A3C700DC1C4B /* privatemessage_normal@2x.png in Resources */, 8EA6D19819E240C40076D59C /* tipIcon_ProjectMember@2x.png in Resources */, + B19D4EE11F690F5E00C598F3 /* file_activity_icon_rename@2x.png in Resources */, + B17CC32E2073212E0077C956 /* code_release_resource_ProjectTopic@2x.png in Resources */, 8E97CEA81A0C7E26006F9AD7 /* coding_emoji_17@2x.png in Resources */, 4E6383B91B32640900D98648 /* messageLeft_bg_img@2x.png in Resources */, + 4E80E95A1E02911E00DE1BC6 /* search_icon_project@2x.png in Resources */, + 4EAAD02B1E5405B4008AA957 /* mrpr_icon_status_cancel@2x.png in Resources */, + 4EAAD02C1E5405B4008AA957 /* mrpr_icon_status_cancel@3x.png in Resources */, + B1AB5CB1202D7D500075A669 /* button_file_createFolder_enable@3x.png in Resources */, + B16E6CAF20C13BF50076026D /* btn_next_unable@2x.png in Resources */, 13FB5D471CA17A6400EE127C /* PR_mergeChanges@2x.png in Resources */, + B16E6CB120C13BF50076026D /* btn_next_unable@3x.png in Resources */, 8E97CEAB1A0C7E26006F9AD7 /* coding_emoji_20@2x.png in Resources */, - 8EA6D1AA19E240C40076D59C /* Images.xcassets in Resources */, 4E63840F1B34124000D98648 /* task_icon_arrow@2x.png in Resources */, 4E6383C71B3265DC00D98648 /* mrpr_icon_refaused@2x.png in Resources */, + B16E6D8620C148E50076026D /* intro_tip_3@2x.png in Resources */, 8ED2AAFB19F60D5200607A1D /* loading_monkey@2x.png in Resources */, 8E97CE981A0C7E26006F9AD7 /* coding_emoji_01@2x.png in Resources */, + B1C871661EB182C7003DACF0 /* taskPriority0@3x.png in Resources */, + B1C8716B1EB182C7003DACF0 /* taskPriority3_small@3x.png in Resources */, 4EB52F3B1C7C45E700B5EBEA /* taskResourceReference@2x.png in Resources */, 8EA6D19519E240C40076D59C /* tipIcon_MergeRequestBean@2x.png in Resources */, - 4E095A7B1B6B1E40008DC439 /* calendar_0x95B763@2x.png in Resources */, 4E66EE271A28226000DA1B3E /* button_file_denete_enable@2x.png in Resources */, - 4EF17EE01B3C3112003CDD2D /* intro_tip_2@2x.png in Resources */, 4E2719C71AB07ED6006AE214 /* dot_line@2x.png in Resources */, 13FB5D441CA17A6400EE127C /* PR_grant_undo@3x.png in Resources */, + B1280D07200EFEA400DEDF78 /* PR_add_watcher@3x.png in Resources */, 4E2DB34D1BA6AEB4002F27C4 /* coding_emoji_gif_01@2x.png in Resources */, - 4E8F92DF1B67BE3C00033D8F /* icon_user_monkey_i6p@3x.png in Resources */, + B1C871241EADF0FF003DACF0 /* addBtn_Artboard@2x.png in Resources */, + B1C8713C1EADF155003DACF0 /* project_item_wiki@2x.png in Resources */, 4E2F6A701C43CA4B00A25502 /* member_type_90@2x.png in Resources */, 4E5D131B1C11865D00985AEB /* share_btn_inform@2x.png in Resources */, + B1C871271EADF0FF003DACF0 /* back_green_Nav@3x.png in Resources */, 8E64ED8B19EE484A006E99DA /* README.textile in Resources */, + B1280D0A200EFEA400DEDF78 /* PR_del_reviewer@3x.png in Resources */, + B16E6D0320C147770076026D /* team_info_pro@2x.png in Resources */, + B16E6D9820C148E50076026D /* intro_page0_ip6@2x.png in Resources */, + 4E80E95D1E02911E00DE1BC6 /* search_icon_task@3x.png in Resources */, + B1BFC4C720B2B250009427FC /* task_activity_icon_remove_milestone@2x.png in Resources */, + B1C871641EB182C7003DACF0 /* checkbox_unchecked@3x.png in Resources */, 8E97CE9D1A0C7E26006F9AD7 /* coding_emoji_06@2x.png in Resources */, + B12B64281FF33E0100ACFDCC /* button_tip_close@3x.png in Resources */, + 4E9423E81E69401B0095F1CD /* blankpage_image_ShopOrder@2x.png in Resources */, 4E0849821A918A7F00BD27F6 /* coding_emoji_40@2x.png in Resources */, + 4E9423DD1E69401B0095F1CD /* blankpage_image_Default@3x.png in Resources */, + B1C60CAB20C0FC750073D3CA /* Launch Screen_E.xib in Resources */, 4EAECBC21C44CB860096CA74 /* member_cell_edit_alias@2x.png in Resources */, 4E6383BA1B32640900D98648 /* messageRight_bg_img@2x.png in Resources */, - 4E9113AC1A1CB19900AC9431 /* icon_file_state_pause@2x.png in Resources */, + B152ED7C20945378004A6E8A /* project_item_taskboard@2x.png in Resources */, + B1C871901EB1E608003DACF0 /* nav_page_selected@3x.png in Resources */, + B1AB5C9E202953E50075A669 /* terminal_more@3x.png in Resources */, + B1C8718D1EB1E608003DACF0 /* btn_setFrequent@3x.png in Resources */, D0C447E41C02DB8900DC1C4B /* tweet_normal@3x.png in Resources */, 8B3516551B6CF69E0049BC45 /* icon_search_clock@2x.png in Resources */, 4E6383AA1B3262D300D98648 /* taskPriority2@2x.png in Resources */, 4EAE06C31B7B51AF00179F4B /* file_activity_icon_upload_file@2x.png in Resources */, 4ECEF9FC1D1D0B3D002A27D3 /* tip_normal_Nav@2x.png in Resources */, + 4E80E9561E02911E00DE1BC6 /* search_icon_user@2x.png in Resources */, 4E66EE281A28226000DA1B3E /* button_file_denete_unable@2x.png in Resources */, + B1C871911EB1E608003DACF0 /* nav_page_unselected@3x.png in Resources */, 8E97CE4A1A0A2E11006F9AD7 /* EmojisList.plist in Resources */, 8BDF9AB51B7474990093BF2C /* keyboard_topic@2x.png in Resources */, + B1817EF92069186E00E9BAD1 /* project_item_tag@3x.png in Resources */, 4EBFBD181AA85B8500E4B10E /* add_user_icon@2x.png in Resources */, 8E97CEA21A0C7E26006F9AD7 /* coding_emoji_11@2x.png in Resources */, 4E2DB3471BA6AEB4002F27C4 /* coding_emoji_gif_02@2x.png in Resources */, + B16E6D7F20C148E50076026D /* intro_tip_4@2x.png in Resources */, 4E996C061ABBF56A00C704F1 /* n_sex_woman_icon@2x.png in Resources */, + B14689BD1EE100B200B01371 /* vip_4_30@3x.png in Resources */, + B1C871451EADF1C1003DACF0 /* taskPriority@3x.png in Resources */, 4EB862AD1CABB21E008074D1 /* tipIcon_TeamMember@2x.png in Resources */, 8E97CE651A0A3424006F9AD7 /* keyboard_emotion_delete@2x.png in Resources */, 8EA6D16C19E240C40076D59C /* nav_tweet_friend@2x.png in Resources */, 8EA6D16E19E240C40076D59C /* nav_tweet_mine@2x.png in Resources */, + 4E80E92E1DFFF06E00DE1BC6 /* shortcut_2FA@3x.png in Resources */, 13FB5D371CA17A6400EE127C /* PR_add@3x.png in Resources */, + B17CC31E20731FF10077C956 /* code_release_resource_Zip@3x.png in Resources */, + B152ED94209453F3004A6E8A /* taskboard_add_page_unselected@3x.png in Resources */, + 4E9423DB1E69401B0095F1CD /* blankpage_image_Activity@3x.png in Resources */, D0C447D01C02DB6700DC1C4B /* pop_Tweet@3x.png in Resources */, - 4E6B07111BA3D9B5007D6027 /* intro_page1_ip4@2x.png in Resources */, - 4E095A7C1B6B1E40008DC439 /* calendar_0x9AAFC2@2x.png in Resources */, - 4EF17EDE1B3C3112003CDD2D /* intro_tip_1@2x.png in Resources */, + 4EAAD0831E55AC6E008AA957 /* icon_code_image@3x.png in Resources */, + B152ED8F209453F3004A6E8A /* taskboard_normal_page_selected@3x.png in Resources */, + B16E6D9020C148E50076026D /* intro_tip_5@2x.png in Resources */, + B1BCB8861FCD006C0098B87B /* icon_file_txt_big@2x.png in Resources */, 4E4D6ACB1B2571B100FD2E49 /* git_icon_stared@2x.png in Resources */, + 4E80E9541E02911E00DE1BC6 /* search_icon_mr@2x.png in Resources */, 4ED20A7A1AFCC43600C63498 /* button_download_cancel@2x.png in Resources */, 4E217F0D1A70EDC700F6DF88 /* SVWebViewController.bundle in Resources */, 4EC480121C2A909D005F1772 /* register_step_ed@3x.png in Resources */, - 4E38CF641A7B8DD4005536C0 /* icon_triangle@2x.png in Resources */, - 4E1D99191DCAE67D00BAE585 /* icon_file_folder_share@3x.png in Resources */, + 4E9DEEC61E30CA3C001B8D1B /* keyboard_emotion_emoji_code@2x.png in Resources */, + B1C871511EADF48B003DACF0 /* cell_arrow_left@3x.png in Resources */, + B14689B61EE100B200B01371 /* vip_3_40@2x.png in Resources */, + 4EAAD0571E542B2D008AA957 /* icon_code_git_link@2x.png in Resources */, 4E4D6AC81B252F4800FD2E49 /* icon_add_comment@2x.png in Resources */, - 4E0022A71B7362EF005308DE /* intro_page0_ip5@2x.png in Resources */, + B1BCB8851FCD006C0098B87B /* icon_file_code_big@2x.png in Resources */, + B1280CF0200EFDC600DEDF78 /* file_changeType_DELETE@3x.png in Resources */, 8E872D0019EFEFF7002C8F34 /* tweet_more_comment_icon@2x.png in Resources */, 4E3DB53C1BFDD0F40062BA52 /* task_activity_icon_add_watcher@2x.png in Resources */, 8EA6D1A019E240C40076D59C /* tipIcon_TweetLike@2x.png in Resources */, + 4E9423E01E69401B0095F1CD /* blankpage_image_LoadFail@2x.png in Resources */, 4E72F8331B15B811001B6CE6 /* gif_mark@2x.png in Resources */, 4EC5AD921A258DF8006FA97C /* icon_file_cell_delete@2x.png in Resources */, + 4E9423F01E69401B0095F1CD /* blankpage_image_Topic@2x.png in Resources */, 8EA6D1F719E240C40076D59C /* MJPhotoBrowser.bundle in Resources */, 4E1D99181DCAE67D00BAE585 /* icon_file_folder_share@2x.png in Resources */, + 4E80E9591E02911E00DE1BC6 /* search_icon_pr@3x.png in Resources */, 4E217F121A70EDC700F6DF88 /* SVWebViewControllerActivityChrome@2x.png in Resources */, + B152ED93209453F3004A6E8A /* taskboard_add_page_selected@3x.png in Resources */, 4E217F161A70EDC700F6DF88 /* SVWebViewControllerActivitySafari@2x.png in Resources */, - 4EF17EE21B3C3112003CDD2D /* intro_tip_3@2x.png in Resources */, + B1BFC4B620B2ACEE009427FC /* editBoardList@3x.png in Resources */, 13FB5D361CA17A6400EE127C /* PR_add@2x.png in Resources */, 4E5D130F1C0ECB3400985AEB /* tweet_btn_reward@2x.png in Resources */, 4E6383D51B32665700D98648 /* project_item_mr_pr@2x.png in Resources */, @@ -6413,131 +10162,1185 @@ D0C447B41C02B1DE00DC1C4B /* btn_fliter_down@2x.png in Resources */, 8EA6D16719E240C40076D59C /* nav_project_activity@2x.png in Resources */, 4EFE8DAD1B394A0D004B7559 /* file_changeType_RENAME@2x.png in Resources */, + 4E9423EF1E69401B0095F1CD /* blankpage_image_Tip@3x.png in Resources */, + B16E6CC020C13F5F0076026D /* btn_project_added@3x.png in Resources */, + B16E6CE320C145BF0076026D /* quick_menu_icon_project@3x.png in Resources */, B9A00D7F1ACA3A05008BA008 /* ProjectSetting.storyboard in Resources */, + B1817F002069197D00E9BAD1 /* icon_release_tag@3x.png in Resources */, 8EA6D19219E240C40076D59C /* timeline_icon_unread@2x.png in Resources */, 4E54C24B1D8FE19100A61023 /* user_info_edit@2x.png in Resources */, + B19D4EFB1F7247BA00C598F3 /* AlipaySDK.bundle in Resources */, 4E095A6D1B69F920008DC439 /* banner__page_selected@2x.png in Resources */, - 4EB52F2F1C77138A00B5EBEA /* button_scan@3x.png in Resources */, 4EB52F5D1C7C5C4F00B5EBEA /* task_resource_reference_MergeRequestBean@3x.png in Resources */, 4E86FEE51BB556D6005E53F3 /* tipIcon_ProjectFileComment@2x.png in Resources */, 4E217F141A70EDC700F6DF88 /* SVWebViewControllerActivitySafari-iPad@2x.png in Resources */, 4EF91F641B00B62B0021C951 /* icon_not_locationed@2x.png in Resources */, 4E6383EA1B32791600D98648 /* checkbox_unchecked@2x.png in Resources */, + B1BCB8801FCD006C0098B87B /* icon_file_psd_big@2x.png in Resources */, 8EA6D19119E240C40076D59C /* timeline_icon_read@2x.png in Resources */, + B184166920513CA100207666 /* topic_add_watcher_btn@3x.png in Resources */, 8E97CEB21A0C7E26006F9AD7 /* coding_emoji_27@2x.png in Resources */, + B12B64751FFB61AD00ACFDCC /* QBImagePicker.strings in Resources */, + B1BCB87E1FCD006C0098B87B /* icon_file_zip_big@2x.png in Resources */, + B1C8711A1EADF0B1003DACF0 /* messageProjectFollows@3x.png in Resources */, 4E4972E21BB5395B00F3AC15 /* tipIcon_CommitLineNote@2x.png in Resources */, + B1890C2E2015D82600F52ABA /* wiki_revert@2x.png in Resources */, + 4E80E94F1E02911E00DE1BC6 /* search_icon_tweet@3x.png in Resources */, + B1C871651EB182C7003DACF0 /* taskPriority0_small@3x.png in Resources */, 8E97CEAF1A0C7E26006F9AD7 /* coding_emoji_24@2x.png in Resources */, - 13FB5D401CA17A6400EE127C /* EPointLikeHead@3x.png in Resources */, 13FB5D4A1CA17A6400EE127C /* PointLikeHead@2x.png in Resources */, 8E97CEA11A0C7E26006F9AD7 /* coding_emoji_10@2x.png in Resources */, D0C447A31C02A3C700DC1C4B /* me_normal@2x.png in Resources */, + B1C8716A1EB182C7003DACF0 /* taskPriority2@3x.png in Resources */, + 4E9423DA1E69401B0095F1CD /* blankpage_image_Activity@2x.png in Resources */, 8E97CEB81A0C7E26006F9AD7 /* coding_emoji_33@2x.png in Resources */, - 4EB5A9441BF1DB4600C23AC3 /* WeiboSDK.bundle in Resources */, + B16E6D7C20C148E50076026D /* intro_icon_0@2x.png in Resources */, 8E97CEAE1A0C7E26006F9AD7 /* coding_emoji_23@2x.png in Resources */, 4E6383E11B32676600D98648 /* taskPriority@2x.png in Resources */, + B17CC3292073212E0077C956 /* code_release_resource_ProjectFile@3x.png in Resources */, 8EA6D19D19E240C40076D59C /* tipIcon_Task@2x.png in Resources */, + 4EAAD0551E542B2D008AA957 /* icon_code_file@2x.png in Resources */, 4E6384001B33C18700D98648 /* task_activity_icon_update_description@2x.png in Resources */, D09E6AC21BF84AC5009D37F8 /* git_icon_star@2x.png in Resources */, 4E095A831B6B24DE008DC439 /* task_description_icon@2x.png in Resources */, 4EB52F201C76BA3B00B5EBEA /* tag_button_editColor@3x.png in Resources */, D0C447F91C02DCA200DC1C4B /* moreBtn_Nav@2x.png in Resources */, 4EFE8DB91B3A5727004B7559 /* Launch Screen.xib in Resources */, - 4EF17ECC1B3C3112003CDD2D /* intro_dot_selected@3x.png in Resources */, 8E97CEAA1A0C7E26006F9AD7 /* coding_emoji_19@2x.png in Resources */, + B16E6D1B20C147770076026D /* team_cell_edit_pro@2x.png in Resources */, 13FB5D521CA17A6400EE127C /* PR_review_undo@3x.png in Resources */, - 4E90F89D1AF709C100B44F03 /* markdown.html in Resources */, + B1C871681EB182C7003DACF0 /* taskPriority1@3x.png in Resources */, + B1BCB89A1FCE93830098B87B /* alipay@3x.png in Resources */, 134116F11CB529E1005E6550 /* PR_more@3x.png in Resources */, 4E2BF3D51B96CDF800A5A0A8 /* share_btn_wxsession@2x.png in Resources */, 4E3DB53D1BFDD0F40062BA52 /* task_activity_icon_MergeRequestBean@2x.png in Resources */, 4E96E7E31A1B537E0037C098 /* icon_file_txt@2x.png in Resources */, - 927AFF551BFF6DAD00AAE593 /* shop_unexchange_icon@3x.png in Resources */, + B1C871381EADF155003DACF0 /* project_item_member@3x.png in Resources */, 8EA6D19419E240C40076D59C /* timeline_line_unread@2x.png in Resources */, 4E94C4F11B4B75DB00EB668A /* tip_2FA@2x.png in Resources */, + B1280CFF200EFEA400DEDF78 /* PR_add_label@3x.png in Resources */, + B1C871281EADF0FF003DACF0 /* back_T_Nav@2x.png in Resources */, + B1C871631EB182C7003DACF0 /* checkbox_checked@3x.png in Resources */, 8E97CE9C1A0C7E26006F9AD7 /* coding_emoji_05@2x.png in Resources */, - 4E095A171D9534CB00E63D9E /* intro_page_unselected@2x.png in Resources */, + B1BCB8991FCE93830098B87B /* alipay@2x.png in Resources */, 4E6383A61B3262D300D98648 /* taskPriority0@2x.png in Resources */, 4E0EF6EC1BF42E4B00F2FCC8 /* task_activity_icon_update_label@2x.png in Resources */, + B1890C2A2015D82600F52ABA /* wiki_menu_2@3x.png in Resources */, + 4E9423EE1E69401B0095F1CD /* blankpage_image_Tip@2x.png in Resources */, 8E97CE621A0A3424006F9AD7 /* keyboard_add_camera@2x.png in Resources */, D0C447E91C02DBC200DC1C4B /* btn_fliter_down@3x.png in Resources */, - 4EAE06C51B7B587200179F4B /* button_file_comment@2x.png in Resources */, + B177F5C82060E6B1006709C2 /* topic-ios.html in Resources */, 4ED4B4891D82646100EED8C6 /* user_info_help@2x.png in Resources */, 4E217F131A70EDC700F6DF88 /* SVWebViewControllerActivitySafari-iPad.png in Resources */, + 4EAAD05B1E544006008AA957 /* icon_triangle@2x.png in Resources */, 8EF6435019FF4E1600F7EEB0 /* comment_count_top_line@2x.png in Resources */, 7E335D9E1B6F5E94003D0F3D /* keyboard_voice_record@2x.png in Resources */, + B1BCB8871FCD006C0098B87B /* icon_file_music_big@2x.png in Resources */, 4EB52F111C74691B00B5EBEA /* password_unlook@2x.png in Resources */, 4E2DB3481BA6AEB4002F27C4 /* coding_emoji_gif_03@2x.png in Resources */, - 4E6B07141BA3D9B5007D6027 /* intro_page1_ip6+@3x.png in Resources */, + 4EAAD09D1E5D8558008AA957 /* mrpr_icon_arrow@2x.png in Resources */, + B14689B91EE100B200B01371 /* vip_3_45@3x.png in Resources */, 8EA6D18219E240C40076D59C /* splitlineImg@2x.png in Resources */, + B1AB5CB9202D7D500075A669 /* button_file_move_enable@3x.png in Resources */, + B1890C292015D82600F52ABA /* wiki_menu_0@2x.png in Resources */, + B17CC31420731E950077C956 /* icon_release_tag_blue@3x.png in Resources */, + 4E80E9501E02911E00DE1BC6 /* search_icon_topic@2x.png in Resources */, + B16E6D8120C148E50076026D /* intro_icon_0@3x.png in Resources */, 4E2BF3BC1B957D4F00A5A0A8 /* file_activity_icon_delete_history@2x.png in Resources */, + B1BCB8811FCD006C0098B87B /* icon_file_unknown_big@2x.png in Resources */, 8EA6D18119E240C40076D59C /* sex_woman_icon@2x.png in Resources */, D0C447DF1C02DB8900DC1C4B /* privatemessage_selected@3x.png in Resources */, + B16E6CE120C145BF0076026D /* quick_menu_icon_task@2x.png in Resources */, 8E7612F41A08B1EA005BE797 /* tipIcon_TaskComment@2x.png in Resources */, 4E6383E01B32676600D98648 /* taskDeadline@2x.png in Resources */, 136526891CAABA2E00C0341D /* AddReviewerViewController.xib in Resources */, 927AFF511BFF6DAD00AAE593 /* shop_exchange_icon@3x.png in Resources */, - 4E8F92DE1B67BE3C00033D8F /* icon_user_monkey_i6@2x.png in Resources */, + B14689B71EE100B200B01371 /* vip_3_40@3x.png in Resources */, 4EAE06A71B7B1AE100179F4B /* button_file_activity@2x.png in Resources */, 4EAE06C21B7B51AF00179F4B /* file_activity_icon_update_file@2x.png in Resources */, 8EC911291A027A54009EAE99 /* nav_project_code@2x.png in Resources */, 4ED4B48E1D82646100EED8C6 /* user_info_project@3x.png in Resources */, + B152ED84209453E8004A6E8A /* taskBoardList@2x.png in Resources */, 4E2DB33D1BA6A1FC002F27C4 /* coding_emoji_gif_08@2x.png in Resources */, D09E6ABA1BF829A1009D37F8 /* icon_project_private@2x.png in Resources */, D0C447FA1C02DCA200DC1C4B /* search_Nav@2x.png in Resources */, - 4E6383C41B3265DC00D98648 /* mrpr_icon_arrow@2x.png in Resources */, + B1AB5CA1202953E50075A669 /* terminal_box_selected@3x.png in Resources */, 4EED9DD11B53BBCF000E5827 /* twoFABtn_Nav@2x.png in Resources */, + B16E6CDD20C145BF0076026D /* quick_menu_icon_message@3x.png in Resources */, D0C447E11C02DB8900DC1C4B /* project_selected@3x.png in Resources */, + B1C871A41EB2D9E6003DACF0 /* task_activity_icon_MergeRequestBean@3x.png in Resources */, D0C447E51C02DB8900DC1C4B /* tweet_selected@3x.png in Resources */, 4E6383AC1B3262D300D98648 /* taskPriority3@2x.png in Resources */, + 4E80E9521E02911E00DE1BC6 /* search_icon_file@2x.png in Resources */, 4E53EB5A1AFB090E0034FE1C /* nav_page_unselected@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; + B1D5EE7520BC06CB00983FB6 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B1D5EE7620BC06CB00983FB6 /* hot_topic_Nav@2x.png in Resources */, + B1D5EE7720BC06CB00983FB6 /* keyboard_add@2x.png in Resources */, + B1D5EE7820BC06CB00983FB6 /* register_step_un@2x.png in Resources */, + B1D5EE7920BC06CB00983FB6 /* task_activity_icon_restore@2x.png in Resources */, + B1D5EE7A20BC06CB00983FB6 /* tipIcon_tweetReward@2x.png in Resources */, + B1D5EE7B20BC06CB00983FB6 /* icon_file_folder_normal@2x.png in Resources */, + B1D5EE7C20BC06CB00983FB6 /* taskboard_add_page_selected@2x.png in Resources */, + B1D5EE7D20BC06CB00983FB6 /* time_clock_icon@3x.png in Resources */, + B1D5EE7E20BC06CB00983FB6 /* task_activity_icon_add_watcher@3x.png in Resources */, + B1D5EE7F20BC06CB00983FB6 /* tipIcon_ProjectTopic@2x.png in Resources */, + B1D5EE8020BC06CB00983FB6 /* SVWebViewControllerActivityReport@2x.png in Resources */, + B16E6DD920C149440076026D /* intro_page1_ip5@2x.png in Resources */, + B1D5EE8120BC06CB00983FB6 /* wiki_menu_icon_share@2x.png in Resources */, + B16E6DDA20C149440076026D /* intro_page_unselected@3x.png in Resources */, + B1D5EE8220BC06CB00983FB6 /* InfoPlist.strings in Resources */, + B1D5EE8320BC06CB00983FB6 /* mrpr_icon_accepted@2x.png in Resources */, + B1D5EE8420BC06CB00983FB6 /* mrpr_icon_status_refused@2x.png in Resources */, + B1D5EE8520BC06CB00983FB6 /* privatemessage_normal@3x.png in Resources */, + B16E6DD420C149440076026D /* intro_page2_ip5@2x.png in Resources */, + B1D5EE8620BC06CB00983FB6 /* btn_project_added@2x.png in Resources */, + B1D5EE8720BC06CB00983FB6 /* nav_tweet_all@2x.png in Resources */, + B1D5EE8820BC06CB00983FB6 /* button_file_createFolder_unable@2x.png in Resources */, + B1D5EE8920BC06CB00983FB6 /* button_file_denete_unable@3x.png in Resources */, + B1D5EE8A20BC06CB00983FB6 /* file_activity_icon_upload_file@3x.png in Resources */, + B1D5EE8B20BC06CB00983FB6 /* QBImagePicker.storyboard in Resources */, + B16E6CBF20C13F5F0076026D /* btn_project_add@3x.png in Resources */, + B1D5EE8C20BC06CB00983FB6 /* taskProject@2x.png in Resources */, + B1D5EE8E20BC06CB00983FB6 /* button_file_upload_enable@3x.png in Resources */, + B1D5EE8F20BC06CB00983FB6 /* tag_button_randomColor@3x.png in Resources */, + B1D5EE9020BC06CB00983FB6 /* user_info_help@3x.png in Resources */, + B1D5EE9120BC06CB00983FB6 /* messageComment@2x.png in Resources */, + B1D5EE9220BC06CB00983FB6 /* upgrade_success@3x.png in Resources */, + B1D5EE9320BC06CB00983FB6 /* tweet_comment_btn@2x.png in Resources */, + B1D5EE9420BC06CB00983FB6 /* fliter_square@2x.png in Resources */, + B1D5EE9520BC06CB00983FB6 /* PR_create@2x.png in Resources */, + B1D5EE9620BC06CB00983FB6 /* user_info_tweet@3x.png in Resources */, + B1D5EE9720BC06CB00983FB6 /* taskPriority2_small@2x.png in Resources */, + B1D5EE9820BC06CB00983FB6 /* pop_2FA@3x.png in Resources */, + B1D5EE9920BC06CB00983FB6 /* code_release_resource_Zip@2x.png in Resources */, + B1D5EE9A20BC06CB00983FB6 /* topic_add_watcher_btn@2x.png in Resources */, + B1D5EE9B20BC06CB00983FB6 /* bubble_right_play_1@2x.png in Resources */, + B1D5EE9C20BC06CB00983FB6 /* search_tweet_colck@2x.png in Resources */, + B1D5EE9D20BC06CB00983FB6 /* keyboard_page_unselected@2x.png in Resources */, + B16E6DC820C1493A0076026D /* intro_icon_wiki_down.gif in Resources */, + B1D5EE9E20BC06CB00983FB6 /* blankpage_image_Project@2x.png in Resources */, + B1D5EEA020BC06CB00983FB6 /* PR_more@2x.png in Resources */, + B1D5EEA120BC06CB00983FB6 /* user_info_edit@3x.png in Resources */, + B1D5EEA220BC06CB00983FB6 /* file_changeType_MODIFY@3x.png in Resources */, + B1D5EEA320BC06CB00983FB6 /* icon_file_apk@2x.png in Resources */, + B1D5EEA420BC06CB00983FB6 /* n_btn_followed_both@2x.png in Resources */, + B15C98AD20D39C4B00DDA425 /* NewProject.storyboard in Resources */, + B1D5EEA520BC06CB00983FB6 /* messageSystem@2x.png in Resources */, + B1D5EEA620BC06CB00983FB6 /* PR_del_watcher@2x.png in Resources */, + B1D5EEA720BC06CB00983FB6 /* taskWatchers@3x.png in Resources */, + B1D5EEA820BC06CB00983FB6 /* mrpr_icon_status_canmerge@3x.png in Resources */, + B1D5EEA920BC06CB00983FB6 /* topic_comment_icon@2x.png in Resources */, + B1D5EEAA20BC06CB00983FB6 /* project_item_activity@3x.png in Resources */, + B1D5EEAB20BC06CB00983FB6 /* member_type_75@3x.png in Resources */, + B1D5EEAC20BC06CB00983FB6 /* bubble_right_play_2@2x.png in Resources */, + B1D5EEAD20BC06CB00983FB6 /* share_btn_coding@2x.png in Resources */, + B1D5EEAE20BC06CB00983FB6 /* commentOrLikeBeginImg@2x.png in Resources */, + B1D5EEAF20BC06CB00983FB6 /* task_resource_reference_ProjectFile@3x.png in Resources */, + B1D5EEB020BC06CB00983FB6 /* PR_mergeChanges@3x.png in Resources */, + B1D5EEB120BC06CB00983FB6 /* user_info_shop@2x.png in Resources */, + B1D5EEB220BC06CB00983FB6 /* ReviewCell.xib in Resources */, + B1D5EEB320BC06CB00983FB6 /* login_suffix@2x.png in Resources */, + B1D5EEB420BC06CB00983FB6 /* password_look@3x.png in Resources */, + B1D5EEB520BC06CB00983FB6 /* emotion_list.plist in Resources */, + B1D5EEB620BC06CB00983FB6 /* wiki_menu_1@3x.png in Resources */, + B1D5EEB720BC06CB00983FB6 /* file_changeType_ADD@2x.png in Resources */, + B16E6DD220C149440076026D /* intro_page1_ip6@2x.png in Resources */, + B16E6DC120C1492F0076026D /* intro_dot_dark_selected@3x.png in Resources */, + B1D5EEB820BC06CB00983FB6 /* icon_best_answer@2x.png in Resources */, + B16E6DCC20C1493A0076026D /* intro_icon_task_up.gif in Resources */, + B1D5EEB920BC06CB00983FB6 /* git_icon_watched@2x.png in Resources */, + B1D5EEBA20BC06CB00983FB6 /* coding_emoji_26@2x.png in Resources */, + B1D5EEBB20BC06CB00983FB6 /* coding_emoji_35@2x.png in Resources */, + B1D5EEBC20BC06CB00983FB6 /* task_activity_icon_update_description@3x.png in Resources */, + B1D5EEBD20BC06CB00983FB6 /* vip_4_40@3x.png in Resources */, + B1D5EEBE20BC06CB00983FB6 /* keyboard_keyboard@2x.png in Resources */, + B1D5EEBF20BC06CB00983FB6 /* icon_release_tag@2x.png in Resources */, + B1D5EEC020BC06CB00983FB6 /* placeholder_monkey_round_48@2x.png in Resources */, + B1D5EEC120BC06CB00983FB6 /* PR_plus@2x.png in Resources */, + B1D5EEC220BC06CB00983FB6 /* xtsegment_bordor_left@2x.png in Resources */, + B1D5EEC320BC06CB00983FB6 /* task_resource_reference_MergeRequestBean@2x.png in Resources */, + B1D5EEC420BC06CB00983FB6 /* icon_file_folder_out@2x.png in Resources */, + B1D5EEC520BC06CB00983FB6 /* messageProjectFollows@2x.png in Resources */, + B1D5EEC620BC06CB00983FB6 /* tweet_btn_comment@2x.png in Resources */, + B1D5EEC720BC06CB00983FB6 /* blankpage_image_ShopOrder@3x.png in Resources */, + B1D5EEC820BC06CB00983FB6 /* banner__page_unselected@2x.png in Resources */, + B1D5EEC920BC06CB00983FB6 /* mrpr_icon_status_accepted@2x.png in Resources */, + B1D5EECA20BC06CB00983FB6 /* icon_file_ai@2x.png in Resources */, + B1D5EECB20BC06CB00983FB6 /* PR_plus@3x.png in Resources */, + B16E6DC420C149350076026D /* intro_dot_light_unselected@2x.png in Resources */, + B1D5EECC20BC06CB00983FB6 /* user_info_tweet@2x.png in Resources */, + B1D5EECD20BC06CB00983FB6 /* coding_emoji_21@2x.png in Resources */, + B1D5EECE20BC06CB00983FB6 /* bubble_left_play_2@2x.png in Resources */, + B1D5EECF20BC06CB00983FB6 /* task_resource_reference_Task@3x.png in Resources */, + B1D5EED020BC06CB00983FB6 /* PR_add_watcher@2x.png in Resources */, + B1D5EED120BC06CB00983FB6 /* file_menu_icon_delete@2x.png in Resources */, + B1D5EED220BC06CB00983FB6 /* button_red_close@3x.png in Resources */, + B1D5EED320BC06CB00983FB6 /* PR_merge@3x.png in Resources */, + B16E6DD320C149440076026D /* intro_page1_ip4@2x.png in Resources */, + B1D5EED420BC06CB00983FB6 /* coding_emoji_25@2x.png in Resources */, + B1D5EED520BC06CB00983FB6 /* keyboard_arrow_down@2x.png in Resources */, + B1D5EED620BC06CB00983FB6 /* taskResourceReference@3x.png in Resources */, + B1D5EED720BC06CB00983FB6 /* tag_button_add@2x.png in Resources */, + B16E6CC120C13F5F0076026D /* btn_project_added@3x.png in Resources */, + B1D5EED820BC06CB00983FB6 /* tweetsBtn_Nav@3x.png in Resources */, + B1D5EED920BC06CB00983FB6 /* icon_branch_protected@2x.png in Resources */, + B1D5EEDA20BC06CB00983FB6 /* taskboard_normal_page_selected@2x.png in Resources */, + B1D5EEDB20BC06CB00983FB6 /* user_info_about@2x.png in Resources */, + B1D5EEDC20BC06CB00983FB6 /* icon_branch_protected@3x.png in Resources */, + B1D5EEDE20BC06CB00983FB6 /* task_activity_icon_create@2x.png in Resources */, + B1D5EEDF20BC06CB00983FB6 /* button_file_download_unable@2x.png in Resources */, + B1D5EEE020BC06CB00983FB6 /* btn_setFrequent@2x.png in Resources */, + B1D5EEE120BC06CB00983FB6 /* task_activity_icon_remove_watcher@3x.png in Resources */, + B1D5EEE220BC06CB00983FB6 /* markdown.html in Resources */, + B1D5EEE320BC06CB00983FB6 /* code_release_resource_ProjectTopic@3x.png in Resources */, + B1D5EEE420BC06CB00983FB6 /* diff-ios.html in Resources */, + B1D5EEE520BC06CB00983FB6 /* little_phone_icon@2x.png in Resources */, + B1D5EEE620BC06CB00983FB6 /* share_btn_sina@2x.png in Resources */, + B1D5EEE820BC06CB00983FB6 /* icon_file_pdf@2x.png in Resources */, + B16E6DD120C149440076026D /* intro_page2_ip6+@3x.png in Resources */, + B1D5EEE920BC06CB00983FB6 /* tipIcon_TweetComment@2x.png in Resources */, + B1D5EEEA20BC06CB00983FB6 /* blankpage_image_LoadFail@3x.png in Resources */, + B1D5EEEB20BC06CB00983FB6 /* taskboard_add_page_unselected@2x.png in Resources */, + B1D5EEEC20BC06CB00983FB6 /* PR_grant_undo@2x.png in Resources */, + B1D5EEED20BC06CB00983FB6 /* back_green_Nav@2x.png in Resources */, + B1D5EEEE20BC06CB00983FB6 /* file_changeType_COPY@2x.png in Resources */, + B16E6CF020C147490076026D /* team_bg@2x.png in Resources */, + B1D5EEEF20BC06CB00983FB6 /* shop_exchange_icon@2x.png in Resources */, + B1D5EEF020BC06CB00983FB6 /* timeBtn_Nav@3x.png in Resources */, + B1D5EEF120BC06CB00983FB6 /* close@2x.png in Resources */, + B1D5EEF220BC06CB00983FB6 /* PR_update_content@3x.png in Resources */, + B1D5EEF320BC06CB00983FB6 /* user_info_detail@2x.png in Resources */, + B1D5EEF420BC06CB00983FB6 /* vip_4_45@2x.png in Resources */, + B1D5EEF520BC06CB00983FB6 /* icon_recommended@2x.png in Resources */, + B1D5EEF620BC06CB00983FB6 /* icon_file_doc@2x.png in Resources */, + B1D5EEF720BC06CB00983FB6 /* hot_topic_Nav@3x.png in Resources */, + B1D5EEF820BC06CB00983FB6 /* EACodeReleaseListCell.xib in Resources */, + B1D5EEF920BC06CB00983FB6 /* user_info_setup@3x.png in Resources */, + B1D5EEFA20BC06CB00983FB6 /* tipIcon_ProjectTweet@2x.png in Resources */, + B16E6D1420C147770076026D /* team_cell_edit_team@2x.png in Resources */, + B1D5EEFB20BC06CB00983FB6 /* share_Nav@2x.png in Resources */, + B1D5EEFC20BC06CB00983FB6 /* tipIcon_User@2x.png in Resources */, + B1D5EEFD20BC06CB00983FB6 /* taskPriority0_small@2x.png in Resources */, + B1D5EEFE20BC06CB00983FB6 /* file_changeType_COPY@3x.png in Resources */, + B1D5EEFF20BC06CB00983FB6 /* btn_project_quit@2x.png in Resources */, + B1D5EF0020BC06CB00983FB6 /* member_type_100@2x.png in Resources */, + B1D5EF0120BC06CB00983FB6 /* dismissBtn_Nav@2x.png in Resources */, + B1D5EF0220BC06CB00983FB6 /* coding_emoji_38@2x.png in Resources */, + B1D5EF0320BC06CB00983FB6 /* keyboard_emotion_emoji@2x.png in Resources */, + B1D5EF0420BC06CB00983FB6 /* taskOwner@2x.png in Resources */, + B1D5EF0520BC06CB00983FB6 /* task_activity_icon_commit_refer@2x.png in Resources */, + B1D5EF0620BC06CB00983FB6 /* project_item_file@3x.png in Resources */, + B1D5EF0720BC06CB00983FB6 /* btn_followed_yes@2x.png in Resources */, + B1D5EF0820BC06CB00983FB6 /* btn_project_add@2x.png in Resources */, + B1D5EF0920BC06CB00983FB6 /* project_item_activity@2x.png in Resources */, + B1D5EF0A20BC06CB00983FB6 /* tips_menu_icon_status@2x.png in Resources */, + B1D5EF0B20BC06CB00983FB6 /* task_selected@2x.png in Resources */, + B1D5EF0C20BC06CB00983FB6 /* project_item_code@3x.png in Resources */, + B1D5EF0D20BC06CB00983FB6 /* terminal_tail@2x.png in Resources */, + B1D5EF0E20BC06CB00983FB6 /* PR_add_reviewer@2x.png in Resources */, + B16E6CDE20C145BF0076026D /* quick_menu_icon_message@3x.png in Resources */, + B1D5EF0F20BC06CB00983FB6 /* PR_push@3x.png in Resources */, + B1D5EF1020BC06CB00983FB6 /* shop_coding_coin_icon@3x.png in Resources */, + B1D5EF1220BC06CB00983FB6 /* project_tag_icon@3x.png in Resources */, + B1D5EF1320BC06CB00983FB6 /* code_lang.plist in Resources */, + B1D5EF1420BC06CB00983FB6 /* logo_coding@2x.png in Resources */, + B1D5EF1520BC06CB00983FB6 /* user_info_project@2x.png in Resources */, + B1D5EF1620BC06CB00983FB6 /* button_file_createFolder_unable@3x.png in Resources */, + B1D5EF1720BC06CB00983FB6 /* icon_project_cell_setNormal@2x.png in Resources */, + B1D5EF1820BC06CB00983FB6 /* search_Nav@3x.png in Resources */, + B1D5EF1920BC06CB00983FB6 /* keyboard_emotion_monkey@2x.png in Resources */, + B1D5EF1A20BC06CB00983FB6 /* icon_file_ppt_big@2x.png in Resources */, + B1D5EF1B20BC06CB00983FB6 /* calendar_0xA1CF64@2x.png in Resources */, + B1DFD0A620C67D3F00F75F2F /* btn_followed_both@3x.png in Resources */, + B1D5EF1C20BC06CB00983FB6 /* blankpage_image_File@3x.png in Resources */, + B1D5EF1D20BC06CB00983FB6 /* SVWebViewControllerActivityChrome-iPad.png in Resources */, + B1D5EF1E20BC06CB00983FB6 /* settingBtn_Nav@3x.png in Resources */, + B1D5EF1F20BC06CB00983FB6 /* PR_del_watcher@3x.png in Resources */, + B1D5EF2020BC06CB00983FB6 /* tweet_btn_comment@3x.png in Resources */, + B1D5EF2120BC06CB00983FB6 /* task_activity_icon_update_deadline@3x.png in Resources */, + B1D5EF2220BC06CB00983FB6 /* close@3x.png in Resources */, + B16E6DCA20C1493A0076026D /* intro_icon_file_up.gif in Resources */, + B1D5EF2320BC06CB00983FB6 /* coding_emoji_14@2x.png in Resources */, + B1D5EF2420BC06CB00983FB6 /* taskboard_normal_page_unselected@2x.png in Resources */, + B1D5EF2520BC06CB00983FB6 /* loading_monkey@2x.gif in Resources */, + B16E6CDC20C145BF0076026D /* quick_menu_icon_message@2x.png in Resources */, + B1D5EF2620BC06CB00983FB6 /* search_icon_topic@3x.png in Resources */, + B1D5EF2720BC06CB00983FB6 /* pop_User@3x.png in Resources */, + B1D5EF2820BC06CB00983FB6 /* taskPriority2_small@3x.png in Resources */, + B1D5EF2920BC06CB00983FB6 /* project_tag_btn@3x.png in Resources */, + B1D5EF2A20BC06CB00983FB6 /* task_resource_reference_Task@2x.png in Resources */, + B1D5EF2B20BC06CB00983FB6 /* tips_menu_icon_mkread@2x.png in Resources */, + B1D5EF2C20BC06CB00983FB6 /* coding_emoji_15@2x.png in Resources */, + B1D5EF2D20BC06CB00983FB6 /* shortcut_task@2x.png in Resources */, + B1D5EF2E20BC06CB00983FB6 /* terminal_triangle@2x.png in Resources */, + B1D5EF2F20BC06CB00983FB6 /* topic_comment_icon@3x.png in Resources */, + B1D5EF3020BC06CB00983FB6 /* placeholder_monkey_round_40@2x.png in Resources */, + B1D5EF3120BC06CB00983FB6 /* PR_merge@2x.png in Resources */, + B1D5EF3220BC06CB00983FB6 /* tweet_btn_like@2x.png in Resources */, + B1D5EF3320BC06CB00983FB6 /* PR_update@2x.png in Resources */, + B1D5EF3420BC06CB00983FB6 /* login_email@2x.png in Resources */, + B1D5EF3520BC06CB00983FB6 /* tweetBtn_Nav@3x.png in Resources */, + B1D5EF3620BC06CB00983FB6 /* mrpr_icon_status_refused@3x.png in Resources */, + B1D5EF3720BC06CB00983FB6 /* login_wechat@3x.png in Resources */, + B1D5EF3820BC06CB00983FB6 /* ReleaseNotes.txt in Resources */, + B1D5EF3920BC06CB00983FB6 /* PR_update_content@2x.png in Resources */, + B1D5EF3A20BC06CB00983FB6 /* ReviewerListController.xib in Resources */, + B16E6D0A20C147770076026D /* team_info_sup@2x.png in Resources */, + B1D5EF3B20BC06CB00983FB6 /* file_activity_icon_create@3x.png in Resources */, + B1D5EF3C20BC06CB00983FB6 /* tipIcon_MergeRequestComment@2x.png in Resources */, + B1D5EF3D20BC06CB00983FB6 /* private_message_send_fail@2x.png in Resources */, + B1D5EF3E20BC06CB00983FB6 /* terminal_box_unselected@2x.png in Resources */, + B1D5EF3F20BC06CB00983FB6 /* keyboard_at@2x.png in Resources */, + B1D5EF4020BC06CB00983FB6 /* coding_emoji_13@2x.png in Resources */, + B1D5EF4120BC06CB00983FB6 /* blankpage_image_Wiki@2x.png in Resources */, + B1D5EF4220BC06CB00983FB6 /* PR_update_title@2x.png in Resources */, + B1D5EF4320BC06CB00983FB6 /* project_item_task@2x.png in Resources */, + B1D5EF4420BC06CB00983FB6 /* icon_file_apk_big@2x.png in Resources */, + B1D5EF4520BC06CB00983FB6 /* file_menu_icon_share@2x.png in Resources */, + B1D5EF4620BC06CB00983FB6 /* btn_delete_tweetimage@2x.png in Resources */, + B1D5EF4720BC06CB00983FB6 /* task_activity_icon_commit_refer@3x.png in Resources */, + B1D5EF4820BC06CB00983FB6 /* icon_code_executable@3x.png in Resources */, + B1D5EF4920BC06CB00983FB6 /* calendar_0x59A2FF@3x.png in Resources */, + B1D5EF4A20BC06CB00983FB6 /* task_activity_icon_create@3x.png in Resources */, + B1D5EF4B20BC06CB00983FB6 /* icon_file_cell_move@2x.png in Resources */, + B1D5EF4C20BC06CB00983FB6 /* mrpr_icon_status_cannotmerge@3x.png in Resources */, + B1D5EF4D20BC06CB00983FB6 /* member_cell_edit_alias@3x.png in Resources */, + B1D5EF4E20BC06CB00983FB6 /* icon_file_cell_rename@2x.png in Resources */, + B1D5EF4F20BC06CB00983FB6 /* PR_grant@3x.png in Resources */, + B1D5EF5020BC06CB00983FB6 /* coding_emoji_03@2x.png in Resources */, + B1D5EF5120BC06CB00983FB6 /* cell_checkmark@3x.png in Resources */, + B1D5EF5220BC06CB00983FB6 /* taskWatchers@2x.png in Resources */, + B1D5EF5320BC06CB00983FB6 /* icon_file_psd@2x.png in Resources */, + B1D5EF5420BC06CB00983FB6 /* sex_man_icon@2x.png in Resources */, + B1D5EF5520BC06CB00983FB6 /* file_changeType_DELETE@2x.png in Resources */, + B1D5EF5620BC06CB00983FB6 /* button_file_move_unable@3x.png in Resources */, + B16E6D1820C147770076026D /* team_cell_edit_delete@2x.png in Resources */, + B1D5EF5720BC06CB00983FB6 /* button_file_history@3x.png in Resources */, + B1D5EF5820BC06CB00983FB6 /* shortcut_2FA@2x.png in Resources */, + B1D5EF5920BC06CB00983FB6 /* button_file_download_enable@3x.png in Resources */, + B1D5EF5A20BC06CB00983FB6 /* icon_file_ai_big@2x.png in Resources */, + B1D5EF5B20BC06CB00983FB6 /* tipIcon_ProjectPayment@2x.png in Resources */, + B1D5EF5C20BC06CB00983FB6 /* MIDAUTUMNIMAGE.jpg in Resources */, + B1D5EF5D20BC06CB00983FB6 /* calendar_0xA9B3BE@2x.png in Resources */, + B1D5EF5E20BC06CB00983FB6 /* project_item_topic@3x.png in Resources */, + B1D5EF5F20BC06CB00983FB6 /* service_terms.html in Resources */, + B1D5EF6020BC06CB00983FB6 /* task_activity_icon_update_priority@2x.png in Resources */, + B1D5EF6120BC06CB00983FB6 /* icon_search_searchbar@3x.png in Resources */, + B1D5EF6220BC06CB00983FB6 /* keyboard_voice@2x.png in Resources */, + B1DFD0A220C67D3F00F75F2F /* btn_followed_yes@3x.png in Resources */, + B1D5EF6320BC06CB00983FB6 /* search_icon_project@3x.png in Resources */, + B16E6DE120C1494B0076026D /* icon_user_monkey@3x.png in Resources */, + B1D5EF6420BC06CB00983FB6 /* button_close@3x.png in Resources */, + B1D5EF6520BC06CB00983FB6 /* btn_followed_not@2x.png in Resources */, + B1D5EF6720BC06CB00983FB6 /* mrpr_icon_fileChange@2x.png in Resources */, + B1D5EF6820BC06CB00983FB6 /* task_activity_icon_finish@2x.png in Resources */, + B1D5EF6920BC06CB00983FB6 /* vip_4_40@2x.png in Resources */, + B1D5EF6A20BC06CB00983FB6 /* taskDeadline@3x.png in Resources */, + B1D5EF6B20BC06CB00983FB6 /* button_arrow_left@2x.png in Resources */, + B1D5EF6C20BC06CB00983FB6 /* taskProgress@2x.png in Resources */, + B1D5EF6D20BC06CB00983FB6 /* tweetBtn_Nav@2x.png in Resources */, + B1D5EF6E20BC06CB00983FB6 /* bubble_left_play_1@2x.png in Resources */, + B1D5EF6F20BC06CB00983FB6 /* placeholder_monkey_round_54@2x.png in Resources */, + B1D5EF7020BC06CB00983FB6 /* tweet_btn_rewarded@3x.png in Resources */, + B1D5EF7120BC06CB00983FB6 /* vip_4_75@2x.png in Resources */, + B1D5EF7220BC06CB00983FB6 /* task_activity_icon_update_deadline@2x.png in Resources */, + B1D5EF7320BC06CB00983FB6 /* TweetSendDetailLoctionCell.xib in Resources */, + B1D5EF7420BC06CB00983FB6 /* project_item_readme@3x.png in Resources */, + B16E6CB420C13BF50076026D /* btn_next_enable@2x.png in Resources */, + B1D5EF7520BC06CB00983FB6 /* icon_file_doc_big@2x.png in Resources */, + B16E6D1020C147770076026D /* team_info_sup@3x.png in Resources */, + B1D5EF7620BC06CB00983FB6 /* icon_locationed@2x.png in Resources */, + B1D5EF7720BC06CB00983FB6 /* tip_normal_Nav@3x.png in Resources */, + B1D5EF7820BC06CB00983FB6 /* tweet_btn_like@3x.png in Resources */, + B1D5EF7920BC06CB00983FB6 /* icon_project_cell_nopin@2x.png in Resources */, + B16E6CA720C13BA20076026D /* btn_dismiss@3x.png in Resources */, + B1D5EF7A20BC06CB00983FB6 /* coding_emoji_39@2x.png in Resources */, + B1D5EF7C20BC06CB00983FB6 /* coding_emoji_08@2x.png in Resources */, + B1D5EF7D20BC06CB00983FB6 /* tweet_btn_liked@2x.png in Resources */, + B1D5EF7E20BC06CB00983FB6 /* FileInfoViewController.xib in Resources */, + B1D5EF7F20BC06CB00983FB6 /* register_step_un@3x.png in Resources */, + B1D5EF8020BC06CB00983FB6 /* blankpage_image_Task@3x.png in Resources */, + B1D5EF8120BC06CB00983FB6 /* TweetSendCreateLocationCell.xib in Resources */, + B1D5EF8320BC06CB00983FB6 /* coding_emoji_36@2x.png in Resources */, + B1D5EF8420BC06CB00983FB6 /* n_btn_followed_yes@2x.png in Resources */, + B1D5EF8520BC06CB00983FB6 /* store_icon@2x.png in Resources */, + B1D5EF8620BC06CB00983FB6 /* vip_4_75@3x.png in Resources */, + B1D5EF8720BC06CB00983FB6 /* button_tip_notice@2x.png in Resources */, + B1D5EF8820BC06CB00983FB6 /* addPictureBgImage@2x.png in Resources */, + B16E6D0620C147770076026D /* team_info_order@2x.png in Resources */, + B1D5EF8920BC06CB00983FB6 /* PRReviewer@3x.png in Resources */, + B1D5EF8A20BC06CB00983FB6 /* button_tip_notice@3x.png in Resources */, + B1D5EF8B20BC06CB00983FB6 /* password_look@2x.png in Resources */, + B1D5EF8C20BC06CB00983FB6 /* SVWebViewControllerActivityReport-iPad@2x.png in Resources */, + B1D5EF8D20BC06CB00983FB6 /* PointLikeHead@3x.png in Resources */, + B1D5EF8E20BC06CB00983FB6 /* btn_file_reDo@2x.png in Resources */, + B1D5EF8F20BC06CB00983FB6 /* vip_4_30@2x.png in Resources */, + B1D5EF9020BC06CB00983FB6 /* mrpr_icon_fileChange@3x.png in Resources */, + B1D5EF9120BC06CB00983FB6 /* project_item_reading@3x.png in Resources */, + B1D5EF9220BC06CB00983FB6 /* icon_code_executable@2x.png in Resources */, + B1D5EF9320BC06CB00983FB6 /* user_info_company@3x.png in Resources */, + B1D5EF9420BC06CB00983FB6 /* upgrade_success@2x.png in Resources */, + B1D5EF9520BC06CB00983FB6 /* pop_Tweet@2x.png in Resources */, + B1D5EF9620BC06CB00983FB6 /* taskPriority1@2x.png in Resources */, + B1D5EF9720BC06CB00983FB6 /* search_icon_pr@2x.png in Resources */, + B1D5EF9820BC06CB00983FB6 /* logo_about@2x.png in Resources */, + B1D5EF9920BC06CB00983FB6 /* button_file_upload_enable@2x.png in Resources */, + B16E6DDC20C149440076026D /* intro_page0_ip6@2x.png in Resources */, + B1D5EF9A20BC06CB00983FB6 /* share_btn_qq@2x.png in Resources */, + B1D5EF9B20BC06CB00983FB6 /* PR_review@2x.png in Resources */, + B1D5EF9C20BC06CB00983FB6 /* pop_Message@2x.png in Resources */, + B1D5EF9D20BC06CB00983FB6 /* terminal_box_selected@2x.png in Resources */, + B1D5EF9E20BC06CB00983FB6 /* git_icon_watch@2x.png in Resources */, + B1D5EF9F20BC06CB00983FB6 /* icon_file_pdf_big@2x.png in Resources */, + B1D5EFA120BC06CB00983FB6 /* placeholder_coding_square_80@2x.png in Resources */, + B1D5EFA220BC06CB00983FB6 /* mrpr_icon_status_cannotmerge@2x.png in Resources */, + B1D5EFA420BC06CB00983FB6 /* loading_loop@2x.png in Resources */, + B1D5EFA520BC06CB00983FB6 /* code_release_resource_Task@3x.png in Resources */, + B1D5EFA620BC06CB00983FB6 /* PR_refuse@2x.png in Resources */, + B1D5EFA720BC06CB00983FB6 /* icon_topic_hotTop@2x.png in Resources */, + B1D5EFA820BC06CB00983FB6 /* wiki_revert@3x.png in Resources */, + B1D5EFA920BC06CB00983FB6 /* share_btn_qzone@2x.png in Resources */, + B1D5EFAA20BC06CB00983FB6 /* project_tag_btn@2x.png in Resources */, + B1D5EFAB20BC06CB00983FB6 /* tipIcon_BranchMember@2x.png in Resources */, + B1D5EFAC20BC06CB00983FB6 /* messageRight_bg_highlight_img@2x.png in Resources */, + B1D5EFAD20BC06CB00983FB6 /* tipIcon_PullRequestBean@2x.png in Resources */, + B1D5EFAE20BC06CB00983FB6 /* btn_privateMsg_friend@2x.png in Resources */, + B16E6CB620C13BF50076026D /* btn_next_enable@3x.png in Resources */, + B1D5EFAF20BC06CB00983FB6 /* btn_file_cancel@2x.png in Resources */, + B1D5EFB020BC06CB00983FB6 /* task_activity_icon_restore@3x.png in Resources */, + B1D5EFB120BC06CB00983FB6 /* user_info_file@3x.png in Resources */, + B1C60C8F20BFF7950073D3CA /* ProjectTypeExplanationViewController.xib in Resources */, + B1D5EFB220BC06CB00983FB6 /* shop_coding_coin_icon@2x.png in Resources */, + B1D5EFB320BC06CB00983FB6 /* shortcut_task@3x.png in Resources */, + B1D5EFB520BC06CB00983FB6 /* taskPriority1_small@3x.png in Resources */, + B1D5EFB620BC06CB00983FB6 /* tasks_all@3x.png in Resources */, + B16E6CEA20C145BF0076026D /* quick_menu_icon_project@2x.png in Resources */, + B1D5EFB720BC06CB00983FB6 /* coding_emoji_09@2x.png in Resources */, + B1D5EFB820BC06CB00983FB6 /* map_annotation@2x.png in Resources */, + B1D5EFB920BC06CB00983FB6 /* code_release_resource_MergeRequestBean@2x.png in Resources */, + B1D5EFBA20BC06CB00983FB6 /* task_resource_reference_ProjectTopic@2x.png in Resources */, + B1D5EFBB20BC06CB00983FB6 /* task_activity_icon_update@2x.png in Resources */, + B1D5EFBC20BC06CB00983FB6 /* button_file_activity@3x.png in Resources */, + B1D5EFBD20BC06CB00983FB6 /* coding_emoji_41@2x.png in Resources */, + B1D5EFBE20BC06CB00983FB6 /* project_item_task@3x.png in Resources */, + B1D5EFBF20BC06CB00983FB6 /* icon_code_image@2x.png in Resources */, + B1D5EFC020BC06CB00983FB6 /* icon_file_xls_big@2x.png in Resources */, + B16E6CD120C144930076026D /* done_un_Nav@3x.png in Resources */, + B1D5EFC120BC06CB00983FB6 /* user_info_topic@3x.png in Resources */, + B1D5EFC220BC06CB00983FB6 /* task_activity_icon_remove_watcher@2x.png in Resources */, + B1D5EFC320BC06CB00983FB6 /* project_item_reading@2x.png in Resources */, + B1D5EFC420BC06CB00983FB6 /* shop_nar_history_icon@2x.png in Resources */, + B1D5EFC520BC06CB00983FB6 /* taskPriority3_small@2x.png in Resources */, + B1D5EFC620BC06CB00983FB6 /* coding_emoji_18@2x.png in Resources */, + B1D5EFC720BC06CB00983FB6 /* user_info_about@3x.png in Resources */, + B1D5EFC820BC06CB00983FB6 /* WeiboSDK.bundle in Resources */, + B1D5EFC920BC06CB00983FB6 /* EAPayViewController.xib in Resources */, + B1D5EFCA20BC06CB00983FB6 /* calendar_0xA1CF64@3x.png in Resources */, + B16E6CE620C145BF0076026D /* quick_menu_icon_2fa@3x.png in Resources */, + B15C98B120D39CA200DDA425 /* project_icon_edit@2x.png in Resources */, + B1D5EFCB20BC06CB00983FB6 /* user_info_file@2x.png in Resources */, + B1D5EFCC20BC06CB00983FB6 /* ShopSwitchCell.xib in Resources */, + B1D5EFCD20BC06CB00983FB6 /* cell_arrow_left@2x.png in Resources */, + B1D5EFCE20BC06CB00983FB6 /* LICENSE in Resources */, + B1D5EFCF20BC06CB00983FB6 /* member_type_90@3x.png in Resources */, + B1D5EFD120BC06CB00983FB6 /* location_checkmark@2x.png in Resources */, + B1D5EFD220BC06CB00983FB6 /* icon_code_tree@2x.png in Resources */, + B1D5EFD320BC06CB00983FB6 /* nav_project_task@2x.png in Resources */, + B1D5EFD420BC06CB00983FB6 /* calendar_0xF68435@2x.png in Resources */, + B1D5EFD520BC06CB00983FB6 /* share_btn_evernote@2x.png in Resources */, + B1D5EFD620BC06CB00983FB6 /* project_item_branch@2x.png in Resources */, + B1D5EFD720BC06CB00983FB6 /* PR_push@2x.png in Resources */, + B1D5EFD820BC06CB00983FB6 /* vip_4_45@3x.png in Resources */, + B1D5EFD920BC06CB00983FB6 /* tipIcon_ProjectTopicCommentVote@2x.png in Resources */, + B1D5EFDB20BC06CB00983FB6 /* icon_file_share_logo@3x.png in Resources */, + B1D5EFDC20BC06CB00983FB6 /* calendar_0xF68435@3x.png in Resources */, + B1D5EFDD20BC06CB00983FB6 /* file_activity_icon_create@2x.png in Resources */, + B1D5EFDE20BC06CB00983FB6 /* tasks_all@2x.png in Resources */, + B1D5EFDF20BC06CB00983FB6 /* EACodeReleaseTopCell.xib in Resources */, + B1D5EFE020BC06CB00983FB6 /* merge-request coding@2x.png in Resources */, + B1C60CAC20C0FC750073D3CA /* Launch Screen_E.xib in Resources */, + B1D5EFE120BC06CB00983FB6 /* file_changeType_ADD@3x.png in Resources */, + B1D5EFE220BC06CB00983FB6 /* calendar_0xA9B3BE@3x.png in Resources */, + B1D5EFE320BC06CB00983FB6 /* messageLeft_bg_highlight_img@2x.png in Resources */, + B1D5EFE420BC06CB00983FB6 /* PR_update@3x.png in Resources */, + B1D5EFE520BC06CB00983FB6 /* nav_project_topic@2x.png in Resources */, + B1D5EFE620BC06CB00983FB6 /* share_btn_wxtimeline@2x.png in Resources */, + B1D5EFE720BC06CB00983FB6 /* icon_file_zip@2x.png in Resources */, + B1D5EFE820BC06CB00983FB6 /* me_normal@3x.png in Resources */, + B1D5EFE920BC06CB00983FB6 /* pop_Project@2x.png in Resources */, + B1D5EFEB20BC06CB00983FB6 /* logo_coding_top@2x.png in Resources */, + B1D5EFEC20BC06CB00983FB6 /* tipIcon_ProjectTweetComment@2x.png in Resources */, + B1D5EFED20BC06CB00983FB6 /* button_file_createFolder_enable@2x.png in Resources */, + B1D5EFEE20BC06CB00983FB6 /* wiki_menu_2@2x.png in Resources */, + B1D5EFEF20BC06CB00983FB6 /* skill_delete@2x.png in Resources */, + B1D5EFF020BC06CB00983FB6 /* calendar_0xF56061@2x.png in Resources */, + B1D5EFF120BC06CB00983FB6 /* project_selected@2x.png in Resources */, + B1D5EFF220BC06CB00983FB6 /* tipIcon_QcTask@2x.png in Resources */, + B1D5EFF320BC06CB00983FB6 /* time_clock_icon@2x.png in Resources */, + B1D5EFF420BC06CB00983FB6 /* tag_button_randomColor@2x.png in Resources */, + B1D5EFF520BC06CB00983FB6 /* blankpage_image_Notice@3x.png in Resources */, + B1D5EFF620BC06CB00983FB6 /* project_item_mr_pr@3x.png in Resources */, + B1D5EFF720BC06CB00983FB6 /* button_tip_close@2x.png in Resources */, + B1D5EFF820BC06CB00983FB6 /* task_activity_icon_reassign@2x.png in Resources */, + B16E6CA120C0FDB50076026D /* logo_coding_top@3x.png in Resources */, + B1D5EFF920BC06CB00983FB6 /* task_resource_reference_ProjectFile@2x.png in Resources */, + B1D5EFFA20BC06CB00983FB6 /* messageAT@2x.png in Resources */, + B1D5EFFB20BC06CB00983FB6 /* tweet_selected@2x.png in Resources */, + B1D5EFFC20BC06CB00983FB6 /* icon_file_code@2x.png in Resources */, + B1D5EFFE20BC06CB00983FB6 /* back_T_Nav@3x.png in Resources */, + B1D5EFFF20BC06CB00983FB6 /* me_selected@2x.png in Resources */, + B1D5F00020BC06CB00983FB6 /* tipIcon_PullRequestComment@2x.png in Resources */, + B1D5F00120BC06CB00983FB6 /* tipIcon_Depot@2x.png in Resources */, + B1D5F00220BC06CB00983FB6 /* cell_checkmark@2x.png in Resources */, + B1D5F00320BC06CB00983FB6 /* PR_add_label@2x.png in Resources */, + B1D5F00520BC06CB00983FB6 /* logo_coding@3x.png in Resources */, + B1D5F00620BC06CB00983FB6 /* PR_del_reviewer@2x.png in Resources */, + B1D5F00720BC06CB00983FB6 /* task_activity_icon_reassign@3x.png in Resources */, + B1D5F00820BC06CB00983FB6 /* placeholder_coding_square_150@2x.png in Resources */, + B1D5F00920BC06CB00983FB6 /* member_cell_edit_remove@2x.png in Resources */, + B1D5F00B20BC06CB00983FB6 /* PR_TaskResource@2x.png in Resources */, + B1D5F00C20BC06CB00983FB6 /* icon_file_share_logo@2x.png in Resources */, + B1D5F00D20BC06CB00983FB6 /* blankpage_image_Notice@2x.png in Resources */, + B1D5F00E20BC06CB00983FB6 /* placeholder_monkey_round_25@2x.png in Resources */, + B16E6CEE20C147490076026D /* team_bg@3x.png in Resources */, + B1D5F00F20BC06CB00983FB6 /* coding_emoji_gif_05@2x.png in Resources */, + B1D5F01020BC06CB00983FB6 /* addBtn_Artboard@3x.png in Resources */, + B1D5F01120BC06CB00983FB6 /* coding_emoji_22@2x.png in Resources */, + B1D5F01220BC06CB00983FB6 /* tweet_btn_rewarded@2x.png in Resources */, + B1D5F01320BC06CB00983FB6 /* button_file_move_enable@2x.png in Resources */, + B1D5F01420BC06CB00983FB6 /* messageSystem@3x.png in Resources */, + B1D5F01520BC06CB00983FB6 /* button_red_close@2x.png in Resources */, + B1D5F01620BC06CB00983FB6 /* blankpage_image_Wiki@3x.png in Resources */, + B1D5F01720BC06CB00983FB6 /* project_tag_icon@2x.png in Resources */, + B1D5F01820BC06CB00983FB6 /* button_terminal@3x.png in Resources */, + B1D5F01920BC06CB00983FB6 /* wiki_menu_0@3x.png in Resources */, + B1D5F01A20BC06CB00983FB6 /* PR_update_title@3x.png in Resources */, + B1D5F01B20BC06CB00983FB6 /* wiki.html in Resources */, + B1D5F01C20BC06CB00983FB6 /* task_activity_icon_update@3x.png in Resources */, + B1D5F01D20BC06CB00983FB6 /* timeline_line_read@2x.png in Resources */, + B1D5F01E20BC06CB00983FB6 /* git_icon_fork@2x.png in Resources */, + B1D5F01F20BC06CB00983FB6 /* tag_button_add@3x.png in Resources */, + B1D5F02020BC06CB00983FB6 /* taskProgress@3x.png in Resources */, + B1D5F02120BC06CB00983FB6 /* taskboard_blankpage@3x.png in Resources */, + B1D5F02320BC06CB00983FB6 /* blankpage_image_Task@2x.png in Resources */, + B1D5F02420BC06CB00983FB6 /* task_activity_icon_update_label@3x.png in Resources */, + B16E6DC620C149350076026D /* intro_dot_light_selected@3x.png in Resources */, + B1D5F02520BC06CB00983FB6 /* search_icon_mr@3x.png in Resources */, + B1D5F02620BC06CB00983FB6 /* blankpage_image_Tweet@3x.png in Resources */, + B1D5F02720BC06CB00983FB6 /* user_info_company@2x.png in Resources */, + B1D5F02820BC06CB00983FB6 /* scan_line@2x.png in Resources */, + B1D5F02920BC06CB00983FB6 /* README.md in Resources */, + B1D5F02A20BC06CB00983FB6 /* icon_file_unknown@2x.png in Resources */, + B1D5F02B20BC06CB00983FB6 /* search_icon_tweet@2x.png in Resources */, + B1D5F02C20BC06CB00983FB6 /* tip_bg@2x.png in Resources */, + B1D5F02D20BC06CB00983FB6 /* SVWebViewControllerActivityChrome-iPad@2x.png in Resources */, + B1D5F02E20BC06CB00983FB6 /* PR_grant@2x.png in Resources */, + B1D5F02F20BC06CB00983FB6 /* settingBtn_Nav@2x.png in Resources */, + B1D5F03020BC06CB00983FB6 /* user_info_topic@2x.png in Resources */, + B1D5F03120BC06CB00983FB6 /* project_item_file@2x.png in Resources */, + B1D5F03220BC06CB00983FB6 /* icon_arrow_searchHistory@2x.png in Resources */, + B16E6CB220C13BF50076026D /* btn_next_unable@3x.png in Resources */, + B1D5F03320BC06CB00983FB6 /* icon_file_movie_big@2x.png in Resources */, + B1D5F03420BC06CB00983FB6 /* icon_file_md_big@2x.png in Resources */, + B1D5F03520BC06CB00983FB6 /* nav_project_member@2x.png in Resources */, + B1D5F03620BC06CB00983FB6 /* blankpage_image_MessageList@2x.png in Resources */, + B1D5F03720BC06CB00983FB6 /* password_unlook@3x.png in Resources */, + B1D5F03820BC06CB00983FB6 /* timeline_icon_unread@3x.png in Resources */, + B16E6CA920C13BA20076026D /* btn_dismiss@2x.png in Resources */, + B1D5F03920BC06CB00983FB6 /* task_activity_icon_add_milestone@3x.png in Resources */, + B16E6DD720C149440076026D /* intro_page_unselected@2x.png in Resources */, + B1D5F03A20BC06CB00983FB6 /* pop_Message@3x.png in Resources */, + B1D5F03B20BC06CB00983FB6 /* EABoardTaskListBlankView.xib in Resources */, + B1D5F03C20BC06CB00983FB6 /* comment_bg@2x.png in Resources */, + B1D5F03D20BC06CB00983FB6 /* button_scan@2x.png in Resources */, + B1D5F03E20BC06CB00983FB6 /* terminal_triangle@3x.png in Resources */, + B1D5F03F20BC06CB00983FB6 /* tweetsBtn_Nav@2x.png in Resources */, + B1D5F04020BC06CB00983FB6 /* coding_emoji_12@2x.png in Resources */, + B1D5F04120BC06CB00983FB6 /* terminal_box_unselected@3x.png in Resources */, + B1D5F04420BC06CB00983FB6 /* terminal_tail@3x.png in Resources */, + B1D5F04520BC06CB00983FB6 /* task_normal@3x.png in Resources */, + B1D5F04620BC06CB00983FB6 /* vip_3_75@2x.png in Resources */, + B16E6DC720C149350076026D /* intro_dot_light_selected@2x.png in Resources */, + B1D5F04720BC06CB00983FB6 /* mock_hotTopiclist.geojson in Resources */, + B1D5F04820BC06CB00983FB6 /* icon_project_cell_pin@2x.png in Resources */, + B1D5F04920BC06CB00983FB6 /* pop_2FA@2x.png in Resources */, + B1D5F04A20BC06CB00983FB6 /* PR_add_reviewer@3x.png in Resources */, + B1D5F04B20BC06CB00983FB6 /* nav_project_file@2x.png in Resources */, + B1D5F04C20BC06CB00983FB6 /* user_info_shop@3x.png in Resources */, + B1D5F04D20BC06CB00983FB6 /* pop_Task@2x.png in Resources */, + B16E6CE020C145BF0076026D /* quick_menu_icon_task@3x.png in Resources */, + B1D5F04E20BC06CB00983FB6 /* section_btn_close@2x.png in Resources */, + B16E6CC320C13F5F0076026D /* btn_project_quit@3x.png in Resources */, + B1D5F04F20BC06CB00983FB6 /* country_code.plist in Resources */, + B1D5F05020BC06CB00983FB6 /* file_menu_icon_info@2x.png in Resources */, + B1D5F05120BC06CB00983FB6 /* coding_emoji_07@2x.png in Resources */, + B1D5F05220BC06CB00983FB6 /* project_item_taskboard@3x.png in Resources */, + B1D5F05320BC06CB00983FB6 /* merge-request coding@3x.png in Resources */, + B1D5F05520BC06CB00983FB6 /* blankpage_image_Team@3x.png in Resources */, + B1D5F05620BC06CB00983FB6 /* mrpr_icon_status_canmerge@2x.png in Resources */, + B16E6DC920C1493A0076026D /* intro_icon_wiki_up.gif in Resources */, + B1D5F05720BC06CB00983FB6 /* blankpage_image_MessageList@3x.png in Resources */, + B1D5F05820BC06CB00983FB6 /* taskPriority1_small@2x.png in Resources */, + B1D5F05920BC06CB00983FB6 /* me_selected@3x.png in Resources */, + B16E6D0C20C147770076026D /* team_info_mem@3x.png in Resources */, + B1D5F05A20BC06CB00983FB6 /* timeBtn_Nav@2x.png in Resources */, + B16E6DC020C1492F0076026D /* intro_dot_dark_unselected@3x.png in Resources */, + B1D5F05B20BC06CB00983FB6 /* bubble_right_play_0@2x.png in Resources */, + B1D5F05C20BC06CB00983FB6 /* ShopMutileValueCell.xib in Resources */, + B1D5F05D20BC06CB00983FB6 /* task_activity_icon_update_priority@3x.png in Resources */, + B1D5F05E20BC06CB00983FB6 /* icon_file_movie@2x.png in Resources */, + B1D5F05F20BC06CB00983FB6 /* file_menu_icon_open@2x.png in Resources */, + B1D5F06020BC06CB00983FB6 /* addBtn_Nav@2x.png in Resources */, + B1D5F06120BC06CB00983FB6 /* messageAT@3x.png in Resources */, + B1D5F06220BC06CB00983FB6 /* search_icon_file@3x.png in Resources */, + B1D5F06420BC06CB00983FB6 /* PR_review@3x.png in Resources */, + B1D5F06520BC06CB00983FB6 /* keyboard_emotion_monkey_gif@2x.png in Resources */, + B1D5F06620BC06CB00983FB6 /* coding_emoji_29@2x.png in Resources */, + B1D5F06720BC06CB00983FB6 /* file_activity_icon_move_file@2x.png in Resources */, + B16E6CCB20C144930076026D /* done_Nav@2x.png in Resources */, + B16E6DDE20C149440076026D /* intro_page0_ip6+@3x.png in Resources */, + B1D5F06820BC06CB00983FB6 /* addBtn_Nav@3x.png in Resources */, + B1D5F06920BC06CB00983FB6 /* vip_3_75@3x.png in Resources */, + B16E6DE020C1494B0076026D /* icon_user_monkey@2x.png in Resources */, + B1D5F06A20BC06CB00983FB6 /* info_Nav@3x.png in Resources */, + B1D5F06B20BC06CB00983FB6 /* terminal_more@2x.png in Resources */, + B1D5F06C20BC06CB00983FB6 /* task_selected@3x.png in Resources */, + B1D5F06D20BC06CB00983FB6 /* blankpage_image_Project@3x.png in Resources */, + B1D5F06E20BC06CB00983FB6 /* keyboard_emotion@2x.png in Resources */, + B1D5F06F20BC06CB00983FB6 /* button_file_history@2x.png in Resources */, + B1D5F07020BC06CB00983FB6 /* wechat@2x.png in Resources */, + B1D5F07120BC06CB00983FB6 /* coding_emoji_43@2x.png in Resources */, + B1D5F07220BC06CB00983FB6 /* tweet_btn_liked@3x.png in Resources */, + B1D5F07320BC06CB00983FB6 /* icon_file_music@2x.png in Resources */, + B1D5F07420BC06CB00983FB6 /* tipIcon_UserFollow@2x.png in Resources */, + B1D5F07520BC06CB00983FB6 /* icon_code_git_link@3x.png in Resources */, + B1D5F07620BC06CB00983FB6 /* file_changeType_RENAME@3x.png in Resources */, + B1D5F07720BC06CB00983FB6 /* member_type_100@3x.png in Resources */, + B1D5F07820BC06CB00983FB6 /* code_release_resource__Default@2x.png in Resources */, + B1D5F07920BC06CB00983FB6 /* button_close@2x.png in Resources */, + B16E6D1C20C147770076026D /* team_cell_edit_pro@2x.png in Resources */, + B1D5F07A20BC06CB00983FB6 /* PR_TaskResource@3x.png in Resources */, + B1D5F07C20BC06CB00983FB6 /* tipIcon_Project@2x.png in Resources */, + B1D5F07D20BC06CB00983FB6 /* icon_code_tree@3x.png in Resources */, + B1D5F07E20BC06CB00983FB6 /* pop_Task@3x.png in Resources */, + B1D5F07F20BC06CB00983FB6 /* tag_button_editColor@2x.png in Resources */, + B1D5F08020BC06CB00983FB6 /* icon_best_answer@3x.png in Resources */, + B1D5F08220BC06CB00983FB6 /* tip_bg@3x.png in Resources */, + B1D5F08320BC06CB00983FB6 /* addUserBtn_Nav@3x.png in Resources */, + B1D5F08420BC06CB00983FB6 /* taskOwner@3x.png in Resources */, + B16E6DDF20C149440076026D /* intro_page2_ip6@2x.png in Resources */, + B1D5F08520BC06CB00983FB6 /* addUserBtn_Nav@2x.png in Resources */, + B1D5F08620BC06CB00983FB6 /* mrpr_icon_status_accepted@3x.png in Resources */, + B1D5F08720BC06CB00983FB6 /* tweet_btn_reward@3x.png in Resources */, + B1D5F08820BC06CB00983FB6 /* member_cell_edit_remove@3x.png in Resources */, + B1D5F08A20BC06CB00983FB6 /* shortcut_tweet@3x.png in Resources */, + B1D5F08B20BC06CB00983FB6 /* coding_emoji_34@2x.png in Resources */, + B1D5F08C20BC06CB00983FB6 /* task_description_icon@3x.png in Resources */, + B1D5F08E20BC06CB00983FB6 /* me_info_arrow_left@2x.png in Resources */, + B1D5F08F20BC06CB00983FB6 /* keyboard_photo@2x.png in Resources */, + B1D5F09020BC06CB00983FB6 /* wechat@3x.png in Resources */, + B1D5F09220BC06CB00983FB6 /* text_clear_btn@2x.png in Resources */, + B16E6DC320C1492F0076026D /* intro_dot_dark_unselected@2x.png in Resources */, + B1D5F09320BC06CB00983FB6 /* task_normal@2x.png in Resources */, + B1D5F09420BC06CB00983FB6 /* icon_file_xls@2x.png in Resources */, + B1D5F09520BC06CB00983FB6 /* coding_emoji_gif_04@2x.png in Resources */, + B1D5F09620BC06CB00983FB6 /* messageProjectFans@2x.png in Resources */, + B1D5F09720BC06CB00983FB6 /* shop_nar_history_icon@3x.png in Resources */, + B16E6CC520C13F5F0076026D /* btn_privateMsg_stranger@3x.png in Resources */, + B1D5F09820BC06CB00983FB6 /* file_changeType_MODIFY@2x.png in Resources */, + B1D5F09920BC06CB00983FB6 /* project_normal@2x.png in Resources */, + B1D5F09A20BC06CB00983FB6 /* reward_tip_logo@2x.png in Resources */, + B1D5F09B20BC06CB00983FB6 /* taskProject@3x.png in Resources */, + B1D5F09C20BC06CB00983FB6 /* user_info_point@3x.png in Resources */, + B16E6D0820C147770076026D /* team_info_order@3x.png in Resources */, + B1D5F20A20BCF6A900983FB6 /* Launch Screen.xib in Resources */, + B1D5F09D20BC06CB00983FB6 /* icon_file_folder_default@2x.png in Resources */, + B1D5F09E20BC06CB00983FB6 /* icon_code_file@3x.png in Resources */, + B1D5F09F20BC06CB00983FB6 /* project_item_readme@2x.png in Resources */, + B1D5F0A020BC06CB00983FB6 /* EACodeBranchListCell.xib in Resources */, + B1D5F0A120BC06CB00983FB6 /* code_release_resource_Default@3x.png in Resources */, + B1D5F0A220BC06CB00983FB6 /* info_Nav@2x.png in Resources */, + B1D5F0A420BC06CB00983FB6 /* file_activity_icon_update_file@3x.png in Resources */, + B1D5F0A520BC06CB00983FB6 /* bubble.html in Resources */, + B1D5F0A620BC06CB00983FB6 /* coding_emoji_gif_06@2x.png in Resources */, + B1D5F0A820BC06CB00983FB6 /* project_item_member@2x.png in Resources */, + B1D5F0A920BC06CB00983FB6 /* tipIcon_Tweet@2x.png in Resources */, + B1D5F0AA20BC06CB00983FB6 /* coding_emoji_04@2x.png in Resources */, + B16E6DD620C149440076026D /* intro_page_selected@2x.png in Resources */, + B1D5F0AB20BC06CB00983FB6 /* nav_tweet_hot@2x.png in Resources */, + B1D5F0AC20BC06CB00983FB6 /* project_item_topic@2x.png in Resources */, + B1D5F0AD20BC06CB00983FB6 /* wiki_menu_1@2x.png in Resources */, + B1D5F0AE20BC06CB00983FB6 /* file_activity_icon_move_file@3x.png in Resources */, + B1D5F0AF20BC06CB00983FB6 /* icon_file_md@2x.png in Resources */, + B1D5F0B020BC06CB00983FB6 /* tweet_normal@2x.png in Resources */, + B1D5F0B120BC06CB00983FB6 /* PR_review_undo@2x.png in Resources */, + B1D5F0B220BC06CB00983FB6 /* blankpage_image_Tweet@2x.png in Resources */, + B16E6DDB20C149440076026D /* intro_page_selected@3x.png in Resources */, + B1D5F0B320BC06CB00983FB6 /* taskBoardList@3x.png in Resources */, + B1D5F0B420BC06CB00983FB6 /* search_tweet_like@2x.png in Resources */, + B1D5F0B520BC06CB00983FB6 /* scan_bg@2x.png in Resources */, + B16E6DCF20C1493A0076026D /* intro_icon_code_down.gif in Resources */, + B1D5F0B620BC06CB00983FB6 /* task_icon_arrow@3x.png in Resources */, + B1D5F0B720BC06CB00983FB6 /* n_btn_followed_not@2x.png in Resources */, + B1D5F0B820BC06CB00983FB6 /* section_btn_open@2x.png in Resources */, + B1D5F0BA20BC06CB00983FB6 /* task_resource_reference_ProjectTopic@3x.png in Resources */, + B1D5F0BB20BC06CB00983FB6 /* skill_delete@3x.png in Resources */, + B1D5F0BD20BC06CB00983FB6 /* button_file_move_unable@2x.png in Resources */, + B1D5F0BE20BC06CB00983FB6 /* mock_topicAdlist.geojson in Resources */, + B1D5F0BF20BC06CB00983FB6 /* placeholder_coding_square_55@2x.png in Resources */, + B1D5F0C020BC06CB00983FB6 /* pop_Project@3x.png in Resources */, + B1D5F0C120BC06CB00983FB6 /* task_activity_icon_remove_milestone@3x.png in Resources */, + B1D5F0C220BC06CB00983FB6 /* button_file_download_unable@3x.png in Resources */, + B1D5F0C320BC06CB00983FB6 /* search_icon_task@2x.png in Resources */, + B1D5F0C420BC06CB00983FB6 /* code_release_resource_Task@2x.png in Resources */, + B1D5F0C520BC06CB00983FB6 /* moreBtn_Nav@3x.png in Resources */, + B1D5F0C620BC06CB00983FB6 /* tweet_comment_btn@3x.png in Resources */, + B1D5F0C720BC06CB00983FB6 /* vip_3_30@2x.png in Resources */, + B1D5F0C820BC06CB00983FB6 /* PR_del_label@3x.png in Resources */, + B1D5F0C920BC06CB00983FB6 /* blankpage_image_Team@2x.png in Resources */, + B1D5F0CA20BC06CB00983FB6 /* icon_release_tag_blue@2x.png in Resources */, + B16E6D1A20C147770076026D /* team_cell_edit_pro@3x.png in Resources */, + B1D5F0CB20BC06CB00983FB6 /* btn_privateMsg_stranger@2x.png in Resources */, + B1D5F0CC20BC06CB00983FB6 /* project_item_wiki@3x.png in Resources */, + B1D5F0CD20BC06CB00983FB6 /* STARTIMAGE.jpg in Resources */, + B1D5F0CE20BC06CB00983FB6 /* messageComment@3x.png in Resources */, + B1D5F0CF20BC06CB00983FB6 /* coding_emoji_02@2x.png in Resources */, + B1D5F0D020BC06CB00983FB6 /* checkbox_checked@2x.png in Resources */, + B1D5F0D120BC06CB00983FB6 /* taskboard_blankpage@2x.png in Resources */, + B1D5F0D220BC06CB00983FB6 /* member_cell_edit_type@3x.png in Resources */, + B1D5F0D320BC06CB00983FB6 /* PR_del_label@2x.png in Resources */, + B1D5F0D420BC06CB00983FB6 /* SVWebViewController.strings in Resources */, + B1D5F0D520BC06CB00983FB6 /* blankpage_image_Topic@3x.png in Resources */, + B1D5F0D720BC06CB00983FB6 /* placeholder_monkey_round_33@2x.png in Resources */, + B1D5F0D820BC06CB00983FB6 /* coding_emoji_30@2x.png in Resources */, + B1D5F0D920BC06CB00983FB6 /* project_item_code@2x.png in Resources */, + B16E6DCD20C1493A0076026D /* intro_icon_file_down.gif in Resources */, + B1D5F0DA20BC06CB00983FB6 /* search_icon_user@3x.png in Resources */, + B1D5F0DB20BC06CB00983FB6 /* code_release_resource_MergeRequestBean@3x.png in Resources */, + B1D5F0DD20BC06CB00983FB6 /* blankpage_image_Default@2x.png in Resources */, + B1D5F0DE20BC06CB00983FB6 /* project_item_tag@2x.png in Resources */, + B1D5F0DF20BC06CB00983FB6 /* PRReviewer@2x.png in Resources */, + B1D5F0E020BC06CB00983FB6 /* login_wechat@2x.png in Resources */, + B1D5F0E120BC06CB00983FB6 /* task_activity_icon_finish@3x.png in Resources */, + B1D5F0E220BC06CB00983FB6 /* taskboard_normal_page_unselected@3x.png in Resources */, + B1D5F0E420BC06CB00983FB6 /* nav_page_selected@2x.png in Resources */, + B1D5F0E520BC06CB00983FB6 /* coding_emoji_28@2x.png in Resources */, + B1D5F0E720BC06CB00983FB6 /* placeholder_monkey_round_50@2x.png in Resources */, + B1D5F0E820BC06CB00983FB6 /* vip_3_45@2x.png in Resources */, + B1D5F0E920BC06CB00983FB6 /* n_sex_man_icon@2x.png in Resources */, + B1D5F0EA20BC06CB00983FB6 /* AppIcon120x120.png in Resources */, + B1D5F0EB20BC06CB00983FB6 /* privatemessage_selected@2x.png in Resources */, + B1D5F0EC20BC06CB00983FB6 /* coding_emoji_gif_07@2x.png in Resources */, + B1D5F0ED20BC06CB00983FB6 /* calendar_0x59A2FF@2x.png in Resources */, + B1D5F0EE20BC06CB00983FB6 /* file_activity_icon_rename@3x.png in Resources */, + B1D5F0EF20BC06CB00983FB6 /* button_file_denete_enable@3x.png in Resources */, + B1D5F0F020BC06CB00983FB6 /* coding_emoji_32@2x.png in Resources */, + B1D5F0F120BC06CB00983FB6 /* coding_emoji_16@2x.png in Resources */, + B1D5F0F220BC06CB00983FB6 /* icon_triangle@3x.png in Resources */, + B1D5F0F320BC06CB00983FB6 /* mrpr_icon_arrow@3x.png in Resources */, + B1D5F0F420BC06CB00983FB6 /* comment_bg@3x.png in Resources */, + B1D5F0F620BC06CB00983FB6 /* btn_followed_both@2x.png in Resources */, + B1D5F0F720BC06CB00983FB6 /* PR_refuse@3x.png in Resources */, + B1D5F0F820BC06CB00983FB6 /* shortcut_tweet@2x.png in Resources */, + B1D5F0F920BC06CB00983FB6 /* vip_3_30@3x.png in Resources */, + B1D5F0FA20BC06CB00983FB6 /* coding_emoji_42@2x.png in Resources */, + B1D5F0FB20BC06CB00983FB6 /* coding_emoji_31@2x.png in Resources */, + B1D5F0FC20BC06CB00983FB6 /* user_info_setup@2x.png in Resources */, + B1D5F0FD20BC06CB00983FB6 /* calendar_0xF56061@3x.png in Resources */, + B16E6CCD20C144930076026D /* done_Nav@3x.png in Resources */, + B1D5F0FE20BC06CB00983FB6 /* blankpage_image_File@2x.png in Resources */, + B1D5F0FF20BC06CB00983FB6 /* icon_add_comment@3x.png in Resources */, + B1D5F10020BC06CB00983FB6 /* button_file_download_enable@2x.png in Resources */, + B1D5F10120BC06CB00983FB6 /* keyboard_page_selected@2x.png in Resources */, + B1D5F10220BC06CB00983FB6 /* taskPriority3@3x.png in Resources */, + B16E6CE820C145BF0076026D /* quick_menu_icon_2fa@2x.png in Resources */, + B1D5F10320BC06CB00983FB6 /* code.html in Resources */, + B1D5F10420BC06CB00983FB6 /* timeline_icon_read@3x.png in Resources */, + B1D5F10520BC06CB00983FB6 /* file_activity_icon_delete_history@3x.png in Resources */, + B1D5F10620BC06CB00983FB6 /* mrpr_icon_commit@2x.png in Resources */, + B1D5F10720BC06CB00983FB6 /* editBoardList@2x.png in Resources */, + B1D5F10820BC06CB00983FB6 /* pop_User@2x.png in Resources */, + B1D5F10920BC06CB00983FB6 /* keyboard_add_photo@2x.png in Resources */, + B1D5F10A20BC06CB00983FB6 /* member_cell_edit_type@2x.png in Resources */, + B1D5F10B20BC06CB00983FB6 /* wiki_menu_icon_delete@2x.png in Resources */, + B1D5F10C20BC06CB00983FB6 /* file_menu_icon_edit@2x.png in Resources */, + B1D5F10D20BC06CB00983FB6 /* AboutPointViewController.xib in Resources */, + B16E6D0E20C147770076026D /* team_info_mem@2x.png in Resources */, + B1D5F10E20BC06CB00983FB6 /* address.json in Resources */, + B1D5F10F20BC06CB00983FB6 /* reward_tip_logo@3x.png in Resources */, + B1D5F11020BC06CB00983FB6 /* code_release_resource_ProjectFile@2x.png in Resources */, + B1D5F11120BC06CB00983FB6 /* share_Nav@3x.png in Resources */, + B1D5F11220BC06CB00983FB6 /* task_activity_icon_add_milestone@2x.png in Resources */, + B1D5F11320BC06CB00983FB6 /* share_btn_copylink@2x.png in Resources */, + B1D5F11420BC06CB00983FB6 /* project_item_branch@3x.png in Resources */, + B1D5F11620BC06CB00983FB6 /* bubble_left_play_0@2x.png in Resources */, + B1D5F11720BC06CB00983FB6 /* little_phone_icon@3x.png in Resources */, + B1D5F11820BC06CB00983FB6 /* icon_file_ppt@2x.png in Resources */, + B1D5F11920BC06CB00983FB6 /* member_type_75@2x.png in Resources */, + B1D5F11A20BC06CB00983FB6 /* icon_search_searchbar@2x.png in Resources */, + B1D5F11B20BC06CB00983FB6 /* register_step_ed@2x.png in Resources */, + B1D5F11C20BC06CB00983FB6 /* project_normal@3x.png in Resources */, + B1D5F11D20BC06CB00983FB6 /* button_terminal@2x.png in Resources */, + B1D5F11E20BC06CB00983FB6 /* privatemessage_normal@2x.png in Resources */, + B1D5F11F20BC06CB00983FB6 /* tipIcon_ProjectMember@2x.png in Resources */, + B1D5F12020BC06CB00983FB6 /* file_activity_icon_rename@2x.png in Resources */, + B1D5F12120BC06CB00983FB6 /* code_release_resource_ProjectTopic@2x.png in Resources */, + B1D5F12220BC06CB00983FB6 /* coding_emoji_17@2x.png in Resources */, + B1D5F12320BC06CB00983FB6 /* messageLeft_bg_img@2x.png in Resources */, + B1D5F12420BC06CB00983FB6 /* search_icon_project@2x.png in Resources */, + B1D5F12520BC06CB00983FB6 /* mrpr_icon_status_cancel@2x.png in Resources */, + B1D5F12620BC06CB00983FB6 /* mrpr_icon_status_cancel@3x.png in Resources */, + B1D5F12720BC06CB00983FB6 /* button_file_createFolder_enable@3x.png in Resources */, + B16E6DD020C149440076026D /* intro_page0_ip5@2x.png in Resources */, + B1D5F12820BC06CB00983FB6 /* PR_mergeChanges@2x.png in Resources */, + B1D5F12920BC06CB00983FB6 /* coding_emoji_20@2x.png in Resources */, + B1D5F12A20BC06CB00983FB6 /* Images.xcassets in Resources */, + B1D5F12B20BC06CB00983FB6 /* task_icon_arrow@2x.png in Resources */, + B1D5F12C20BC06CB00983FB6 /* mrpr_icon_refaused@2x.png in Resources */, + B1D5F12D20BC06CB00983FB6 /* loading_monkey@2x.png in Resources */, + B1D5F12E20BC06CB00983FB6 /* coding_emoji_01@2x.png in Resources */, + B1D5F12F20BC06CB00983FB6 /* taskPriority0@3x.png in Resources */, + B16E6D1620C147770076026D /* team_cell_edit_delete@3x.png in Resources */, + B1D5F13020BC06CB00983FB6 /* taskPriority3_small@3x.png in Resources */, + B1D5F13120BC06CB00983FB6 /* taskResourceReference@2x.png in Resources */, + B1D5F13220BC06CB00983FB6 /* tipIcon_MergeRequestBean@2x.png in Resources */, + B1D5F13320BC06CB00983FB6 /* button_file_denete_enable@2x.png in Resources */, + B1D5F13520BC06CB00983FB6 /* dot_line@2x.png in Resources */, + B1D5F13620BC06CB00983FB6 /* PR_grant_undo@3x.png in Resources */, + B1D5F13720BC06CB00983FB6 /* PR_add_watcher@3x.png in Resources */, + B1D5F13820BC06CB00983FB6 /* coding_emoji_gif_01@2x.png in Resources */, + B1D5F13920BC06CB00983FB6 /* addBtn_Artboard@2x.png in Resources */, + B1D5F13B20BC06CB00983FB6 /* project_item_wiki@2x.png in Resources */, + B1D5F13C20BC06CB00983FB6 /* member_type_90@2x.png in Resources */, + B1D5F13D20BC06CB00983FB6 /* share_btn_inform@2x.png in Resources */, + B1D5F13E20BC06CB00983FB6 /* back_green_Nav@3x.png in Resources */, + B1D5F13F20BC06CB00983FB6 /* README.textile in Resources */, + B1D5F14020BC06CB00983FB6 /* PR_del_reviewer@3x.png in Resources */, + B1D5F14120BC06CB00983FB6 /* search_icon_task@3x.png in Resources */, + B1D5F14220BC06CB00983FB6 /* task_activity_icon_remove_milestone@2x.png in Resources */, + B1D5F14320BC06CB00983FB6 /* checkbox_unchecked@3x.png in Resources */, + B1D5F14420BC06CB00983FB6 /* coding_emoji_06@2x.png in Resources */, + B1D5F14520BC06CB00983FB6 /* button_tip_close@3x.png in Resources */, + B1D5F14620BC06CB00983FB6 /* blankpage_image_ShopOrder@2x.png in Resources */, + B1D5F14720BC06CB00983FB6 /* coding_emoji_40@2x.png in Resources */, + B1D5F14820BC06CB00983FB6 /* blankpage_image_Default@3x.png in Resources */, + B1D5F14920BC06CB00983FB6 /* member_cell_edit_alias@2x.png in Resources */, + B1D5F14A20BC06CB00983FB6 /* messageRight_bg_img@2x.png in Resources */, + B1D5F14B20BC06CB00983FB6 /* project_item_taskboard@2x.png in Resources */, + B1D5F14C20BC06CB00983FB6 /* nav_page_selected@3x.png in Resources */, + B1D5F14D20BC06CB00983FB6 /* terminal_more@3x.png in Resources */, + B16E6CCF20C144930076026D /* done_un_Nav@2x.png in Resources */, + B1D5F14E20BC06CB00983FB6 /* btn_setFrequent@3x.png in Resources */, + B1D5F14F20BC06CB00983FB6 /* tweet_normal@3x.png in Resources */, + B1D5F15020BC06CB00983FB6 /* icon_search_clock@2x.png in Resources */, + B1D5F15120BC06CB00983FB6 /* taskPriority2@2x.png in Resources */, + B1D5F15220BC06CB00983FB6 /* file_activity_icon_upload_file@2x.png in Resources */, + B1D5F15320BC06CB00983FB6 /* tip_normal_Nav@2x.png in Resources */, + B1D5F15420BC06CB00983FB6 /* search_icon_user@2x.png in Resources */, + B16E6DC520C149350076026D /* intro_dot_light_unselected@3x.png in Resources */, + B1D5F15520BC06CB00983FB6 /* button_file_denete_unable@2x.png in Resources */, + B1D5F15620BC06CB00983FB6 /* nav_page_unselected@3x.png in Resources */, + B1D5F15720BC06CB00983FB6 /* EmojisList.plist in Resources */, + B1D5F15820BC06CB00983FB6 /* keyboard_topic@2x.png in Resources */, + B1D5F15920BC06CB00983FB6 /* project_item_tag@3x.png in Resources */, + B1D5F15A20BC06CB00983FB6 /* add_user_icon@2x.png in Resources */, + B1D5F15B20BC06CB00983FB6 /* coding_emoji_11@2x.png in Resources */, + B16E6DDD20C149440076026D /* intro_page2_ip4@2x.png in Resources */, + B1D5F15C20BC06CB00983FB6 /* coding_emoji_gif_02@2x.png in Resources */, + B1D5F15D20BC06CB00983FB6 /* n_sex_woman_icon@2x.png in Resources */, + B1D5F15E20BC06CB00983FB6 /* vip_4_30@3x.png in Resources */, + B1D5F15F20BC06CB00983FB6 /* taskPriority@3x.png in Resources */, + B1D5F16020BC06CB00983FB6 /* tipIcon_TeamMember@2x.png in Resources */, + B1D5F16120BC06CB00983FB6 /* keyboard_emotion_delete@2x.png in Resources */, + B1D5F16220BC06CB00983FB6 /* nav_tweet_friend@2x.png in Resources */, + B1D5F16320BC06CB00983FB6 /* nav_tweet_mine@2x.png in Resources */, + B1D5F16420BC06CB00983FB6 /* shortcut_2FA@3x.png in Resources */, + B1D5F16520BC06CB00983FB6 /* PR_add@3x.png in Resources */, + B1D5F16620BC06CB00983FB6 /* code_release_resource_Zip@3x.png in Resources */, + B1D5F16720BC06CB00983FB6 /* taskboard_add_page_unselected@3x.png in Resources */, + B1D5F16820BC06CB00983FB6 /* blankpage_image_Activity@3x.png in Resources */, + B1D5F16920BC06CB00983FB6 /* pop_Tweet@3x.png in Resources */, + B1D5F16A20BC06CB00983FB6 /* icon_code_image@3x.png in Resources */, + B1D5F16B20BC06CB00983FB6 /* taskboard_normal_page_selected@3x.png in Resources */, + B1D5F16D20BC06CB00983FB6 /* icon_file_txt_big@2x.png in Resources */, + B1D5F16E20BC06CB00983FB6 /* git_icon_stared@2x.png in Resources */, + B1D5F16F20BC06CB00983FB6 /* search_icon_mr@2x.png in Resources */, + B1D5F17020BC06CB00983FB6 /* button_download_cancel@2x.png in Resources */, + B1D5F17120BC06CB00983FB6 /* SVWebViewController.bundle in Resources */, + B1D5F17220BC06CB00983FB6 /* register_step_ed@3x.png in Resources */, + B1D5F17320BC06CB00983FB6 /* keyboard_emotion_emoji_code@2x.png in Resources */, + B1D5F17420BC06CB00983FB6 /* cell_arrow_left@3x.png in Resources */, + B1D5F17520BC06CB00983FB6 /* vip_3_40@2x.png in Resources */, + B1D5F17620BC06CB00983FB6 /* icon_code_git_link@2x.png in Resources */, + B1D5F17720BC06CB00983FB6 /* icon_add_comment@2x.png in Resources */, + B1D5F17920BC06CB00983FB6 /* icon_file_code_big@2x.png in Resources */, + B1D5F17A20BC06CB00983FB6 /* file_changeType_DELETE@3x.png in Resources */, + B1D5F17B20BC06CB00983FB6 /* tweet_more_comment_icon@2x.png in Resources */, + B1D5F17C20BC06CB00983FB6 /* task_activity_icon_add_watcher@2x.png in Resources */, + B1D5F17D20BC06CB00983FB6 /* tipIcon_TweetLike@2x.png in Resources */, + B16E6DCB20C1493A0076026D /* intro_icon_code_up.gif in Resources */, + B1D5F17E20BC06CB00983FB6 /* blankpage_image_LoadFail@2x.png in Resources */, + B1D5F17F20BC06CB00983FB6 /* gif_mark@2x.png in Resources */, + B1D5F18020BC06CB00983FB6 /* icon_file_cell_delete@2x.png in Resources */, + B1D5F18120BC06CB00983FB6 /* blankpage_image_Topic@2x.png in Resources */, + B1D5F18220BC06CB00983FB6 /* MJPhotoBrowser.bundle in Resources */, + B1D5F18320BC06CB00983FB6 /* icon_file_folder_share@2x.png in Resources */, + B1D5F18420BC06CB00983FB6 /* search_icon_pr@3x.png in Resources */, + B1D5F18520BC06CB00983FB6 /* SVWebViewControllerActivityChrome@2x.png in Resources */, + B1D5F18620BC06CB00983FB6 /* taskboard_add_page_selected@3x.png in Resources */, + B1D5F18720BC06CB00983FB6 /* SVWebViewControllerActivitySafari@2x.png in Resources */, + B1D5F18820BC06CB00983FB6 /* editBoardList@3x.png in Resources */, + B1D5F18A20BC06CB00983FB6 /* PR_add@2x.png in Resources */, + B1D5F18B20BC06CB00983FB6 /* tweet_btn_reward@2x.png in Resources */, + B1D5F18C20BC06CB00983FB6 /* project_item_mr_pr@2x.png in Resources */, + B16E6DC220C1492F0076026D /* intro_dot_dark_selected@2x.png in Resources */, + B1D5F18D20BC06CB00983FB6 /* user_info_point@2x.png in Resources */, + B1D5F18E20BC06CB00983FB6 /* btn_fliter_down@2x.png in Resources */, + B1D5F18F20BC06CB00983FB6 /* nav_project_activity@2x.png in Resources */, + B16E6CE420C145BF0076026D /* quick_menu_icon_project@3x.png in Resources */, + B1D5F19020BC06CB00983FB6 /* file_changeType_RENAME@2x.png in Resources */, + B1D5F19120BC06CB00983FB6 /* blankpage_image_Tip@3x.png in Resources */, + B1D5F19220BC06CB00983FB6 /* ProjectSetting.storyboard in Resources */, + B1D5F19320BC06CB00983FB6 /* icon_release_tag@3x.png in Resources */, + B1D5F19420BC06CB00983FB6 /* timeline_icon_unread@2x.png in Resources */, + B1D5F19520BC06CB00983FB6 /* user_info_edit@2x.png in Resources */, + B1D5F19620BC06CB00983FB6 /* AlipaySDK.bundle in Resources */, + B16E6D0220C147770076026D /* team_info_pro@3x.png in Resources */, + B1D5F19720BC06CB00983FB6 /* banner__page_selected@2x.png in Resources */, + B16E6CE220C145BF0076026D /* quick_menu_icon_task@2x.png in Resources */, + B1D5F19820BC06CB00983FB6 /* task_resource_reference_MergeRequestBean@3x.png in Resources */, + B1D5F19920BC06CB00983FB6 /* tipIcon_ProjectFileComment@2x.png in Resources */, + B1D5F19A20BC06CB00983FB6 /* SVWebViewControllerActivitySafari-iPad@2x.png in Resources */, + B1D5F19B20BC06CB00983FB6 /* icon_not_locationed@2x.png in Resources */, + B1D5F19C20BC06CB00983FB6 /* checkbox_unchecked@2x.png in Resources */, + B1D5F19D20BC06CB00983FB6 /* icon_file_psd_big@2x.png in Resources */, + B16E6CB020C13BF50076026D /* btn_next_unable@2x.png in Resources */, + B1D5F19E20BC06CB00983FB6 /* timeline_icon_read@2x.png in Resources */, + B1D5F19F20BC06CB00983FB6 /* topic_add_watcher_btn@3x.png in Resources */, + B1D5F1A020BC06CB00983FB6 /* coding_emoji_27@2x.png in Resources */, + B1D5F1A120BC06CB00983FB6 /* QBImagePicker.strings in Resources */, + B1D5F1A220BC06CB00983FB6 /* icon_file_zip_big@2x.png in Resources */, + B16E6D1220C147770076026D /* team_cell_edit_team@3x.png in Resources */, + B1D5F1A320BC06CB00983FB6 /* messageProjectFollows@3x.png in Resources */, + B1D5F1A420BC06CB00983FB6 /* tipIcon_CommitLineNote@2x.png in Resources */, + B1D5F1A520BC06CB00983FB6 /* wiki_revert@2x.png in Resources */, + B1D5F1A620BC06CB00983FB6 /* search_icon_tweet@3x.png in Resources */, + B1D5F1A720BC06CB00983FB6 /* taskPriority0_small@3x.png in Resources */, + B16E6DD520C149440076026D /* intro_page1_ip6+@3x.png in Resources */, + B1D5F1A820BC06CB00983FB6 /* coding_emoji_24@2x.png in Resources */, + B1D5F1A920BC06CB00983FB6 /* PointLikeHead@2x.png in Resources */, + B1D5F1AA20BC06CB00983FB6 /* coding_emoji_10@2x.png in Resources */, + B1D5F1AB20BC06CB00983FB6 /* me_normal@2x.png in Resources */, + B1D5F1AC20BC06CB00983FB6 /* taskPriority2@3x.png in Resources */, + B1D5F1AD20BC06CB00983FB6 /* blankpage_image_Activity@2x.png in Resources */, + B1DFD0A820C67D3F00F75F2F /* btn_privateMsg_friend@3x.png in Resources */, + B1D5F1AE20BC06CB00983FB6 /* coding_emoji_33@2x.png in Resources */, + B1D5F1AF20BC06CB00983FB6 /* coding_emoji_23@2x.png in Resources */, + B1D5F1B020BC06CB00983FB6 /* taskPriority@2x.png in Resources */, + B1D5F1B120BC06CB00983FB6 /* code_release_resource_ProjectFile@3x.png in Resources */, + B1D5F1B220BC06CB00983FB6 /* tipIcon_Task@2x.png in Resources */, + B1D5F1B320BC06CB00983FB6 /* icon_code_file@2x.png in Resources */, + B1D5F1B420BC06CB00983FB6 /* task_activity_icon_update_description@2x.png in Resources */, + B1D5F1B520BC06CB00983FB6 /* git_icon_star@2x.png in Resources */, + B1D5F1B620BC06CB00983FB6 /* task_description_icon@2x.png in Resources */, + B1D5F1B720BC06CB00983FB6 /* tag_button_editColor@3x.png in Resources */, + B1D5F1B820BC06CB00983FB6 /* moreBtn_Nav@2x.png in Resources */, + B1D5F1BB20BC06CB00983FB6 /* coding_emoji_19@2x.png in Resources */, + B1D5F1BC20BC06CB00983FB6 /* PR_review_undo@3x.png in Resources */, + B1D5F1BD20BC06CB00983FB6 /* taskPriority1@3x.png in Resources */, + B1D5F1BE20BC06CB00983FB6 /* alipay@3x.png in Resources */, + B16E6D0420C147770076026D /* team_info_pro@2x.png in Resources */, + B1D5F1BF20BC06CB00983FB6 /* PR_more@3x.png in Resources */, + B1D5F1C020BC06CB00983FB6 /* share_btn_wxsession@2x.png in Resources */, + B1D5F1C120BC06CB00983FB6 /* task_activity_icon_MergeRequestBean@2x.png in Resources */, + B1D5F1C220BC06CB00983FB6 /* icon_file_txt@2x.png in Resources */, + B1D5F1C320BC06CB00983FB6 /* project_item_member@3x.png in Resources */, + B1D5F1C420BC06CB00983FB6 /* timeline_line_unread@2x.png in Resources */, + B1D5F1C520BC06CB00983FB6 /* tip_2FA@2x.png in Resources */, + B1D5F1C620BC06CB00983FB6 /* PR_add_label@3x.png in Resources */, + B1D5F1C720BC06CB00983FB6 /* back_T_Nav@2x.png in Resources */, + B1D5F1C820BC06CB00983FB6 /* checkbox_checked@3x.png in Resources */, + B1D5F1C920BC06CB00983FB6 /* coding_emoji_05@2x.png in Resources */, + B1D5F1CA20BC06CB00983FB6 /* alipay@2x.png in Resources */, + B1DFD0A420C67D3F00F75F2F /* btn_followed_not@3x.png in Resources */, + B16E6DD820C149440076026D /* intro_page0_ip4@2x.png in Resources */, + B1D5F1CC20BC06CB00983FB6 /* taskPriority0@2x.png in Resources */, + B1D5F1CD20BC06CB00983FB6 /* task_activity_icon_update_label@2x.png in Resources */, + B1D5F1CE20BC06CB00983FB6 /* wiki_menu_2@3x.png in Resources */, + B1D5F1CF20BC06CB00983FB6 /* blankpage_image_Tip@2x.png in Resources */, + B1D5F1D020BC06CB00983FB6 /* keyboard_add_camera@2x.png in Resources */, + B16E6DCE20C1493A0076026D /* intro_icon_task_down.gif in Resources */, + B1D5F1D120BC06CB00983FB6 /* btn_fliter_down@3x.png in Resources */, + B1D5F1D220BC06CB00983FB6 /* topic-ios.html in Resources */, + B1D5F1D320BC06CB00983FB6 /* user_info_help@2x.png in Resources */, + B1D5F1D420BC06CB00983FB6 /* SVWebViewControllerActivitySafari-iPad.png in Resources */, + B1D5F1D520BC06CB00983FB6 /* icon_triangle@2x.png in Resources */, + B1D5F1D620BC06CB00983FB6 /* comment_count_top_line@2x.png in Resources */, + B1D5F1D720BC06CB00983FB6 /* keyboard_voice_record@2x.png in Resources */, + B1D5F1D820BC06CB00983FB6 /* icon_file_music_big@2x.png in Resources */, + B1D5F1D920BC06CB00983FB6 /* password_unlook@2x.png in Resources */, + B1D5F1DA20BC06CB00983FB6 /* coding_emoji_gif_03@2x.png in Resources */, + B1D5F1DB20BC06CB00983FB6 /* mrpr_icon_arrow@2x.png in Resources */, + B1D5F1DC20BC06CB00983FB6 /* vip_3_45@3x.png in Resources */, + B1D5F1DD20BC06CB00983FB6 /* splitlineImg@2x.png in Resources */, + B1D5F1DE20BC06CB00983FB6 /* button_file_move_enable@3x.png in Resources */, + B1D5F1DF20BC06CB00983FB6 /* wiki_menu_0@2x.png in Resources */, + B1D5F1E020BC06CB00983FB6 /* icon_release_tag_blue@3x.png in Resources */, + B1D5F1E120BC06CB00983FB6 /* search_icon_topic@2x.png in Resources */, + B1D5F1E220BC06CB00983FB6 /* file_activity_icon_delete_history@2x.png in Resources */, + B1D5F1E320BC06CB00983FB6 /* icon_file_unknown_big@2x.png in Resources */, + B1D5F1E420BC06CB00983FB6 /* sex_woman_icon@2x.png in Resources */, + B1D5F1E520BC06CB00983FB6 /* privatemessage_selected@3x.png in Resources */, + B1D5F1E620BC06CB00983FB6 /* tipIcon_TaskComment@2x.png in Resources */, + B1D5F1E720BC06CB00983FB6 /* taskDeadline@2x.png in Resources */, + B1D5F1E820BC06CB00983FB6 /* AddReviewerViewController.xib in Resources */, + B1D5F1E920BC06CB00983FB6 /* shop_exchange_icon@3x.png in Resources */, + B1D5F1EA20BC06CB00983FB6 /* vip_3_40@3x.png in Resources */, + B1D5F1EC20BC06CB00983FB6 /* button_file_activity@2x.png in Resources */, + B1D5F1ED20BC06CB00983FB6 /* file_activity_icon_update_file@2x.png in Resources */, + B1D5F1EE20BC06CB00983FB6 /* nav_project_code@2x.png in Resources */, + B1D5F1EF20BC06CB00983FB6 /* user_info_project@3x.png in Resources */, + B1D5F1F020BC06CB00983FB6 /* taskBoardList@2x.png in Resources */, + B1D5F1F120BC06CB00983FB6 /* coding_emoji_gif_08@2x.png in Resources */, + B1D5F1F220BC06CB00983FB6 /* icon_project_private@2x.png in Resources */, + B1D5F1F320BC06CB00983FB6 /* search_Nav@2x.png in Resources */, + B1D5F1F420BC06CB00983FB6 /* terminal_box_selected@3x.png in Resources */, + B1D5F1F520BC06CB00983FB6 /* twoFABtn_Nav@2x.png in Resources */, + B15C98B320D39CA200DDA425 /* project_icon_edit@3x.png in Resources */, + B1D5F1F620BC06CB00983FB6 /* project_selected@3x.png in Resources */, + B1D5F1F720BC06CB00983FB6 /* task_activity_icon_MergeRequestBean@3x.png in Resources */, + B1D5F1F820BC06CB00983FB6 /* tweet_selected@3x.png in Resources */, + B1D5F1F920BC06CB00983FB6 /* taskPriority3@2x.png in Resources */, + B1D5F1FA20BC06CB00983FB6 /* search_icon_file@2x.png in Resources */, + B1D5F1FB20BC06CB00983FB6 /* nav_page_unselected@2x.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 23542360C260462A83BCBCAD /* Check Pods Manifest.lock */ = { + 4E9EC23F1E0B78F00098C761 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "$(SRCROOT)/Carthage/Build/iOS/ObjectiveGit.framework", ); - name = "Check Pods Manifest.lock"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + shellScript = "/usr/local/bin/carthage copy-frameworks"; showEnvVarsInLog = 0; }; - 2BE7A354A6FF9E5410B304BF /* Embed Pods Frameworks */ = { + B1D5EBF220BC06CB00983FB6 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); - name = "Embed Pods Frameworks"; + name = "[CP] Check Pods Manifest.lock"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Coding_iOS-Coding_Enterprise_iOS-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Coding_iOS/Pods-Coding_iOS-frameworks.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 96A9263FF11A4AA8B5F6BB6B /* Copy Pods Resources */ = { + B1D5F1FC20BC06CB00983FB6 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Coding_iOS-Coding_Enterprise_iOS/Pods-Coding_iOS-Coding_Enterprise_iOS-resources.sh", + "${PODS_ROOT}/FontAwesome+iOS/Resources/FontAwesome.ttf", + "${PODS_ROOT}/UMengUShare/UShareSDK/UMSocialSDK/UMSocialSDKPromptResources.bundle", + "${PODS_ROOT}/UMengUShare/UShareSDK/SocialLibraries/QQ/QQSDK/TencentOpenApi_IOS_Bundle.bundle", + "${PODS_ROOT}/UMengUShare/UShareSDK/SocialLibraries/Sina/SinaSDK/WeiboSDK.bundle", + "${PODS_ROOT}/evernote-cloud-sdk-ios/ENSDKResources.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome.ttf", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UMSocialSDKPromptResources.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TencentOpenApi_IOS_Bundle.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/WeiboSDK.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ENSDKResources.bundle", + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Coding_iOS-Coding_Enterprise_iOS/Pods-Coding_iOS-Coding_Enterprise_iOS-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + B1D5F1FE20BC06CB00983FB6 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "$(SRCROOT)/Carthage/Build/iOS/ObjectiveGit.framework", ); - name = "Copy Pods Resources"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Coding_iOS/Pods-Coding_iOS-resources.sh\"\n"; + shellScript = "/usr/local/bin/carthage copy-frameworks"; + showEnvVarsInLog = 0; + }; + B7C390DEFD2073480C56FD88 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Coding_iOS/Pods-Coding_iOS-resources.sh", + "${PODS_ROOT}/FontAwesome+iOS/Resources/FontAwesome.ttf", + "${PODS_ROOT}/UMengUShare/UShareSDK/UMSocialSDK/UMSocialSDKPromptResources.bundle", + "${PODS_ROOT}/UMengUShare/UShareSDK/SocialLibraries/QQ/QQSDK/TencentOpenApi_IOS_Bundle.bundle", + "${PODS_ROOT}/UMengUShare/UShareSDK/SocialLibraries/Sina/SinaSDK/WeiboSDK.bundle", + "${PODS_ROOT}/evernote-cloud-sdk-ios/ENSDKResources.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome.ttf", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UMSocialSDKPromptResources.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TencentOpenApi_IOS_Bundle.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/WeiboSDK.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ENSDKResources.bundle", + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Coding_iOS/Pods-Coding_iOS-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + B7F20F3BC924F718A926E931 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Coding_iOS-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -6560,7 +11363,6 @@ 4E8765691A22E5B40090CFB9 /* SWUtilityButtonTapGestureRecognizer.m in Sources */, 4ECE8B041A3946C10021E29C /* UnReadManager.m in Sources */, 4EA679131A1466A6001A0324 /* ProjectFiles.m in Sources */, - 4EBDA87C1A6640340035ED96 /* UIActionSheet+Common.m in Sources */, 4E4D6A581B1C5DC000FD2E49 /* MRPRCommentCell.m in Sources */, 7EB02FF11B6D111300D2166C /* AudioPlayView.m in Sources */, B94C1B6E1AC98CCE0000C271 /* NewProjectTypeViewController.m in Sources */, @@ -6574,10 +11376,14 @@ 8EF643C919FF7E2900F7EEB0 /* TopicCommentCell.m in Sources */, 7EB02FF61B6DAF3800D2166C /* AudioVolumeView.m in Sources */, 4E8D5D6E1B45400100B70936 /* ZXScanCodeViewController.m in Sources */, + 4E3068431E0B781A00AEE0CE /* LDNetTimer.m in Sources */, + B16EEF13209080D7005ABFD5 /* TaskBoardsViewController.m in Sources */, 4ECD72EF1AAD7EC300D69AE1 /* Tweet.m in Sources */, 13DA65E81CBE668E00810CB7 /* PRDetailViewController.m in Sources */, 8EF643CD19FF7E2900F7EEB0 /* TweetCommentMoreCell.m in Sources */, 8E59F1001A01133C009A905F /* CodeTree.m in Sources */, + B1890C3D2015D8C900F52ABA /* WikiMenuListCell.m in Sources */, + B1944147206BB89100147158 /* EALocalCodeViewController.m in Sources */, 4E93F2331B84243D00017916 /* KxMenu.m in Sources */, D0C447B91C02C63000DC1C4B /* UserSearchCell.m in Sources */, 4E83AE7B1CF30F1A006BA3BB /* SettingEmailViewController.m in Sources */, @@ -6596,14 +11402,19 @@ 4E4D6A851B1C6D8200FD2E49 /* FileChangeListCell.m in Sources */, 4E996BE21ABA957B00C704F1 /* ProjectListViewController.m in Sources */, 4E743E6D1A88A3CC00DADDE5 /* EaseMarkdownTextView.m in Sources */, + 09A0588A1E0AA9AE00C1CA3F /* ActivityView.m in Sources */, 8EA6D1B519E240C40076D59C /* ListGroupItem.m in Sources */, + 4E80E93C1E02353900DE1BC6 /* CodingSearchDisplayView.m in Sources */, + B1D5F21E20BD50D000983FB6 /* ProjectRole.m in Sources */, 8EA6D13919E240C40076D59C /* MyTask_RootViewController.m in Sources */, 8E1C3E0A19E8DFE300EF3032 /* SettingAccountViewController.m in Sources */, 4E8765681A22E5B40090CFB9 /* SWTableViewCell.m in Sources */, 4E94C4E71B4A6AC700EB668A /* ScanBGView.m in Sources */, + B12B641F1FF2835800ACFDCC /* CodingVipTipManager.m in Sources */, 4E0BD8701B6C7E3D0061CAA6 /* CSTopicHeaderView.m in Sources */, 4EBB624D1A6F526C0045DAEF /* NJKWebViewProgressView.m in Sources */, 4E6383F21B32CC7600D98648 /* TaskActivityCell.m in Sources */, + 09A058801E0AA97000C1CA3F /* ActivenessModel.m in Sources */, 4E554D6E1C9804F40008686A /* Close2FAViewController.m in Sources */, 4ECE8ADA1A3943E80021E29C /* NSDate+Common.m in Sources */, 8EA6D20A19E240C40076D59C /* RDVTabBar.m in Sources */, @@ -6619,6 +11430,7 @@ 4E2ECEAD1BD4D51000CB6EC9 /* ProjectTransferSettingViewController.m in Sources */, 4EABD2571AD3CAAC005E515F /* UIMessageInputView_Add.m in Sources */, 7EB02FCE1B6CF5D500D2166C /* UIMessageInputView_Voice.m in Sources */, + B1C60C8220BFCEFD0073D3CA /* NFileListViewController.m in Sources */, 8E59F0E21A0098BA009A905F /* UIScrollView+SVInfiniteScrolling.m in Sources */, 4E0022831B72095E005308DE /* PointRecord.m in Sources */, 927AFF3E1BFF608700AAE593 /* ShopGoodsCCell.m in Sources */, @@ -6638,6 +11450,7 @@ 8EA6D1FC19E240C40076D59C /* MJPhotoView.m in Sources */, 8E59F10A1A021053009A905F /* CodeListViewController.m in Sources */, 4ECF702C1B1704C5000280FF /* NProjectItemCell.m in Sources */, + B1817EC7206397F500E9BAD1 /* EACodeReleases.m in Sources */, 4ED4B4AF1D82B28B00EED8C6 /* TeamMembersViewController.m in Sources */, 8E1C3DEC19E7D58A00EF3032 /* ActionSheetDatePicker.m in Sources */, 8EF643B619FF7E2900F7EEB0 /* Input_OnlyText_Cell.m in Sources */, @@ -6650,7 +11463,9 @@ 4EA7F1591A6D192B00A046BD /* NSData+ImageContentType.m in Sources */, 4E8D5D631B45295D00B70936 /* UIColor+MobileColors.m in Sources */, 8EA6D1FA19E240C40076D59C /* MJPhotoProgressView.m in Sources */, + 4E30683D1E0B781A00AEE0CE /* EADeviceToServerLog.m in Sources */, 4E4D6A641B1C65F700FD2E49 /* MRPRFilesViewController.m in Sources */, + B12B64821FFC73A900ACFDCC /* PHAsset+Common.m in Sources */, 4EA6791D1A15A943001A0324 /* FileListFolderCell.m in Sources */, 8EA6D1C419E240C40076D59C /* Users.m in Sources */, 8EF643D219FF7E2900F7EEB0 /* UserCell.m in Sources */, @@ -6665,24 +11480,31 @@ 8EF643BE19FF7E2900F7EEB0 /* ProjectTaskListViewCell.m in Sources */, 4ECE8AE31A3943E80021E29C /* UIDevice+Info.m in Sources */, 4EABD25D1AD3CBB9005E515F /* UIMessageInputView_Media.m in Sources */, + B12B64781FFB61AD00ACFDCC /* QBAlbumCell.m in Sources */, 4EAE06B71B7B330900179F4B /* FileActivityCell.m in Sources */, 4E6BA2E31A1EE6AF005FD721 /* UIAlertView+AFNetworking.m in Sources */, + B1890C492015D92600F52ABA /* WikiHistoryListViewController.m in Sources */, 4E4D6AAF1B2047DE00FD2E49 /* CommitCommentCell.m in Sources */, D066BB401BF623DD005AB5D6 /* ProjectAboutOthersListCell.m in Sources */, 4EA7F15F1A6D192B00A046BD /* SDWebImageManager.m in Sources */, - 8E64ED8519ED0CE3006E99DA /* QBImagePickerThumbnailView.m in Sources */, 7EB02FE41B6D0F3E00D2166C /* amrFileCodec.m in Sources */, 8E1C3E0D19E8DFE300EF3032 /* SettingViewController.m in Sources */, + 09A058891E0AA9AE00C1CA3F /* ActivityMonScrollView.m in Sources */, 8E1C3DEF19E7D58A00EF3032 /* ActionSheetStringPicker.m in Sources */, 8EF643B919FF7E2900F7EEB0 /* LeftImage_LRTextCell.m in Sources */, + B152ED4E2090B223004A6E8A /* ProjectSettingEntranceController.m in Sources */, + B1890C4D2019B29900F52ABA /* UINavigationBar+Common.m in Sources */, 926C043E1C01A212004937D8 /* ShopOrderListView.m in Sources */, 8E1C3DF119E7D58A00EF3032 /* SWActionSheet.m in Sources */, 4E1A22821AB1729700CFC14F /* ProjectInfoCell.m in Sources */, + B14DE6DE20C914E70072ECEA /* AnimatedGIFImageSerialization.m in Sources */, 8EA6D1BF19E240C40076D59C /* Task.m in Sources */, 0A0519E21ABA918100551B61 /* TweetSendDetailLoctionCell.m in Sources */, 4E5C06EB1AC4009100F427C5 /* CannotLoginViewController.m in Sources */, 927AFF381BFF1CC200AAE593 /* ShopViewController.m in Sources */, 1309BA021CA2EF370034C7A3 /* Reviewer.m in Sources */, + B1944144206BB87F00147158 /* EALocalCodeListViewController.m in Sources */, + B12B640A1FE900D400ACFDCC /* AMPopTip+Exit.m in Sources */, 8EA6D12819E240C40076D59C /* AppDelegate.m in Sources */, 7EB02FE51B6D0F3E00D2166C /* AudioAmrUtil.m in Sources */, 4ECE8AFF1A3946C10021E29C /* Coding_NetAPIManager.m in Sources */, @@ -6694,12 +11516,14 @@ D0C4481B1C034C3F00DC1C4B /* TopicSearchCell.m in Sources */, 4E4D6A6D1B1C68D700FD2E49 /* ProjectCommitsViewController.m in Sources */, 4E6BA2E61A1EE6AF005FD721 /* UIProgressView+AFNetworking.m in Sources */, + 09A0588F1E0AA9D600C1CA3F /* UserActiveGraphCell.m in Sources */, 4EB0C2001A807ED00042FC4F /* NSURL+Common.m in Sources */, 4E6BA2E71A1EE6AF005FD721 /* UIRefreshControl+AFNetworking.m in Sources */, + B1890C3E2015D8C900F52ABA /* WikiHistoryCell.m in Sources */, 4EE1A22D1B5D02CA004284F1 /* ProjectCodeListView.m in Sources */, 4EF374191BB1255E00DDA662 /* LocalFilesViewController.m in Sources */, 8EF643BF19FF7E2900F7EEB0 /* SettingTextCell.m in Sources */, - 8E64ED8419ED0CE3006E99DA /* QBImagePickerGroupCell.m in Sources */, + 4E30683F1E0B781A00AEE0CE /* LDNetConnect.m in Sources */, 136A6DBF1CAF6BAC004AA983 /* MRDetailViewController.m in Sources */, 4ECE8AE71A3943E80021E29C /* UITableView+Common.m in Sources */, 4E996BC81ABA754600C704F1 /* JDStatusBarNotification.m in Sources */, @@ -6709,16 +11533,20 @@ 4ED20A781AFC7C8B00C63498 /* EasePageViewController.m in Sources */, 8EA6D1CF19E240C40076D59C /* ObjcRuntime.m in Sources */, 4E03ACA61A5D2060002B000B /* UIVerticalAlignmentLabel.m in Sources */, + 09A0589E1E0AAA8800C1CA3F /* TaskSelectionCell.m in Sources */, + 4E30683E1E0B781A00AEE0CE /* EANetTraceRoute.m in Sources */, 4E6BA2DF1A1EE6AF005FD721 /* AFURLRequestSerialization.m in Sources */, 8EA6D1CD19E240C40076D59C /* UIUnderlinedButton.m in Sources */, 4E5F39021AC951060010515D /* TaskCommentCCell.m in Sources */, 4E095A661B6909F9008DC439 /* AutoSlideScrollView.m in Sources */, 4EF374161BB1254700DDA662 /* LocalFoldersViewController.m in Sources */, + 4E3068411E0B781A00AEE0CE /* LDNetGetAddress.m in Sources */, 4ECE8AD91A3943E80021E29C /* UIViewController+DownMenu.m in Sources */, 4E94C5011B4D2B9300EB668A /* PopMenu.m in Sources */, 8EA6D13019E240C40076D59C /* LikersViewController.m in Sources */, 8EF643C719FF7E2900F7EEB0 /* TitleValueMoreCell.m in Sources */, 4E0BD8821B6C7F0A0061CAA6 /* CSSearchModel.m in Sources */, + B1890C412015D8F700F52ABA /* WikiHeaderView.m in Sources */, 8EF643C119FF7E2900F7EEB0 /* TaskCommentCell.m in Sources */, 8E97CE481A0A2DF8006F9AD7 /* AGEmojiPageView.m in Sources */, 4E9113A31A1C426000AC9431 /* ASProgressPopUpView.m in Sources */, @@ -6731,23 +11559,29 @@ 4E72F82D1B144778001B6CE6 /* NSMutableString+Common.m in Sources */, 4E25271A1C327FAE0032A7F4 /* UIViewController+BackButtonHandler.m in Sources */, 4EBD7FB41CE4833D00B3AF49 /* CountryCodeCell.m in Sources */, + B152ED68209420CD004A6E8A /* RATaskBoardListListViewController.m in Sources */, 13C8FE7F1CA79B90001E30FA /* DynamicActivityCell.m in Sources */, 4E4D6A791B1C6C7800FD2E49 /* MRPRDetailCell.m in Sources */, 8EF643CA19FF7E2900F7EEB0 /* TopicContentCell.m in Sources */, 4E0B9A371BAD377600D57D54 /* ForkTreeCell.m in Sources */, + B12B64071FE900D400ACFDCC /* AMPopTip.m in Sources */, + B1D5F20E20BD3BF400983FB6 /* UINavigationController+FullscreenPopGesture.m in Sources */, 4E4D6A6A1B1C688200FD2E49 /* MRPRAcceptViewController.m in Sources */, 4ECE8AE81A3943E80021E29C /* UIView+Common.m in Sources */, 4EA7F15E1A6D192B00A046BD /* SDWebImageDownloaderOperation.m in Sources */, + B12B647B1FFB61AD00ACFDCC /* QBAssetsViewController.m in Sources */, 4E996BD81ABA776500C704F1 /* UserInfoIconCell.m in Sources */, 923399781C00BFC700F29E04 /* ShopOderCell.m in Sources */, 8E1C3E0C19E8DFE300EF3032 /* SettingPasswordViewController.m in Sources */, 4EAE06B41B7B325600179F4B /* FileCommentCell.m in Sources */, 4E9113A21A1C426000AC9431 /* ASPopUpView.m in Sources */, 4E6BA2E21A1EE6AF005FD721 /* UIActivityIndicatorView+AFNetworking.m in Sources */, + 4EAAD05F1E545516008AA957 /* ProjectCodeListSearchCell.m in Sources */, 0A782FDD1AB5B78B00E96661 /* TweetSendCreateLocationCell.m in Sources */, 4E07D3111A4D1484009EDDF2 /* EaseStartView.m in Sources */, 4EE1A2321B5D02CA004284F1 /* ProjectTopicListView.m in Sources */, 8EA6D13819E240C40076D59C /* Message_RootViewController.m in Sources */, + 4E3068451E0B781A00AEE0CE /* LDSimplePing.m in Sources */, 4E44DCFA1D81486600E7F9AF /* HelpViewController.m in Sources */, 4E0BD8831B6C7F0A0061CAA6 /* CSSearchVC.m in Sources */, 4EC461AD1B39084100D08970 /* FunctionTipsManager.m in Sources */, @@ -6759,9 +11593,12 @@ 0A6E6BAD1AB08540004C0107 /* TweetSendLocation.m in Sources */, 4ECE8B001A3946C10021E29C /* CodingNetAPIClient.m in Sources */, 927AFF5B1BFF772A00AAE593 /* ShopOrderTextFieldCell.m in Sources */, + 09A0589B1E0AAA7200C1CA3F /* ScreenCell.m in Sources */, 8EF643B119FF7E2900F7EEB0 /* ConversationCell.m in Sources */, 4ED4B49A1D8295EA00EED8C6 /* TeamListViewController.m in Sources */, + B186AEB020F462F600A6AF35 /* UIAlertController+Common.m in Sources */, 8EF643D019FF7E2900F7EEB0 /* TweetSendImagesCell.m in Sources */, + B1890C482015D92600F52ABA /* WikiEditViewController.m in Sources */, 4ECF704C1B1876CB000280FF /* MRPRListCell.m in Sources */, 3A38784F1AE557700078D5DE /* TopicPreviewCell.m in Sources */, 8ED0D87519FBA6EA00FBA818 /* NSString+Emojize.m in Sources */, @@ -6778,11 +11615,15 @@ 4EBD7FAF1CE4827A00B3AF49 /* CountryCodeListViewController.m in Sources */, D09AA5B71BFDA38D008CA9EB /* AllSearchDisplayVC.m in Sources */, 0A27A05D1AB5A13B00067833 /* TweetSendLocationDetailViewController.m in Sources */, + B1D5F22220BEA37600983FB6 /* MeRootCompanyCell.m in Sources */, + B1816063202063440022B4C6 /* EATerminalViewController.m in Sources */, 0AB591B01AB6D6BE0076C454 /* TweetSendMapAnnotation.m in Sources */, 4ECF70491B185BCC000280FF /* MRPR.m in Sources */, + 09A058921E0AA9FC00C1CA3F /* EaseUserInfoCell.m in Sources */, 4E095A5C1B6907AA008DC439 /* CodingBannersView.m in Sources */, 4E8D5D661B45306900B70936 /* OTPListViewController.m in Sources */, 4EA7F1651A6D192B00A046BD /* UIImageView+WebCache.m in Sources */, + B1D5F21820BD485D00983FB6 /* TeamPurchaseBilling.m in Sources */, 8EF643B819FF7E2900F7EEB0 /* InputOnlyTextPlainCell.m in Sources */, 4E095A681B6909F9008DC439 /* NSTimer+Addition.m in Sources */, 4E6BA2DB1A1EE6AF005FD721 /* AFURLSessionManager.m in Sources */, @@ -6793,33 +11634,41 @@ 8EA6D1F919E240C40076D59C /* MJPhotoLoadingView.m in Sources */, 4E753D441B8AFDEC003A00B9 /* FileEditViewController.m in Sources */, 8EA6D14419E240C40076D59C /* TopicDetailViewController.m in Sources */, + B1C60CA420C0DDF60073D3CA /* TeamSettingViewController.m in Sources */, 4EA7F1641A6D192B00A046BD /* UIImageView+HighlightedWebCache.m in Sources */, E7A046A01A47279E00528C12 /* Helper.m in Sources */, 4E00228C1B721955005308DE /* PointTopCell.m in Sources */, - 8E64ED8019ED0CE3006E99DA /* QBAssetsCollectionViewController.m in Sources */, 4ED4B4AC1D829E1200EED8C6 /* TeamMemberCell.m in Sources */, 13972E2C1CA616AC00489EBA /* ReviewerListController.m in Sources */, 4E996BD71ABA776500C704F1 /* UserInfoDetailTagCell.m in Sources */, 4E87656A1A22E5B40090CFB9 /* SWUtilityButtonView.m in Sources */, 7EB02FFC1B6E001300D2166C /* VoiceMedia.m in Sources */, 8EABE3C819F10D2400A17784 /* TaskComment.m in Sources */, + B1817EE72064FC6100E9BAD1 /* EACodeReleaseTopCell.m in Sources */, + B1BCB88F1FCE61D60098B87B /* EAPayViewController.m in Sources */, 8E97CE471A0A2DF8006F9AD7 /* AGEmojiKeyBoardView.m in Sources */, 4E53EB521AFA03990034FE1C /* RKSwipeBetweenViewControllers.m in Sources */, 8EA6D12C19E240C40076D59C /* EditTopicViewController.m in Sources */, 4E94C4FE1B4D2B9300EB668A /* GlowImageView.m in Sources */, 4E24B2681B43D33F004D7989 /* ProjectToChooseListViewController.m in Sources */, 4EA7F15B1A6D192B00A046BD /* SDWebImageCompat.m in Sources */, + B1817EEA2064FC7300E9BAD1 /* EACodeReleaseBodyCell.m in Sources */, 8EA6D13A19E240C40076D59C /* Project_RootViewController.m in Sources */, 4ECF70401B180740000280FF /* EaseGitButtonsView.m in Sources */, 8EF83F8A19E92AA500E86DE7 /* SettingTagsViewController.m in Sources */, + B194414A206BB8BB00147158 /* EALocalCodeListCell.m in Sources */, + B1D5F23220BEADD200983FB6 /* TeamSupportCell.m in Sources */, 8EF643D319FF7E2900F7EEB0 /* ValueListCell.m in Sources */, 4EB52F3F1C7C464400B5EBEA /* TaskResourceReferenceViewController.m in Sources */, 4E217F0C1A70EDC700F6DF88 /* SVModalWebViewController.m in Sources */, - 4E19E7071BCE03CD00C66DC6 /* UIActionSheet+Front.m in Sources */, + B19D4EF21F710EF900C598F3 /* ShopSwitchCell.m in Sources */, 4EF17E5F1B3AB10F003CDD2D /* IntroductionViewController.m in Sources */, 4EA7F1601A6D192B00A046BD /* SDWebImagePrefetcher.m in Sources */, 4E4D6A941B1D851E00FD2E49 /* FileChanges.m in Sources */, 4E6BA2E81A1EE6AF005FD721 /* UIWebView+AFNetworking.m in Sources */, + B1890C352015D87900F52ABA /* EAWiki.m in Sources */, + B1890C382015D89A00F52ABA /* WikiMenuListView.m in Sources */, + B1817EC4206397E000E9BAD1 /* EACodeRelease.m in Sources */, 4E0B9A341BAC1CD100D57D54 /* ForkTreeViewController.m in Sources */, 4E4D6A7F1B1C6D1E00FD2E49 /* CommitContentCell.m in Sources */, 8EA6D13519E240C40076D59C /* ProjectViewController.m in Sources */, @@ -6827,22 +11676,29 @@ 4E996BDC1ABA79AB00C704F1 /* UserInfoDetailViewController.m in Sources */, B9A00D851ACA3A55008BA008 /* ProjectAdvancedSettingViewController.m in Sources */, 4E8765671A22E5B40090CFB9 /* SWLongPressGestureRecognizer.m in Sources */, + B12B647A1FFB61AD00ACFDCC /* QBAlbumsViewController.m in Sources */, 0AB591AC1AB6D2F60076C454 /* TweetSendLocaitonMapViewController.m in Sources */, 4EA7F1611A6D192B00A046BD /* UIButton+WebCache.m in Sources */, + B152ED6320935524004A6E8A /* EABoardTaskListBlankView.m in Sources */, 8EE72BE419E3F2E8002C11D9 /* SDWebImageManager+MJ.m in Sources */, 3A38784C1AE36EF00078D5DE /* TopicListView.m in Sources */, 8E1C3DEA19E7D58A00EF3032 /* AbstractActionSheetPicker.m in Sources */, 8EA6D1AF19E240C40076D59C /* CodingTips.m in Sources */, 4E4D6A5B1B1C5DDF00FD2E49 /* MRPRCommentCCell.m in Sources */, + B12B64061FE900D400ACFDCC /* AMPopTip+Animation.m in Sources */, + B1C60C9020BFF7950073D3CA /* ProjectTypeExplanationViewController.m in Sources */, 8EF643C219FF7E2900F7EEB0 /* TaskCommentTopCell.m in Sources */, 4E4D6A611B1C65C100FD2E49 /* MRPRCommitsViewController.m in Sources */, - 8E64ED7D19ED0CE3006E99DA /* QBAssetsCollectionOverlayView.m in Sources */, + B1817EBF2063951000E9BAD1 /* EABasePageModel.m in Sources */, + B1C871541EADF4D4003DACF0 /* UITableViewCell+Common.m in Sources */, + B1817ECA20639E9500E9BAD1 /* EACodeReleaseListCell.m in Sources */, 4E0BD86B1B6C7E3D0061CAA6 /* CSLikesVC.m in Sources */, 8EA6D14919E240C40076D59C /* UserOrProjectTweetsViewController.m in Sources */, 4E4D6AA01B1D89D400FD2E49 /* CommitDetail.m in Sources */, 4ECE8AD71A3943E80021E29C /* DownMenuCell.m in Sources */, 4E6C41201A846AC30098DC17 /* RFToolbarButton.m in Sources */, 3A3878491AE36ED70078D5DE /* TopicListButton.m in Sources */, + B1C60CA820C0DDF60073D3CA /* TeamSupportViewController.m in Sources */, 4ECE8B011A3946C10021E29C /* ImageSizeManager.m in Sources */, 8EA6D1B319E240C40076D59C /* File.m in Sources */, 923399751C00ABDE00F29E04 /* ShopOrderViewController.m in Sources */, @@ -6855,7 +11711,9 @@ 8EF643C419FF7E2900F7EEB0 /* TitleDisclosureCell.m in Sources */, 4E2906A21A403B7D008A5B97 /* FileDownloadView.m in Sources */, 4E6BA2DC1A1EE6AF005FD721 /* AFNetworkReachabilityManager.m in Sources */, + 4E3068441E0B781A00AEE0CE /* LDNetTraceRoute.m in Sources */, D09E6AD11BF9D999009D37F8 /* SearchViewController.m in Sources */, + B12B647C1FFB61AD00ACFDCC /* QBImagePickerController.m in Sources */, 4EB52F251C76C16300B5EBEA /* EditColorViewController.m in Sources */, 8E59F0E31A0098BA009A905F /* UIScrollView+SVPullToRefresh.m in Sources */, 4E8D5D5B1B45295D00B70936 /* NSData+OTPBase32Encoding.m in Sources */, @@ -6870,20 +11728,25 @@ D0C448181C03187100DC1C4B /* TaskSearchCell.m in Sources */, 4E6BA2D91A1EE6AF005FD721 /* AFURLConnectionOperation.m in Sources */, 8EA6D1BB19E240C40076D59C /* ProjectTopic.m in Sources */, + B1817EB62063899400E9BAD1 /* EACodeBranchListViewController.m in Sources */, 4ED4B4A01D82962100EED8C6 /* TeamProjectsViewController.m in Sources */, 8EA6D13219E240C40076D59C /* RegisterViewController.m in Sources */, 923399661C00441700F29E04 /* ShopBanner.m in Sources */, 8EF643C519FF7E2900F7EEB0 /* TitleRImageMoreCell.m in Sources */, + B152ED602093018A004A6E8A /* EABoardTaskListView.m in Sources */, 4E4969401DCB0BCE0065028E /* FileShare.m in Sources */, 4ED6181B1C3A72AE0017946C /* ShopMutileValueCell.m in Sources */, 4E217F151A70EDC700F6DF88 /* SVWebViewControllerActivitySafari.m in Sources */, 4E8D5D5A1B45295D00B70936 /* HOTPGenerator.m in Sources */, + B1890C4A2015D92600F52ABA /* WikiViewController.m in Sources */, 8EA6D14519E240C40076D59C /* TweetDetailViewController.m in Sources */, 4ED4B4971D82939700EED8C6 /* Team.m in Sources */, 8EA6D13119E240C40076D59C /* LoginViewController.m in Sources */, - 8E64ED7C19ED0CE3006E99DA /* QBAssetsCollectionFooterView.m in Sources */, + 4E3068461E0B781A00AEE0CE /* NSData+gzip.m in Sources */, 4E8D5D5C1B45295D00B70936 /* NSString+OTPURLArguments.m in Sources */, D066BB3A1BF30EB9005AB5D6 /* ProjectSquareViewController.m in Sources */, + B1817EBC2063936100E9BAD1 /* EACodeBranches.m in Sources */, + B1BCB8931FCE662A0098B87B /* NSLayoutConstraintLine.m in Sources */, 8E6F1C951A03BD6000BF79C8 /* ProjectMemberActivityListViewController.m in Sources */, 8EA6D13619E240C40076D59C /* BaseViewController.m in Sources */, 4E5F39051ACA958C0010515D /* TopicCommentCCell.m in Sources */, @@ -6895,11 +11758,14 @@ D031F5DB1BFAD6690008E964 /* FRDLivelyButton.m in Sources */, 4ECE8AE21A3943E80021E29C /* UIColor+expanded.m in Sources */, 4E6318A21BDA261100EFED97 /* MRListView.m in Sources */, + 09A0588C1E0AA9AE00C1CA3F /* UserActiveStatusView.m in Sources */, + 09A058981E0AAA5300C1CA3F /* ScreenView.m in Sources */, D0A32BF61BF1CA8F00336C52 /* ProjectCount.m in Sources */, 4EB52F381C7C38F600B5EBEA /* ResourceReference.m in Sources */, 4EA7F15D1A6D192B00A046BD /* SDWebImageDownloader.m in Sources */, 8EA6D1B419E240C40076D59C /* HtmlMedia.m in Sources */, 3A3878451AE296240078D5DE /* EditLabelCell.m in Sources */, + B1C60CA620C0DDF60073D3CA /* TeamPurchaseViewController.m in Sources */, 4ECE8ADE1A3943E80021E29C /* NSString+Common.m in Sources */, 4ECE8B081A3947300021E29C /* BasicPreviewItem.m in Sources */, 4E2247FC1D82C98800551EA4 /* MeDisplayViewController.m in Sources */, @@ -6913,6 +11779,7 @@ 4EAE06A41B7AE4EF00179F4B /* FileComment.m in Sources */, 8EA6D13C19E240C40076D59C /* Tweet_RootViewController.m in Sources */, B93D904B1ACBA3110057A6EE /* ProjectDeleteAlertControllerVisualStyle.m in Sources */, + B1D5F21620BD485D00983FB6 /* TeamPurchaseOrder.m in Sources */, 4E1A22851AB172C400CFC14F /* ProjectItemsCell.m in Sources */, 4ECE8B051A3946C10021E29C /* WebContentManager.m in Sources */, 4E94C4F41B4D007600EB668A /* Login2FATipCell.m in Sources */, @@ -6920,29 +11787,35 @@ 8EA6D1F819E240C40076D59C /* MJPhotoBrowser.m in Sources */, 4E0BD86C1B6C7E3D0061CAA6 /* CSMyTopicVC.m in Sources */, 4ED618151C3A6B4B0017946C /* LocationViewController.m in Sources */, + B12B641C1FF0F5E400ACFDCC /* JDStatusBarLayoutMarginHelper.m in Sources */, 8ED4612019E4DC470059B3BE /* iCarousel.m in Sources */, 4E1A22881AB1731600CFC14F /* ProjectDescriptionCell.m in Sources */, 4ECE8AE11A3943E80021E29C /* UIButton+Common.m in Sources */, 4ECE8AD81A3943E80021E29C /* UIDownMenuButton.m in Sources */, 4E6CBE511D8E962300644086 /* TopicAnswerDetailViewController.m in Sources */, 8EA6D14819E240C40076D59C /* UsersViewController.m in Sources */, + B12B64151FF0DE4800ACFDCC /* SkillCCell.m in Sources */, 4E94C4FF1B4D2B9300EB668A /* MenuButton.m in Sources */, + B12B64091FE900D400ACFDCC /* AMPopTip+Draw.m in Sources */, + B152ED542091B7CB004A6E8A /* ProjectArchiveViewController.m in Sources */, 4ED4B49D1D8295F600EED8C6 /* TeamViewController.m in Sources */, 4EF3741C1BB1258600DDA662 /* LocalFileViewController.m in Sources */, 3A3878401AE295970078D5DE /* ResetLabelCell.m in Sources */, - 4EA679201A15AB9F001A0324 /* FileListViewController.m in Sources */, + B1817ECD20639F0A00E9BAD1 /* EACodeBranchListCell.m in Sources */, 8EA6D14119E240C40076D59C /* ValueListViewController.m in Sources */, 4EB52F151C7599FC00B5EBEA /* ActivateViewController.m in Sources */, + 4EAAD0141E5306F3008AA957 /* MRPRListViewController.m in Sources */, 4ECE8ADD1A3943E80021E29C /* NSObject+ObjectMap.m in Sources */, 4E8765661A22E5B40090CFB9 /* SWCellScrollView.m in Sources */, 8E1C3DEB19E7D58A00EF3032 /* ActionSheetCustomPicker.m in Sources */, D02BE0AF1C0434DB008374C0 /* PRMRSearchCell.m in Sources */, 8EA6D14619E240C40076D59C /* TweetSendViewController.m in Sources */, 8EA6D1B819E240C40076D59C /* PrivateMessages.m in Sources */, - 8E64ED7F19ED0CE3006E99DA /* QBAssetsCollectionViewCell.m in Sources */, 4E6D718A1A75F00E005AD988 /* YLImageView.m in Sources */, 4E095A591B690494008DC439 /* CodingBanner.m in Sources */, 9233997B1C00C55600F29E04 /* ShopOrderModel.m in Sources */, + B12B63F91FE8FF0400ACFDCC /* MartFunctionTipView.m in Sources */, + B19D4EEE1F6FCEAC00C598F3 /* CodingSkill.m in Sources */, 923399721C00A9EF00F29E04 /* DashesLineView.m in Sources */, 8EA6D1C119E240C40076D59C /* Tweets.m in Sources */, 4E8D5D5F1B45295D00B70936 /* OTPAuthURL.m in Sources */, @@ -6954,6 +11827,7 @@ 4E0022921B721973005308DE /* PointRecordCell.m in Sources */, 4E5A66951B268D160007A0AD /* UIView+PressMenu.m in Sources */, 8EA6D1C019E240C40076D59C /* Tasks.m in Sources */, + B1C60C9820C004C80073D3CA /* TeamPurchaseTopCell.m in Sources */, 8EE72BE819E3F4A8002C11D9 /* MBProgressHUD+Add.m in Sources */, 8E59F10D1A02188D009A905F /* CodeViewController.m in Sources */, 4E59D32F1D3E1920008C914B /* ProjectTweetSendViewController.m in Sources */, @@ -6962,7 +11836,9 @@ 8EA6D20B19E240C40076D59C /* RDVTabBarController.m in Sources */, 4E787DE21B0329B300F06E83 /* ProjectLineNote.m in Sources */, D066BB3D1BF38844005AB5D6 /* ProjectAboutMeListCell.m in Sources */, + 4EAAD0171E53EFF2008AA957 /* EAFliterMenu.m in Sources */, 8BDF9AA61B7456060093BF2C /* HotTopicBannerView.m in Sources */, + B1D5F21A20BD485D00983FB6 /* TeamPurchaseBillingDetail.m in Sources */, 8EA6D12E19E240C40076D59C /* EditTaskViewController.m in Sources */, 4EB52F2B1C76ED7000B5EBEA /* TagColorDisplayCell.m in Sources */, 8EA6D1BC19E240C40076D59C /* ProjectTopics.m in Sources */, @@ -6978,14 +11854,15 @@ 4E0BD8721B6C7E3D0061CAA6 /* CSTopicModel.m in Sources */, 4E4D6AA31B1DB63A00FD2E49 /* FileLineChange.m in Sources */, 4E5C06EE1AC4405300F427C5 /* PasswordViewController.m in Sources */, + B1C60C7E20BFCDBE0073D3CA /* EditMemberTypeProjectListViewController.m in Sources */, 927AFF441BFF61FF00AAE593 /* BaseCollectionCell.m in Sources */, 4E217F0E1A70EDC700F6DF88 /* SVWebViewController.m in Sources */, + B1817EE42064F92C00E9BAD1 /* EACodeReleaseViewController.m in Sources */, 4E6BA2DE1A1EE6AF005FD721 /* AFSecurityPolicy.m in Sources */, 4EA7F1631A6D192B00A046BD /* UIImage+MultiFormat.m in Sources */, 8EF643AE19FF7E2900F7EEB0 /* TweetMediaItemSingleCCell.m in Sources */, 8EF643AC19FF7E2900F7EEB0 /* TweetLikeUserCCell.m in Sources */, - 8E64ED7B19ED0CE3006E99DA /* QBAssetsCollectionCheckmarkView.m in Sources */, - 4EE1A22E1B5D02CA004284F1 /* ProjectFolderListView.m in Sources */, + 4E80E9351E011D6000DE1BC6 /* RewardTipManager.m in Sources */, 4E4D6A701B1C68F100FD2E49 /* CommitFilesViewController.m in Sources */, 4E4D6A911B1D84B400FD2E49 /* FileChange.m in Sources */, 8EA6D1AB19E240C40076D59C /* main.m in Sources */, @@ -6994,13 +11871,18 @@ 4E996BD91ABA776500C704F1 /* UserInfoTextCell.m in Sources */, 4E4D6AA61B1DBA3A00FD2E49 /* MRPRDisclosureCell.m in Sources */, 8E1C3E0819E8DFE300EF3032 /* AboutViewController.m in Sources */, + B12B647F1FFB61AD00ACFDCC /* QBAssetCell.m in Sources */, + B1817EB9206389F500E9BAD1 /* EACodeReleaseListViewController.m in Sources */, 4E87DDFD1D813B1E00D1B5B1 /* MeRootUserCell.m in Sources */, 9233996C1C00524A00F29E04 /* ShopGoods.m in Sources */, + B12B64081FE900D400ACFDCC /* AMPopTip+Entrance.m in Sources */, 4E0022861B720966005308DE /* PointRecords.m in Sources */, + B12B647D1FFB61AD00ACFDCC /* QBCheckmarkView.m in Sources */, 4E6BA2D71A1EE6AF005FD721 /* AFHTTPRequestOperation.m in Sources */, 4EF8181F1B05C9D8005F974B /* ProjectLineNoteActivity.m in Sources */, 8EF643A919FF7E2900F7EEB0 /* MessageMediaItemCCell.m in Sources */, 4ECF70461B18557E000280FF /* MRPRS.m in Sources */, + B1817F062069F67700E9BAD1 /* EAEditCodeReleaseViewController.m in Sources */, 4ECE8AE41A3943E80021E29C /* UIImage+Common.m in Sources */, 8EF643D619FF7E9F00F7EEB0 /* ProjectTopicCell.m in Sources */, 4E4D6A8B1B1C6E3100FD2E49 /* TextCheckMarkCell.m in Sources */, @@ -7008,20 +11890,21 @@ 4E94C5121B4E0C0300EB668A /* XHRealTimeBlur.m in Sources */, 4EA6790A1A1461C3001A0324 /* ProjectFile.m in Sources */, 4E0BD8711B6C7E3D0061CAA6 /* CSTopiclistView.m in Sources */, - 4E63189C1BDA198000EFED97 /* MRListViewController.m in Sources */, 4ECE8AE61A3943E80021E29C /* UILabel+Common.m in Sources */, + B12B647E1FFB61AD00ACFDCC /* QBSlomoIconView.m in Sources */, 4EA7F15C1A6D192B00A046BD /* SDWebImageDecoder.m in Sources */, - 8E64ED8219ED0CE3006E99DA /* QBImagePickerController.m in Sources */, D09AA5BD1BFDE5F5008CA9EB /* TweetSearchCell.m in Sources */, 4E6BA2E01A1EE6AF005FD721 /* AFURLResponseSerialization.m in Sources */, 8E59F1031A0120F1009A905F /* CodeFile.m in Sources */, + B1ACFE0D20A975E2000BC41E /* EAMilestone.m in Sources */, 4E0BD8801B6C7F0A0061CAA6 /* CSSearchCell.m in Sources */, + B1C60C9A20C004C80073D3CA /* TeamPurchaseBillingCell.m in Sources */, 4E996BCA1ABA754600C704F1 /* JDStatusBarView.m in Sources */, 4E4D6A881B1C6E1B00FD2E49 /* MRPRAcceptEditCell.m in Sources */, + B1817EED2064FD9400E9BAD1 /* EACodeReleaseAttachmentsOrReferencesCell.m in Sources */, 4E94C5001B4D2B9300EB668A /* MenuItem.m in Sources */, 8EF643AD19FF7E2900F7EEB0 /* TweetMediaItemCCell.m in Sources */, 3A3878461AE296240078D5DE /* EditLabelHeadCell.m in Sources */, - 8E64ED7E19ED0CE3006E99DA /* QBAssetsCollectionVideoIndicatorView.m in Sources */, 8EF643C319FF7E2900F7EEB0 /* TaskContentCell.m in Sources */, 4E59E1D31A5E6B34004DAEEC /* TaskDescriptionViewController.m in Sources */, 4ECE8AFD1A3946C10021E29C /* AddressManager.m in Sources */, @@ -7030,26 +11913,32 @@ 8E59F0F41A00F3B9009A905F /* ProjectCodeListCell.m in Sources */, 4E87DE031D813BBE00D1B5B1 /* UserServiceInfo.m in Sources */, 0A6E6BAA1AAF4B24004C0107 /* TweetSendLocationViewController.m in Sources */, + B1C60C7A20BFA2150073D3CA /* NProjectFileListView.m in Sources */, 8E59F0F71A00F3E2009A905F /* ProjectFolderListCell.m in Sources */, 8EA6D1C319E240C40076D59C /* User.m in Sources */, 8EA6D1FB19E240C40076D59C /* MJPhotoToolbar.m in Sources */, 8EF643CF19FF7E2900F7EEB0 /* TweetDetailCommentCell.m in Sources */, + B12B64121FF0D54800ACFDCC /* SettingSkillsViewController.m in Sources */, 4E4D6A8E1B1D5B9A00FD2E49 /* MRPRBaseInfo.m in Sources */, 7EB02FF31B6D111300D2166C /* AudioRecordView.m in Sources */, 4EB52F281C76ED4A00B5EBEA /* TagColorEditCell.m in Sources */, + B12B64771FFB61AD00ACFDCC /* QBVideoIndicatorView.m in Sources */, + B1C60C9C20C004C80073D3CA /* TeamPurchaseOrderCell.m in Sources */, 4E93F2441B85C4C300017916 /* FileInfoViewController.m in Sources */, 4E4D6A9A1B1D893500FD2E49 /* CommitInfo.m in Sources */, 4E38CF5F1A7A28AF005536C0 /* CodeBranchTagButton.m in Sources */, 9233996F1C00970900F29E04 /* ShopGoodsInfoView.m in Sources */, - 8E64ED8119ED0CE3006E99DA /* QBAssetsCollectionViewLayout.m in Sources */, 8EA6D1C819E240C40076D59C /* UIBadgeView.m in Sources */, 927AFF411BFF613500AAE593 /* BaseModel.m in Sources */, + 09A058951E0AAA2F00C1CA3F /* TaskSelectionView.m in Sources */, 8EF643BD19FF7E2900F7EEB0 /* ProjectListCell.m in Sources */, + B152ED5A2092BF46004A6E8A /* EABoardTaskList.m in Sources */, 4E0BD86F1B6C7E3D0061CAA6 /* CSTopicDetailVC.m in Sources */, 8EF643C819FF7E2900F7EEB0 /* ToMessageCell.m in Sources */, 4E217F111A70EDC700F6DF88 /* SVWebViewControllerActivityChrome.m in Sources */, 4EC4800C1C2936DA005F1772 /* PhoneCodeButton.m in Sources */, 4E6CBE4E1D8E7E8000644086 /* TopicAnswerCommentMoreCell.m in Sources */, + 4E3068421E0B781A00AEE0CE /* LDNetPing.m in Sources */, 13C8FE6E1CA75816001E30FA /* DynamicCommentCell.m in Sources */, 4E0BD86D1B6C7E3D0061CAA6 /* CSScrollview.m in Sources */, D09AA5C01BFDEDD1008CA9EB /* NSString+Attribute.m in Sources */, @@ -7057,9 +11946,12 @@ 4EA6790D1A1461DC001A0324 /* ProjectFolder.m in Sources */, 8EF643BC19FF7E2900F7EEB0 /* ProjectActivityListCell.m in Sources */, 4E996BC91ABA754600C704F1 /* JDStatusBarStyle.m in Sources */, + 4E3068401E0B781A00AEE0CE /* LDNetDiagnoService.m in Sources */, 4E2F6A571C437D1D00A25502 /* EditCodeViewController.m in Sources */, 8EF83F9419EB78CC00E86DE7 /* SettingTextViewController.m in Sources */, + B152ED5D2092D51E004A6E8A /* EATaskBoardListTaskCell.m in Sources */, 4ED618181C3A6CA50017946C /* LocationCell.m in Sources */, + B12B64761FFB61AD00ACFDCC /* QBVideoIconView.m in Sources */, 8EA6D1B019E240C40076D59C /* Comment.m in Sources */, 0A6E6BA71AAF4162004C0107 /* TweetSendLocationCell.m in Sources */, 4E9E3B751DCC2DB10005FD79 /* HtmlMediaViewController.m in Sources */, @@ -7069,11 +11961,11 @@ 8ECA8BB419FB42CC00C598C6 /* UILongPressMenuImageView.m in Sources */, 4E4D6A821B1C6D5F00FD2E49 /* FileChangesIntroduceCell.m in Sources */, 8EA6D1BE19E240C40076D59C /* Register.m in Sources */, - 4ECF70431B18514F000280FF /* PRListViewController.m in Sources */, 926C043B1C019CD3004937D8 /* ShopOrder.m in Sources */, 4E6CBE4B1D8E71DC00644086 /* TopicAnswerCell.m in Sources */, 4E969CD01AF0EB87005C0CCE /* NSTimer+Common.m in Sources */, 8EF643B019FF7E2900F7EEB0 /* CodingTipCell.m in Sources */, + B19D4EEA1F6FAA6000C598F3 /* AboutPointViewController.m in Sources */, 4E6FB0581B58DB0A00B0A17B /* ProjectTagsView.m in Sources */, 8EA6D1BA19E240C40076D59C /* Projects.m in Sources */, 4E996BDF1ABA7CE100C704F1 /* UserInfoDetailUserCell.m in Sources */, @@ -7085,10 +11977,647 @@ 4EAE06AB1B7B23EA00179F4B /* FileActivitiesViewController.m in Sources */, 4E715A321BB1278200A5D24B /* LocalFolderCell.m in Sources */, 4E217F171A70EDC700F6DF88 /* SVWebViewControllerActivity.m in Sources */, + 09A058A11E0AAACA00C1CA3F /* TagsScrollView.m in Sources */, 4E996BE81ABBCD2D00C704F1 /* TaskDescriptionCell.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; + B1D5EBF320BC06CB00983FB6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B1D5EBF420BC06CB00983FB6 /* RootTabViewController.m in Sources */, + B1D5EBF520BC06CB00983FB6 /* WebViewController.m in Sources */, + B1D5EBF620BC06CB00983FB6 /* ProjectTag.m in Sources */, + B1D5EBF720BC06CB00983FB6 /* SendRewardManager.m in Sources */, + B1D5EBF820BC06CB00983FB6 /* UIImageView+AFNetworking.m in Sources */, + B1D5EBF920BC06CB00983FB6 /* ExchangeGoodsViewController.m in Sources */, + B1D5EBFA20BC06CB00983FB6 /* ProjectMember.m in Sources */, + B1D5EBFB20BC06CB00983FB6 /* UserInfoViewController.m in Sources */, + B1D5EBFC20BC06CB00983FB6 /* Me_RootViewController.m in Sources */, + B1D5EBFD20BC06CB00983FB6 /* ProjectActivity.m in Sources */, + B1D5EBFE20BC06CB00983FB6 /* SWUtilityButtonTapGestureRecognizer.m in Sources */, + B1D5EBFF20BC06CB00983FB6 /* UnReadManager.m in Sources */, + B1D5EC0020BC06CB00983FB6 /* ProjectFiles.m in Sources */, + B1D5EC0220BC06CB00983FB6 /* MRPRCommentCell.m in Sources */, + B1D5EC0320BC06CB00983FB6 /* AudioPlayView.m in Sources */, + B1D5EC0420BC06CB00983FB6 /* NewProjectTypeViewController.m in Sources */, + B1D5EC0520BC06CB00983FB6 /* EAIntroPage.m in Sources */, + B1D5EC0620BC06CB00983FB6 /* PopFliterMenu.m in Sources */, + B1D5EC0720BC06CB00983FB6 /* ProjectPublicListCell.m in Sources */, + B1D5EC0820BC06CB00983FB6 /* DirectoryWatcher.m in Sources */, + B1D5EC0920BC06CB00983FB6 /* SVWebViewControllerActivityReport.m in Sources */, + B1D5EC0A20BC06CB00983FB6 /* TeamMember.m in Sources */, + B1D5EC0B20BC06CB00983FB6 /* UIButton+AFNetworking.m in Sources */, + B1D5EC0C20BC06CB00983FB6 /* TopicCommentCell.m in Sources */, + B1D5EC0D20BC06CB00983FB6 /* AudioVolumeView.m in Sources */, + B1D5EC0E20BC06CB00983FB6 /* ZXScanCodeViewController.m in Sources */, + B1D5EC0F20BC06CB00983FB6 /* LDNetTimer.m in Sources */, + B1D5EC1020BC06CB00983FB6 /* TaskBoardsViewController.m in Sources */, + B1D5EC1120BC06CB00983FB6 /* Tweet.m in Sources */, + B1D5EC1220BC06CB00983FB6 /* PRDetailViewController.m in Sources */, + B1D5EC1320BC06CB00983FB6 /* TweetCommentMoreCell.m in Sources */, + B1D5EC1420BC06CB00983FB6 /* CodeTree.m in Sources */, + B1D5EC1520BC06CB00983FB6 /* WikiMenuListCell.m in Sources */, + B1D5EC1620BC06CB00983FB6 /* EALocalCodeViewController.m in Sources */, + B1D5EC1720BC06CB00983FB6 /* KxMenu.m in Sources */, + B1D5EC1820BC06CB00983FB6 /* UserSearchCell.m in Sources */, + B1D5EC1920BC06CB00983FB6 /* SettingEmailViewController.m in Sources */, + B1D5EC1A20BC06CB00983FB6 /* MemberCell.m in Sources */, + B1D5EC1B20BC06CB00983FB6 /* JobManager.m in Sources */, + B1D5EC1C20BC06CB00983FB6 /* UIView+Frame.m in Sources */, + B1D5EC1D20BC06CB00983FB6 /* TagsManager.m in Sources */, + B1D5EC1E20BC06CB00983FB6 /* AddCommentCell.m in Sources */, + B1D5EC1F20BC06CB00983FB6 /* UITTTAttributedLabel.m in Sources */, + B1D5EC2020BC06CB00983FB6 /* TitleValueCell.m in Sources */, + B1D5EC2120BC06CB00983FB6 /* ODRefreshControl.m in Sources */, + B1D5EC2220BC06CB00983FB6 /* FileSearchCell.m in Sources */, + B1D5EC2320BC06CB00983FB6 /* RDVTabBarItem.m in Sources */, + B1D5EC2420BC06CB00983FB6 /* PointShopCell.m in Sources */, + B1D5EC2520BC06CB00983FB6 /* ProjectTopicActivity.m in Sources */, + B1D5EC2620BC06CB00983FB6 /* FileChangeListCell.m in Sources */, + B1D5EC2720BC06CB00983FB6 /* ProjectListViewController.m in Sources */, + B1D5EC2820BC06CB00983FB6 /* EaseMarkdownTextView.m in Sources */, + B1D5EC2920BC06CB00983FB6 /* ActivityView.m in Sources */, + B1D5EC2A20BC06CB00983FB6 /* ListGroupItem.m in Sources */, + B1D5EC2B20BC06CB00983FB6 /* CodingSearchDisplayView.m in Sources */, + B1D5F21F20BD50D000983FB6 /* ProjectRole.m in Sources */, + B1D5EC2C20BC06CB00983FB6 /* MyTask_RootViewController.m in Sources */, + B1D5EC2D20BC06CB00983FB6 /* SettingAccountViewController.m in Sources */, + B1D5EC2E20BC06CB00983FB6 /* SWTableViewCell.m in Sources */, + B1D5EC2F20BC06CB00983FB6 /* ScanBGView.m in Sources */, + B1D5EC3020BC06CB00983FB6 /* CodingVipTipManager.m in Sources */, + B1D5EC3120BC06CB00983FB6 /* CSTopicHeaderView.m in Sources */, + B1D5EC3220BC06CB00983FB6 /* NJKWebViewProgressView.m in Sources */, + B1D5EC3320BC06CB00983FB6 /* TaskActivityCell.m in Sources */, + B1D5EC3420BC06CB00983FB6 /* ActivenessModel.m in Sources */, + B1D5EC3520BC06CB00983FB6 /* Close2FAViewController.m in Sources */, + B1D5EC3620BC06CB00983FB6 /* NSDate+Common.m in Sources */, + B1D5EC3720BC06CB00983FB6 /* RDVTabBar.m in Sources */, + B1D5EC3820BC06CB00983FB6 /* TMCacheExtend.m in Sources */, + B1D5EC3920BC06CB00983FB6 /* CodingShareView.m in Sources */, + B1D5EC3A20BC06CB00983FB6 /* DistancePickerView.m in Sources */, + B1D5EC3B20BC06CB00983FB6 /* FileVersionsViewController.m in Sources */, + B1D5EC3C20BC06CB00983FB6 /* FileVersion.m in Sources */, + B1D5EC3D20BC06CB00983FB6 /* Depot.m in Sources */, + B1D5EC3E20BC06CB00983FB6 /* ReportIllegalViewController.m in Sources */, + B1D5EC3F20BC06CB00983FB6 /* ShopBannerView.m in Sources */, + B1D5EC4020BC06CB00983FB6 /* TweetDetailCell.m in Sources */, + B1D5EC4120BC06CB00983FB6 /* ProjectTransferSettingViewController.m in Sources */, + B1D5EC4220BC06CB00983FB6 /* UIMessageInputView_Add.m in Sources */, + B1D5EC4320BC06CB00983FB6 /* UIMessageInputView_Voice.m in Sources */, + B1C60C8320BFCEFD0073D3CA /* NFileListViewController.m in Sources */, + B1D5EC4420BC06CB00983FB6 /* UIScrollView+SVInfiniteScrolling.m in Sources */, + B1D5EC4520BC06CB00983FB6 /* PointRecord.m in Sources */, + B1D5EC4620BC06CB00983FB6 /* ShopGoodsCCell.m in Sources */, + B1D5EC4720BC06CB00983FB6 /* FolderToMoveViewController.m in Sources */, + B1D5EC4820BC06CB00983FB6 /* Shop.m in Sources */, + B1D5EC4920BC06CB00983FB6 /* CategorySearchBar.m in Sources */, + B1D5EC4A20BC06CB00983FB6 /* UISearchBar+Common.m in Sources */, + B1D5EC4B20BC06CB00983FB6 /* UIImage+GIF.m in Sources */, + B1D5EC4C20BC06CB00983FB6 /* MessageCell.m in Sources */, + B1D5EC4D20BC06CB00983FB6 /* SettingMineInfoViewController.m in Sources */, + B1D5EC4E20BC06CB00983FB6 /* TweetSendImageCCell.m in Sources */, + B1D5EC4F20BC06CB00983FB6 /* OTPGenerator.m in Sources */, + B1D5EC5020BC06CB00983FB6 /* AddUserViewController.m in Sources */, + B1D5EC5120BC06CB00983FB6 /* TaskResourceReferenceCell.m in Sources */, + B1D5EC5220BC06CB00983FB6 /* UIButton+Bootstrap.m in Sources */, + B1D5EC5320BC06CB00983FB6 /* NSDate+Helper.m in Sources */, + B1D5EC5420BC06CB00983FB6 /* MJPhotoView.m in Sources */, + B1D5EC5520BC06CB00983FB6 /* CodeListViewController.m in Sources */, + B1D5EC5620BC06CB00983FB6 /* NProjectItemCell.m in Sources */, + B1D5EC5720BC06CB00983FB6 /* EACodeReleases.m in Sources */, + B1D5EC5820BC06CB00983FB6 /* TeamMembersViewController.m in Sources */, + B1D5EC5920BC06CB00983FB6 /* ActionSheetDatePicker.m in Sources */, + B1D5EC5A20BC06CB00983FB6 /* Input_OnlyText_Cell.m in Sources */, + B1D5EC5B20BC06CB00983FB6 /* FileListUploadCell.m in Sources */, + B1D5EC5C20BC06CB00983FB6 /* ProjectServiceInfo.m in Sources */, + B1D5EC5D20BC06CB00983FB6 /* ProjectListView.m in Sources */, + B1D5EC5E20BC06CB00983FB6 /* EAIntroView.m in Sources */, + B1D5EC5F20BC06CB00983FB6 /* ProjectFolders.m in Sources */, + B1D5EC6020BC06CB00983FB6 /* ProjectTagLabel.m in Sources */, + B1D5EC6120BC06CB00983FB6 /* NSData+ImageContentType.m in Sources */, + B1D5EC6220BC06CB00983FB6 /* UIColor+MobileColors.m in Sources */, + B1D5EC6320BC06CB00983FB6 /* MJPhotoProgressView.m in Sources */, + B1D5EC6420BC06CB00983FB6 /* EADeviceToServerLog.m in Sources */, + B1D5EC6520BC06CB00983FB6 /* MRPRFilesViewController.m in Sources */, + B1D5EC6620BC06CB00983FB6 /* PHAsset+Common.m in Sources */, + B1D5EC6720BC06CB00983FB6 /* FileListFolderCell.m in Sources */, + B1D5EC6820BC06CB00983FB6 /* Users.m in Sources */, + B1D5EC6920BC06CB00983FB6 /* UserCell.m in Sources */, + B1D5EC6A20BC06CB00983FB6 /* PointRecordsViewController.m in Sources */, + B1D5EC6B20BC06CB00983FB6 /* OTPAuthClock.m in Sources */, + B1D5EC6C20BC06CB00983FB6 /* TOTPGenerator.m in Sources */, + B1D5EC6D20BC06CB00983FB6 /* CSHotTopicView.m in Sources */, + B1D5EC6E20BC06CB00983FB6 /* CodingTip.m in Sources */, + B1D5EC6F20BC06CB00983FB6 /* NProjectViewController.m in Sources */, + B1D5EC7020BC06CB00983FB6 /* SettingPhoneViewController.m in Sources */, + B1D5EC7120BC06CB00983FB6 /* PrivateMessage.m in Sources */, + B1D5EC7220BC06CB00983FB6 /* ProjectTaskListViewCell.m in Sources */, + B1D5EC7320BC06CB00983FB6 /* UIDevice+Info.m in Sources */, + B1D5EC7420BC06CB00983FB6 /* UIMessageInputView_Media.m in Sources */, + B1D5EC7520BC06CB00983FB6 /* QBAlbumCell.m in Sources */, + B1D5EC7620BC06CB00983FB6 /* FileActivityCell.m in Sources */, + B1D5EC7720BC06CB00983FB6 /* UIAlertView+AFNetworking.m in Sources */, + B1D5EC7820BC06CB00983FB6 /* WikiHistoryListViewController.m in Sources */, + B1D5EC7920BC06CB00983FB6 /* CommitCommentCell.m in Sources */, + B1D5EC7A20BC06CB00983FB6 /* ProjectAboutOthersListCell.m in Sources */, + B1D5EC7B20BC06CB00983FB6 /* SDWebImageManager.m in Sources */, + B1D5EC7C20BC06CB00983FB6 /* amrFileCodec.m in Sources */, + B1D5EC7D20BC06CB00983FB6 /* SettingViewController.m in Sources */, + B1D5EC7E20BC06CB00983FB6 /* ActivityMonScrollView.m in Sources */, + B1D5EC7F20BC06CB00983FB6 /* ActionSheetStringPicker.m in Sources */, + B1D5EC8020BC06CB00983FB6 /* LeftImage_LRTextCell.m in Sources */, + B1D5EC8120BC06CB00983FB6 /* ProjectSettingEntranceController.m in Sources */, + B1D5EC8220BC06CB00983FB6 /* UINavigationBar+Common.m in Sources */, + B1D5EC8320BC06CB00983FB6 /* ShopOrderListView.m in Sources */, + B1D5EC8420BC06CB00983FB6 /* SWActionSheet.m in Sources */, + B1D5EC8520BC06CB00983FB6 /* ProjectInfoCell.m in Sources */, + B14DE6DF20C914E70072ECEA /* AnimatedGIFImageSerialization.m in Sources */, + B1D5EC8620BC06CB00983FB6 /* Task.m in Sources */, + B1D5EC8720BC06CB00983FB6 /* TweetSendDetailLoctionCell.m in Sources */, + B1D5EC8820BC06CB00983FB6 /* CannotLoginViewController.m in Sources */, + B1D5EC8920BC06CB00983FB6 /* ShopViewController.m in Sources */, + B1D5EC8A20BC06CB00983FB6 /* Reviewer.m in Sources */, + B1D5EC8B20BC06CB00983FB6 /* EALocalCodeListViewController.m in Sources */, + B1D5EC8C20BC06CB00983FB6 /* AMPopTip+Exit.m in Sources */, + B1D5EC8D20BC06CB00983FB6 /* AppDelegate.m in Sources */, + B1D5EC8E20BC06CB00983FB6 /* AudioAmrUtil.m in Sources */, + B1D5EC8F20BC06CB00983FB6 /* Coding_NetAPIManager.m in Sources */, + B1D5EC9020BC06CB00983FB6 /* FileListFileCell.m in Sources */, + B1D5EC9120BC06CB00983FB6 /* TipsViewController.m in Sources */, + B1D5EC9220BC06CB00983FB6 /* ReviewCell.m in Sources */, + B1D5EC9320BC06CB00983FB6 /* TopicHotkeyView.m in Sources */, + B1D5EC9420BC06CB00983FB6 /* UIPlaceHolderTextView.m in Sources */, + B1D5EC9520BC06CB00983FB6 /* TopicSearchCell.m in Sources */, + B1D5EC9620BC06CB00983FB6 /* ProjectCommitsViewController.m in Sources */, + B1D5EC9720BC06CB00983FB6 /* UIProgressView+AFNetworking.m in Sources */, + B1D5EC9820BC06CB00983FB6 /* UserActiveGraphCell.m in Sources */, + B1D5EC9920BC06CB00983FB6 /* NSURL+Common.m in Sources */, + B1D5EC9A20BC06CB00983FB6 /* UIRefreshControl+AFNetworking.m in Sources */, + B1D5EC9B20BC06CB00983FB6 /* WikiHistoryCell.m in Sources */, + B1D5EC9C20BC06CB00983FB6 /* ProjectCodeListView.m in Sources */, + B1D5EC9D20BC06CB00983FB6 /* LocalFilesViewController.m in Sources */, + B1D5EC9E20BC06CB00983FB6 /* SettingTextCell.m in Sources */, + B1D5EC9F20BC06CB00983FB6 /* LDNetConnect.m in Sources */, + B1D5ECA020BC06CB00983FB6 /* MRDetailViewController.m in Sources */, + B1D5ECA120BC06CB00983FB6 /* UITableView+Common.m in Sources */, + B1D5ECA220BC06CB00983FB6 /* JDStatusBarNotification.m in Sources */, + B1D5ECA320BC06CB00983FB6 /* RFKeyboardToolbar.m in Sources */, + B1D5ECA420BC06CB00983FB6 /* CSSearchDisplayVC.m in Sources */, + B1D5ECA520BC06CB00983FB6 /* CodeBranchOrTag.m in Sources */, + B1D5ECA620BC06CB00983FB6 /* EasePageViewController.m in Sources */, + B1D5ECA720BC06CB00983FB6 /* ObjcRuntime.m in Sources */, + B1D5ECA820BC06CB00983FB6 /* UIVerticalAlignmentLabel.m in Sources */, + B1D5ECA920BC06CB00983FB6 /* TaskSelectionCell.m in Sources */, + B1D5ECAA20BC06CB00983FB6 /* EANetTraceRoute.m in Sources */, + B1D5ECAB20BC06CB00983FB6 /* AFURLRequestSerialization.m in Sources */, + B1D5ECAC20BC06CB00983FB6 /* UIUnderlinedButton.m in Sources */, + B1D5ECAD20BC06CB00983FB6 /* TaskCommentCCell.m in Sources */, + B1D5ECAE20BC06CB00983FB6 /* AutoSlideScrollView.m in Sources */, + B1D5ECAF20BC06CB00983FB6 /* LocalFoldersViewController.m in Sources */, + B1D5ECB020BC06CB00983FB6 /* LDNetGetAddress.m in Sources */, + B1D5ECB120BC06CB00983FB6 /* UIViewController+DownMenu.m in Sources */, + B1D5ECB220BC06CB00983FB6 /* PopMenu.m in Sources */, + B1D5ECB320BC06CB00983FB6 /* LikersViewController.m in Sources */, + B1D5ECB420BC06CB00983FB6 /* TitleValueMoreCell.m in Sources */, + B1D5ECB520BC06CB00983FB6 /* CSSearchModel.m in Sources */, + B1D5ECB620BC06CB00983FB6 /* WikiHeaderView.m in Sources */, + B1D5ECB720BC06CB00983FB6 /* TaskCommentCell.m in Sources */, + B1D5ECB820BC06CB00983FB6 /* AGEmojiPageView.m in Sources */, + B1D5ECB920BC06CB00983FB6 /* ASProgressPopUpView.m in Sources */, + B1D5ECBA20BC06CB00983FB6 /* EditLabelViewController.m in Sources */, + B1D5ECBB20BC06CB00983FB6 /* AddMDCommentViewController.m in Sources */, + B1D5ECBC20BC06CB00983FB6 /* Coding_FileManager.m in Sources */, + B1D5ECBD20BC06CB00983FB6 /* UIMessageInputView.m in Sources */, + B1D5ECBE20BC06CB00983FB6 /* AudioManager.m in Sources */, + B1D5ECBF20BC06CB00983FB6 /* MRPRPreInfo.m in Sources */, + B1D5ECC020BC06CB00983FB6 /* NSMutableString+Common.m in Sources */, + B1D5ECC120BC06CB00983FB6 /* UIViewController+BackButtonHandler.m in Sources */, + B1D5ECC220BC06CB00983FB6 /* CountryCodeCell.m in Sources */, + B1D5ECC320BC06CB00983FB6 /* RATaskBoardListListViewController.m in Sources */, + B1D5ECC420BC06CB00983FB6 /* DynamicActivityCell.m in Sources */, + B1D5ECC520BC06CB00983FB6 /* MRPRDetailCell.m in Sources */, + B1D5ECC620BC06CB00983FB6 /* TopicContentCell.m in Sources */, + B1D5ECC720BC06CB00983FB6 /* ForkTreeCell.m in Sources */, + B1D5ECC820BC06CB00983FB6 /* AMPopTip.m in Sources */, + B1D5F20F20BD3BF400983FB6 /* UINavigationController+FullscreenPopGesture.m in Sources */, + B1D5ECC920BC06CB00983FB6 /* MRPRAcceptViewController.m in Sources */, + B1D5ECCA20BC06CB00983FB6 /* UIView+Common.m in Sources */, + B1D5ECCB20BC06CB00983FB6 /* SDWebImageDownloaderOperation.m in Sources */, + B1D5ECCC20BC06CB00983FB6 /* QBAssetsViewController.m in Sources */, + B1D5ECCD20BC06CB00983FB6 /* UserInfoIconCell.m in Sources */, + B1D5ECCE20BC06CB00983FB6 /* ShopOderCell.m in Sources */, + B1D5ECCF20BC06CB00983FB6 /* SettingPasswordViewController.m in Sources */, + B1D5ECD020BC06CB00983FB6 /* FileCommentCell.m in Sources */, + B1D5ECD120BC06CB00983FB6 /* ASPopUpView.m in Sources */, + B1D5ECD220BC06CB00983FB6 /* UIActivityIndicatorView+AFNetworking.m in Sources */, + B1D5ECD320BC06CB00983FB6 /* ProjectCodeListSearchCell.m in Sources */, + B1D5ECD420BC06CB00983FB6 /* TweetSendCreateLocationCell.m in Sources */, + B1D5ECD520BC06CB00983FB6 /* EaseStartView.m in Sources */, + B1D5ECD620BC06CB00983FB6 /* ProjectTopicListView.m in Sources */, + B1D5ECD720BC06CB00983FB6 /* Message_RootViewController.m in Sources */, + B1D5ECD820BC06CB00983FB6 /* LDSimplePing.m in Sources */, + B1D5ECD920BC06CB00983FB6 /* HelpViewController.m in Sources */, + B1D5ECDA20BC06CB00983FB6 /* CSSearchVC.m in Sources */, + B1D5ECDB20BC06CB00983FB6 /* FunctionTipsManager.m in Sources */, + B1D5ECDC20BC06CB00983FB6 /* TweetSendCreateLocationViewController.m in Sources */, + B1D5ECDD20BC06CB00983FB6 /* Commits.m in Sources */, + B1D5ECDE20BC06CB00983FB6 /* QcTask.m in Sources */, + B1D5ECDF20BC06CB00983FB6 /* FileViewController.m in Sources */, + B1D5ECE020BC06CB00983FB6 /* UIImage+WebP.m in Sources */, + B1D5ECE120BC06CB00983FB6 /* TweetSendLocation.m in Sources */, + B1D5ECE220BC06CB00983FB6 /* CodingNetAPIClient.m in Sources */, + B1D5ECE320BC06CB00983FB6 /* ShopOrderTextFieldCell.m in Sources */, + B1D5ECE420BC06CB00983FB6 /* ScreenCell.m in Sources */, + B1D5ECE520BC06CB00983FB6 /* ConversationCell.m in Sources */, + B1D5ECE620BC06CB00983FB6 /* TeamListViewController.m in Sources */, + B186AEB120F462F600A6AF35 /* UIAlertController+Common.m in Sources */, + B1D5ECE720BC06CB00983FB6 /* TweetSendImagesCell.m in Sources */, + B1D5ECE820BC06CB00983FB6 /* WikiEditViewController.m in Sources */, + B1D5ECE920BC06CB00983FB6 /* MRPRListCell.m in Sources */, + B1D5ECEA20BC06CB00983FB6 /* TopicPreviewCell.m in Sources */, + B1D5ECEB20BC06CB00983FB6 /* NSString+Emojize.m in Sources */, + B1D5ECEC20BC06CB00983FB6 /* EaseGitButton.m in Sources */, + B1D5ECED20BC06CB00983FB6 /* ProjectListTaCell.m in Sources */, + B1D5ECEE20BC06CB00983FB6 /* UIImageView+MJWebCache.m in Sources */, + B1D5ECEF20BC06CB00983FB6 /* Commit.m in Sources */, + B1D5ECF020BC06CB00983FB6 /* FileVersionCell.m in Sources */, + B1D5ECF120BC06CB00983FB6 /* TeamListCell.m in Sources */, + B1D5ECF220BC06CB00983FB6 /* UIView+WebCacheOperation.m in Sources */, + B1D5ECF320BC06CB00983FB6 /* TweetSendTextCell.m in Sources */, + B1D5ECF420BC06CB00983FB6 /* XTSegmentControl.m in Sources */, + B1D5ECF520BC06CB00983FB6 /* YLGIFImage.m in Sources */, + B1D5ECF620BC06CB00983FB6 /* CountryCodeListViewController.m in Sources */, + B1D5ECF720BC06CB00983FB6 /* AllSearchDisplayVC.m in Sources */, + B1D5ECF820BC06CB00983FB6 /* TweetSendLocationDetailViewController.m in Sources */, + B1D5F22320BEA37600983FB6 /* MeRootCompanyCell.m in Sources */, + B1D5ECF920BC06CB00983FB6 /* EATerminalViewController.m in Sources */, + B1D5ECFA20BC06CB00983FB6 /* TweetSendMapAnnotation.m in Sources */, + B1D5ECFB20BC06CB00983FB6 /* MRPR.m in Sources */, + B1D5ECFC20BC06CB00983FB6 /* EaseUserInfoCell.m in Sources */, + B1D5ECFD20BC06CB00983FB6 /* CodingBannersView.m in Sources */, + B1D5ECFE20BC06CB00983FB6 /* OTPListViewController.m in Sources */, + B1D5ECFF20BC06CB00983FB6 /* UIImageView+WebCache.m in Sources */, + B1D5F21920BD485D00983FB6 /* TeamPurchaseBilling.m in Sources */, + B1D5ED0020BC06CB00983FB6 /* InputOnlyTextPlainCell.m in Sources */, + B1D5ED0120BC06CB00983FB6 /* NSTimer+Addition.m in Sources */, + B1D5ED0220BC06CB00983FB6 /* AFURLSessionManager.m in Sources */, + B1D5ED0320BC06CB00983FB6 /* MeRootServiceCell.m in Sources */, + B1D5ED0420BC06CB00983FB6 /* ActionSheetLocalePicker.m in Sources */, + B1D5ED0520BC06CB00983FB6 /* UIViewController+Swizzle.m in Sources */, + B1D5ED0620BC06CB00983FB6 /* PublicSearchModel.m in Sources */, + B1D5ED0720BC06CB00983FB6 /* MJPhotoLoadingView.m in Sources */, + B1D5ED0820BC06CB00983FB6 /* FileEditViewController.m in Sources */, + B1D5ED0920BC06CB00983FB6 /* TopicDetailViewController.m in Sources */, + B1C60CA520C0DDF60073D3CA /* TeamSettingViewController.m in Sources */, + B1D5ED0A20BC06CB00983FB6 /* UIImageView+HighlightedWebCache.m in Sources */, + B1D5ED0B20BC06CB00983FB6 /* Helper.m in Sources */, + B1D5ED0C20BC06CB00983FB6 /* PointTopCell.m in Sources */, + B1D5ED0D20BC06CB00983FB6 /* TeamMemberCell.m in Sources */, + B1D5ED0E20BC06CB00983FB6 /* ReviewerListController.m in Sources */, + B1D5ED0F20BC06CB00983FB6 /* UserInfoDetailTagCell.m in Sources */, + B1D5ED1020BC06CB00983FB6 /* SWUtilityButtonView.m in Sources */, + B1D5ED1120BC06CB00983FB6 /* VoiceMedia.m in Sources */, + B1D5ED1220BC06CB00983FB6 /* TaskComment.m in Sources */, + B1D5ED1320BC06CB00983FB6 /* EACodeReleaseTopCell.m in Sources */, + B1D5ED1420BC06CB00983FB6 /* EAPayViewController.m in Sources */, + B1D5ED1520BC06CB00983FB6 /* AGEmojiKeyBoardView.m in Sources */, + B1D5ED1620BC06CB00983FB6 /* RKSwipeBetweenViewControllers.m in Sources */, + B1D5ED1720BC06CB00983FB6 /* EditTopicViewController.m in Sources */, + B1D5ED1820BC06CB00983FB6 /* GlowImageView.m in Sources */, + B1D5ED1920BC06CB00983FB6 /* ProjectToChooseListViewController.m in Sources */, + B1D5ED1A20BC06CB00983FB6 /* SDWebImageCompat.m in Sources */, + B1D5ED1B20BC06CB00983FB6 /* EACodeReleaseBodyCell.m in Sources */, + B1D5ED1C20BC06CB00983FB6 /* Project_RootViewController.m in Sources */, + B1D5ED1D20BC06CB00983FB6 /* EaseGitButtonsView.m in Sources */, + B1D5ED1E20BC06CB00983FB6 /* SettingTagsViewController.m in Sources */, + B1D5ED1F20BC06CB00983FB6 /* EALocalCodeListCell.m in Sources */, + B1D5F23320BEADD200983FB6 /* TeamSupportCell.m in Sources */, + B1D5ED2020BC06CB00983FB6 /* ValueListCell.m in Sources */, + B1D5ED2120BC06CB00983FB6 /* TaskResourceReferenceViewController.m in Sources */, + B1D5ED2220BC06CB00983FB6 /* SVModalWebViewController.m in Sources */, + B1D5ED2320BC06CB00983FB6 /* ShopSwitchCell.m in Sources */, + B1D5ED2520BC06CB00983FB6 /* IntroductionViewController.m in Sources */, + B1D5ED2620BC06CB00983FB6 /* SDWebImagePrefetcher.m in Sources */, + B1D5ED2720BC06CB00983FB6 /* FileChanges.m in Sources */, + B1D5ED2820BC06CB00983FB6 /* UIWebView+AFNetworking.m in Sources */, + B1D5ED2920BC06CB00983FB6 /* EAWiki.m in Sources */, + B1D5ED2A20BC06CB00983FB6 /* WikiMenuListView.m in Sources */, + B1D5ED2B20BC06CB00983FB6 /* EACodeRelease.m in Sources */, + B1D5ED2C20BC06CB00983FB6 /* ForkTreeViewController.m in Sources */, + B1D5ED2D20BC06CB00983FB6 /* CommitContentCell.m in Sources */, + B1D5ED2E20BC06CB00983FB6 /* ProjectViewController.m in Sources */, + B1D5ED2F20BC06CB00983FB6 /* TagCCell.m in Sources */, + B1D5ED3020BC06CB00983FB6 /* UserInfoDetailViewController.m in Sources */, + B1D5ED3120BC06CB00983FB6 /* ProjectAdvancedSettingViewController.m in Sources */, + B1D5ED3220BC06CB00983FB6 /* SWLongPressGestureRecognizer.m in Sources */, + B1D5ED3320BC06CB00983FB6 /* QBAlbumsViewController.m in Sources */, + B1D5ED3420BC06CB00983FB6 /* TweetSendLocaitonMapViewController.m in Sources */, + B1D5ED3520BC06CB00983FB6 /* UIButton+WebCache.m in Sources */, + B1D5ED3620BC06CB00983FB6 /* EABoardTaskListBlankView.m in Sources */, + B1D5ED3720BC06CB00983FB6 /* SDWebImageManager+MJ.m in Sources */, + B1D5ED3820BC06CB00983FB6 /* TopicListView.m in Sources */, + B1D5ED3920BC06CB00983FB6 /* AbstractActionSheetPicker.m in Sources */, + B1D5ED3A20BC06CB00983FB6 /* CodingTips.m in Sources */, + B1D5ED3B20BC06CB00983FB6 /* MRPRCommentCCell.m in Sources */, + B1D5ED3C20BC06CB00983FB6 /* AMPopTip+Animation.m in Sources */, + B1C60C9120BFF7950073D3CA /* ProjectTypeExplanationViewController.m in Sources */, + B1D5ED3D20BC06CB00983FB6 /* TaskCommentTopCell.m in Sources */, + B1D5ED3E20BC06CB00983FB6 /* MRPRCommitsViewController.m in Sources */, + B1D5ED3F20BC06CB00983FB6 /* EABasePageModel.m in Sources */, + B1D5ED4020BC06CB00983FB6 /* UITableViewCell+Common.m in Sources */, + B1D5ED4120BC06CB00983FB6 /* EACodeReleaseListCell.m in Sources */, + B1D5ED4220BC06CB00983FB6 /* CSLikesVC.m in Sources */, + B1D5ED4320BC06CB00983FB6 /* UserOrProjectTweetsViewController.m in Sources */, + B1D5ED4420BC06CB00983FB6 /* CommitDetail.m in Sources */, + B1D5ED4520BC06CB00983FB6 /* DownMenuCell.m in Sources */, + B1D5ED4620BC06CB00983FB6 /* RFToolbarButton.m in Sources */, + B1D5ED4720BC06CB00983FB6 /* TopicListButton.m in Sources */, + B1C60CA920C0DDF60073D3CA /* TeamSupportViewController.m in Sources */, + B1D5ED4820BC06CB00983FB6 /* ImageSizeManager.m in Sources */, + B1D5ED4920BC06CB00983FB6 /* File.m in Sources */, + B1D5ED4A20BC06CB00983FB6 /* ShopOrderViewController.m in Sources */, + B1D5ED4B20BC06CB00983FB6 /* OTPTableViewCell.m in Sources */, + B1D5ED4C20BC06CB00983FB6 /* UIMessageInputView_CCell.m in Sources */, + B1D5ED4D20BC06CB00983FB6 /* DemoModel.m in Sources */, + B1D5ED4E20BC06CB00983FB6 /* TaskCommentBlankCell.m in Sources */, + B1D5ED4F20BC06CB00983FB6 /* AFNetworkActivityIndicatorManager.m in Sources */, + B1D5ED5020BC06CB00983FB6 /* Login.m in Sources */, + B1D5ED5120BC06CB00983FB6 /* TitleDisclosureCell.m in Sources */, + B1D5ED5220BC06CB00983FB6 /* FileDownloadView.m in Sources */, + B1D5ED5320BC06CB00983FB6 /* AFNetworkReachabilityManager.m in Sources */, + B1D5ED5420BC06CB00983FB6 /* LDNetTraceRoute.m in Sources */, + B1D5ED5520BC06CB00983FB6 /* SearchViewController.m in Sources */, + B1D5ED5620BC06CB00983FB6 /* QBImagePickerController.m in Sources */, + B1D5ED5720BC06CB00983FB6 /* EditColorViewController.m in Sources */, + B1D5ED5820BC06CB00983FB6 /* UIScrollView+SVPullToRefresh.m in Sources */, + B1D5ED5920BC06CB00983FB6 /* NSData+OTPBase32Encoding.m in Sources */, + B1D5ED5A20BC06CB00983FB6 /* StartImagesManager.m in Sources */, + B1D5ED5B20BC06CB00983FB6 /* ProjectMemberListViewController.m in Sources */, + B1D5ED5C20BC06CB00983FB6 /* ProjectActivitiesView.m in Sources */, + B1D5ED5D20BC06CB00983FB6 /* MRReviewerCell.m in Sources */, + B1D5ED5E20BC06CB00983FB6 /* TweetCommentCell.m in Sources */, + B1D5ED5F20BC06CB00983FB6 /* BaseNavigationController.m in Sources */, + B1D5ED6020BC06CB00983FB6 /* LocationHelper.m in Sources */, + B1D5ED6120BC06CB00983FB6 /* CSHotTopicPagesVC.m in Sources */, + B1D5ED6220BC06CB00983FB6 /* TaskSearchCell.m in Sources */, + B1D5ED6320BC06CB00983FB6 /* AFURLConnectionOperation.m in Sources */, + B1D5ED6420BC06CB00983FB6 /* ProjectTopic.m in Sources */, + B1D5ED6520BC06CB00983FB6 /* EACodeBranchListViewController.m in Sources */, + B1D5ED6620BC06CB00983FB6 /* TeamProjectsViewController.m in Sources */, + B1D5ED6720BC06CB00983FB6 /* RegisterViewController.m in Sources */, + B1D5ED6820BC06CB00983FB6 /* ShopBanner.m in Sources */, + B1D5ED6920BC06CB00983FB6 /* TitleRImageMoreCell.m in Sources */, + B1D5ED6A20BC06CB00983FB6 /* EABoardTaskListView.m in Sources */, + B1D5ED6B20BC06CB00983FB6 /* FileShare.m in Sources */, + B1D5ED6C20BC06CB00983FB6 /* ShopMutileValueCell.m in Sources */, + B1D5ED6D20BC06CB00983FB6 /* SVWebViewControllerActivitySafari.m in Sources */, + B1D5ED6E20BC06CB00983FB6 /* HOTPGenerator.m in Sources */, + B1D5ED6F20BC06CB00983FB6 /* WikiViewController.m in Sources */, + B1D5ED7020BC06CB00983FB6 /* TweetDetailViewController.m in Sources */, + B1D5ED7120BC06CB00983FB6 /* Team.m in Sources */, + B1D5ED7220BC06CB00983FB6 /* LoginViewController.m in Sources */, + B1D5ED7320BC06CB00983FB6 /* NSData+gzip.m in Sources */, + B1D5ED7420BC06CB00983FB6 /* NSString+OTPURLArguments.m in Sources */, + B1D5ED7520BC06CB00983FB6 /* ProjectSquareViewController.m in Sources */, + B1D5ED7620BC06CB00983FB6 /* EACodeBranches.m in Sources */, + B1D5ED7720BC06CB00983FB6 /* NSLayoutConstraintLine.m in Sources */, + B1D5ED7820BC06CB00983FB6 /* ProjectMemberActivityListViewController.m in Sources */, + B1D5ED7920BC06CB00983FB6 /* BaseViewController.m in Sources */, + B1D5ED7A20BC06CB00983FB6 /* TopicCommentCCell.m in Sources */, + B1D5ED7B20BC06CB00983FB6 /* EaseToolBar.m in Sources */, + B1D5ED7C20BC06CB00983FB6 /* Project.m in Sources */, + B1D5ED7D20BC06CB00983FB6 /* ProjectActivityListView.m in Sources */, + B1D5ED7E20BC06CB00983FB6 /* AFHTTPRequestOperationManager.m in Sources */, + B1D5ED7F20BC06CB00983FB6 /* BubblePlayView.m in Sources */, + B1D5ED8020BC06CB00983FB6 /* FRDLivelyButton.m in Sources */, + B1D5ED8120BC06CB00983FB6 /* UIColor+expanded.m in Sources */, + B1D5ED8220BC06CB00983FB6 /* MRListView.m in Sources */, + B1D5ED8320BC06CB00983FB6 /* UserActiveStatusView.m in Sources */, + B1D5ED8420BC06CB00983FB6 /* ScreenView.m in Sources */, + B1D5ED8520BC06CB00983FB6 /* ProjectCount.m in Sources */, + B1D5ED8620BC06CB00983FB6 /* ResourceReference.m in Sources */, + B1D5ED8720BC06CB00983FB6 /* SDWebImageDownloader.m in Sources */, + B1D5ED8820BC06CB00983FB6 /* HtmlMedia.m in Sources */, + B1D5ED8920BC06CB00983FB6 /* EditLabelCell.m in Sources */, + B1C60CA720C0DDF60073D3CA /* TeamPurchaseViewController.m in Sources */, + B1D5ED8A20BC06CB00983FB6 /* NSString+Common.m in Sources */, + B1D5ED8B20BC06CB00983FB6 /* BasicPreviewItem.m in Sources */, + B1D5ED8C20BC06CB00983FB6 /* MeDisplayViewController.m in Sources */, + B1D5ED8D20BC06CB00983FB6 /* SDImageCache.m in Sources */, + B1D5ED8E20BC06CB00983FB6 /* AddReviewerViewController.m in Sources */, + B1D5ED8F20BC06CB00983FB6 /* FunctionIntroManager.m in Sources */, + B1D5ED9020BC06CB00983FB6 /* NJKWebViewProgress.m in Sources */, + B1D5ED9120BC06CB00983FB6 /* MRPRTopCell.m in Sources */, + B1D5ED9220BC06CB00983FB6 /* ProjectTaskListView.m in Sources */, + B1D5ED9320BC06CB00983FB6 /* ResetLabelViewController.m in Sources */, + B1D5ED9420BC06CB00983FB6 /* FileComment.m in Sources */, + B1D5ED9520BC06CB00983FB6 /* Tweet_RootViewController.m in Sources */, + B1D5ED9620BC06CB00983FB6 /* ProjectDeleteAlertControllerVisualStyle.m in Sources */, + B1D5F21720BD485D00983FB6 /* TeamPurchaseOrder.m in Sources */, + B1D5ED9720BC06CB00983FB6 /* ProjectItemsCell.m in Sources */, + B1D5ED9820BC06CB00983FB6 /* WebContentManager.m in Sources */, + B1D5ED9920BC06CB00983FB6 /* Login2FATipCell.m in Sources */, + B1D5ED9A20BC06CB00983FB6 /* FileChangeDetailViewController.m in Sources */, + B1D5ED9B20BC06CB00983FB6 /* MJPhotoBrowser.m in Sources */, + B1D5ED9C20BC06CB00983FB6 /* CSMyTopicVC.m in Sources */, + B1D5ED9D20BC06CB00983FB6 /* LocationViewController.m in Sources */, + B1D5ED9E20BC06CB00983FB6 /* JDStatusBarLayoutMarginHelper.m in Sources */, + B1D5ED9F20BC06CB00983FB6 /* iCarousel.m in Sources */, + B1D5EDA020BC06CB00983FB6 /* ProjectDescriptionCell.m in Sources */, + B1D5EDA120BC06CB00983FB6 /* UIButton+Common.m in Sources */, + B1D5EDA220BC06CB00983FB6 /* UIDownMenuButton.m in Sources */, + B1D5EDA320BC06CB00983FB6 /* TopicAnswerDetailViewController.m in Sources */, + B1D5EDA420BC06CB00983FB6 /* UsersViewController.m in Sources */, + B1D5EDA520BC06CB00983FB6 /* SkillCCell.m in Sources */, + B1D5EDA620BC06CB00983FB6 /* MenuButton.m in Sources */, + B1D5EDA720BC06CB00983FB6 /* AMPopTip+Draw.m in Sources */, + B1D5EDA820BC06CB00983FB6 /* ProjectArchiveViewController.m in Sources */, + B1D5EDA920BC06CB00983FB6 /* TeamViewController.m in Sources */, + B1D5EDAA20BC06CB00983FB6 /* LocalFileViewController.m in Sources */, + B1D5EDAB20BC06CB00983FB6 /* ResetLabelCell.m in Sources */, + B1D5EDAD20BC06CB00983FB6 /* EACodeBranchListCell.m in Sources */, + B1D5EDAE20BC06CB00983FB6 /* ValueListViewController.m in Sources */, + B1D5EDAF20BC06CB00983FB6 /* ActivateViewController.m in Sources */, + B1D5EDB020BC06CB00983FB6 /* MRPRListViewController.m in Sources */, + B1D5EDB120BC06CB00983FB6 /* NSObject+ObjectMap.m in Sources */, + B1D5EDB220BC06CB00983FB6 /* SWCellScrollView.m in Sources */, + B1D5EDB320BC06CB00983FB6 /* ActionSheetCustomPicker.m in Sources */, + B1D5EDB420BC06CB00983FB6 /* PRMRSearchCell.m in Sources */, + B1D5EDB520BC06CB00983FB6 /* TweetSendViewController.m in Sources */, + B1D5EDB620BC06CB00983FB6 /* PrivateMessages.m in Sources */, + B1D5EDB720BC06CB00983FB6 /* YLImageView.m in Sources */, + B1D5EDB820BC06CB00983FB6 /* CodingBanner.m in Sources */, + B1D5EDB920BC06CB00983FB6 /* ShopOrderModel.m in Sources */, + B1D5EDBA20BC06CB00983FB6 /* MartFunctionTipView.m in Sources */, + B1D5EDBB20BC06CB00983FB6 /* CodingSkill.m in Sources */, + B1D5EDBC20BC06CB00983FB6 /* DashesLineView.m in Sources */, + B1D5EDBD20BC06CB00983FB6 /* Tweets.m in Sources */, + B1D5EDBE20BC06CB00983FB6 /* OTPAuthURL.m in Sources */, + B1D5EDBF20BC06CB00983FB6 /* MJPhoto.m in Sources */, + B1D5EDC020BC06CB00983FB6 /* TweetCell.m in Sources */, + B1D5EDC120BC06CB00983FB6 /* UIBarButtonItem+Common.m in Sources */, + B1D5EDC220BC06CB00983FB6 /* RRFPSBar.m in Sources */, + B1D5EDC320BC06CB00983FB6 /* EaseUserHeaderView.m in Sources */, + B1D5EDC420BC06CB00983FB6 /* PointRecordCell.m in Sources */, + B1D5EDC520BC06CB00983FB6 /* UIView+PressMenu.m in Sources */, + B1D5EDC620BC06CB00983FB6 /* Tasks.m in Sources */, + B1C60C9920C004C80073D3CA /* TeamPurchaseTopCell.m in Sources */, + B1D5EDC720BC06CB00983FB6 /* MBProgressHUD+Add.m in Sources */, + B1D5EDC820BC06CB00983FB6 /* CodeViewController.m in Sources */, + B1D5EDC920BC06CB00983FB6 /* ProjectTweetSendViewController.m in Sources */, + B1D5EDCA20BC06CB00983FB6 /* CommitListCell.m in Sources */, + B1D5EDCB20BC06CB00983FB6 /* EARestrictedScrollView.m in Sources */, + B1D5EDCC20BC06CB00983FB6 /* RDVTabBarController.m in Sources */, + B1D5EDCD20BC06CB00983FB6 /* ProjectLineNote.m in Sources */, + B1D5EDCE20BC06CB00983FB6 /* ProjectAboutMeListCell.m in Sources */, + B1D5EDCF20BC06CB00983FB6 /* EAFliterMenu.m in Sources */, + B1D5EDD020BC06CB00983FB6 /* HotTopicBannerView.m in Sources */, + B1D5F21B20BD485D00983FB6 /* TeamPurchaseBillingDetail.m in Sources */, + B1D5EDD120BC06CB00983FB6 /* EditTaskViewController.m in Sources */, + B1D5EDD220BC06CB00983FB6 /* TagColorDisplayCell.m in Sources */, + B1D5EDD320BC06CB00983FB6 /* ProjectTopics.m in Sources */, + B1D5EDD420BC06CB00983FB6 /* ReviewersInfo.m in Sources */, + B1D5EDD520BC06CB00983FB6 /* ProjectTasksView.m in Sources */, + B1D5EDD620BC06CB00983FB6 /* UICustomCollectionView.m in Sources */, + B1D5EDD720BC06CB00983FB6 /* NSObject+Common.m in Sources */, + B1D5EDD820BC06CB00983FB6 /* SMPageControl.m in Sources */, + B1D5EDD920BC06CB00983FB6 /* Coding_iOS.xcdatamodeld in Sources */, + B1D5EDDA20BC06CB00983FB6 /* ConversationViewController.m in Sources */, + B1D5EDDB20BC06CB00983FB6 /* EaseInputTipsView.m in Sources */, + B1D5EDDC20BC06CB00983FB6 /* NSDate+convenience.m in Sources */, + B1D5EDDD20BC06CB00983FB6 /* CSTopicModel.m in Sources */, + B1D5EDDE20BC06CB00983FB6 /* FileLineChange.m in Sources */, + B1D5EDDF20BC06CB00983FB6 /* PasswordViewController.m in Sources */, + B1C60C7F20BFCDBE0073D3CA /* EditMemberTypeProjectListViewController.m in Sources */, + B1D5EDE020BC06CB00983FB6 /* BaseCollectionCell.m in Sources */, + B1D5EDE120BC06CB00983FB6 /* SVWebViewController.m in Sources */, + B1D5EDE220BC06CB00983FB6 /* EACodeReleaseViewController.m in Sources */, + B1D5EDE320BC06CB00983FB6 /* AFSecurityPolicy.m in Sources */, + B1D5EDE420BC06CB00983FB6 /* UIImage+MultiFormat.m in Sources */, + B1D5EDE520BC06CB00983FB6 /* TweetMediaItemSingleCCell.m in Sources */, + B1D5EDE620BC06CB00983FB6 /* TweetLikeUserCCell.m in Sources */, + B1D5EDE720BC06CB00983FB6 /* RewardTipManager.m in Sources */, + B1D5EDE920BC06CB00983FB6 /* CommitFilesViewController.m in Sources */, + B1D5EDEA20BC06CB00983FB6 /* FileChange.m in Sources */, + B1D5EDEB20BC06CB00983FB6 /* main.m in Sources */, + B1D5EDEC20BC06CB00983FB6 /* NewProjectViewController.m in Sources */, + B1D5EDED20BC06CB00983FB6 /* TeamTopCell.m in Sources */, + B1D5EDEE20BC06CB00983FB6 /* UserInfoTextCell.m in Sources */, + B1D5EDEF20BC06CB00983FB6 /* MRPRDisclosureCell.m in Sources */, + B1D5EDF020BC06CB00983FB6 /* AboutViewController.m in Sources */, + B1D5EDF120BC06CB00983FB6 /* QBAssetCell.m in Sources */, + B1D5EDF220BC06CB00983FB6 /* EACodeReleaseListViewController.m in Sources */, + B1D5EDF320BC06CB00983FB6 /* MeRootUserCell.m in Sources */, + B1D5EDF420BC06CB00983FB6 /* ShopGoods.m in Sources */, + B1D5EDF520BC06CB00983FB6 /* AMPopTip+Entrance.m in Sources */, + B1D5EDF620BC06CB00983FB6 /* PointRecords.m in Sources */, + B1D5EDF720BC06CB00983FB6 /* QBCheckmarkView.m in Sources */, + B1D5EDF820BC06CB00983FB6 /* AFHTTPRequestOperation.m in Sources */, + B1D5EDF920BC06CB00983FB6 /* ProjectLineNoteActivity.m in Sources */, + B1D5EDFA20BC06CB00983FB6 /* MessageMediaItemCCell.m in Sources */, + B1D5EDFB20BC06CB00983FB6 /* MRPRS.m in Sources */, + B1D5EDFC20BC06CB00983FB6 /* EAEditCodeReleaseViewController.m in Sources */, + B1D5EDFD20BC06CB00983FB6 /* UIImage+Common.m in Sources */, + B1D5EDFE20BC06CB00983FB6 /* ProjectTopicCell.m in Sources */, + B1D5EDFF20BC06CB00983FB6 /* TextCheckMarkCell.m in Sources */, + B1D5EE0020BC06CB00983FB6 /* AFHTTPSessionManager.m in Sources */, + B1D5EE0120BC06CB00983FB6 /* XHRealTimeBlur.m in Sources */, + B1D5EE0220BC06CB00983FB6 /* ProjectFile.m in Sources */, + B1D5EE0320BC06CB00983FB6 /* CSTopiclistView.m in Sources */, + B1D5EE0420BC06CB00983FB6 /* UILabel+Common.m in Sources */, + B1D5EE0520BC06CB00983FB6 /* QBSlomoIconView.m in Sources */, + B1D5EE0620BC06CB00983FB6 /* SDWebImageDecoder.m in Sources */, + B1D5EE0720BC06CB00983FB6 /* TweetSearchCell.m in Sources */, + B1D5EE0820BC06CB00983FB6 /* AFURLResponseSerialization.m in Sources */, + B1D5EE0920BC06CB00983FB6 /* CodeFile.m in Sources */, + B1D5EE0A20BC06CB00983FB6 /* EAMilestone.m in Sources */, + B1D5EE0B20BC06CB00983FB6 /* CSSearchCell.m in Sources */, + B1C60C9B20C004C80073D3CA /* TeamPurchaseBillingCell.m in Sources */, + B1D5EE0C20BC06CB00983FB6 /* JDStatusBarView.m in Sources */, + B1D5EE0D20BC06CB00983FB6 /* MRPRAcceptEditCell.m in Sources */, + B1D5EE0E20BC06CB00983FB6 /* EACodeReleaseAttachmentsOrReferencesCell.m in Sources */, + B1D5EE0F20BC06CB00983FB6 /* MenuItem.m in Sources */, + B1D5EE1020BC06CB00983FB6 /* TweetMediaItemCCell.m in Sources */, + B1D5EE1120BC06CB00983FB6 /* EditLabelHeadCell.m in Sources */, + B1D5EE1220BC06CB00983FB6 /* TaskContentCell.m in Sources */, + B1D5EE1320BC06CB00983FB6 /* TaskDescriptionViewController.m in Sources */, + B1D5EE1420BC06CB00983FB6 /* AddressManager.m in Sources */, + B1D5EE1520BC06CB00983FB6 /* ProjectSettingViewController.m in Sources */, + B1D5EE1620BC06CB00983FB6 /* ActionSheetDistancePicker.m in Sources */, + B1D5EE1720BC06CB00983FB6 /* ProjectCodeListCell.m in Sources */, + B1D5EE1820BC06CB00983FB6 /* UserServiceInfo.m in Sources */, + B1D5EE1920BC06CB00983FB6 /* TweetSendLocationViewController.m in Sources */, + B1C60C7B20BFA2150073D3CA /* NProjectFileListView.m in Sources */, + B1D5EE1A20BC06CB00983FB6 /* ProjectFolderListCell.m in Sources */, + B1D5EE1B20BC06CB00983FB6 /* User.m in Sources */, + B1D5EE1C20BC06CB00983FB6 /* MJPhotoToolbar.m in Sources */, + B1D5EE1D20BC06CB00983FB6 /* TweetDetailCommentCell.m in Sources */, + B1D5EE1E20BC06CB00983FB6 /* SettingSkillsViewController.m in Sources */, + B1D5EE1F20BC06CB00983FB6 /* MRPRBaseInfo.m in Sources */, + B1D5EE2020BC06CB00983FB6 /* AudioRecordView.m in Sources */, + B1D5EE2120BC06CB00983FB6 /* TagColorEditCell.m in Sources */, + B1D5EE2220BC06CB00983FB6 /* QBVideoIndicatorView.m in Sources */, + B1C60C9D20C004C80073D3CA /* TeamPurchaseOrderCell.m in Sources */, + B1D5EE2320BC06CB00983FB6 /* FileInfoViewController.m in Sources */, + B1D5EE2420BC06CB00983FB6 /* CommitInfo.m in Sources */, + B1D5EE2520BC06CB00983FB6 /* CodeBranchTagButton.m in Sources */, + B1D5EE2620BC06CB00983FB6 /* ShopGoodsInfoView.m in Sources */, + B1D5EE2720BC06CB00983FB6 /* UIBadgeView.m in Sources */, + B1D5EE2820BC06CB00983FB6 /* BaseModel.m in Sources */, + B1D5EE2920BC06CB00983FB6 /* TaskSelectionView.m in Sources */, + B1D5EE2A20BC06CB00983FB6 /* ProjectListCell.m in Sources */, + B1D5EE2B20BC06CB00983FB6 /* EABoardTaskList.m in Sources */, + B1D5EE2C20BC06CB00983FB6 /* CSTopicDetailVC.m in Sources */, + B1D5EE2D20BC06CB00983FB6 /* ToMessageCell.m in Sources */, + B1D5EE2E20BC06CB00983FB6 /* SVWebViewControllerActivityChrome.m in Sources */, + B1D5EE2F20BC06CB00983FB6 /* PhoneCodeButton.m in Sources */, + B1D5EE3020BC06CB00983FB6 /* TopicAnswerCommentMoreCell.m in Sources */, + B1D5EE3120BC06CB00983FB6 /* LDNetPing.m in Sources */, + B1D5EE3220BC06CB00983FB6 /* DynamicCommentCell.m in Sources */, + B1D5EE3320BC06CB00983FB6 /* CSScrollview.m in Sources */, + B1D5EE3420BC06CB00983FB6 /* NSString+Attribute.m in Sources */, + B1D5EE3520BC06CB00983FB6 /* ProjectTopicsView.m in Sources */, + B1D5EE3620BC06CB00983FB6 /* ProjectFolder.m in Sources */, + B1D5EE3720BC06CB00983FB6 /* ProjectActivityListCell.m in Sources */, + B1D5EE3820BC06CB00983FB6 /* JDStatusBarStyle.m in Sources */, + B1D5EE3920BC06CB00983FB6 /* LDNetDiagnoService.m in Sources */, + B1D5EE3A20BC06CB00983FB6 /* EditCodeViewController.m in Sources */, + B1D5EE3B20BC06CB00983FB6 /* SettingTextViewController.m in Sources */, + B1D5EE3C20BC06CB00983FB6 /* EATaskBoardListTaskCell.m in Sources */, + B1D5EE3D20BC06CB00983FB6 /* LocationCell.m in Sources */, + B1D5EE3E20BC06CB00983FB6 /* QBVideoIconView.m in Sources */, + B1D5EE3F20BC06CB00983FB6 /* Comment.m in Sources */, + B1D5EE4020BC06CB00983FB6 /* TweetSendLocationCell.m in Sources */, + B1D5EE4120BC06CB00983FB6 /* HtmlMediaViewController.m in Sources */, + B1D5EE4220BC06CB00983FB6 /* CSTopicCreateVC.m in Sources */, + B1D5EE4320BC06CB00983FB6 /* NSMutableArray+SWUtilityButtons.m in Sources */, + B1D5EE4420BC06CB00983FB6 /* MActivityInfo.m in Sources */, + B1D5EE4520BC06CB00983FB6 /* UILongPressMenuImageView.m in Sources */, + B1D5EE4620BC06CB00983FB6 /* FileChangesIntroduceCell.m in Sources */, + B1D5EE4720BC06CB00983FB6 /* Register.m in Sources */, + B1D5EE4820BC06CB00983FB6 /* ShopOrder.m in Sources */, + B1D5EE4920BC06CB00983FB6 /* TopicAnswerCell.m in Sources */, + B1D5EE4A20BC06CB00983FB6 /* NSTimer+Common.m in Sources */, + B1D5EE4B20BC06CB00983FB6 /* CodingTipCell.m in Sources */, + B1D5EE4C20BC06CB00983FB6 /* AboutPointViewController.m in Sources */, + B1D5EE4D20BC06CB00983FB6 /* ProjectTagsView.m in Sources */, + B1D5EE4E20BC06CB00983FB6 /* Projects.m in Sources */, + B1D5EE4F20BC06CB00983FB6 /* UserInfoDetailUserCell.m in Sources */, + B1D5EE5020BC06CB00983FB6 /* ProjectActivities.m in Sources */, + B1D5EE5120BC06CB00983FB6 /* LocalFileCell.m in Sources */, + B1D5EE5220BC06CB00983FB6 /* MRReviewerListCell.m in Sources */, + B1D5EE5320BC06CB00983FB6 /* UITapImageView.m in Sources */, + B1D5EE5420BC06CB00983FB6 /* NSURL+OTPURLArguments.m in Sources */, + B1D5EE5520BC06CB00983FB6 /* FileActivitiesViewController.m in Sources */, + B1D5EE5620BC06CB00983FB6 /* LocalFolderCell.m in Sources */, + B1D5EE5720BC06CB00983FB6 /* SVWebViewControllerActivity.m in Sources */, + B1D5EE5820BC06CB00983FB6 /* TagsScrollView.m in Sources */, + B1D5EE5920BC06CB00983FB6 /* TaskDescriptionCell.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ @@ -7110,6 +12639,18 @@ name = InfoPlist.strings; sourceTree = ""; }; + B12B645A1FFB61AD00ACFDCC /* QBImagePicker.strings */ = { + isa = PBXVariantGroup; + children = ( + B12B645B1FFB61AD00ACFDCC /* de */, + B12B645D1FFB61AD00ACFDCC /* zh-Hans */, + B12B645E1FFB61AD00ACFDCC /* ja */, + B12B64631FFB61AD00ACFDCC /* en */, + B12B64641FFB61AD00ACFDCC /* es */, + ); + name = QBImagePicker.strings; + sourceTree = ""; + }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ @@ -7117,24 +12658,38 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = NO; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = NO; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Yuanchuang Wang (6KJRVPP9CY)"; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -7147,7 +12702,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; @@ -7157,23 +12712,37 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = NO; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = NO; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Distribution"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: Shenzhen Coding Network Technology Co., Ltd. (QN5Z87S3LH)"; COPY_PHASE_STRIP = YES; ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_PREPROCESSOR_DEFINITIONS = NS_BLOCK_ASSERTIONS; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -7181,7 +12750,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; ONLY_ACTIVE_ARCH = NO; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; @@ -7190,18 +12759,20 @@ }; 8E477043198770E700997D05 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A64F1BDEE7EF5AF0AEA5F032 /* Pods-Coding_iOS.debug.xcconfig */; + baseConfigurationReference = 34E37865A7DAAE68AEF68258 /* Pods-Coding_iOS.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CODE_SIGN_ENTITLEMENTS = Coding_iOS/Coding_iOS.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = QN5Z87S3LH; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + "$(PROJECT_DIR)/Coding_iOS/Vendor/AlipaySDK", ); GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -7211,18 +12782,20 @@ /usr/include/libxml2, /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, "Pods/evernote-cloud-sdk-ios/**", + "$(SRCROOT)/Carthage/Build/iOS/ObjectiveGit.framework/Headers/", ); INFOPLIST_FILE = "Coding_iOS/Coding_iOS-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 7.1; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Coding_iOS/Vendor/XGPush", "$(PROJECT_DIR)/Coding_iOS/Util/Audio/opencore-amr-iOS/lib", - "$(PROJECT_DIR)/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO", ); PRODUCT_BUNDLE_IDENTIFIER = net.coding.CodingForiOS; PRODUCT_NAME = Coding_iOS; PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; TARGETED_DEVICE_FAMILY = 1; WRAPPER_EXTENSION = app; }; @@ -7230,18 +12803,20 @@ }; 8E477044198770E700997D05 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 1F50C85531CF9D72938EE577 /* Pods-Coding_iOS.release.xcconfig */; + baseConfigurationReference = 2FD5D8DD0689696D28A6D49E /* Pods-Coding_iOS.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CODE_SIGN_ENTITLEMENTS = Coding_iOS/Coding_iOS.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = QN5Z87S3LH; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + "$(PROJECT_DIR)/Coding_iOS/Vendor/AlipaySDK", ); GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -7251,18 +12826,108 @@ /usr/include/libxml2, /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, "Pods/evernote-cloud-sdk-ios/**", + "$(SRCROOT)/Carthage/Build/iOS/ObjectiveGit.framework/Headers/", ); INFOPLIST_FILE = "Coding_iOS/Coding_iOS-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 7.1; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Coding_iOS/Vendor/XGPush", "$(PROJECT_DIR)/Coding_iOS/Util/Audio/opencore-amr-iOS/lib", - "$(PROJECT_DIR)/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO", ); PRODUCT_BUNDLE_IDENTIFIER = net.coding.CodingForiOS; PRODUCT_NAME = Coding_iOS; PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; + TARGETED_DEVICE_FAMILY = 1; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; + B1D5F20020BC06CB00983FB6 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 59EA81AF0F8C7610F675E1EB /* Pods-Coding_iOS-Coding_Enterprise_iOS.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon_E; + CODE_SIGN_ENTITLEMENTS = Coding_iOS/Coding_Enterprise_iOS.entitlements; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = QN5Z87S3LH; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + "$(PROJECT_DIR)/Coding_iOS/Vendor/AlipaySDK", + ); + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "Coding_iOS/Coding_Enterprise_iOS-Prefix.pch"; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /usr/include/libxml2, + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + "Pods/evernote-cloud-sdk-ios/**", + "$(SRCROOT)/Carthage/Build/iOS/ObjectiveGit.framework/Headers/", + ); + INFOPLIST_FILE = "$(SRCROOT)/Coding_iOS/Coding_Enterprise_iOS-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Coding_iOS/Vendor/XGPush", + "$(PROJECT_DIR)/Coding_iOS/Util/Audio/opencore-amr-iOS/lib", + ); + PRODUCT_BUNDLE_IDENTIFIER = net.coding.CodingEnterpriseForiOS; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; + TARGETED_DEVICE_FAMILY = 1; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + B1D5F20120BC06CB00983FB6 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 22A08D8B77355DB8A773B8E2 /* Pods-Coding_iOS-Coding_Enterprise_iOS.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon_E; + CODE_SIGN_ENTITLEMENTS = Coding_iOS/Coding_Enterprise_iOS.entitlements; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = QN5Z87S3LH; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + "$(PROJECT_DIR)/Coding_iOS/Vendor/AlipaySDK", + ); + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "Coding_iOS/Coding_Enterprise_iOS-Prefix.pch"; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /usr/include/libxml2, + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + "Pods/evernote-cloud-sdk-ios/**", + "$(SRCROOT)/Carthage/Build/iOS/ObjectiveGit.framework/Headers/", + ); + INFOPLIST_FILE = "$(SRCROOT)/Coding_iOS/Coding_Enterprise_iOS-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Coding_iOS/Vendor/XGPush", + "$(PROJECT_DIR)/Coding_iOS/Util/Audio/opencore-amr-iOS/lib", + ); + PRODUCT_BUNDLE_IDENTIFIER = net.coding.CodingEnterpriseForiOS; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; TARGETED_DEVICE_FAMILY = 1; WRAPPER_EXTENSION = app; }; @@ -7289,6 +12954,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + B1D5F1FF20BC06CB00983FB6 /* Build configuration list for PBXNativeTarget "Coding_Enterprise_iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B1D5F20020BC06CB00983FB6 /* Debug */, + B1D5F20120BC06CB00983FB6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ /* Begin XCVersionGroup section */ diff --git a/Coding_iOS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Coding_iOS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/Coding_iOS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Coding_iOS.xcodeproj/xcshareddata/xcschemes/Coding_Enterprise_iOS.xcscheme b/Coding_iOS.xcodeproj/xcshareddata/xcschemes/Coding_Enterprise_iOS.xcscheme new file mode 100644 index 000000000..b934a3b52 --- /dev/null +++ b/Coding_iOS.xcodeproj/xcshareddata/xcschemes/Coding_Enterprise_iOS.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Coding_iOS.xcodeproj/xcshareddata/xcschemes/Coding_iOS.xcscheme b/Coding_iOS.xcodeproj/xcshareddata/xcschemes/Coding_iOS.xcscheme new file mode 100644 index 000000000..7eacabe99 --- /dev/null +++ b/Coding_iOS.xcodeproj/xcshareddata/xcschemes/Coding_iOS.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Coding_iOS.xcworkspace/contents.xcworkspacedata b/Coding_iOS.xcworkspace/contents.xcworkspacedata old mode 100755 new mode 100644 index 7c557954e..790df574d --- a/Coding_iOS.xcworkspace/contents.xcworkspacedata +++ b/Coding_iOS.xcworkspace/contents.xcworkspacedata @@ -1 +1,10 @@ - \ No newline at end of file + + + + + + + diff --git a/Coding_iOS.xcworkspace/xcshareddata/Coding_iOS.xcscmblueprint b/Coding_iOS.xcworkspace/xcshareddata/Coding_iOS.xcscmblueprint deleted file mode 100644 index f116bcfea..000000000 --- a/Coding_iOS.xcworkspace/xcshareddata/Coding_iOS.xcscmblueprint +++ /dev/null @@ -1,37 +0,0 @@ -{ - "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "9F3660E5AC46AAE96CC141F90EBB3A671D67F2C2", - "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { - - }, - "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { - "0BE8B4916C79C0D6BC415A5C19AC33B37D62A706" : 0, - "B810104048DF61B07FF1F2922D434EA5073F4362" : 0, - "9F3660E5AC46AAE96CC141F90EBB3A671D67F2C2" : 0 - }, - "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "433ECD69-91E4-4E60-9763-B27EA86C3648", - "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { - "0BE8B4916C79C0D6BC415A5C19AC33B37D62A706" : "Coding-iOS\/Coding_iOS\/Resources\/webview\/", - "B810104048DF61B07FF1F2922D434EA5073F4362" : "Coding_iOS", - "9F3660E5AC46AAE96CC141F90EBB3A671D67F2C2" : "Coding-iOS\/" - }, - "DVTSourceControlWorkspaceBlueprintNameKey" : "Coding_iOS", - "DVTSourceControlWorkspaceBlueprintVersion" : 204, - "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Coding_iOS.xcworkspace", - "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ - { - "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "git:\/\/git.coding.net\/bluishoul\/CodingAppWebviewTemplate.git", - "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", - "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "0BE8B4916C79C0D6BC415A5C19AC33B37D62A706" - }, - { - "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/coding.net\/coding\/Coding-iOS.git", - "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", - "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "9F3660E5AC46AAE96CC141F90EBB3A671D67F2C2" - }, - { - "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/coding.net\/ease\/Coding-iOS.git", - "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", - "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "B810104048DF61B07FF1F2922D434EA5073F4362" - } - ] -} \ No newline at end of file diff --git a/Coding_iOS.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Coding_iOS.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/Coding_iOS.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Coding_iOS.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Coding_iOS.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 000000000..08de0be8d --- /dev/null +++ b/Coding_iOS.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded + + + diff --git a/Coding_iOS.xcworkspace/xcshareddata/xcdebugger/Breakpoints_v2.xcbkptlist b/Coding_iOS.xcworkspace/xcshareddata/xcdebugger/Breakpoints_v2.xcbkptlist deleted file mode 100644 index 62cf889c4..000000000 --- a/Coding_iOS.xcworkspace/xcshareddata/xcdebugger/Breakpoints_v2.xcbkptlist +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/Coding_iOS/.DS_Store b/Coding_iOS/.DS_Store index fe06cf627..cb024efb6 100644 Binary files a/Coding_iOS/.DS_Store and b/Coding_iOS/.DS_Store differ diff --git a/Coding_iOS/AppDelegate.m b/Coding_iOS/AppDelegate.m index 3acc5188c..cf64487f2 100644 --- a/Coding_iOS/AppDelegate.m +++ b/Coding_iOS/AppDelegate.m @@ -28,13 +28,15 @@ #import "PasswordViewController.h" #import "IntroductionViewController.h" #import "TweetSendViewController.h" +#import "ProjectToChooseListViewController.h" +#import "OTPListViewController.h" +#import "WikiEditViewController.h" #import "FunctionIntroManager.h" -#import -#import -#import #import -#import "UMSocialSinaSSOHandler.h" +#import "Coding_NetAPIManager.h" +#import "EADeviceToServerLog.h" +#import #import "Tweet.h" #import "sys/utsname.h" @@ -47,34 +49,25 @@ @implementation AppDelegate #pragma mark XGPush - (void)registerPush{ - float sysVer = [[[UIDevice currentDevice] systemVersion] floatValue]; - if(sysVer < 8){ - [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)]; - }else{ -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= _IPHONE80_ - UIMutableUserNotificationCategory *categorys = [[UIMutableUserNotificationCategory alloc] init]; - UIUserNotificationSettings *userSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert - categories:[NSSet setWithObject:categorys]]; - [[UIApplication sharedApplication] registerUserNotificationSettings:userSettings]; - [[UIApplication sharedApplication] registerForRemoteNotifications]; -#endif - } + UIMutableUserNotificationCategory *categorys = [[UIMutableUserNotificationCategory alloc] init]; + UIUserNotificationSettings *userSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert + categories:[NSSet setWithObject:categorys]]; + [[UIApplication sharedApplication] registerUserNotificationSettings:userSettings]; } #pragma mark UserAgent - (void)registerUserAgent{ - struct utsname systemInfo; - uname(&systemInfo); - NSString *deviceString = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding]; - NSString *userAgent = [NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleIdentifierKey], (__bridge id)CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), kCFBundleVersionKey) ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleVersionKey], deviceString, [[UIDevice currentDevice] systemVersion], ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] ? [[UIScreen mainScreen] scale] : 1.0f)]; + NSString *userAgent = [NSString userAgentStr]; NSDictionary *dictionary = @{@"UserAgent" : userAgent};//User-Agent [[NSUserDefaults standardUserDefaults] registerDefaults:dictionary]; } - #pragma lifeCycle -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions -{ +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ + if (kTarget_Enterprise) {//这是很早之前为测试弄的吧 + [NSObject preCookieHandle];//cookie 设置 + } + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for customization after application launch. self.window.backgroundColor = [UIColor whiteColor]; @@ -102,18 +95,21 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( [self.window makeKeyAndVisible]; [FunctionIntroManager showIntroPage]; - EaseStartView *startView = [EaseStartView startView]; - @weakify(self); - [startView startAnimationWithCompletionBlock:^(EaseStartView *easeStartView) { - @strongify(self); + if (kTarget_Enterprise) { [self completionStartAnimationWithOptions:launchOptions]; - }]; + }else{ + EaseStartView *startView = [EaseStartView new]; + @weakify(self); + [startView startAnimationWithCompletionBlock:^(EaseStartView *easeStartView) { + @strongify(self); + [self completionStartAnimationWithOptions:launchOptions]; + }]; + } #if DEBUG -// [[RRFPSBar sharedInstance] setShowsAverage:YES]; -// [[RRFPSBar sharedInstance] setHidden:NO]; + [[RRFPSBar sharedInstance] setShowsAverage:YES]; + [[RRFPSBar sharedInstance] setHidden:NO]; #endif - return YES; } @@ -126,30 +122,19 @@ - (void)completionStartAnimationWithOptions:(NSDictionary *)launchOptions{ } // UMENG 统计 - [MobClick startWithAppkey:kUmeng_AppKey reportPolicy:BATCH channelId:nil]; + UMConfigInstance.appKey = kUmeng_AppKey; + [MobClick startWithConfigure:UMConfigInstance]; - // UMENG Social Account - [UMSocialData setAppKey:kUmeng_AppKey]; - [UMSocialWechatHandler setWXAppId:kSocial_WX_ID appSecret:kSocial_WX_Secret url:[NSObject baseURLStr]]; - [UMSocialQQHandler setQQWithAppId:kSocial_QQ_ID appKey:kSocial_QQ_Secret url:[NSObject baseURLStr]]; - [ENSession setSharedSessionConsumerKey:kSocial_EN_Key consumerSecret:kSocial_EN_Secret optionalHost:nil]; - [UMSocialSinaSSOHandler openNewSinaSSOWithRedirectURL:kSocial_Sina_RedirectURL]; - - // UMENG Social Config - [UMSocialConfig setFollowWeiboUids:@{UMShareToSina : kSocial_Sina_OfficailAccount}];//设置默认关注官方账号 - [UMSocialConfig setFinishToastIsHidden:YES position:UMSocialiToastPositionCenter]; - [UMSocialConfig setNavigationBarConfig:^(UINavigationBar *bar, UIButton *closeButton, UIButton *backButton, UIButton *postButton, UIButton *refreshButton, UINavigationItem *navigationItem) { - if (bar) { - [bar setBackgroundImage:[UIImage imageWithColor:kColorNavBG] forBarMetrics:UIBarMetricsDefault]; - } - if (navigationItem) { - if ([[navigationItem titleView] isKindOfClass:[UILabel class]]) { - UILabel *titleL = (UILabel *)[navigationItem titleView]; - titleL.font = [UIFont boldSystemFontOfSize:kNavTitleFontSize]; - titleL.textColor = [UIColor whiteColor]; - } - } - }]; + if (!kTarget_Enterprise) { + //UMSocialManager & 第三方登录 + [[UMSocialManager defaultManager] openLog:YES]; + [UMSocialGlobal shareInstance].isUsingHttpsWhenShareContent = NO; + [[UMSocialManager defaultManager] setUmSocialAppkey:kUmeng_AppKey]; + [[UMSocialManager defaultManager] setPlaform:UMSocialPlatformType_WechatSession appKey:kSocial_WX_ID appSecret:kSocial_WX_Secret redirectURL:nil]; + [[UMSocialManager defaultManager] setPlaform:UMSocialPlatformType_QQ appKey:kSocial_QQ_ID appSecret:kSocial_QQ_Secret redirectURL:nil]; + [[UMSocialManager defaultManager] setPlaform:UMSocialPlatformType_Sina appKey:kSocial_Sina_ID appSecret:kSocial_Sina_Secret redirectURL:kSocial_Sina_RedirectURL]; + [ENSession setSharedSessionConsumerKey:kSocial_EN_Key consumerSecret:kSocial_EN_Secret optionalHost:nil]; + } // 信鸽推送 [XGPush startApp:kXGPush_Id appKey:kXGPush_Key]; @@ -158,7 +143,7 @@ - (void)completionStartAnimationWithOptions:(NSDictionary *)launchOptions{ @weakify(self); void (^successCallback)(void) = ^(void){ //如果变成需要注册状态 - if(![XGPush isUnRegisterStatus] && [Login isLogin]){ + if([XGPush isUnRegisterStatus] && [Login isLogin]){ @strongify(self); [self registerPush]; } @@ -175,6 +160,9 @@ - (void)applicationWillResignActive:(UIApplication *)application { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. + if ([[BaseViewController presentingVC] isKindOfClass:[WikiEditViewController class]]) { + [(WikiEditViewController *)[BaseViewController presentingVC] saveWikiDraft]; + } [[ImageSizeManager shareManager] save]; [[Tweet tweetForSend] saveSendData]; } @@ -205,6 +193,8 @@ - (void)applicationDidBecomeActive:(UIApplication *)application #pragma clang diagnostic pop } } + // CODING 报告 + [[EADeviceToServerLog shareManager] tryToStart]; } - (void)applicationWillTerminate:(UIApplication *)application @@ -212,6 +202,27 @@ - (void)applicationWillTerminate:(UIApplication *)application // Saves changes in the application's managed object context before the application terminates. [self saveContext]; } + +#ifndef Target_Enterprise + +// Universal Links - 个人版支持的东西 +#pragma mark Universal Links + +- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray * __nullable restorableObjects))restorationHandler{ + if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) { +// UIViewController *vc = [BaseViewController analyseVCFromLinkStr:userActivity.webpageURL.absoluteString]; +// if (vc) { +// [BaseViewController presentVC:vc]; +// } + [BaseViewController presentLinkStr:userActivity.webpageURL.absoluteString];//支持的链接就 native 打开,不支持的就用 web 打开 + }else{ + [[UIApplication sharedApplication] openURL:userActivity.webpageURL]; + } + return YES; +} + +#endif + #pragma mark - XGPush Message - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { @@ -226,15 +237,40 @@ - (void)application:(UIApplication *)application didReceiveRemoteNotification:(N [BaseViewController handleNotificationInfo:userInfo applicationState:[application applicationState]]; } +- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{ + DebugLog(@"%@", error); +} + +- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings{ + DebugLog(@"%@", notificationSettings); + [application registerForRemoteNotifications]; +} + #pragma mark - Methods Private - (void)setupLoginViewController{ +#ifdef Target_Enterprise + + IntroductionViewController *introductionVC = [[IntroductionViewController alloc] init]; + [self.window setRootViewController:introductionVC]; + [introductionVC presentLoginUI]; + +#else + LoginViewController *loginVC = [[LoginViewController alloc] init]; - [self.window setRootViewController:[[BaseNavigationController alloc] initWithRootViewController:loginVC]]; + [self.window setRootViewController:[[UINavigationController alloc] initWithRootViewController:loginVC]]; + +#endif } - (void)setupIntroductionViewController{ - IntroductionViewController *introductionVC = [[IntroductionViewController alloc] init]; - [self.window setRootViewController:introductionVC]; + if (kTarget_Enterprise) { + IntroductionViewController *introductionVC = [[IntroductionViewController alloc] init]; + [self.window setRootViewController:introductionVC]; + }else{ + [self setupLoginViewController];//猥琐换 +// IntroductionViewController *introductionVC = [[IntroductionViewController alloc] init]; +// [self.window setRootViewController:introductionVC]; + } } - (void)setupTabViewController{ @@ -245,27 +281,40 @@ - (void)setupTabViewController{ } - (void)customizeInterface { + {//UIBarButtonItem 颜色&字体 + NSDictionary *textAttributes = @{ + NSFontAttributeName: [UIFont systemFontOfSize:kBackButtonFontSize], + NSForegroundColorAttributeName: kColorLightBlue, + }; + [[UIBarButtonItem appearance] setTitleTextAttributes:textAttributes forState:UIControlStateNormal]; + [[UIBarButtonItem appearance] setTitleTextAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:kBackButtonFontSize]} forState:UIControlStateDisabled]; + [[UIBarButtonItem appearance] setTitleTextAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:kBackButtonFontSize]} forState:UIControlStateHighlighted]; + } //设置Nav的背景色和title色 UINavigationBar *navigationBarAppearance = [UINavigationBar appearance]; - [navigationBarAppearance setBackgroundImage:[UIImage imageWithColor:[NSObject baseURLStrIsProduction]? kColorNavBG: kColorBrandGreen] forBarMetrics:UIBarMetricsDefault]; - [navigationBarAppearance setTintColor:kColorBrandGreen];//返回按钮的箭头颜色 + [navigationBarAppearance setBackgroundImage:[UIImage imageWithColor:[NSObject baseURLStrIsProduction]? kColorNavBG: kColorActionYellow] forBarMetrics:UIBarMetricsDefault]; + [navigationBarAppearance setTintColor:kColorLightBlue];//返回按钮的箭头颜色 NSDictionary *textAttributes = @{ NSFontAttributeName: [UIFont systemFontOfSize:kNavTitleFontSize], NSForegroundColorAttributeName: kColorNavTitle, }; [navigationBarAppearance setTitleTextAttributes:textAttributes]; - - [[UITextField appearance] setTintColor:kColorBrandGreen];//设置UITextField的光标颜色 - [[UITextView appearance] setTintColor:kColorBrandGreen];//设置UITextView的光标颜色 + navigationBarAppearance.backIndicatorImage = [UIImage imageNamed:@"back_green_Nav"]; + navigationBarAppearance.backIndicatorTransitionMaskImage = [UIImage imageNamed:@"back_green_Nav"]; + + [[UITextField appearance] setTintColor:kColorLightBlue];//设置UITextField的光标颜色 + [[UITextView appearance] setTintColor:kColorLightBlue];//设置UITextView的光标颜色 [[UISearchBar appearance] setBackgroundImage:[UIImage imageWithColor:kColorTableSectionBg] forBarPosition:0 barMetrics:UIBarMetricsDefault]; } #pragma mark URL Schemes -- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{ +- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options{ DebugLog(@"path: %@, params: %@", [url path], [url queryParams]); if ([url.absoluteString hasPrefix:kCodingAppScheme]) { NSDictionary *queryParams = [url queryParams]; - if (queryParams[@"email"] && queryParams[@"key"]) {//重置密码 + if ([url.host isEqualToString:@"safepay"]) {//支付宝支付 + [self p_handlePayURL:url]; + }else if (queryParams[@"email"] && queryParams[@"key"]) {//重置密码 [self showPasswordWithURL:url]; }else if ([queryParams[@"type"] isEqualToString:@"tweet"]){//发冒泡 if ([Login isLogin]) { @@ -276,12 +325,51 @@ - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceAppl }else{//一般模式解析网页 [BaseViewController presentLinkStr:url.absoluteString]; } - return YES; + }else if ([url.scheme isEqualToString:kSocial_WX_ID] && [url.host isEqualToString:@"pay"]){//微信支付 + [self p_handlePayURL:url]; }else if ([url.absoluteString hasPrefix:@"en-:"]){ return [[ENSession sharedSession] handleOpenURL:url]; }else{ - return [UMSocialSnsService handleOpenURL:url]; + return [[UMSocialManager defaultManager] handleOpenURL:url options:options]; } + return YES; +} + +//- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{ +// DebugLog(@"path: %@, params: %@", [url path], [url queryParams]); +// if ([url.absoluteString hasPrefix:kCodingAppScheme]) { +// NSDictionary *queryParams = [url queryParams]; +// if ([url.host isEqualToString:@"safepay"]) {//支付宝支付 +// [self p_handlePayURL:url]; +// }else if (queryParams[@"email"] && queryParams[@"key"]) {//重置密码 +// [self showPasswordWithURL:url]; +// }else if ([queryParams[@"type"] isEqualToString:@"tweet"]){//发冒泡 +// if ([Login isLogin]) { +// [TweetSendViewController presentWithParams:queryParams]; +// }else{ +// [NSObject showHudTipStr:@"未登录"]; +// } +// }else{//一般模式解析网页 +// [BaseViewController presentLinkStr:url.absoluteString]; +// } +// }else if ([url.scheme isEqualToString:kSocial_WX_ID] && [url.host isEqualToString:@"pay"]){//微信支付 +// [self p_handlePayURL:url]; +// }else if ([url.absoluteString hasPrefix:@"en-:"]){ +// return [[ENSession sharedSession] handleOpenURL:url]; +// }else{ +// return [[UMSocialManager defaultManager] handleOpenURL:url sourceApplication:sourceApplication annotation:annotation]; +// } +// return YES; +//} + +- (void)p_handlePayURL:(NSURL *)url{ + UIViewController *vc = [BaseViewController presentingVC]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundeclared-selector" + if ([vc respondsToSelector:@selector(handlePayURL:)]) { + [vc performSelector:@selector(handlePayURL:) withObject:url]; + } +#pragma clang diagnostic pop } - (BOOL)showPasswordWithURL:(NSURL *)url{ @@ -423,4 +511,49 @@ - (NSURL *)applicationDocumentsDirectory return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; } +#pragma mark 3D Touch +- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void(^)(BOOL succeeded))completionHandler{ + if ([shortcutItem.type isEqualToString:@"shortcut_2FA"]){ + OTPListViewController *vc = [OTPListViewController new]; + [BaseViewController presentVC:vc]; + }else if (![Login isLogin]) { + UIViewController *presentingVC = [BaseViewController presentingVC]; + if (![presentingVC isKindOfClass:[LoginViewController class]]) { + LoginViewController *vc = [[LoginViewController alloc] init]; + vc.showDismissButton = YES; + UINavigationController *nav = [[BaseNavigationController alloc] initWithRootViewController:vc]; + [presentingVC presentViewController:nav animated:YES completion:nil]; + } + }else{ + if ([kKeyWindow.rootViewController isKindOfClass:[RootTabViewController class]]) { + RootTabViewController *vc = (RootTabViewController *)kKeyWindow.rootViewController; + vc.selectedIndex = ([shortcutItem.type isEqualToString:@"shortcut_task"]? 1: + 2); + } + if ([shortcutItem.type isEqualToString:@"shortcut_task"]) { + ProjectToChooseListViewController *chooseVC = [[ProjectToChooseListViewController alloc] init]; + [BaseViewController goToVC:chooseVC]; + }else if ([shortcutItem.type isEqualToString:@"shortcut_tweet"]){ + TweetSendViewController *vc = [[TweetSendViewController alloc] init]; + vc.sendNextTweet = ^(Tweet *nextTweet){ + [[Coding_NetAPIManager sharedManager] request_Tweet_DoTweet_WithObj:nextTweet andBlock:^(id data, NSError *error) { + if (data) { + if ([[BaseViewController presentingVC] respondsToSelector:NSSelectorFromString(@"refresh")]) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + [[BaseViewController presentingVC] performSelector:NSSelectorFromString(@"refresh")]; +#pragma clang diagnostic pop + + } + [Tweet deleteSendData];//发送成功后删除草稿 + }else{ + [nextTweet saveSendData];//发送失败,保存草稿 + } + }]; + }; + [BaseViewController presentVC:vc]; + } + } + completionHandler(YES); +} @end diff --git a/Coding_iOS/Coding_Enterprise_iOS-Info.plist b/Coding_iOS/Coding_Enterprise_iOS-Info.plist new file mode 100644 index 000000000..d652e9f7b --- /dev/null +++ b/Coding_iOS/Coding_Enterprise_iOS-Info.plist @@ -0,0 +1,134 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + CODING + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + 2.10 + CFBundleSignature + ???? + CFBundleURLTypes + + + CFBundleURLName + net.coding.CodingForiOS + + + CFBundleVersion + 2.10.20190523.1 + ITSAppUsesNonExemptEncryption + + LSApplicationQueriesSchemes + + wechat + weixin + sinaweibohd + sinaweibo + sinaweibosso + weibosdk + weibosdk2.5 + mqqapi + mqq + mqqOpensdkSSoLogin + mqqconnect + mqqopensdkdataline + mqqopensdkgrouptribeshare + mqqopensdkfriend + mqqopensdkapi + mqqopensdkapiV2 + mqqopensdkapiV3 + mqzoneopensdk + wtloginmqq + wtloginmqq2 + mqqwpa + mqzone + mqzonev2 + mqzoneshare + wtloginqzone + mqzonewx + mqzoneopensdkapiV2 + mqzoneopensdkapi19 + mqzoneopensdkapi + mqzoneopensdk + evernote + mart-coding-net + + LSRequiresIPhoneOS + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + NSCameraUsageDescription + 需要扫描二维码或拍照,是否允许打开相机? + NSLocationWhenInUseUsageDescription + 需要通过定位获取您周边的地理位置信息,是否允许获取你的定位? + NSMicrophoneUsageDescription + 需要录制音频,是否允许打开麦克风? + NSPhotoLibraryAddUsageDescription + 需要存储图片到相册,是够允许向相册添加照片? + NSPhotoLibraryUsageDescription + 需要添加照片,是否允许访问相册? + UIAppFonts + + FontAwesome.ttf + + UIApplicationShortcutItems + + + UIApplicationShortcutItemIconFile + shortcut_task + UIApplicationShortcutItemTitle + 新任务 + UIApplicationShortcutItemType + shortcut_task + UIApplicationShortcutItemUserInfo + + + + UIApplicationShortcutItemIconFile + shortcut_2FA + UIApplicationShortcutItemTitle + 两步验证 + UIApplicationShortcutItemType + shortcut_2FA + UIApplicationShortcutItemUserInfo + + + + UIFileSharingEnabled + + UILaunchStoryboardName + Launch Screen_E + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UIStatusBarStyle + UIStatusBarStyleDefault + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/Coding_iOS/Coding_Enterprise_iOS.entitlements b/Coding_iOS/Coding_Enterprise_iOS.entitlements new file mode 100644 index 000000000..903def2af --- /dev/null +++ b/Coding_iOS/Coding_Enterprise_iOS.entitlements @@ -0,0 +1,8 @@ + + + + + aps-environment + development + + diff --git a/Coding_iOS/Coding_iOS-Info.plist b/Coding_iOS/Coding_iOS-Info.plist index 160b12e97..9abf93e37 100644 --- a/Coding_iOS/Coding_iOS-Info.plist +++ b/Coding_iOS/Coding_iOS-Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion en CFBundleDisplayName - Coding + CODING CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 4.0.8 + 5.4.5 CFBundleSignature ???? CFBundleURLTypes @@ -30,13 +30,14 @@ coding-net wb600921819 QQ41C16356 - wx261aca93a0e9893c + tencent1103192918 + wx6ef6df9e9706b1bd en- CFBundleVersion - 4.0.8.201611031640 + 5.4.5.20190219.1 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes @@ -82,17 +83,52 @@ NSCameraUsageDescription - 我们需要您的同意才能使用相机 + 需要扫描二维码或拍照,是否允许打开相机? NSLocationWhenInUseUsageDescription - 我们需要通过您的地理位置信息获取您周边的相关数据 + 需要通过定位获取您周边的地理位置信息,是否允许获取你的定位? NSMicrophoneUsageDescription - 我们需要您的同意才能使用麦克风 + 需要录制音频,是否允许打开麦克风? + NSPhotoLibraryAddUsageDescription + 需要存储图片到相册,是够允许向相册添加照片? NSPhotoLibraryUsageDescription - 我们需要您的同意才能读取您的照片 + 需要添加照片,是否允许访问相册? UIAppFonts FontAwesome.ttf + UIApplicationShortcutItems + + + UIApplicationShortcutItemIconFile + shortcut_task + UIApplicationShortcutItemTitle + 新任务 + UIApplicationShortcutItemType + shortcut_task + UIApplicationShortcutItemUserInfo + + + + UIApplicationShortcutItemIconFile + shortcut_tweet + UIApplicationShortcutItemTitle + 发冒泡 + UIApplicationShortcutItemType + shortcut_tweet + UIApplicationShortcutItemUserInfo + + + + UIApplicationShortcutItemIconFile + shortcut_2FA + UIApplicationShortcutItemTitle + 两步验证 + UIApplicationShortcutItemType + shortcut_2FA + UIApplicationShortcutItemUserInfo + + + UIFileSharingEnabled UILaunchStoryboardName diff --git a/Coding_iOS/Coding_iOS-Prefix.pch.example b/Coding_iOS/Coding_iOS-Prefix.pch.example index ee27a9580..25cc487e5 100644 --- a/Coding_iOS/Coding_iOS-Prefix.pch.example +++ b/Coding_iOS/Coding_iOS-Prefix.pch.example @@ -26,18 +26,21 @@ #import "UILabel+Common.h" #import "NSDate+Common.h" #import "UIBarButtonItem+Common.h" -#import "UIActionSheet+Common.h" #import "NSURL+Common.h" #import "UISearchBar+Common.h" #import "UITTTAttributedLabel.h" #import "NSObject+ObjectMap.h" #import "ImageSizeManager.h" -#import "MobClick.h" +#import #import #import #import #import "UIImageView+WebCache.h" #import +#import "UIView+SDAutoLayout.h" +#import "UITableView+SDAutoTableViewCellHeight.h" +#import "PHAsset+Common.h" +#import "UINavigationBar+Common.h" #import "BaseNavigationController.h" #import "BaseViewController.h" @@ -64,6 +67,9 @@ #define kSocial_Sina_RedirectURL @"" #define kSocial_Sina_OfficailAccount @"" +#define kSocial_Sina_ID @"" +#define kSocial_Sina_Secret @"" + //信鸽推送 #define kXGPush_Id 123456 #define kXGPush_Key @"" @@ -104,6 +110,16 @@ #define kDevice_Is_iPhone5 ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 1136), [[UIScreen mainScreen] currentMode].size) : NO) #define kDevice_Is_iPhone6 ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(750, 1334), [[UIScreen mainScreen] currentMode].size) : NO) #define kDevice_Is_iPhone6Plus ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1242, 2208), [[UIScreen mainScreen] currentMode].size) : NO) +#define kDevice_Is_iPhoneX ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size) : NO) +#define kDevice_Is_iPhoneXR ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(828, 1792), [[UIScreen mainScreen] currentMode].size) : NO) +#define kDevice_Is_iPhoneXMax ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1242, 2688), [[UIScreen mainScreen] currentMode].size) : NO) +#define kDevice_Is_FullScreen (kDevice_Is_iPhoneX || kDevice_Is_iPhoneXR || kDevice_Is_iPhoneXMax) +#define kDevice_Is_iPad [[UIDevice currentDevice].model isEqualToString:@"iPad"] +#define kDevice_Use_iPhone4_Layout (kDevice_Is_iPhone4 || kDevice_Is_iPad) + +#define kSafeArea_Top (kDevice_Is_FullScreen? 44: 20) +#define kSafeArea_Bottom (kDevice_Is_FullScreen? 34: 0) +#define kLine_MinHeight (1.0/ [UIScreen mainScreen].scale) #define kScreen_Bounds [UIScreen mainScreen].bounds #define kScreen_Height [UIScreen mainScreen].bounds.size.height @@ -119,17 +135,39 @@ #define kDefaultLastId [NSNumber numberWithInteger:99999999] -#define kColorNavBG [UIColor colorWithHexString:@"0xF8F8F8"] +//#define kColorNavBG [UIColor colorWithHexString:@"0xF8F8F8"] +#define kColorNavBG [UIColor colorWithHexString:@"0xFFFFFF" andAlpha:1.0] #define kColorNavTitle [UIColor colorWithHexString:@"0x323A45"] #define kColorTableBG [UIColor colorWithHexString:@"0xFFFFFF"] #define kColorTableSectionBg [UIColor colorWithHexString:@"0xF2F4F6"] #define kColor222 [UIColor colorWithHexString:@"0x222222"] #define kColor666 [UIColor colorWithHexString:@"0x666666"] #define kColor999 [UIColor colorWithHexString:@"0x999999"] -#define kColorDDD [UIColor colorWithHexString:@"0xDDDDDD"] -#define kColorCCC [UIColor colorWithHexString:@"0xCCCCCC"] -#define kColorBrandGreen [UIColor colorWithHexString:@"0x3BBD79"] -#define kColorBrandRed [UIColor colorWithHexString:@"0xFF5846"] +//#define kColorDDD [UIColor colorWithHexString:@"0xDDDDDD"] +//#define kColorCCC [UIColor colorWithHexString:@"0xCCCCCC"] +#define kColorDDD kColorD8DDE4 +#define kColorCCC kColorD8DDE4 +#define kColorD8DDE4 [UIColor colorWithHexString:@"0xD8DDE4"] +#define kColorBrandGreen [UIColor colorWithHexString:@"0x2EBE76"] +#define kColorBrandBlue [UIColor colorWithHexString:@"0x0060FF"] +#define kColorBrandRed [UIColor colorWithHexString:@"0xF56061"] +#define kColorBrandOrange [UIColor colorWithHexString:@"0xF68435"] +#define kColorLightBlue [UIColor colorWithHexString:@"0x136BFB"] +#define kColorLinkBlue [UIColor colorWithHexString:@"0x2D59A2"] + +#pragma mark New Color +#define kColorDark2 [UIColor colorWithHexString:@"0x272C33"] +#define kColorDark3 [UIColor colorWithHexString:@"0x323A45"] +#define kColorDark4 [UIColor colorWithHexString:@"0x425063"] +#define kColorDark7 [UIColor colorWithHexString:@"0x76808E"] +#define kColorDarkA [UIColor colorWithHexString:@"0xA9B3BE"] +#define kColorDarkD [UIColor colorWithHexString:@"0xD8DDE4"] +#define kColorDarkF [UIColor colorWithHexString:@"0xF2F4F6"] +#define kColorWhite [UIColor colorWithHexString:@"0xFFFFFF"] +#define kColorActionGreen [UIColor colorWithHexString:@"0x2EBE76"] +#define kColorActionBlue [UIColor colorWithHexString:@"0x0060FF"] +#define kColorActionRed [UIColor colorWithHexString:@"0xF56061"] +#define kColorActionYellow [UIColor colorWithHexString:@"0xF3C033"] #define kPlaceholderMonkeyRoundWidth(_width_) [UIImage imageNamed:[NSString stringWithFormat:@"placeholder_monkey_round_%.0f", _width_]] #define kPlaceholderMonkeyRoundView(_view_) [UIImage imageNamed:[NSString stringWithFormat:@"placeholder_monkey_round_%.0f", CGRectGetWidth(_view_.frame)]] @@ -193,4 +231,4 @@ /** defines a weak `self` named `__weakSelf` */ #define ESWeakSelf ESWeak(self, __weakSelf); /** defines a strong `self` named `_self` from `__weakSelf` */ -#define ESStrongSelf ESStrong(__weakSelf, _self); \ No newline at end of file +#define ESStrongSelf ESStrong(__weakSelf, _self); diff --git a/Coding_iOS/Coding_iOS.entitlements b/Coding_iOS/Coding_iOS.entitlements index 903def2af..8593d979d 100644 --- a/Coding_iOS/Coding_iOS.entitlements +++ b/Coding_iOS/Coding_iOS.entitlements @@ -4,5 +4,9 @@ aps-environment development + com.apple.developer.associated-domains + + applinks:coding.net + diff --git a/Coding_iOS/Controllers/AboutPointViewController.h b/Coding_iOS/Controllers/AboutPointViewController.h new file mode 100644 index 000000000..4f55e75e9 --- /dev/null +++ b/Coding_iOS/Controllers/AboutPointViewController.h @@ -0,0 +1,13 @@ +// +// AboutPointViewController.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2017/9/18. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "BaseViewController.h" + +@interface AboutPointViewController : BaseViewController + +@end diff --git a/Coding_iOS/Controllers/AboutPointViewController.m b/Coding_iOS/Controllers/AboutPointViewController.m new file mode 100644 index 000000000..aead75ef5 --- /dev/null +++ b/Coding_iOS/Controllers/AboutPointViewController.m @@ -0,0 +1,43 @@ +// +// AboutPointViewController.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2017/9/18. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "AboutPointViewController.h" + +@interface AboutPointViewController () +@property (weak, nonatomic) IBOutlet UILabel *aboutL; + +@end + +@implementation AboutPointViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view from its nib. + self.title = @"关于码币"; + + NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:_aboutL.text]; + //段落 + NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; + [paragraphStyle setLineSpacing:5.0]; +// [paragraphStyle setParagraphSpacing:10]; + [paragraphStyle setLineBreakMode:_aboutL.lineBreakMode]; + [paragraphStyle setAlignment:_aboutL.textAlignment]; + [attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [_aboutL.text length])]; + //标题 + NSArray *titleList = @[@"什么是码币", @"码币的用途", @"如何获取码币"]; + for (NSString *title in titleList) { + NSRange textR = [_aboutL.text rangeOfString:title]; + if (textR.location != NSNotFound) { + [attributedString addAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:15 weight:UIFontWeightMedium], + NSForegroundColorAttributeName: kColorDark3} range:textR]; + } + } + _aboutL.attributedText = attributedString; +} + +@end diff --git a/Coding_iOS/Controllers/AboutPointViewController.xib b/Coding_iOS/Controllers/AboutPointViewController.xib new file mode 100644 index 000000000..5c48e111e --- /dev/null +++ b/Coding_iOS/Controllers/AboutPointViewController.xib @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Coding_iOS/Controllers/AddMDCommentViewController.h b/Coding_iOS/Controllers/AddMDCommentViewController.h index fdd0a859f..a9c840453 100644 --- a/Coding_iOS/Controllers/AddMDCommentViewController.h +++ b/Coding_iOS/Controllers/AddMDCommentViewController.h @@ -15,5 +15,6 @@ @property (strong, nonatomic) NSMutableDictionary *requestParams; @property (strong, nonatomic) NSString *contentStr; @property (strong, nonatomic) Project *curProject; +@property (assign, nonatomic) BOOL isLineNote;//这个字段单纯是为友盟统计的,没啥特别的作用 @end diff --git a/Coding_iOS/Controllers/AddMDCommentViewController.m b/Coding_iOS/Controllers/AddMDCommentViewController.m index c54c32053..ba8aa69f6 100644 --- a/Coding_iOS/Controllers/AddMDCommentViewController.m +++ b/Coding_iOS/Controllers/AddMDCommentViewController.m @@ -174,8 +174,11 @@ - (void)previewLoadMDData{ - (void)saveBtnClicked{ _contentStr = [_contentStr aliasedString]; [_requestParams setObject:_contentStr forKey:@"content"]; - + _requestParams[@"isLineNote"] = @(_isLineNote); + + [NSObject showHUDQueryStr:@"正在保存..."]; [[Coding_NetAPIManager sharedManager] request_PostCommentWithPath:_requestPath params:_requestParams andBlock:^(id data, NSError *error) { + [NSObject hideHUDQuery]; if (data) { if (self.completeBlock) { self.completeBlock(data); diff --git a/Coding_iOS/Controllers/AddReviewerViewController.m b/Coding_iOS/Controllers/AddReviewerViewController.m index 93fef76af..bc5db3f6a 100644 --- a/Coding_iOS/Controllers/AddReviewerViewController.m +++ b/Coding_iOS/Controllers/AddReviewerViewController.m @@ -51,7 +51,7 @@ -(void)viewDidLoad { UISearchBar *searchBar = [[UISearchBar alloc] init]; searchBar.delegate = self; [searchBar sizeToFit]; - [searchBar setPlaceholder:@"昵称,个性后缀"]; + [searchBar setPlaceholder:@"昵称,用户名"]; searchBar; }); [self.myTableView sizeToFit]; @@ -132,9 +132,9 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ ReviewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_ReviewCell forIndexPath:indexPath]; User* cellReviewer = self.allUsers[indexPath.row]; - cell.tintColor = kColorBrandGreen; + cell.tintColor = kColorBrandBlue; [cell initCellWithUsers:cellReviewer]; - [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:60]; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:70]; NSInteger index = indexPath.row; NSNumber* userState = self.selectUsers[index]; // cell.selectionStyle = UITableViewCellSelectionStyleNone; diff --git a/Coding_iOS/Controllers/AddReviewerViewController.xib b/Coding_iOS/Controllers/AddReviewerViewController.xib index 8341b5ebd..d205e6fb5 100644 --- a/Coding_iOS/Controllers/AddReviewerViewController.xib +++ b/Coding_iOS/Controllers/AddReviewerViewController.xib @@ -1,8 +1,11 @@ - + + + + - + @@ -18,6 +21,7 @@ + diff --git a/Coding_iOS/Controllers/AddUserViewController.h b/Coding_iOS/Controllers/AddUserViewController.h index 8b208e044..3a5bf5b7e 100755 --- a/Coding_iOS/Controllers/AddUserViewController.h +++ b/Coding_iOS/Controllers/AddUserViewController.h @@ -14,6 +14,7 @@ typedef NS_ENUM(NSInteger, AddUserType) { AddUserTypeProjectRoot = 0, AddUserTypeProjectFollows,//我的关注 AddUserTypeProjectFans,//我的粉丝 + AddUserTypeProjectCompany,//企业成员 AddUserTypeFollow//添加好友 }; @interface AddUserViewController : BaseViewController diff --git a/Coding_iOS/Controllers/AddUserViewController.m b/Coding_iOS/Controllers/AddUserViewController.m index 2e5021b8d..45065de6f 100755 --- a/Coding_iOS/Controllers/AddUserViewController.m +++ b/Coding_iOS/Controllers/AddUserViewController.m @@ -30,7 +30,8 @@ - (void)viewDidLoad { if (self.type < AddUserTypeFollow) { self.title = (self.type == AddUserTypeProjectRoot? @"添加成员": self.type == AddUserTypeProjectFollows? @"我的关注": - @"我的粉丝"); + self.type == AddUserTypeProjectFans? @"我的粉丝": + @"企业成员"); _queryingArray = [NSMutableArray array]; _searchedArray = [NSMutableArray array]; }else if (self.type == AddUserTypeFollow){ @@ -49,20 +50,26 @@ - (void)viewDidLoad { [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _mySearchBar = ({ UISearchBar *searchBar = [[UISearchBar alloc] init]; searchBar.delegate = self; [searchBar sizeToFit]; - [searchBar setPlaceholder:@"昵称/个性后缀"]; + [searchBar setPlaceholder:@"昵称/用户名"]; searchBar; }); _myTableView.tableHeaderView = _mySearchBar; - if (self.type == AddUserTypeProjectFollows || self.type == AddUserTypeProjectFans) { + if (self.type == AddUserTypeProjectFollows || self.type == AddUserTypeProjectFans || self.type == AddUserTypeProjectCompany) { _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; [_myRefreshControl addTarget:self action:@selector(refresh) forControlEvents:UIControlEventValueChanged]; - _curUsers = [Users usersWithOwner:[Login curLoginUser] Type:self.type == AddUserTypeProjectFollows? UsersTypeFriends_Attentive: UsersTypeFollowers]; + UsersType userType = (self.type == AddUserTypeProjectFollows? UsersTypeFriends_Attentive: + self.type == AddUserTypeProjectFans? UsersTypeFollowers: + UsersType_CompanyMember); + _curUsers = [Users usersWithOwner:[Login curLoginUser] Type:userType]; [self refresh]; } } @@ -131,14 +138,14 @@ - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSIntege } - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ - if (_type == AddUserTypeFollow) { + if (_type == AddUserTypeFollow || kTarget_Enterprise) { return [UIView new]; }else{ NSInteger leftNum = _curProject.max_member.integerValue - _addedArray.count; UILabel *label = [UILabel labelWithSystemFontSize:13 textColorHexString:leftNum > 0? @"0x999999": @"0xF34A4A"]; label.backgroundColor = self.view.backgroundColor; label.textAlignment = NSTextAlignmentCenter; - label.text = leftNum > 0? [NSString stringWithFormat:@"你还可以添加 %lu 个项目成员", leftNum]: @"已到达到成员最大数,不能再继续选择成员!"; + label.text = leftNum > 0? [NSString stringWithFormat:@"你还可以添加 %lu 个项目成员", leftNum]: @"已达到成员最大数,不能再继续选择成员!"; return label; } } @@ -213,9 +220,15 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath } - (void)goToUserInfo:(User *)user{ - UserInfoViewController *vc = [[UserInfoViewController alloc] init]; - vc.curUser = user; - [self.navigationController pushViewController:vc animated:YES]; + if (kTarget_Enterprise) { + UserInfoDetailViewController *vc = [UserInfoDetailViewController new]; + vc.curUser = user; + [self.navigationController pushViewController:vc animated:YES]; + }else{ + UserInfoViewController *vc = [[UserInfoViewController alloc] init]; + vc.curUser = user; + [self.navigationController pushViewController:vc animated:YES]; + } } #pragma mark ScrollView Delegate diff --git a/Coding_iOS/Controllers/AllSearchDisplayVC.h b/Coding_iOS/Controllers/AllSearchDisplayVC.h index e94586ac2..d85d7b213 100644 --- a/Coding_iOS/Controllers/AllSearchDisplayVC.h +++ b/Coding_iOS/Controllers/AllSearchDisplayVC.h @@ -6,22 +6,10 @@ // Copyright © 2015年 Coding. All rights reserved. // -typedef NS_ENUM(NSUInteger, eSearchType) { - eSearchType_Project=0, - eSearchType_Task, - eSearchType_Topic, - eSearchType_Tweet, - eSearchType_Document, - eSearchType_User, - eSearchType_Merge, - eSearchType_Pull, - eSearchType_All -}; - #import +#import "CodingSearchDisplayView.h" @interface AllSearchDisplayVC : UISearchDisplayController @property (nonatomic,weak)UIViewController *parentVC; -@property (nonatomic,assign)eSearchType curSearchType; -(void)reloadDisplayData; @end diff --git a/Coding_iOS/Controllers/AllSearchDisplayVC.m b/Coding_iOS/Controllers/AllSearchDisplayVC.m index 4bb553e05..1f0be70dd 100644 --- a/Coding_iOS/Controllers/AllSearchDisplayVC.m +++ b/Coding_iOS/Controllers/AllSearchDisplayVC.m @@ -37,21 +37,25 @@ #import "TweetDetailViewController.h" #import "ConversationViewController.h" -@interface AllSearchDisplayVC () +#import "iCarousel.h" +#import "XTSegmentControl.h" + +@interface AllSearchDisplayVC () @property (nonatomic, strong) UIView *contentView; @property (nonatomic, strong) XHRealTimeBlur *backgroundView; @property (nonatomic, strong) UIButton *btnMore; @property (nonatomic, strong) TopicHotkeyView *topicHotkeyView; -@property (nonatomic, strong) UITableView *searchTableView; +@property (nonatomic, strong) UIView *searchResultView; @property (nonatomic, strong) ODRefreshControl *refreshControl; -@property (nonatomic, strong) NSMutableArray *dateSource; -@property (nonatomic, assign) BOOL isLoading; -@property (nonatomic, strong) UILabel *headerLabel; @property (nonatomic, strong) PublicSearchModel *searchPros; @property (nonatomic, strong) UIScrollView *searchHistoryView; @property (nonatomic, assign) double historyHeight; +@property (strong, nonatomic) XTSegmentControl *mySegmentControl; +@property (strong, nonatomic) NSArray *titlesArray; +@property (strong, nonatomic) iCarousel *myCarousel; + - (void)initSearchResultsTableView; - (void)initSearchHistoryView; - (void)didClickedMoreHotkey:(UIGestureRecognizer *)sender; @@ -68,16 +72,23 @@ - (void)dealloc { _searchHistoryView.delegate = nil; } +- (NSArray *)titlesArray{ + if (!_titlesArray) { +// _titlesArray = @[@"项目", @"任务", @"讨论", @"冒泡", @"文档", @"用户", @"合并请求", @"Pull 请求"]; + _titlesArray = @[@"项目", @"任务", @"冒泡", @"文档", @"用户", @"合并请求"]; + } + return _titlesArray; +} - (void)setActive:(BOOL)visible animated:(BOOL)animated { if(!visible) { - [_searchTableView removeFromSuperview]; + [_searchResultView removeFromSuperview]; [_backgroundView removeFromSuperview]; [_contentView removeFromSuperview]; - _searchTableView = nil; + _searchResultView = nil; _contentView = nil; _backgroundView = nil; _searchHistoryView = nil; @@ -139,56 +150,38 @@ - (void)setActive:(BOOL)visible animated:(BOOL)animated { #pragma mark - UI - (void)initSearchResultsTableView { - - _dateSource = [[NSMutableArray alloc] init]; - - if(!_searchTableView) { - _searchTableView = ({ - UITableView *tableView = [[UITableView alloc] initWithFrame:_contentView.frame style:UITableViewStylePlain]; - tableView.backgroundColor = [UIColor whiteColor]; - tableView.separatorStyle = UITableViewCellSeparatorStyleNone; - [tableView registerClass:[TweetSearchCell class] forCellReuseIdentifier:@"TweetSearchCell"]; - [tableView registerClass:[ProjectAboutMeListCell class] forCellReuseIdentifier:@"ProjectAboutMeListCell"]; - [tableView registerClass:[FileSearchCell class] forCellReuseIdentifier:@"FileSearchCell"]; - [tableView registerClass:[UserSearchCell class] forCellReuseIdentifier:@"UserSearchCell"]; - [tableView registerClass:[TaskSearchCell class] forCellReuseIdentifier:@"TaskSearchCell"]; - [tableView registerClass:[TopicSearchCell class] forCellReuseIdentifier:@"TopicSearchCell"]; - [tableView registerClass:[PRMRSearchCell class] forCellReuseIdentifier:@"PRMRSearchCell"]; - - tableView.dataSource = self; - tableView.delegate = self; - { - __weak typeof(self) weakSelf = self; - [tableView addInfiniteScrollingWithActionHandler:^{ - [weakSelf loadMore]; - }]; - } - - [self.parentVC.view addSubview:tableView]; - - self.headerLabel = ({ - UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 2, kScreen_Width, 44)]; - label.backgroundColor = [UIColor clearColor]; - label.textColor = kColor999; - label.textAlignment = NSTextAlignmentCenter; - label.font = [UIFont systemFontOfSize:12]; - label; - }); - - UIView *headview = ({ - UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 44)]; - v.backgroundColor = [UIColor whiteColor]; - [v addSubview:self.headerLabel]; - v; - }); - tableView.tableHeaderView = headview; - - tableView; + if (!self.searchResultView) { + self.searchResultView = [[UIView alloc] initWithFrame:_contentView.bounds]; + //添加myCarousel + self.myCarousel = ({ + CGRect iFrame = _contentView.bounds; + iFrame.origin.y = kMySegmentControl_Height; + iFrame.size.height -= kMySegmentControl_Height; + iCarousel *icarousel = [[iCarousel alloc] initWithFrame:iFrame]; + icarousel.dataSource = self; + icarousel.delegate = self; + icarousel.decelerationRate = 1.0; + icarousel.scrollSpeed = 1.0; + icarousel.type = iCarouselTypeLinear; + icarousel.pagingEnabled = YES; + icarousel.clipsToBounds = YES; + icarousel.bounceDistance = 0.2; + [self.searchResultView addSubview:icarousel]; + icarousel; }); + + //添加滑块 + __weak typeof(_myCarousel) weakCarousel = _myCarousel; + + self.mySegmentControl = [[XTSegmentControl alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, kMySegmentControl_Height) Items:self.titlesArray selectedBlock:^(NSInteger index) { + [weakCarousel scrollToItemAtIndex:index animated:NO]; + }]; + self.mySegmentControl.backgroundColor = kColorNavBG; + + [self.searchResultView addSubview:self.mySegmentControl]; + [self.parentVC.view addSubview:self.searchResultView]; } - [_searchTableView.superview bringSubviewToFront:_searchTableView]; - - [_searchTableView reloadData]; + [_searchResultView.superview bringSubviewToFront:_searchResultView]; [self refresh]; } @@ -202,76 +195,121 @@ - (void)initSearchHistoryView { self.searchBar.delegate=self; [self registerForKeyboardNotifications]; } - [[_searchHistoryView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)]; - - { - UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 0.5)]; - view.backgroundColor = kColorDDD; - [_searchHistoryView addSubview:view]; - } NSArray *array = [CSSearchModel getSearchHistory]; - CGFloat imageLeft = 12.0f; - CGFloat textLeft = 34.0f; - CGFloat height = 44.0f; - - _historyHeight=height*(array.count+1); - //set history list - [_searchHistoryView mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.mas_equalTo(@0); - make.left.mas_equalTo(@0); - make.width.mas_equalTo(kScreen_Width); - make.height.mas_equalTo(_historyHeight); - }]; - _searchHistoryView.contentSize = CGSizeMake(kScreen_Width, _historyHeight); - - - for (int i = 0; i < array.count; i++) { - - UILabel *lblHistory = [[UILabel alloc] initWithFrame:CGRectMake(textLeft, i * height, kScreen_Width - textLeft, height)]; - lblHistory.userInteractionEnabled = YES; - lblHistory.font = [UIFont systemFontOfSize:14]; - lblHistory.textColor = kColor222; - lblHistory.text = array[i]; - - UIImageView *leftView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 15, 15)]; - leftView.left = 12; - leftView.centerY = lblHistory.centerY; - leftView.image = [UIImage imageNamed:@"icon_search_clock"]; - - UIImageView *rightImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 14, 14)]; - rightImageView.right = kScreen_Width - 12; - rightImageView.centerY = lblHistory.centerY; - rightImageView.image = [UIImage imageNamed:@"icon_arrow_searchHistory"]; - - UIView *view = [[UIView alloc] initWithFrame:CGRectMake(imageLeft, (i + 1) * height, kScreen_Width - imageLeft, 0.5)]; - view.backgroundColor = kColorDDD; - - UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didClickedHistory:)]; - [lblHistory addGestureRecognizer:tapGestureRecognizer]; - - [_searchHistoryView addSubview:lblHistory]; - [_searchHistoryView addSubview:leftView]; - [_searchHistoryView addSubview:rightImageView]; - [_searchHistoryView addSubview:view]; - } - - if(array.count) { - - UIButton *btnClean = [UIButton buttonWithType:UIButtonTypeCustom]; - btnClean.titleLabel.font = [UIFont systemFontOfSize:14]; - [btnClean setTitle:@"清除搜索历史" forState:UIControlStateNormal]; - [btnClean setTitleColor:[UIColor colorWithHexString:@"0x1bbf75"] forState:UIControlStateNormal]; - [btnClean setFrame:CGRectMake(0, array.count * height, kScreen_Width, height)]; - [_searchHistoryView addSubview:btnClean]; - [btnClean addTarget:self action:@selector(didCLickedCleanSearchHistory:) forControlEvents:UIControlEventTouchUpInside]; + if (array.count > 0) { + CGFloat imageLeft = 12.0f; + CGFloat textLeft = 34.0f; + CGFloat height = 44.0f; + _historyHeight=height*(array.count+1); + //set history list + [_searchHistoryView mas_remakeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(@0); + make.left.mas_equalTo(@0); + make.width.mas_equalTo(kScreen_Width); + make.height.mas_equalTo(_historyHeight); + }]; + _searchHistoryView.contentSize = CGSizeMake(kScreen_Width, _historyHeight); + for (int i = 0; i < array.count; i++) { + UILabel *lblHistory = [[UILabel alloc] initWithFrame:CGRectMake(textLeft, i * height, kScreen_Width - textLeft, height)]; + lblHistory.userInteractionEnabled = YES; + lblHistory.font = [UIFont systemFontOfSize:14]; + lblHistory.textColor = kColor222; + lblHistory.text = array[i]; + + UIImageView *leftView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 15, 15)]; + leftView.left = 12; + leftView.centerY = lblHistory.centerY; + leftView.image = [UIImage imageNamed:@"icon_search_clock"]; + + UIImageView *rightImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 14, 14)]; + rightImageView.right = kScreen_Width - 12; + rightImageView.centerY = lblHistory.centerY; + rightImageView.image = [UIImage imageNamed:@"icon_arrow_searchHistory"]; + + UIView *view = [[UIView alloc] initWithFrame:CGRectMake(imageLeft, (i + 1) * height, kScreen_Width - imageLeft, 0.5)]; + view.backgroundColor = kColorDDD; + + UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didClickedHistory:)]; + [lblHistory addGestureRecognizer:tapGestureRecognizer]; + + [_searchHistoryView addSubview:lblHistory]; + [_searchHistoryView addSubview:leftView]; + [_searchHistoryView addSubview:rightImageView]; + [_searchHistoryView addSubview:view]; + } { + UIButton *btnClean = [UIButton buttonWithType:UIButtonTypeCustom]; + btnClean.titleLabel.font = [UIFont systemFontOfSize:14]; + [btnClean setTitle:@"清除搜索历史" forState:UIControlStateNormal]; + [btnClean setTitleColor:[UIColor colorWithHexString:@"0x1bbf75"] forState:UIControlStateNormal]; + [btnClean setFrame:CGRectMake(0, array.count * height, kScreen_Width, height)]; + [_searchHistoryView addSubview:btnClean]; + [btnClean addTarget:self action:@selector(didCLickedCleanSearchHistory:) forControlEvents:UIControlEventTouchUpInside]; UIView *view = [[UIView alloc] initWithFrame:CGRectMake(imageLeft, (array.count + 1) * height, kScreen_Width - imageLeft, 0.5)]; view.backgroundColor = kColorDDD; [_searchHistoryView addSubview:view]; } + + + }else{ + _historyHeight = kScreen_Height - 236 - 64; + //set history list + [_searchHistoryView mas_remakeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(@0); + make.left.mas_equalTo(@0); + make.width.mas_equalTo(kScreen_Width); + make.height.mas_equalTo(_historyHeight); + }]; + _searchHistoryView.contentSize = CGSizeMake(kScreen_Width, _historyHeight); + NSInteger itemNum = 3; + CGFloat designScale = (kScreen_Width/ 375); + CGFloat tipVWidth = 210 * designScale; + CGFloat imageWidth = 24 * designScale; + CGFloat paddingWidth = MAX(0, (tipVWidth - itemNum* imageWidth)/ (itemNum - 1)); + CGFloat fontSize = 13 * designScale; + + UIView *tipV = [UIView new]; + UILabel *titleL = [UILabel labelWithSystemFontSize:15 * designScale textColorHexString:@"0x999999"]; + titleL.text = @"搜索更多内容"; + UIView *lineV = [UIView new]; + lineV.backgroundColor = kColorDDD; + [tipV addSubview:titleL]; + [tipV addSubview:lineV]; + [titleL mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(tipV); + make.top.equalTo(tipV).offset(50); + }]; + [lineV mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.equalTo(tipV); + make.top.equalTo(titleL.mas_bottom).offset(15); + make.height.mas_equalTo(1); + }]; +// NSArray *imageArray = @[@"project", @"task", @"topic", @"tweet", @"file", @"user", @"mr", @"pr"]; + NSArray *imageArray = @[@"project", @"task", @"tweet", @"file", @"user", @"mr"]; + for (int index = 0; index < self.titlesArray.count && index < imageArray.count; index++) { + UIImageView *imageV = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:@"search_icon_%@", imageArray[index]]]]; + UILabel *label = [UILabel labelWithSystemFontSize:fontSize textColorHexString:@"0x999999"]; + label.text = self.titlesArray[index]; + [tipV addSubview:imageV]; + [tipV addSubview:label]; + [imageV mas_makeConstraints:^(MASConstraintMaker *make) { + make.size.mas_equalTo(CGSizeMake(imageWidth, imageWidth)); + make.top.equalTo(lineV.mas_bottom).offset(20 + (imageWidth + 45) * (index / itemNum)); + make.left.equalTo(tipV).offset((paddingWidth + imageWidth) * (index % itemNum)); + }]; + [label mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(imageV.mas_bottom).offset(10); + make.centerX.equalTo(imageV); + }]; + } + [_searchHistoryView addSubview:tipV]; + [tipV mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(_searchHistoryView); + make.left.equalTo(_searchHistoryView).offset((kScreen_Width - tipVWidth)/ 2); + make.size.mas_equalTo(CGSizeMake(tipVWidth, _historyHeight)); + }]; } - } #pragma mark - event @@ -306,6 +344,27 @@ - (void)didClickedHistory:(UIGestureRecognizer *)sender { #pragma mark -- goVC +- (void)cellClickedObj:(id)obj type:(eSearchType)type{ + if(type==eSearchType_Tweet) { + [self goToTweet:obj]; + }else if(type==eSearchType_Project){ + [self goToProject:obj]; + }else if (type==eSearchType_Document){ + [self goToFileVC:obj]; + }else if (type==eSearchType_User){ + [self goToUserInfo:obj]; + }else if (type==eSearchType_Task){ + [self goToTask:obj]; +// }else if (type==eSearchType_Topic){ +// [self goToTopic:obj]; + }else if (type==eSearchType_Merge){ + [self goToMRDetail:obj]; + } +// else if(type==eSearchType_Pull){ +// [self goToMRDetail:obj]; +// } +} + - (void)goToProject:(Project *)project{ UIViewController *vc = [BaseViewController analyseVCFromLinkStr:project.project_path]; [self.parentVC.navigationController pushViewController:vc animated:TRUE]; @@ -344,252 +403,29 @@ - (void)goToMRDetail:(MRPR *)curMR{ [self.parentVC.navigationController pushViewController:vc animated:YES]; } +- (void)goToConversation:(User *)curUser{ + ConversationViewController *vc = [[ConversationViewController alloc] init]; + User *copyUser=[curUser copy]; + copyUser.name=[NSString getStr:copyUser.name removeEmphasize:@"em"]; + copyUser.global_key=[NSString getStr:copyUser.global_key removeEmphasize:@"em"]; + copyUser.pinyinName=[NSString getStr:copyUser.pinyinName removeEmphasize:@"em"]; + vc.myPriMsgs = [PrivateMessages priMsgsWithUser:copyUser]; + [self.parentVC.navigationController pushViewController:vc animated:YES]; +} + #pragma mark - #pragma mark Search Data Request - (void)refresh { - if(_isLoading){ - [_searchTableView.infiniteScrollingView stopAnimating]; - return; - } [self requestAll]; } -- (void)loadMore { - if(_isLoading){ - [_searchTableView.infiniteScrollingView stopAnimating]; - return; - } - - //判断分类 - int currentPage; - int totalPage; - - switch (_curSearchType) { - case eSearchType_Project: - currentPage=[_searchPros.projects.page intValue]; - totalPage=[_searchPros.projects.totalPage intValue]; - break; - case eSearchType_Tweet: - currentPage=[_searchPros.tweets.page intValue]; - totalPage=[_searchPros.tweets.totalPage intValue]; - break; - case eSearchType_Document: - currentPage=[_searchPros.files.page intValue]; - totalPage=[_searchPros.files.totalPage intValue]; - break; - case eSearchType_User: - currentPage=[_searchPros.friends.page intValue]; - totalPage=[_searchPros.friends.totalPage intValue]; - break; - case eSearchType_Task: - currentPage=[_searchPros.tasks.page intValue]; - totalPage=[_searchPros.tasks.totalPage intValue]; - break; - case eSearchType_Topic: - currentPage=[_searchPros.project_topics.page intValue]; - totalPage=[_searchPros.project_topics.totalPage intValue]; - break; - case eSearchType_Merge: - currentPage=[_searchPros.merge_requests.page intValue]; - totalPage=[_searchPros.merge_requests.totalPage intValue]; - break; - case eSearchType_Pull: - currentPage=[_searchPros.pull_requests.page intValue]; - totalPage=[_searchPros.pull_requests.totalPage intValue]; - break; - default: - break; - } - - if(currentPage >= totalPage) - { - [_searchTableView.infiniteScrollingView stopAnimating]; - return; - } - - [self requestDataWithPage:currentPage + 1]; -} - -(void)reloadDisplayData{ - [self.dateSource removeAllObjects]; - switch (_curSearchType) { - case eSearchType_Project: - [self.dateSource addObjectsFromArray:_searchPros.projects.list]; - break; - case eSearchType_Tweet: - [self.dateSource addObjectsFromArray:_searchPros.tweets.list]; - break; - case eSearchType_Document: - [self.dateSource addObjectsFromArray:_searchPros.files.list]; - break; - case eSearchType_User: - [self.dateSource addObjectsFromArray:_searchPros.friends.list]; - break; - case eSearchType_Task: - [self.dateSource addObjectsFromArray:_searchPros.tasks.list]; - break; - case eSearchType_Topic: - [self.dateSource addObjectsFromArray:_searchPros.project_topics.list]; - break; - case eSearchType_Merge: - [self.dateSource addObjectsFromArray:_searchPros.merge_requests.list]; - break; - case eSearchType_Pull: - [self.dateSource addObjectsFromArray:_searchPros.pull_requests.list]; - break; - default: - break; + for (CodingSearchDisplayView *view in _myCarousel.visibleItemViews) { + view.searchBarText = self.searchBar.text; + view.searchPros = _searchPros; } - - __weak typeof(self) weakSelf = self; - - [_searchTableView configBlankPage:EaseBlankPageTypeProject_SEARCH hasData:[self noEmptyList] hasError:NO reloadButtonBlock:^(id sender) { - [weakSelf requestAll]; - }]; - - //空白页按钮事件 - _searchTableView.blankPageView.clickButtonBlock=^(EaseBlankPageType curType) { - [weakSelf requestAll]; - }; - - [self refreshHeaderTitle]; - _searchTableView.showsInfiniteScrolling = [self showTotalPage]; - [self.searchTableView reloadData]; -} - -//是否显示加载更多 --(BOOL)showTotalPage{ - switch (_curSearchType) { - case eSearchType_Project: - return _searchPros.projects.page<_searchPros.projects.totalPage; - break; - case eSearchType_Tweet: - return _searchPros.tweets.page<_searchPros.tweets.totalPage; - break; - case eSearchType_Document: - return _searchPros.files.page<_searchPros.files.totalPage; - break; - case eSearchType_User: - return _searchPros.friends.page<_searchPros.friends.totalPage; - break; - case eSearchType_Task: - return _searchPros.tasks.page<_searchPros.tasks.totalPage; - break; - case eSearchType_Topic: - return _searchPros.project_topics.page<_searchPros.project_topics.totalPage; - break; - case eSearchType_Merge: - return _searchPros.merge_requests.page<_searchPros.merge_requests.totalPage; - break; - case eSearchType_Pull: - return _searchPros.pull_requests.page<_searchPros.pull_requests.totalPage; - break; - default: - return NO; - break; - } -} - -//判断是否空 --(BOOL)noEmptyList{ - switch (_curSearchType) { - case eSearchType_Project: - return [_searchPros.projects.list count]; - break; - case eSearchType_Tweet: - return [_searchPros.tweets.list count]; - break; - case eSearchType_Document: - return [_searchPros.files.list count]; - break; - case eSearchType_User: - return [_searchPros.friends.list count]; - break; - case eSearchType_Task: - return [_searchPros.tasks.list count]; - break; - case eSearchType_Topic: - return [_searchPros.project_topics.list count]; - break; - case eSearchType_Merge: - return [_searchPros.merge_requests.list count]; - break; - case eSearchType_Pull: - return [_searchPros.pull_requests.list count]; - break; - default: - return TRUE; - break; - } -} - - -//更新header数量和类型统计 -- (void)refreshHeaderTitle{ - NSString *titleStr; - switch (_curSearchType) { - case eSearchType_Project: - if ([_searchPros.projects.totalRow longValue]==0) { - titleStr=nil; - }else{ - titleStr=[NSString stringWithFormat:@"共搜索到 %ld 个与\"%@\"相关的项目", [_searchPros.projects.totalRow longValue],self.searchBar.text]; - } - break; - case eSearchType_Tweet: - if ([_searchPros.tweets.totalRow longValue]==0) { - titleStr=nil; - }else{ - titleStr=[NSString stringWithFormat:@"共搜索到 %ld 个与\"%@\"相关的冒泡", [_searchPros.tweets.totalRow longValue],self.searchBar.text]; - } - break; - case eSearchType_Document: - if ([_searchPros.files.totalRow longValue]==0) { - titleStr=nil; - }else{ - titleStr=[NSString stringWithFormat:@"共搜索到 %ld 个与\"%@\"相关的文档", [_searchPros.files.totalRow longValue],self.searchBar.text]; - } - break; - case eSearchType_User: - if ([_searchPros.friends.totalRow longValue]==0) { - titleStr=nil; - }else{ - titleStr=[NSString stringWithFormat:@"共搜索到 %ld 个与\"%@\"相关的用户", [_searchPros.friends.totalRow longValue],self.searchBar.text]; - } - break; - case eSearchType_Task: - if ([_searchPros.tasks.totalRow longValue]==0) { - titleStr=nil; - }else{ - titleStr=[NSString stringWithFormat:@"共搜索到 %ld 个与\"%@\"相关的任务", [_searchPros.tasks.totalRow longValue],self.searchBar.text]; - } - break; - case eSearchType_Topic: - if ([_searchPros.project_topics.totalRow longValue]==0) { - titleStr=nil; - }else{ - titleStr=[NSString stringWithFormat:@"共搜索到 %ld 个与\"%@\"相关的讨论", [_searchPros.project_topics.totalRow longValue],self.searchBar.text]; - } - break; - case eSearchType_Merge: - if ([_searchPros.merge_requests.totalRow longValue]==0) { - titleStr=nil; - }else{ - titleStr=[NSString stringWithFormat:@"共搜索到 %ld 个与\"%@\"相关的合并请求", [_searchPros.merge_requests.totalRow longValue],self.searchBar.text]; - } - break; - case eSearchType_Pull: - if ([_searchPros.pull_requests.totalRow longValue]==0) { - titleStr=nil; - }else{ - titleStr=[NSString stringWithFormat:@"共搜索到 %ld 个与\"%@\"相关的 pull 请求", [_searchPros.pull_requests.totalRow longValue],self.searchBar.text]; - } - break; - default: - break; - } - self.headerLabel.text=titleStr; } -(void)requestAll{ @@ -598,7 +434,6 @@ -(void)requestAll{ __weak typeof(self) weakSelf = self; [[Coding_NetAPIManager sharedManager] requestWithSearchString:self.searchBar.text typeStr:@"all" andPage:1 andBlock:^(id data, NSError *error) { if(data) { - [weakSelf.dateSource removeAllObjects]; weakSelf.searchPros = [NSObject objectOfClass:@"PublicSearchModel" fromJSON:data]; NSDictionary *dataDic = (NSDictionary *)data; @@ -619,210 +454,11 @@ -(void)requestAll{ curTask.descript= [[[resultTask objectAtIndex:i] objectForKey:@"description"] firstObject]; } } - - switch (weakSelf.curSearchType) { - case eSearchType_Project: - [weakSelf.dateSource addObjectsFromArray:weakSelf.searchPros.projects.list]; - break; - case eSearchType_Tweet: - [weakSelf.dateSource addObjectsFromArray:weakSelf.searchPros.tweets.list]; - break; - case eSearchType_Document: - [weakSelf.dateSource addObjectsFromArray:weakSelf.searchPros.files.list]; - break; - case eSearchType_User: - [weakSelf.dateSource addObjectsFromArray:weakSelf.searchPros.friends.list]; - break; - case eSearchType_Task: - [weakSelf.dateSource addObjectsFromArray:weakSelf.searchPros.tasks.list]; - break; - case eSearchType_Topic: - [weakSelf.dateSource addObjectsFromArray:weakSelf.searchPros.project_topics.list]; - break; - case eSearchType_Merge: - [weakSelf.dateSource addObjectsFromArray:weakSelf.searchPros.merge_requests.list]; - break; - case eSearchType_Pull: - [weakSelf.dateSource addObjectsFromArray:weakSelf.searchPros.pull_requests.list]; - break; - default: - break; - } - - [weakSelf.searchTableView configBlankPage:EaseBlankPageTypeProject_SEARCH hasData:[weakSelf noEmptyList] hasError:(error != nil) reloadButtonBlock:^(id sender) { - }]; - - [weakSelf.searchTableView reloadData]; - [weakSelf.searchTableView.infiniteScrollingView stopAnimating]; - weakSelf.searchTableView.showsInfiniteScrolling = [weakSelf showTotalPage]; + [weakSelf reloadDisplayData]; } - weakSelf.isLoading = NO; - [self refreshHeaderTitle]; }]; } -- (void)requestDataWithPage:(NSInteger)page { - - _isLoading = YES; - - __weak typeof(self) weakSelf = self; - if (_curSearchType==eSearchType_Tweet) { - [[Coding_NetAPIManager sharedManager] requestWithSearchString:self.searchBar.text typeStr:@"tweet" andPage:page andBlock:^(id data, NSError *error) { - if(data) { - NSDictionary *dataDic = (NSDictionary *)data; - NSArray *resultA = [NSObject arrayFromJSON:dataDic[@"list"] ofObjects:@"Tweet"]; - [weakSelf.searchPros.tweets.list addObjectsFromArray:resultA]; - //更新page - weakSelf.searchPros.tweets.page = dataDic[@"page"] ; - weakSelf.searchPros.tweets.totalPage = dataDic[@"totalPage"] ; - [weakSelf.dateSource addObjectsFromArray:resultA]; - [weakSelf.searchTableView reloadData]; - [weakSelf.searchTableView.infiniteScrollingView stopAnimating]; - weakSelf.searchTableView.showsInfiniteScrolling = [weakSelf showTotalPage]; - } - weakSelf.isLoading = NO; - }]; - }else if(_curSearchType==eSearchType_Project){ - [[Coding_NetAPIManager sharedManager] requestWithSearchString:self.searchBar.text typeStr:@"project" andPage:page andBlock:^(id data, NSError *error) { - if(data) { - NSDictionary *dataDic = (NSDictionary *)data; - NSArray *resultA = [NSObject arrayFromJSON:dataDic[@"list"] ofObjects:@"Project"]; - [weakSelf.searchPros.projects.list addObjectsFromArray:resultA]; - //更新page - weakSelf.searchPros.projects.page = dataDic[@"page"] ; - weakSelf.searchPros.projects.totalPage = dataDic[@"totalPage"] ; - [weakSelf.dateSource addObjectsFromArray:resultA]; - [weakSelf.searchTableView reloadData]; - [weakSelf.searchTableView.infiniteScrollingView stopAnimating]; - weakSelf.searchTableView.showsInfiniteScrolling = [weakSelf showTotalPage]; - } - weakSelf.isLoading = NO; - }]; - }else if(_curSearchType==eSearchType_Document){ - [[Coding_NetAPIManager sharedManager] requestWithSearchString:self.searchBar.text typeStr:@"file" andPage:page andBlock:^(id data, NSError *error) { - if(data) { - NSDictionary *dataDic = (NSDictionary *)data; - NSArray *resultA = [NSObject arrayFromJSON:dataDic[@"list"] ofObjects:@"ProjectFile"]; - [weakSelf.searchPros.files.list addObjectsFromArray:resultA]; - //更新page - weakSelf.searchPros.files.page = dataDic[@"page"] ; - weakSelf.searchPros.files.totalPage = dataDic[@"totalPage"] ; - [weakSelf.dateSource addObjectsFromArray:resultA]; - [weakSelf.searchTableView reloadData]; - [weakSelf.searchTableView.infiniteScrollingView stopAnimating]; - weakSelf.searchTableView.showsInfiniteScrolling = [weakSelf showTotalPage]; - } - weakSelf.isLoading = NO; - }]; - }else if(_curSearchType==eSearchType_Merge){ - [[Coding_NetAPIManager sharedManager] requestWithSearchString:self.searchBar.text typeStr:@"mr" andPage:page andBlock:^(id data, NSError *error) { - if(data) { - NSDictionary *dataDic = (NSDictionary *)data; - NSArray *resultA = [NSObject arrayFromJSON:dataDic[@"list"] ofObjects:@"MRPR"]; - [weakSelf.searchPros.merge_requests.list addObjectsFromArray:resultA]; - //更新page - weakSelf.searchPros.merge_requests.page = dataDic[@"page"] ; - weakSelf.searchPros.merge_requests.totalPage = dataDic[@"totalPage"] ; - [weakSelf.dateSource addObjectsFromArray:resultA]; - [weakSelf.searchTableView reloadData]; - [weakSelf.searchTableView.infiniteScrollingView stopAnimating]; - weakSelf.searchTableView.showsInfiniteScrolling = [weakSelf showTotalPage]; - } - weakSelf.isLoading = NO; - }]; - }else if(_curSearchType==eSearchType_Pull){ - [[Coding_NetAPIManager sharedManager] requestWithSearchString:self.searchBar.text typeStr:@"pr" andPage:page andBlock:^(id data, NSError *error) { - if(data) { - NSDictionary *dataDic = (NSDictionary *)data; - NSArray *resultA = [NSObject arrayFromJSON:dataDic[@"list"] ofObjects:@"MRPR"]; - [weakSelf.searchPros.pull_requests.list addObjectsFromArray:resultA]; - //更新page - weakSelf.searchPros.pull_requests.page = dataDic[@"page"] ; - weakSelf.searchPros.pull_requests.totalPage = dataDic[@"totalPage"] ; - [weakSelf.dateSource addObjectsFromArray:resultA]; - [weakSelf.searchTableView reloadData]; - [weakSelf.searchTableView.infiniteScrollingView stopAnimating]; - weakSelf.searchTableView.showsInfiniteScrolling = [weakSelf showTotalPage]; - } - weakSelf.isLoading = NO; - }]; - }else if(_curSearchType==eSearchType_Task){ - [[Coding_NetAPIManager sharedManager] requestWithSearchString:self.searchBar.text typeStr:@"task" andPage:page andBlock:^(id data, NSError *error) { - if(data) { - NSDictionary *dataDic = (NSDictionary *)data; - NSArray *resultA = [NSObject arrayFromJSON:dataDic[@"list"] ofObjects:@"Task"]; - - //task 处理 description 关键字 - NSArray *resultTask =dataDic[@"list"]; - for (int i=0;i<[resultA count];i++) { - Task *curTask=[resultA objectAtIndex:i]; - if ([resultTask count]>i) { - curTask.descript= [[[resultTask objectAtIndex:i] objectForKey:@"description"] firstObject]; - } - } - - [weakSelf.searchPros.tasks.list addObjectsFromArray:resultA]; - //更新page - weakSelf.searchPros.tasks.page = dataDic[@"page"] ; - weakSelf.searchPros.tasks.totalPage = dataDic[@"totalPage"] ; - - - [weakSelf.dateSource addObjectsFromArray:resultA]; - [weakSelf.searchTableView reloadData]; - [weakSelf.searchTableView.infiniteScrollingView stopAnimating]; - weakSelf.searchTableView.showsInfiniteScrolling = [weakSelf showTotalPage]; - } - weakSelf.isLoading = NO; - }]; - }else if(_curSearchType==eSearchType_User){ - [[Coding_NetAPIManager sharedManager] requestWithSearchString:self.searchBar.text typeStr:@"user" andPage:page andBlock:^(id data, NSError *error) { - if(data) { - NSDictionary *dataDic = (NSDictionary *)data; - NSArray *resultA = [NSObject arrayFromJSON:dataDic[@"list"] ofObjects:@"User"]; - [weakSelf.searchPros.friends.list addObjectsFromArray:resultA]; - //更新page - weakSelf.searchPros.friends.page = dataDic[@"page"] ; - weakSelf.searchPros.friends.totalPage = dataDic[@"totalPage"] ; - [weakSelf.dateSource addObjectsFromArray:resultA]; - [weakSelf.searchTableView reloadData]; - [weakSelf.searchTableView.infiniteScrollingView stopAnimating]; - weakSelf.searchTableView.showsInfiniteScrolling = [weakSelf showTotalPage]; - } - weakSelf.isLoading = NO; - }]; - }else if(_curSearchType==eSearchType_Topic){ - [[Coding_NetAPIManager sharedManager] requestWithSearchString:self.searchBar.text typeStr:@"topic" andPage:page andBlock:^(id data, NSError *error) { - if(data) { - NSDictionary *dataDic = (NSDictionary *)data; - NSArray *resultA = [NSObject arrayFromJSON:dataDic[@"list"] ofObjects:@"ProjectTopic"]; - - //topic 处理 content 关键字 - NSArray *resultTopic =dataDic[@"list"]; - for (int i=0;i<[resultA count];i++) { - ProjectTopic *curTopic=[resultA objectAtIndex:i]; - if ([resultTopic count]>i) { - curTopic.contentStr= [[[resultTopic objectAtIndex:i] objectForKey:@"content"] firstObject]; - } - } - - [weakSelf.searchPros.project_topics.list addObjectsFromArray:resultA]; - //更新page - weakSelf.searchPros.project_topics.page = dataDic[@"page"] ; - weakSelf.searchPros.project_topics.totalPage = dataDic[@"totalPage"] ; - [weakSelf.dateSource addObjectsFromArray:resultA]; - [weakSelf.searchTableView reloadData]; - [weakSelf.searchTableView.infiniteScrollingView stopAnimating]; - weakSelf.searchTableView.showsInfiniteScrolling = [weakSelf showTotalPage]; - } - weakSelf.isLoading = NO; - }]; - }else{ - [self.searchTableView.infiniteScrollingView stopAnimating]; - self.searchTableView.showsInfiniteScrolling = NO; - self.isLoading=NO; - } -} - - (void)analyseLinkStr:(NSString *)linkStr{ if (linkStr.length <= 0) { return; @@ -880,138 +516,57 @@ - (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar { [self initSearchResultsTableView]; } -#pragma mark - UITableViewDelegate & UITableViewDataSource Support - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - - return [_dateSource count]; +- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar{ + return TRUE; } -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - if (_curSearchType==eSearchType_Tweet) { - TweetSearchCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TweetSearchCell" forIndexPath:indexPath]; - cell.selectionStyle = UITableViewCellSelectionStyleNone; - Tweet *tweet = _dateSource[indexPath.row]; - cell.tweet = tweet; - [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; - return cell; - }else if(_curSearchType==eSearchType_Project){ - ProjectAboutMeListCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ProjectAboutMeListCell" forIndexPath:indexPath]; - cell.openKeywords=TRUE; - Project *project=_dateSource[indexPath.row]; - [cell setProject:project hasSWButtons:NO hasBadgeTip:YES hasIndicator:NO]; - [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; - return cell; - }else if(_curSearchType==eSearchType_Document){ - FileSearchCell *cell = [tableView dequeueReusableCellWithIdentifier:@"FileSearchCell" forIndexPath:indexPath]; - ProjectFile *file =_dateSource[indexPath.row]; - cell.file = file; - [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; - return cell; - }else if(_curSearchType==eSearchType_User){ - UserSearchCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UserSearchCell" forIndexPath:indexPath]; - User *curUser = _dateSource[indexPath.row]; - cell.curUser = curUser; - __weak typeof(self) weakSelf = self; - cell.rightBtnClickedBlock=^(User *curUser) { - ConversationViewController *vc = [[ConversationViewController alloc] init]; - User *copyUser=[curUser copy]; - copyUser.name=[NSString getStr:copyUser.name removeEmphasize:@"em"]; - copyUser.global_key=[NSString getStr:copyUser.global_key removeEmphasize:@"em"]; - copyUser.pinyinName=[NSString getStr:copyUser.pinyinName removeEmphasize:@"em"]; - vc.myPriMsgs = [PrivateMessages priMsgsWithUser:copyUser]; - [weakSelf.parentVC.navigationController pushViewController:vc animated:YES]; - }; - [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; - return cell; - }else if(_curSearchType==eSearchType_Task){ - TaskSearchCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TaskSearchCell" forIndexPath:indexPath]; - Task *task =_dateSource[indexPath.row]; - cell.task=task; - [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; - return cell; - }else if(_curSearchType==eSearchType_Topic){ - TopicSearchCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TopicSearchCell" forIndexPath:indexPath]; - ProjectTopic *topic =_dateSource[indexPath.row]; - cell.curTopic = topic; - [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; - return cell; - }else if(_curSearchType==eSearchType_Merge){ - PRMRSearchCell *cell = [tableView dequeueReusableCellWithIdentifier:@"PRMRSearchCell" forIndexPath:indexPath]; - MRPR *curMRPR =_dateSource[indexPath.row]; - cell.curMRPR = curMRPR; - [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; - return cell; - }else if(_curSearchType==eSearchType_Pull){ - PRMRSearchCell *cell = [tableView dequeueReusableCellWithIdentifier:@"PRMRSearchCell" forIndexPath:indexPath]; - MRPR *curMRPR =_dateSource[indexPath.row]; - cell.curMRPR = curMRPR; - [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; - return cell; - }else{ - return nil; - } +#pragma mark iCarousel M +- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel{ + return [self.titlesArray count]; } - -- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { - if (_curSearchType==eSearchType_Tweet) { - Tweet *tweet = _dateSource[indexPath.row]; - return[TweetSearchCell cellHeightWithObj:tweet]; - }else if(_curSearchType==eSearchType_Project){ - return kProjectAboutMeListCellHeight; - }else if(_curSearchType==eSearchType_Document){ - return kFileSearchCellHeight; - }else if(_curSearchType==eSearchType_User){ - return kUserSearchCellHeight; - }else if(_curSearchType==eSearchType_Task){ - Task *task = _dateSource[indexPath.row]; - return [TaskSearchCell cellHeightWithObj:task]; - }else if(_curSearchType==eSearchType_Topic){ - ProjectTopic *topic = _dateSource[indexPath.row]; - return [TopicSearchCell cellHeightWithObj:topic]; - }else if (_curSearchType==eSearchType_Pull){ - MRPR *mrpr = _dateSource[indexPath.row]; - return [PRMRSearchCell cellHeightWithObj:mrpr]; - }else if (_curSearchType==eSearchType_Merge){ - MRPR *mrpr = _dateSource[indexPath.row]; - return [PRMRSearchCell cellHeightWithObj:mrpr]; +- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view{ + CodingSearchDisplayView *listView = (CodingSearchDisplayView *)view; + if (listView) { + listView.curSearchType = index; + listView.searchBarText = self.searchBar.text; + listView.searchPros = _searchPros; }else{ - return 100; + listView = [[CodingSearchDisplayView alloc] initWithFrame:carousel.bounds]; + listView.curSearchType = index; + listView.searchBarText = self.searchBar.text; + listView.searchPros = _searchPros; + __weak typeof(self) weakSelf = self; + [listView setCellClickedBlock:^(id clickedItem, eSearchType searType) { + [weakSelf cellClickedObj:clickedItem type:searType]; + }]; + [listView setGoToConversationBlock:^(User *curUser) { + [weakSelf goToConversation:curUser]; + }]; + [listView setRefreshAllBlock:^{ + [weakSelf refresh]; + }]; } + [listView setSubScrollsToTop:(index == carousel.currentItemIndex)]; + return listView; } -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - [tableView deselectRowAtIndexPath:indexPath animated:NO]; - if(_curSearchType==eSearchType_Tweet) { - [self goToTweet:_dateSource[indexPath.row]]; - }else if(_curSearchType==eSearchType_Project){ - [self goToProject:_dateSource[indexPath.row]]; - }else if (_curSearchType==eSearchType_Document){ - [self goToFileVC:_dateSource[indexPath.row]]; - }else if (_curSearchType==eSearchType_User){ - [self goToUserInfo:_dateSource[indexPath.row]]; - }else if (_curSearchType==eSearchType_Task){ - [self goToTask:_dateSource[indexPath.row]]; - }else if (_curSearchType==eSearchType_Topic){ - [self goToTopic:_dateSource[indexPath.row]]; - }else if (_curSearchType==eSearchType_Merge){ - [self goToMRDetail:_dateSource[indexPath.row]]; - }else if(_curSearchType==eSearchType_Pull){ - [self goToMRDetail:_dateSource[indexPath.row]]; +- (void)carouselDidScroll:(iCarousel *)carousel{ + if (_mySegmentControl) { + float offset = carousel.scrollOffset; + if (offset > 0) { + [_mySegmentControl moveIndexWithProgress:offset]; + } } } - - -- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar{ -// [self setActive:TRUE]; - - return TRUE; +- (void)carouselCurrentItemIndexDidChange:(iCarousel *)carousel{ + if (_mySegmentControl) { + _mySegmentControl.currentIndex = carousel.currentItemIndex; + } + [carousel.visibleItemViews enumerateObjectsUsingBlock:^(UIView *obj, NSUInteger idx, BOOL *stop) { + [obj setSubScrollsToTop:(obj == carousel.currentItemView)]; + }]; } - - - - @end diff --git a/Coding_iOS/Controllers/CodeListViewController.h b/Coding_iOS/Controllers/CodeListViewController.h index f36c3a072..b1b6d19e1 100755 --- a/Coding_iOS/Controllers/CodeListViewController.h +++ b/Coding_iOS/Controllers/CodeListViewController.h @@ -13,4 +13,7 @@ @interface CodeListViewController : BaseViewController @property (strong, nonatomic) Project *myProject; @property (strong, nonatomic) CodeTree *myCodeTree; + +@property (assign, nonatomic) BOOL hideBranchTagButton; + @end diff --git a/Coding_iOS/Controllers/CodeListViewController.m b/Coding_iOS/Controllers/CodeListViewController.m index cbdf4165b..52bc530c1 100755 --- a/Coding_iOS/Controllers/CodeListViewController.m +++ b/Coding_iOS/Controllers/CodeListViewController.m @@ -10,9 +10,10 @@ #import "CodeViewController.h" #import "ProjectViewController.h" #import "ProjectCommitsViewController.h" +#import "ProjectViewController.h" @interface CodeListViewController () - +@property (strong, nonatomic) ProjectCodeListView *listView; @end @implementation CodeListViewController @@ -23,20 +24,19 @@ - (void)viewDidLoad { self.title = [[_myCodeTree.path componentsSeparatedByString:@"/"] lastObject]; [self configRightNavBtn]; - ProjectCodeListView *listView = [[ProjectCodeListView alloc] initWithFrame:self.view.bounds project:_myProject andCodeTree:_myCodeTree]; + _listView = [[ProjectCodeListView alloc] initWithFrame:self.view.bounds project:_myProject andCodeTree:_myCodeTree]; + _listView.hideBranchTagButton = _hideBranchTagButton; __weak typeof(self) weakSelf = self; - listView.codeTreeFileOfRefBlock = ^(CodeTree_File *curCodeTreeFile, NSString *ref){ + _listView.codeTreeFileOfRefBlock = ^(CodeTree_File *curCodeTreeFile, NSString *ref){ [weakSelf goToVCWith:curCodeTreeFile andRef:ref]; }; - listView.refChangedBlock = ^(NSString *ref){ - weakSelf.myCodeTree.ref = ref; + _listView.codeTreeChangedBlock = ^(CodeTree *tree){ + weakSelf.myCodeTree = tree; }; - [self.view addSubview:listView]; - [listView mas_makeConstraints:^(MASConstraintMaker *make) { + [self.view addSubview:_listView]; + [_listView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; - [listView addBranchTagButton]; - } - (void)configRightNavBtn{ @@ -46,45 +46,28 @@ - (void)configRightNavBtn{ } - (void)rightNavBtnClicked{ + NSMutableArray *actionTitles = @[@"上传图片", @"创建文本文件", @"查看提交记录", @"退出代码查看"].mutableCopy; + if (!self.myCodeTree.can_edit) { + [actionTitles removeObjectsInRange:NSMakeRange(0, 2)]; + } __weak typeof(self) weakSelf = self; - [[UIActionSheet bk_actionSheetCustomWithTitle:nil buttonTitles:@[@"查看提交记录", @"退出代码查看"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { - switch (index) { - case 0:{ - [weakSelf goToCommitsVC]; - } - break; - case 1:{ - [weakSelf.navigationController.viewControllers enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(UIViewController *obj, NSUInteger idx, BOOL *stop) { - if (![obj isKindOfClass:[CodeViewController class]] && - ![obj isKindOfClass:[CodeListViewController class]] && - !([obj isKindOfClass:[ProjectViewController class]] && [(ProjectViewController *)obj curType] == ProjectViewTypeCodes)) { - *stop = YES; - [weakSelf.navigationController popToViewController:obj animated:YES]; - } - }]; - } - break; - default: - break; + [[UIAlertController ea_actionSheetCustomWithTitle:nil buttonTitles:actionTitles destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (!weakSelf.myCodeTree.can_edit) { + index += 2; + } + if (index == 0) { + [weakSelf.listView uploadImageClicked]; + }else if (index == 1){ + [weakSelf.listView createFileClicked]; + }else if (index == 2){ + [weakSelf goToCommitsVC]; + }else if (index == 3){ + [weakSelf popOutCodeVC]; } }] showInView:self.view]; } -- (void)didReceiveMemoryWarning { - [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. -} - -/* -#pragma mark - Navigation - -// In a storyboard-based application, you will often want to do a little preparation before navigation -- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { - // Get the new view controller using [segue destinationViewController]. - // Pass the selected object to the new view controller. -} -*/ - +#pragma mark action - (void)goToVCWith:(CodeTree_File *)codeTreeFile andRef:(NSString *)ref{ DebugLog(@"%@", codeTreeFile.path); if ([codeTreeFile.mode isEqualToString:@"tree"]) {//文件夹 @@ -92,11 +75,19 @@ - (void)goToVCWith:(CodeTree_File *)codeTreeFile andRef:(NSString *)ref{ CodeListViewController *vc = [[CodeListViewController alloc] init]; vc.myProject = _myProject; vc.myCodeTree = nextCodeTree; + vc.hideBranchTagButton = self.hideBranchTagButton; [self.navigationController pushViewController:vc animated:YES]; }else if ([@[@"file", @"image", @"sym_link", @"executable"] containsObject:codeTreeFile.mode]){//文件 CodeFile *nextCodeFile = [CodeFile codeFileWithRef:ref andPath:codeTreeFile.path]; CodeViewController *vc = [CodeViewController codeVCWithProject:_myProject andCodeFile:nextCodeFile]; [self.navigationController pushViewController:vc animated:YES]; + }else if ([codeTreeFile.mode isEqualToString:@"git_link"]){ + UIViewController *vc = [BaseViewController analyseVCFromLinkStr:codeTreeFile.info.submoduleLink]; + if (vc) { + [self.navigationController pushViewController:vc animated:YES]; + }else{ + [NSObject showHudTipStr:@"有些文件还不支持查看呢_(:з」∠)_"]; + } }else{ [NSObject showHudTipStr:@"有些文件还不支持查看呢_(:з」∠)_"]; } @@ -109,4 +100,16 @@ - (void)goToCommitsVC{ [self.navigationController pushViewController:vc animated:YES]; } +- (void)popOutCodeVC{ + __weak typeof(self) weakSelf = self; + [self.navigationController.viewControllers enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(UIViewController *obj, NSUInteger idx, BOOL *stop) { + if (![obj isKindOfClass:[CodeViewController class]] && + ![obj isKindOfClass:[CodeListViewController class]] && + !([obj isKindOfClass:[ProjectViewController class]] && [(ProjectViewController *)obj curType] == ProjectViewTypeCodes)) { + *stop = YES; + [weakSelf.navigationController popToViewController:obj animated:YES]; + } + }]; +} + @end diff --git a/Coding_iOS/Controllers/CodeViewController.m b/Coding_iOS/Controllers/CodeViewController.m index 89346fe59..70bdc92a2 100755 --- a/Coding_iOS/Controllers/CodeViewController.m +++ b/Coding_iOS/Controllers/CodeViewController.m @@ -91,36 +91,56 @@ - (void)doSomethingWithResponse:(id)data andError:(NSError *)error{ self.myCodeFile = data; [self refreshCodeViewData]; }else{ - self.myCodeFile = [CodeFile codeFileWithMDStr:data]; + self.myCodeFile = [CodeFile codeFileWithMDPreview:data]; [self refreshCodeViewData]; } - [self.view configBlankPage:EaseBlankPageTypeView hasData:(data != nil) hasError:(error != nil) reloadButtonBlock:^(id sender) { + BOOL hasError = (error != nil && error.code != 1204);//depot_has_no_commit + [self.view configBlankPage:EaseBlankPageTypeCode hasData:(data != nil) hasError:hasError reloadButtonBlock:^(id sender) { [self sendRequest]; }]; + self.webContentView.hidden = hasError; [self configRightNavBtn]; } - (void)refreshCodeViewData{ if ([_myCodeFile.file.mode isEqualToString:@"image"]) { // NSURL *imageUrl = [NSURL URLWithString:[NSString stringWithFormat:@"%@u/%@/p/%@/git/raw/%@", [NSObject baseURLStr], _myProject.owner_user_name, _myProject.name, [NSString handelRef:_myCodeFile.ref path:_myCodeFile.file.path]]]; - NSURL *imageUrl = [NSURL URLWithString:[NSString stringWithFormat:@"%@u/%@/p/%@/git/raw/%@/%@", [NSObject baseURLStr], _myProject.owner_user_name, _myProject.name, _myCodeFile.ref, _myCodeFile.file.path]]; + NSURL *imageUrl; + if (kTarget_Enterprise) {//企业版不需要 owner_user_name + imageUrl = [NSURL URLWithString:[NSString stringWithFormat:@"%@p/%@/git/raw/%@/%@", [NSObject baseURLStr], _myProject.name, _myCodeFile.ref, _myCodeFile.file.path]]; + }else{ + imageUrl = [NSURL URLWithString:[NSString stringWithFormat:@"%@u/%@/p/%@/git/raw/%@/%@", [NSObject baseURLStr], _myProject.owner_user_name, _myProject.name, _myCodeFile.ref, _myCodeFile.file.path]]; + } DebugLog(@"imageUrl: %@", imageUrl); [self.webContentView loadRequest:[NSURLRequest requestWithURL:imageUrl]]; }else if ([@[@"file", @"sym_link", @"executable"] containsObject:_myCodeFile.file.mode]){ NSString *contentStr = [WebContentManager codePatternedWithContent:_myCodeFile isEdit:NO]; - [self.webContentView loadHTMLString:contentStr baseURL:nil]; + [self.webContentView loadHTMLString:contentStr baseURL:[NSURL URLWithString:[self p_baseHref]]]; } } +- (NSString *)p_baseHref{//写在 html 文件里的,没有 baseHref 的话,锚点会异常 + return @"https://coding.net/"; +} + #pragma mark UIWebViewDelegate - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ DebugLog(@"strLink=[%@]",request.URL.absoluteString); if ([_myCodeFile.file.mode isEqualToString:@"image"]) { - NSString *imageStr = [NSString stringWithFormat:@"%@u/%@/p/%@/git/raw/%@/%@", [NSObject baseURLStr], _myProject.owner_user_name, _myProject.name, _myCodeFile.ref, _myCodeFile.file.path]; + NSString *imageStr; + if (kTarget_Enterprise) { + imageStr = [NSString stringWithFormat:@"%@p/%@/git/raw/%@/%@", [NSObject baseURLStr], _myProject.name, _myCodeFile.ref, _myCodeFile.file.path]; + }else{ + imageStr = [NSString stringWithFormat:@"%@u/%@/p/%@/git/raw/%@/%@", [NSObject baseURLStr], _myProject.owner_user_name, _myProject.name, _myCodeFile.ref, _myCodeFile.file.path]; + } if ([imageStr isEqualToString:request.URL.absoluteString]) { return YES; } } + if ([request.URL.absoluteString isEqualToString:[self p_baseHref]] || + [request.URL.absoluteString hasPrefix:[[self p_baseHref] stringByAppendingString:@"#"]]) { + return YES; + } UIViewController *vc = [BaseViewController analyseVCFromLinkStr:request.URL.absoluteString]; if (vc) { [self.navigationController pushViewController:vc animated:YES]; @@ -146,7 +166,11 @@ - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{ - (void)configRightNavBtn{ if (!self.navigationItem.rightBarButtonItem) { if (_isReadMe) { - [self.navigationItem setRightBarButtonItem:[[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"tweetBtn_Nav"] style:UIBarButtonItemStylePlain target:self action:@selector(goToEditVC)] animated:NO]; + if (self.myCodeFile.can_edit) { + [self.navigationItem setRightBarButtonItem:[[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"tweetBtn_Nav"] style:UIBarButtonItemStylePlain target:self action:@selector(goToEditVC)] animated:NO]; + }else{ + [self.navigationItem setRightBarButtonItem:nil animated:NO]; + } }else{ [self.navigationItem setRightBarButtonItem:[[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"moreBtn_Nav"] style:UIBarButtonItemStylePlain target:self action:@selector(rightNavBtnClicked)] animated:NO]; } @@ -155,17 +179,17 @@ - (void)configRightNavBtn{ - (void)rightNavBtnClicked{ NSMutableArray *actionTitles = @[@"编辑代码", @"查看提交记录", @"退出代码查看"].mutableCopy; - if (!self.myCodeFile.can_edit) { + if (!self.myCodeFile.can_edit || [self.myCodeFile.file.mode isEqualToString:@"image"]) { [actionTitles removeObjectAtIndex:0]; } __weak typeof(self) weakSelf = self; - [[UIActionSheet bk_actionSheetCustomWithTitle:nil buttonTitles:actionTitles destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { - [weakSelf actionSheetClicked:sheet index:index]; + [[UIAlertController ea_actionSheetCustomWithTitle:nil buttonTitles:actionTitles destructiveTitle:self.myCodeFile.can_edit? @"删除文件": nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + [weakSelf actionSheetClickedIndex:index]; }] showInView:self.view]; } -- (void)actionSheetClicked:(UIActionSheet *)sheet index:(NSInteger)index{ - if (!self.myCodeFile.can_edit) { +- (void)actionSheetClickedIndex:(NSInteger)index{ + if (!self.myCodeFile.can_edit || [self.myCodeFile.file.mode isEqualToString:@"image"]) { index++; } if (index == 0) { @@ -174,9 +198,33 @@ - (void)actionSheetClicked:(UIActionSheet *)sheet index:(NSInteger)index{ [self goToCommitsVC]; }else if (index == 2){ [self popOut]; + }else if (index == 3 && self.myCodeFile.can_edit){ + [self deleteBtnClicked]; } } +- (void)deleteBtnClicked{ + __weak typeof(self) weakSelf = self; + [[UIAlertController ea_actionSheetCustomWithTitle:[NSString stringWithFormat:@"确定要删除文件 %@ 吗?", _myCodeFile.file.name] buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { + [weakSelf sendDeleteRequst]; + } + }] showInView:self.view]; +} + +- (void)sendDeleteRequst{ + [NSObject showHUDQueryStr:@"正在删除..."]; + [[Coding_NetAPIManager sharedManager] request_DeleteCodeFile:_myCodeFile withPro:_myProject andBlock:^(id data, NSError *error) { + [NSObject hideHUDQuery]; + if (data) { + // if (self.savedSucessBlock) { + // self.savedSucessBlock(); + // } + [self.navigationController popViewControllerAnimated:YES]; + } + }]; +} + - (void)goToEditVC{ __weak typeof(self) weakSelf = self; diff --git a/Coding_iOS/Controllers/CommitFilesViewController.m b/Coding_iOS/Controllers/CommitFilesViewController.m index 1622c72bb..61ede2d4c 100644 --- a/Coding_iOS/Controllers/CommitFilesViewController.m +++ b/Coding_iOS/Controllers/CommitFilesViewController.m @@ -71,6 +71,9 @@ - (void)viewDidLoad{ [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; diff --git a/Coding_iOS/Controllers/ConversationViewController.m b/Coding_iOS/Controllers/ConversationViewController.m index a72d143dc..5824870b0 100755 --- a/Coding_iOS/Controllers/ConversationViewController.m +++ b/Coding_iOS/Controllers/ConversationViewController.m @@ -59,6 +59,9 @@ - (void)viewDidLoad [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); // _refreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; @@ -155,7 +158,7 @@ - (void)messageInputView:(UIMessageInputView *)inputView heightToBottomChenged:( static BOOL keyboard_is_down = YES; static CGPoint keyboard_down_ContentOffset; static CGFloat keyboard_down_InputViewHeight; - if (heightToBottom > CGRectGetHeight(inputView.frame)) { + if (heightToBottom > [inputView heightWithSafeArea]) { if (keyboard_is_down) { keyboard_down_ContentOffset = self.myTableView.contentOffset; keyboard_down_InputViewHeight = CGRectGetHeight(inputView.frame); @@ -264,19 +267,24 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N preMsg = [_myPriMsgs.dataList objectAtIndex:curIndex+1]; } cell.tapUserIconBlock = ^(User *sender){ - UserInfoViewController *vc = [[UserInfoViewController alloc] init]; - vc.curUser = sender; - [self.navigationController pushViewController:vc animated:YES]; + if (kTarget_Enterprise) { + UserInfoDetailViewController *vc = [[UserInfoDetailViewController alloc] init]; + vc.curUser = sender; + [self.navigationController pushViewController:vc animated:YES]; + }else{ + UserInfoViewController *vc = [[UserInfoViewController alloc] init]; + vc.curUser = sender; + [self.navigationController pushViewController:vc animated:YES]; + } }; ESWeakSelf; cell.resendMessageBlock = ^(PrivateMessage *curMessage){ ESStrongSelf; _self.messageToResendOrDelete = curMessage; [_self.myMsgInputView isAndResignFirstResponder]; - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"重新发送" buttonTitles:@[@"发送"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + UIAlertController *actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"重新发送" buttonTitles:@[@"发送"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0 && _self.messageToResendOrDelete) { [_self sendPrivateMessageWithMsg:_messageToResendOrDelete]; - } }]; [actionSheet showInView:self.view]; @@ -325,7 +333,7 @@ - (void)showAlertToDeleteMessage:(PrivateMessage *)toDeleteMsg{ self.messageToResendOrDelete = toDeleteMsg; [self.myMsgInputView isAndResignFirstResponder]; ESWeakSelf - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"删除后将不会出现在你的私信记录中" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + UIAlertController *actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"删除后将不会出现在你的私信记录中" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { ESStrongSelf if (index == 0 && _self.messageToResendOrDelete) { [_self deletePrivateMessageWithMsg:_messageToResendOrDelete]; @@ -410,6 +418,16 @@ - (void)sendPrivateMessageWithMsg:(PrivateMessage *)nextMsg{ [[Coding_NetAPIManager sharedManager] request_SendPrivateMessage:nextMsg andBlock:^(id data, NSError *error) { if (data) { [weakSelf.myPriMsgs sendSuccessMessage:data andOldMessage:nextMsg]; + }else if (error.userInfo[@"msg"][@"message_need_captcha"]){ + NSDictionary *params = @{@"type": @2, + @"receiver_global_key": nextMsg.friend.global_key ?: @"", + }; + [NSObject showCaptchaViewParams:params.mutableCopy success:^{ + [NSObject showHudTipStr:@"验证码正确"]; + weakSelf.messageToResendOrDelete = nextMsg; + [weakSelf.myMsgInputView isAndResignFirstResponder]; + [weakSelf sendPrivateMessageWithMsg:weakSelf.messageToResendOrDelete]; + }]; } [weakSelf dataChangedWithError:NO scrollToBottom:YES animated:YES]; } progerssBlock:^(CGFloat progressValue) { @@ -435,12 +453,11 @@ - (void)inputViewAddIndex:(NSInteger)index{ return; } QBImagePickerController *imagePickerController = [[QBImagePickerController alloc] init]; - imagePickerController.filterType = QBImagePickerControllerFilterTypePhotos; + imagePickerController.mediaType = QBImagePickerMediaTypeImage; imagePickerController.delegate = self; imagePickerController.allowsMultipleSelection = YES; imagePickerController.maximumNumberOfSelection = 6; - UINavigationController *navigationController = [[BaseNavigationController alloc] initWithRootViewController:imagePickerController]; - [self presentViewController:navigationController animated:YES completion:NULL]; + [self presentViewController:imagePickerController animated:YES completion:NULL]; } break; case 1: @@ -477,16 +494,9 @@ - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{ } #pragma mark QBImagePickerControllerDelegate -- (void)qb_imagePickerController:(QBImagePickerController *)imagePickerController didSelectAssets:(NSArray *)assets{ - for (ALAsset *assetItem in assets) { - @weakify(self); - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - UIImage *highQualityImage = [UIImage fullScreenImageALAsset:assetItem]; - dispatch_async(dispatch_get_main_queue(), ^{ - @strongify(self); - [self sendPrivateMessage:highQualityImage]; - }); - }); +- (void)qb_imagePickerController:(QBImagePickerController *)imagePickerController didFinishPickingAssets:(NSArray *)assets{ + for (PHAsset *assetItem in assets) { + [self sendPrivateMessage:assetItem.loadImage]; } [self dismissViewControllerAnimated:YES completion:nil]; } diff --git a/Coding_iOS/Controllers/CountryCodeListViewController.m b/Coding_iOS/Controllers/CountryCodeListViewController.m index 2d1c51221..33b54f232 100644 --- a/Coding_iOS/Controllers/CountryCodeListViewController.m +++ b/Coding_iOS/Controllers/CountryCodeListViewController.m @@ -29,11 +29,14 @@ - (void)viewDidLoad{ [tableView registerClass:[CountryCodeCell class] forCellReuseIdentifier:kCellIdentifier_CountryCodeCell]; tableView.sectionIndexBackgroundColor = [UIColor clearColor]; tableView.sectionIndexTrackingBackgroundColor = [UIColor clearColor]; - tableView.sectionIndexColor = kColor666; + tableView.sectionIndexColor = kColorDark2; [self.view addSubview:tableView]; [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _mySearchBar = ({ @@ -95,19 +98,19 @@ -(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{ } - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ - return 20; + return 30; } - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ UIView *headerV = [UIView new]; headerV.backgroundColor = self.myTableView.backgroundColor; UILabel *titleL = [UILabel new]; - titleL.font = [UIFont systemFontOfSize:12]; - titleL.textColor = kColor999; + titleL.font = [UIFont systemFontOfSize:14]; + titleL.textColor = kColorDark2; titleL.text = [_keyList[section+ 1] isEqualToString:@"#"]? @"常用": _keyList[section+ 1]; [headerV addSubview:titleL]; [titleL mas_makeConstraints:^(MASConstraintMaker *make) { - make.edges.equalTo(headerV).insets(UIEdgeInsetsMake(4, 15, 4, 15)); + make.edges.equalTo(headerV).insets(UIEdgeInsetsMake(0, 15, 0, 15)); }]; return headerV; } diff --git a/Coding_iOS/Controllers/DynamicCommentCell.m b/Coding_iOS/Controllers/DynamicCommentCell.m index 4dedc9742..e90d6d01f 100644 --- a/Coding_iOS/Controllers/DynamicCommentCell.m +++ b/Coding_iOS/Controllers/DynamicCommentCell.m @@ -36,7 +36,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (self) { // Initialization code self.selectionStyle = UITableViewCellSelectionStyleNone; - CGFloat curBottomY = 15; + CGFloat curBottomY = 25; if (!_contentBGView) { _contentBGView = [UIImageView new]; _contentBGView.image = [[UIImage imageNamed:@"comment_bg"] resizableImageWithCapInsets:UIEdgeInsetsMake(35, 15, 5, 5)]; @@ -52,7 +52,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus CGFloat borderWidth = 2; UIView *bgView = [[UIView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth - borderWidth, curBottomY, 28+ 2*borderWidth, 28 + 2*borderWidth)]; bgView.backgroundColor = kColorTableBG; - _ownerIconView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 28, 28)]; + _ownerIconView = [[YLImageView alloc] initWithFrame:CGRectMake(0, 0, 28, 28)]; _ownerIconView.layer.masksToBounds = YES; _ownerIconView.layer.cornerRadius = _ownerIconView.frame.size.width/2; @@ -65,7 +65,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus } if (!_contentLabel) { _contentLabel = [[UITTTAttributedLabel alloc] initWithFrame:CGRectMake(kTaskCommentCell_LeftContentPading, curBottomY, kTaskCommentCell_ContentWidth, 30)]; - _contentLabel.textColor = kColor222; + _contentLabel.textColor = kColorDark3; _contentLabel.font = kTaskCommentCell_FontContent; _contentLabel.linkAttributes = kLinkAttributes; _contentLabel.activeLinkAttributes = kLinkAttributesActive; @@ -74,7 +74,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus } if (!_timeLabel) { _timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(kTaskCommentCell_LeftContentPading, 0, kTaskCommentCell_ContentWidth, 20)]; - _timeLabel.textColor = kColor999; + _timeLabel.textColor = kColorDark7; _timeLabel.font = [UIFont systemFontOfSize:12]; [self.contentView addSubview:_timeLabel]; } @@ -92,20 +92,20 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus } } [_contentBGView mas_makeConstraints:^(MASConstraintMaker *make) { - make.edges.equalTo(self.contentView).insets(UIEdgeInsetsMake(5, 60- 7, 5, 20)); + make.edges.equalTo(self.contentView).insets(UIEdgeInsetsMake(10, 60- 7, 10, 20)); }]; if (!_detailBtn) { - _detailBtn = [UIButton buttonWithTitle:@"查看详情" titleColor:kColorBrandGreen]; + _detailBtn = [UIButton buttonWithTitle:@"查看详情" titleColor:kColorBrandBlue]; _detailBtn.titleLabel.font = [UIFont systemFontOfSize:12]; [_detailBtn addTarget:self action:@selector(goToDetail) forControlEvents:UIControlEventTouchUpInside]; [self.contentView addSubview:_detailBtn]; [_detailBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.size.mas_equalTo(CGSizeMake(60, 30)); make.right.equalTo(_contentBGView).offset(-10); - make.bottom.equalTo(_contentBGView).offset(-5); + make.centerY.equalTo(_timeLabel); }]; } - + _timeLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; } return self; } @@ -121,7 +121,7 @@ - (void)setCurComment:(ProjectLineNote *)curComment{ return; } _detailBtn.hidden = ![self.curComment.htmlMedia needToShowDetail]; - CGFloat curBottomY = 15; + CGFloat curBottomY = 25; [_ownerIconView sd_setImageWithURL:[_curComment.author.avatar urlImageWithCodePathResizeToView:_ownerIconView] placeholderImage:kPlaceholderMonkeyRoundWidth(33.0)]; NSString *contentStr = _curComment.content; [_contentLabel setLongString:contentStr withFitWidth:kTaskCommentCell_ContentWidth]; @@ -141,6 +141,7 @@ - (void)setCurComment:(ProjectLineNote *)curComment{ } curBottomY += [DynamicCommentCell imageCollectionViewHeightWithCount:imagesCount]; [_timeLabel setY:curBottomY]; + _timeLabel.width = _detailBtn.hidden? kTaskCommentCell_ContentWidth: kTaskCommentCell_ContentWidth - 60; _timeLabel.text = [NSString stringWithFormat:@"%@ 发布于 %@", _curComment.author.name,[_curComment.created_at stringDisplay_HHmm]]; } @@ -163,9 +164,9 @@ + (CGFloat)cellHeightWithObj:(id)obj { if ([obj isKindOfClass:[ProjectLineNote class]]) { ProjectLineNote *curComment = (ProjectLineNote *)obj; NSString *contentStr = curComment.content; - cellHeight += 10 +[contentStr getHeightWithFont:kTaskCommentCell_FontContent constrainedToSize:CGSizeMake(kTaskCommentCell_ContentWidth, CGFLOAT_MAX)] + 5 +20 +10; + cellHeight += 20 +[contentStr getHeightWithFont:kTaskCommentCell_FontContent constrainedToSize:CGSizeMake(kTaskCommentCell_ContentWidth, CGFLOAT_MAX)] + 5 +20 +10; cellHeight += [self imageCollectionViewHeightWithCount:curComment.htmlMedia.imageItems.count]; - cellHeight += 10; + cellHeight += 20; } return cellHeight; } diff --git a/Coding_iOS/Controllers/EACodeBranchListViewController.h b/Coding_iOS/Controllers/EACodeBranchListViewController.h new file mode 100644 index 000000000..204f32431 --- /dev/null +++ b/Coding_iOS/Controllers/EACodeBranchListViewController.h @@ -0,0 +1,15 @@ +// +// EACodeBranchListViewController.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/22. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "BaseViewController.h" +#import "Project.h" + +@interface EACodeBranchListViewController : BaseViewController +@property (nonatomic, strong) Project *myProject; + +@end diff --git a/Coding_iOS/Controllers/EACodeBranchListViewController.m b/Coding_iOS/Controllers/EACodeBranchListViewController.m new file mode 100644 index 000000000..61fc0544b --- /dev/null +++ b/Coding_iOS/Controllers/EACodeBranchListViewController.m @@ -0,0 +1,163 @@ +// +// EACodeBranchListViewController.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/22. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "EACodeBranchListViewController.h" +#import "EACodeBranches.h" +#import "ODRefreshControl.h" +#import "SVPullToRefresh.h" +#import "Coding_NetAPIManager.h" +#import "EACodeBranchListCell.h" +#import "ProjectViewController.h" + +@interface EACodeBranchListViewController () +@property (strong, nonatomic) UITableView *myTableView; +@property (nonatomic, strong) ODRefreshControl *myRefreshControl; + +@property (strong, nonatomic) EACodeBranches *myCodeBranches; + +@end + +@implementation EACodeBranchListViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + self.title = @"分支管理"; + self.view.backgroundColor = kColorTableSectionBg; + _myTableView = ({ + UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; + tableView.backgroundColor = [UIColor clearColor]; + tableView.dataSource = self; + tableView.delegate = self; + tableView.separatorStyle = UITableViewCellSeparatorStyleNone; +// [tableView registerClass:[EACodeBranchListCell class] forCellReuseIdentifier:[EACodeBranchListCell nameOfClass]]; + [tableView registerNib:[UINib nibWithNibName:[EACodeBranchListCell nameOfClass] bundle:nil] forCellReuseIdentifier:[EACodeBranchListCell nameOfClass]]; + [self.view addSubview:tableView]; + [tableView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; + UIEdgeInsets insets = UIEdgeInsetsMake(0, 0, 0, 0); + tableView.contentInset = insets; + tableView.scrollIndicatorInsets = insets; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; + tableView; + }); + _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; + [_myRefreshControl addTarget:self action:@selector(refresh) forControlEvents:UIControlEventValueChanged]; + + __weak typeof(self) weakSelf = self; + [_myTableView addInfiniteScrollingWithActionHandler:^{ + [weakSelf refreshMore:YES]; + }]; + [self refresh]; +} + +- (void)setMyProject:(Project *)myProject{ + _myProject = myProject; + _myCodeBranches = [EACodeBranches new]; + _myCodeBranches.curPro = _myProject; +} + +#pragma Data +- (void)refresh{ + [self refreshMore:NO]; +} +- (void)refreshMore:(BOOL)willLoadMore{ + if (_myCodeBranches.isLoading) { + return; + } + if (willLoadMore && !_myCodeBranches.canLoadMore) { + [_myTableView.infiniteScrollingView stopAnimating]; + return; + } + _myCodeBranches.willLoadMore = willLoadMore; + [self sendRequest]; +} + +- (void)sendRequest{ + if (_myCodeBranches.list.count <= 0) { + [self.view beginLoading]; + } + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_CodeBranches_WithObj:_myCodeBranches andBlock:^(EACodeBranches *data, NSError *error) { + [weakSelf.view endLoading]; + [weakSelf.myRefreshControl endRefreshing]; + [weakSelf.myTableView.infiniteScrollingView stopAnimating]; + if (data) { + [weakSelf.myCodeBranches configWithObj:data]; + [weakSelf.myTableView reloadData]; + weakSelf.myTableView.showsInfiniteScrolling = weakSelf.myCodeBranches.canLoadMore; + } + [weakSelf.view configBlankPage:EaseBlankPageTypeView hasData:(weakSelf.myCodeBranches.list.count > 0) hasError:(error != nil) reloadButtonBlock:^(id sender) { + [weakSelf refreshMore:NO]; + }]; + }]; +} + +#pragma mark TableM +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + return _myCodeBranches.list.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + EACodeBranchListCell *cell = [tableView dequeueReusableCellWithIdentifier:[EACodeBranchListCell nameOfClass] forIndexPath:indexPath]; + cell.curBranch = self.myCodeBranches.list[indexPath.row]; + cell.delegate = self; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; + return cell; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ + return 80; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + CodeBranchOrTag *curB = self.myCodeBranches.list[indexPath.row]; + ProjectViewController *vc = [ProjectViewController codeVCWithCodeRef:curB.name andProject:self.myProject]; + vc.hideBranchTagButton = YES; + [self.navigationController pushViewController:vc animated:YES]; +} + +#pragma mark SWTableViewCellDelegate +- (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerRightUtilityButtonWithIndex:(NSInteger)index{ + NSIndexPath *indexPath = [self.myTableView indexPathForCell:cell]; + CodeBranchOrTag *curB = self.myCodeBranches.list[indexPath.row]; + __weak typeof(self) weakSelf = self; + [[UIAlertController ea_actionSheetCustomWithTitle:[NSString stringWithFormat:@"请确认是否要删除分支 %@ ?", curB.name] buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { + [weakSelf deleteBranch:curB]; + } + }] showInView:self.view]; +} +- (BOOL)swipeableTableViewCellShouldHideUtilityButtonsOnSwipe:(SWTableViewCell *)cell{ + return YES; +} +- (BOOL)swipeableTableViewCell:(SWTableViewCell *)cell canSwipeToState:(SWCellState)state{ + NSIndexPath *indexPath = [self.myTableView indexPathForCell:cell]; + CodeBranchOrTag *curB = self.myCodeBranches.list[indexPath.row]; + return !curB.is_default_branch.boolValue; +} + +- (void)deleteBranch:(CodeBranchOrTag *)curB{ + __weak typeof(self) weakSelf = self; + [NSObject showHUDQueryStr:@"请稍等..."]; + [[Coding_NetAPIManager sharedManager] request_DeleteCodeBranch:curB inProject:_myProject andBlock:^(id data, NSError *error) { + [NSObject hideHUDQuery]; + if (data) { + [NSObject showHudTipStr:@"删除成功"]; +// [weakSelf.myCodeBranches.list removeObject:curB]; +// [weakSelf.myTableView reloadData]; + [weakSelf refresh]; + } + }]; +} + +@end diff --git a/Coding_iOS/Controllers/EACodeReleaseListViewController.h b/Coding_iOS/Controllers/EACodeReleaseListViewController.h new file mode 100644 index 000000000..c0f3cb8ca --- /dev/null +++ b/Coding_iOS/Controllers/EACodeReleaseListViewController.h @@ -0,0 +1,15 @@ +// +// EACodeReleaseListViewController.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/22. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "BaseViewController.h" +#import "Project.h" + +@interface EACodeReleaseListViewController : BaseViewController +@property (nonatomic, strong) Project *myProject; + +@end diff --git a/Coding_iOS/Controllers/EACodeReleaseListViewController.m b/Coding_iOS/Controllers/EACodeReleaseListViewController.m new file mode 100644 index 000000000..6970b1701 --- /dev/null +++ b/Coding_iOS/Controllers/EACodeReleaseListViewController.m @@ -0,0 +1,159 @@ +// +// EACodeReleaseListViewController.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/22. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "EACodeReleaseListViewController.h" +#import "EACodeReleases.h" +#import "ODRefreshControl.h" +#import "SVPullToRefresh.h" +#import "Coding_NetAPIManager.h" +#import "EACodeReleaseListCell.h" +#import "EACodeReleaseViewController.h" + +@interface EACodeReleaseListViewController () +@property (strong, nonatomic) UITableView *myTableView; +@property (nonatomic, strong) ODRefreshControl *myRefreshControl; + +@property (strong, nonatomic) EACodeReleases *myCodeReleases; +@property (strong, nonatomic) NSArray *dataList; +@end + +@implementation EACodeReleaseListViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + self.title = @"发布管理"; + self.view.backgroundColor = kColorTableSectionBg; + _myTableView = ({ + UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; + tableView.backgroundColor = [UIColor clearColor]; + tableView.dataSource = self; + tableView.delegate = self; + tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + [tableView registerNib:[UINib nibWithNibName:[EACodeReleaseListCell nameOfClass] bundle:nil] forCellReuseIdentifier:[EACodeReleaseListCell nameOfClass]]; + [self.view addSubview:tableView]; + [tableView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; + UIEdgeInsets insets = UIEdgeInsetsMake(0, 0, 0, 0); + tableView.contentInset = insets; + tableView.scrollIndicatorInsets = insets; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; + tableView; + }); + _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; + [_myRefreshControl addTarget:self action:@selector(refresh) forControlEvents:UIControlEventValueChanged]; + + __weak typeof(self) weakSelf = self; + [_myTableView addInfiniteScrollingWithActionHandler:^{ + [weakSelf refreshMore:YES]; + }]; + [self refresh]; +} + +- (void)setMyProject:(Project *)myProject{ + _myProject = myProject; + _myCodeReleases = [EACodeReleases new]; + _myCodeReleases.curPro = _myProject; +} + +#pragma Data +- (void)refresh{ + [self refreshMore:NO]; +} +- (void)refreshMore:(BOOL)willLoadMore{ + if (_myCodeReleases.isLoading) { + return; + } + if (willLoadMore && !_myCodeReleases.canLoadMore) { + [_myTableView.infiniteScrollingView stopAnimating]; + return; + } + _myCodeReleases.willLoadMore = willLoadMore; + [self sendRequest]; +} + +- (void)sendRequest{ + if (_myCodeReleases.list.count <= 0) { + [self.view beginLoading]; + } + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_CodeReleases_WithObj:_myCodeReleases andBlock:^(EACodeReleases *data, NSError *error) { + [weakSelf.view endLoading]; + [weakSelf.myRefreshControl endRefreshing]; + [weakSelf.myTableView.infiniteScrollingView stopAnimating]; + if (data) { + [weakSelf.myCodeReleases configWithObj:data]; + [weakSelf.myTableView reloadData]; + weakSelf.myTableView.showsInfiniteScrolling = weakSelf.myCodeReleases.canLoadMore; + } + [weakSelf.view configBlankPage:EaseBlankPageTypeView hasData:(weakSelf.myCodeReleases.list.count > 0) hasError:(error != nil) reloadButtonBlock:^(id sender) { + [weakSelf refreshMore:NO]; + }]; + }]; +} + +#pragma mark TableM +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + return _myCodeReleases.list.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + EACodeReleaseListCell *cell = [tableView dequeueReusableCellWithIdentifier:[EACodeReleaseListCell nameOfClass] forIndexPath:indexPath]; + cell.curCodeRelease = self.myCodeReleases.list[indexPath.row]; + cell.delegate = self; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; + return cell; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ + return 65; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + EACodeReleaseViewController *vc = [EACodeReleaseViewController new]; + vc.curRelease = self.myCodeReleases.list[indexPath.row]; + [self.navigationController pushViewController:vc animated:YES]; +} + +#pragma mark SWTableViewCellDelegate +- (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerRightUtilityButtonWithIndex:(NSInteger)index{ + NSIndexPath *indexPath = [self.myTableView indexPathForCell:cell]; + EACodeRelease *curR = self.myCodeReleases.list[indexPath.row]; + __weak typeof(self) weakSelf = self; + [[UIAlertController ea_actionSheetCustomWithTitle:[NSString stringWithFormat:@"请确认是否删除版本 %@ ?", curR.tag_name] buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { + [weakSelf deleteRelease:curR]; + } + }] showInView:self.view]; +} +- (BOOL)swipeableTableViewCellShouldHideUtilityButtonsOnSwipe:(SWTableViewCell *)cell{ + return YES; +} +- (BOOL)swipeableTableViewCell:(SWTableViewCell *)cell canSwipeToState:(SWCellState)state{ + return YES; +} + +- (void)deleteRelease:(EACodeRelease *)curR{ + __weak typeof(self) weakSelf = self; + [NSObject showHUDQueryStr:@"请稍等..."]; + [[Coding_NetAPIManager sharedManager] request_DeleteCodeRelease:curR andBlock:^(id data, NSError *error) { + [NSObject hideHUDQuery]; + if (data) { + [NSObject showHudTipStr:@"删除成功"]; +// [weakSelf.myCodeReleases.list removeObject:curR]; +// [weakSelf.myTableView reloadData]; + [weakSelf refresh]; + } + }]; +} + +@end diff --git a/Coding_iOS/Controllers/EACodeReleaseViewController.h b/Coding_iOS/Controllers/EACodeReleaseViewController.h new file mode 100644 index 000000000..148653c6c --- /dev/null +++ b/Coding_iOS/Controllers/EACodeReleaseViewController.h @@ -0,0 +1,14 @@ +// +// EACodeReleaseViewController.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/23. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "BaseViewController.h" +#import "EACodeRelease.h" + +@interface EACodeReleaseViewController : BaseViewController +@property (strong, nonatomic) EACodeRelease *curRelease; +@end diff --git a/Coding_iOS/Controllers/EACodeReleaseViewController.m b/Coding_iOS/Controllers/EACodeReleaseViewController.m new file mode 100644 index 000000000..58ce3853b --- /dev/null +++ b/Coding_iOS/Controllers/EACodeReleaseViewController.m @@ -0,0 +1,185 @@ +// +// EACodeReleaseViewController.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/23. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "EACodeReleaseViewController.h" +#import "ODRefreshControl.h" +#import "Coding_NetAPIManager.h" +#import "EACodeReleaseTopCell.h" +#import "EACodeReleaseBodyCell.h" +#import "EACodeReleaseAttachmentsOrReferencesCell.h" +#import "ProjectViewController.h" +#import "WebViewController.h" +#import "EAEditCodeReleaseViewController.h" + +@interface EACodeReleaseViewController () +@property (strong, nonatomic) UITableView *myTableView; +@property (nonatomic, strong) ODRefreshControl *myRefreshControl; + +@end + +@implementation EACodeReleaseViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + self.title = _curRelease.tag_name; + self.view.backgroundColor = kColorTableBG; + _myTableView = ({ + UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; + tableView.backgroundColor = [UIColor clearColor]; + tableView.dataSource = self; + tableView.delegate = self; + tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + [tableView registerNib:[UINib nibWithNibName:[EACodeReleaseTopCell nameOfClass] bundle:nil] forCellReuseIdentifier:[EACodeReleaseTopCell nameOfClass]]; + [tableView registerClass:[EACodeReleaseBodyCell class] forCellReuseIdentifier:[EACodeReleaseBodyCell nameOfClass]]; + [tableView registerClass:[EACodeReleaseAttachmentsOrReferencesCell class] forCellReuseIdentifier:[EACodeReleaseAttachmentsOrReferencesCell nameOfClass]]; + [self.view addSubview:tableView]; + [tableView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; + UIEdgeInsets insets = UIEdgeInsetsMake(0, 0, 0, 0); + tableView.contentInset = insets; + tableView.scrollIndicatorInsets = insets; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; + tableView; + }); + _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; + [_myRefreshControl addTarget:self action:@selector(refresh) forControlEvents:UIControlEventValueChanged]; + + [self.navigationItem setRightBarButtonItem:[UIBarButtonItem itemWithBtnTitle:@"编辑" target:self action:@selector(editBtnClicked)] animated:YES]; +} + +- (void)viewWillAppear:(BOOL)animated{ + [super viewWillAppear:animated]; + [self refresh]; +} + +#pragma Data +- (void)refresh{ + if (!_curRelease.author) { + [self.view beginLoading]; + } + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_CodeRelease_WithObj:_curRelease andBlock:^(EACodeRelease *data, NSError *error) { + [weakSelf.view endLoading]; + [weakSelf.myRefreshControl endRefreshing]; + if (data) { + if (weakSelf.curRelease.contentHeight > 1) { + [(EACodeRelease *)data setContentHeight:weakSelf.curRelease.contentHeight]; + } + weakSelf.curRelease = data; + [weakSelf.myTableView reloadData]; + } + [weakSelf.view configBlankPage:EaseBlankPageTypeView hasData:(weakSelf.curRelease.author != nil) hasError:(error != nil) reloadButtonBlock:^(id sender) { + [weakSelf refresh]; + }]; + }]; +} + +#pragma mark TableM +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + return _curRelease.author != nil? 4: 0; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + if (indexPath.row == 0) { + EACodeReleaseTopCell *cell = [tableView dequeueReusableCellWithIdentifier:[EACodeReleaseTopCell nameOfClass] forIndexPath:indexPath]; + cell.curR = self.curRelease; + __weak typeof(self) weakSelf = self; + cell.tagClickedBlock = ^(EACodeRelease *curR) { + ProjectViewController *vc = [ProjectViewController codeVCWithCodeRef:curR.tag_name andProject:curR.project]; + vc.hideBranchTagButton = YES; + [weakSelf.navigationController pushViewController:vc animated:YES]; + }; + return cell; + }else if (indexPath.row == 1){ + EACodeReleaseBodyCell *cell = [tableView dequeueReusableCellWithIdentifier:[EACodeReleaseBodyCell nameOfClass] forIndexPath:indexPath]; + cell.curR = self.curRelease; + __weak typeof(self) weakSelf = self; + cell.cellHeightChangedBlock = ^{ + [weakSelf.myTableView reloadData]; + }; + cell.loadRequestBlock = ^(NSURLRequest *curRequest) { + [weakSelf loadRequest:curRequest]; + }; + return cell; + }else{ + EACodeReleaseAttachmentsOrReferencesCell *cell = [tableView dequeueReusableCellWithIdentifier:[EACodeReleaseAttachmentsOrReferencesCell nameOfClass] forIndexPath:indexPath]; + [cell setupCodeRelease:_curRelease type:(indexPath.row - 2)]; + __weak typeof(self) weakSelf = self; + cell.itemClickedBlock = ^(id item) { + [weakSelf handleItem:item]; + }; + return cell; + } +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ + CGFloat cellHeight = 0; + if (indexPath.row == 0) { + cellHeight = [EACodeReleaseTopCell cellHeightWithObj:_curRelease]; + }else if (indexPath.row == 1){ + cellHeight = [EACodeReleaseBodyCell cellHeightWithObj:_curRelease]; + }else{ + cellHeight = [EACodeReleaseAttachmentsOrReferencesCell cellHeightWithObj:_curRelease type:(indexPath.row - 2)]; + } + return cellHeight; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; +} + +#pragma mark loadCellRequest +- (void)loadRequest:(NSURLRequest *)curRequest +{ + NSString *linkStr = curRequest.URL.absoluteString; + [self analyseLinkStr:linkStr]; +} + +- (void)analyseLinkStr:(NSString *)linkStr +{ + if (linkStr.length <= 0) { + return; + } + UIViewController *vc = [BaseViewController analyseVCFromLinkStr:linkStr]; + if (vc) { + [self.navigationController pushViewController:vc animated:YES]; + }else{ + // 跳转去网页 + WebViewController *webVc = [WebViewController webVCWithUrlStr:linkStr]; + [self.navigationController pushViewController:webVc animated:YES]; + } +} + +#pragma mark goTo + +- (void)handleItem:(id)item{ + if ([item isKindOfClass:[EACodeReleaseAttachment class]]) { + NSString *linkStr = [NSString stringWithFormat:@"/api/user/%@/project/%@/git/releases/attachments/download/%@", _curRelease.project.owner_user_name, _curRelease.project.name, ((EACodeReleaseAttachment *)item).id]; + WebViewController *webVc = [WebViewController webVCWithUrlStr:linkStr]; + [self.navigationController pushViewController:webVc animated:YES]; + }else if ([item isKindOfClass:[ResourceReferenceItem class]]){ + UIViewController *vc = [BaseViewController analyseVCFromLinkStr:((ResourceReferenceItem *)item).link]; + if (vc) { + [self.navigationController pushViewController:vc animated:YES]; + }else{ + [NSObject showHudTipStr:@"暂时不支持查看该资源"]; + } + } +} + +- (void)editBtnClicked{ + EAEditCodeReleaseViewController *vc = [EAEditCodeReleaseViewController new]; + vc.curR = _curRelease; + [self.navigationController pushViewController:vc animated:YES]; +} + +@end diff --git a/Coding_iOS/Controllers/EAEditCodeReleaseViewController.h b/Coding_iOS/Controllers/EAEditCodeReleaseViewController.h new file mode 100644 index 000000000..f34ee57c9 --- /dev/null +++ b/Coding_iOS/Controllers/EAEditCodeReleaseViewController.h @@ -0,0 +1,15 @@ +// +// EAEditCodeReleaseViewController.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/27. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "BaseViewController.h" +#import "EACodeRelease.h" + +@interface EAEditCodeReleaseViewController : BaseViewController +@property (strong, nonatomic) EACodeRelease *curR; + +@end diff --git a/Coding_iOS/Controllers/EAEditCodeReleaseViewController.m b/Coding_iOS/Controllers/EAEditCodeReleaseViewController.m new file mode 100644 index 000000000..d7d5e2c03 --- /dev/null +++ b/Coding_iOS/Controllers/EAEditCodeReleaseViewController.m @@ -0,0 +1,286 @@ +// +// EAEditCodeReleaseViewController.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/27. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "EAEditCodeReleaseViewController.h" +#import "Coding_NetAPIManager.h" +#import "EaseMarkdownTextView.h" +#import "WebContentManager.h" +#import "WebViewController.h" +#import "UIViewController+BackButtonHandler.h" + +@interface EAEditCodeReleaseViewController () + +@property (strong, nonatomic) UISegmentedControl *segmentedControl; +@property (assign, nonatomic) NSInteger curIndex; + +@property (strong, nonatomic) UIWebView *preview; +@property (strong, nonatomic) UIActivityIndicatorView *activityIndicator; + +@property (strong, nonatomic) UIView *editView; +@property (strong, nonatomic) UITextField *inputTitleView; +@property (strong, nonatomic) EaseMarkdownTextView *inputContentView; +@property (strong, nonatomic) UIView *lineView; +@end + +@implementation EAEditCodeReleaseViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + self.view.backgroundColor = kColorTableBG; + if (!_segmentedControl) { + _segmentedControl = ({ + UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:@[@"编辑", @"预览"]]; + [segmentedControl setWidth:80 forSegmentAtIndex:0]; + [segmentedControl setWidth:80 forSegmentAtIndex:1]; + [segmentedControl setTitleTextAttributes:@{ + NSFontAttributeName: [UIFont systemFontOfSize:16], + NSForegroundColorAttributeName: [UIColor whiteColor] + } + forState:UIControlStateSelected]; + [segmentedControl setTitleTextAttributes:@{ + NSFontAttributeName: [UIFont systemFontOfSize:16], + NSForegroundColorAttributeName: kColorNavTitle + } forState:UIControlStateNormal]; + [segmentedControl addTarget:self action:@selector(segmentedControlSelected:) forControlEvents:UIControlEventValueChanged]; + segmentedControl; + }); + + self.navigationItem.titleView = _segmentedControl; + } + + [self.navigationItem setRightBarButtonItem:[UIBarButtonItem itemWithBtnTitle:@"保存" target:self action:@selector(saveBtnClicked)] animated:YES]; + self.navigationItem.rightBarButtonItem.enabled = NO; + + [[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillChangeFrameNotification object:nil] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(NSNotification *aNotification) { + if (self.inputContentView) { + NSDictionary* userInfo = [aNotification userInfo]; + CGRect keyboardEndFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; + self.inputContentView.contentInset = UIEdgeInsetsMake(0, 0, CGRectGetHeight(keyboardEndFrame), 0); + self.inputContentView.scrollIndicatorInsets = self.inputContentView.contentInset; + } + }]; + self.curIndex = 0; +} + + +- (void)refreshUI{ + self.inputTitleView.text = self.curR.editTitle; + self.inputContentView.text = self.curR.editBody; + if (_curIndex == 1) { + [self loadPreview]; + } +} + +- (void)viewDidAppear:(BOOL)animated{ + [super viewDidAppear:animated]; + if (_curIndex == 0) { + [self loadEditView]; + } else { + [self loadPreview]; + } + //禁用屏幕左滑返回手势 + if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) { + self.navigationController.interactivePopGestureRecognizer.enabled = NO; + } +} + +- (void)viewDidDisappear:(BOOL)animated { + [super viewDidDisappear:animated]; + //开启屏幕左滑返回手势 + if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) { + self.navigationController.interactivePopGestureRecognizer.enabled = YES; + } +} + +- (BOOL)navigationShouldPopOnBackButton{ + self.curR.editTitle = _inputTitleView.text; + self.curR.editBody = _inputContentView.text; + if ([self.curR hasChanged]) { + __weak typeof(self) weakSelf = self; + [[UIAlertController ea_alertViewWithTitle:@"提示" message:@"如果不保存,更改将丢失,是否确认返回?" buttonTitles:@[@"确认返回"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { + [weakSelf.navigationController popViewControllerAnimated:YES]; + } + }] show]; + return NO; + }else{ + return YES; + } +} + +#pragma mark UISegmentedControl +- (void)segmentedControlSelected:(id)sender{ + UISegmentedControl *segmentedControl = (UISegmentedControl *)sender; + self.curIndex = segmentedControl.selectedSegmentIndex; +} + +#pragma mark index_view +- (void)setCurIndex:(NSInteger)curIndex{ + _curIndex = curIndex; + if (_segmentedControl.selectedSegmentIndex != curIndex) { + [_segmentedControl setSelectedSegmentIndex:_curIndex]; + } + + if (_curIndex == 0) { + [self loadEditView]; + } else { + [self loadPreview]; + } +} + +#pragma mark PreView + +- (void)loadPreview{ + if (!_preview) { + _preview = [[UIWebView alloc] initWithFrame:self.view.bounds]; + _preview.delegate = self; + _preview.backgroundColor = [UIColor clearColor]; + _preview.opaque = NO; + _preview.scalesPageToFit = YES; + [self.view addSubview:_preview]; + //webview加载指示 + _activityIndicator = [[UIActivityIndicatorView alloc] + initWithActivityIndicatorStyle: + UIActivityIndicatorViewStyleGray]; + _activityIndicator.hidesWhenStopped = YES; + [_activityIndicator setCenter:CGPointMake(CGRectGetWidth(_preview.frame)/2, CGRectGetHeight(_preview.frame)/2)]; + [_preview addSubview:_activityIndicator]; + [_preview mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; + } + self.curR.editTitle = _inputTitleView.text; + self.curR.editBody = _inputContentView.text; + + _preview.hidden = NO; + _editView.hidden = YES; + [self.view endEditing:YES]; + [self previewLoadMDData]; +} + +- (void)previewLoadMDData{ + NSString *mdStr = [NSString stringWithFormat:@"# %@ \n\n%@", self.curR.editTitle, self.curR.editBody]; + @weakify(self); + [[Coding_NetAPIManager sharedManager] request_MDHtmlStr_WithMDStr:mdStr inProject:self.curR.project andBlock:^(id data, NSError *error) { + @strongify(self); + NSString *htmlStr = data? data : error.description; + NSString *contentStr = [WebContentManager wikiPatternedWithContent:htmlStr]; + [self.preview loadHTMLString:contentStr baseURL:nil]; + }]; +} +#pragma mark EditView + + +- (void)loadEditView{ + if (!_editView) { + //控件 + _editView = [[UIView alloc] initWithFrame:self.view.bounds]; + [self.view addSubview:_editView]; + + _inputTitleView = [UITextField new]; + _inputTitleView.textColor = kColor222; + _inputTitleView.font = [UIFont systemFontOfSize:18]; + _inputTitleView.placeholder = @"Release 标题"; + [_editView addSubview:_inputTitleView]; + + _lineView = [UIView new]; + _lineView.backgroundColor = kColorDDD; + [_editView addSubview:_lineView]; + + _inputContentView = [[EaseMarkdownTextView alloc] initWithFrame:CGRectZero]; + _inputContentView.curProject = self.curR.project; + _inputContentView.textColor = kColor222; + _inputContentView.placeholder = @"Release 的描述内容"; + _inputContentView.backgroundColor = [UIColor clearColor]; + _inputContentView.font = [UIFont systemFontOfSize:15]; + _inputContentView.textContainerInset = UIEdgeInsetsMake(10, kPaddingLeftWidth - 5, 8, kPaddingLeftWidth - 5); + [_editView addSubview:_inputContentView]; + + [self.view addSubview:_editView]; + // 布局 + [_editView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; + [_inputTitleView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(_editView.mas_top).offset(10.0); + make.height.mas_equalTo(25); + make.left.equalTo(_editView).offset(kPaddingLeftWidth); + make.right.equalTo(_editView).offset(-kPaddingLeftWidth); + }]; + [_lineView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(_inputTitleView.mas_bottom).offset(10.0); + make.left.equalTo(_editView).offset(kPaddingLeftWidth); + make.height.mas_equalTo(1.0); + make.right.equalTo(_editView); + }]; + [_inputContentView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(_lineView.mas_bottom).offset(5.0); + make.left.right.bottom.equalTo(_editView); + }]; + // 内容 + @weakify(self); + RAC(self.navigationItem.rightBarButtonItem, enabled) = [RACSignal combineLatest:@[self.inputTitleView.rac_textSignal, + self.inputContentView.rac_textSignal] + reduce:^id (NSString *title, NSString *content) { + @strongify(self); + title = self.inputTitleView.text; + content = self.inputContentView.text; + BOOL enabled = ([title stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]].length > 0 + && (![title isEqualToString:self.curR.editTitle] || ![content isEqualToString:self.curR.editBody])); + return @(enabled); + }]; + _inputTitleView.text = _curR.editTitle; + _inputContentView.text = _curR.editBody; + } + _editView.hidden = NO; + _preview.hidden = YES; +} + +#pragma mark - click +- (void)saveBtnClicked{ + self.curR.editTitle = _inputTitleView.text; + self.curR.editBody = _inputContentView.text; + + self.navigationItem.rightBarButtonItem.enabled = NO; + [NSObject showHUDQueryStr:@"正在保存..."]; + @weakify(self); + [[Coding_NetAPIManager sharedManager] request_ModifyCodeRelease:_curR andBlock:^(EACodeRelease *data, NSError *error) { + @strongify(self); + self.navigationItem.rightBarButtonItem.enabled = YES; + [NSObject hideHUDQuery]; + if (data) { + [NSObject showHudTipStr:@"保存成功"]; + [self.navigationController popViewControllerAnimated:YES]; + } + }]; +} + +#pragma mark UIWebViewDelegate +- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ + DebugLog(@"strLink=[%@]",request.URL.absoluteString); + UIViewController *vc = [BaseViewController analyseVCFromLinkStr:request.URL.absoluteString]; + if (vc) { + [self.navigationController pushViewController:vc animated:YES]; + return NO; + } + return YES; +} +- (void)webViewDidStartLoad:(UIWebView *)webView{ + [_activityIndicator startAnimating]; +} +- (void)webViewDidFinishLoad:(UIWebView *)webView{ + [_activityIndicator stopAnimating]; +} +- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{ + if([error code] == NSURLErrorCancelled) + return; + else + DebugLog(@"%@", error.description); +} +@end diff --git a/Coding_iOS/Controllers/EALocalCodeListViewController.h b/Coding_iOS/Controllers/EALocalCodeListViewController.h new file mode 100644 index 000000000..f530a2bf2 --- /dev/null +++ b/Coding_iOS/Controllers/EALocalCodeListViewController.h @@ -0,0 +1,18 @@ +// +// EALocalCodeListViewController.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/28. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "BaseViewController.h" +#import "Project.h" + +@interface EALocalCodeListViewController : BaseViewController +@property (strong, nonatomic) Project *curPro; +@property (strong, nonatomic) GTRepository *curRepo; +@property (strong, nonatomic) NSURL *curURL; + +- (void)pullRepo; +@end diff --git a/Coding_iOS/Controllers/EALocalCodeListViewController.m b/Coding_iOS/Controllers/EALocalCodeListViewController.m new file mode 100644 index 000000000..36b18c24b --- /dev/null +++ b/Coding_iOS/Controllers/EALocalCodeListViewController.m @@ -0,0 +1,219 @@ +// +// EALocalCodeListViewController.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/28. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "EALocalCodeListViewController.h" +#import "EALocalCodeViewController.h" +#import "EALocalCodeListCell.h" + +@interface EALocalCodeListViewController () +@property (nonatomic, strong) UITableView *myTableView; +@property (strong, nonatomic) UISearchBar *mySearchBar; + +@property (strong, nonatomic) NSArray *fileList, *searchedFileList; +@property (strong, nonatomic) NSMutableDictionary *isDirDict; +@property (strong, nonatomic, readonly) NSArray *dataList; +@property (assign, nonatomic, readonly) BOOL isSearching; +@end + +@implementation EALocalCodeListViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + _myTableView = ({ + UITableView *tableView = [UITableView new]; + tableView.backgroundColor = [UIColor clearColor]; + tableView.delegate = self; + tableView.dataSource = self; + [tableView registerClass:[EALocalCodeListCell class] forCellReuseIdentifier:[EALocalCodeListCell nameOfClass]]; + tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + [self.view addSubview:tableView]; + [tableView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; + tableView; + }); + _mySearchBar = ({ + UISearchBar *searchBar = [[UISearchBar alloc] init]; + searchBar.delegate = self; + [searchBar sizeToFit]; + [searchBar setPlaceholder:@"寻找文件"]; + searchBar; + }); + _myTableView.tableHeaderView = _mySearchBar; + [self setupNavBtnAndTitle]; + [self setupData]; +} + +- (void)setupData{ + NSFileManager *fileManager = [NSFileManager defaultManager]; + self.fileList = [[fileManager contentsOfDirectoryAtURL:_curURL includingPropertiesForKeys:nil options:0 error:nil] sortedArrayUsingComparator:^NSComparisonResult(NSURL *obj1, NSURL *obj2) { + NSDictionary *attr1 = [obj1 resourceValuesForKeys:@[NSURLIsDirectoryKey] error:nil]; + BOOL isDir1 = [attr1[NSURLIsDirectoryKey] boolValue]; + NSDictionary *attr2 = [obj2 resourceValuesForKeys:@[NSURLIsDirectoryKey] error:nil]; + BOOL isDir2 = [attr2[NSURLIsDirectoryKey] boolValue]; + NSComparisonResult result = [(isDir1? @0: @1) compare:(isDir2? @0: @1)]; + if (result == NSOrderedSame) { + result = [obj1.lastPathComponent compare:obj2.lastPathComponent]; + } + return result; + }]; + [self.myTableView reloadData]; +} + +- (BOOL)isSearching{ + return ![_mySearchBar.text isEmpty]; +} + +- (NSArray *)dataList{ + return self.isSearching? _searchedFileList: _fileList; +} + +#pragma mark Nav +- (void)setupNavBtnAndTitle{ + if ([_curURL.absoluteString isEqualToString:_curPro.localURL.absoluteString]) {//根目录 + NSArray *branchList = [_curPro.localRepo localBranchesWithError:nil]; + self.title = branchList.count > 0? branchList.firstObject.shortName: _curURL.lastPathComponent; + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"moreBtn_Nav"] style:UIBarButtonItemStylePlain target:self action:@selector(navBtnClicked)]; + }else{ + self.title = _curURL.lastPathComponent; + } +} + +- (void)navBtnClicked{ + __weak typeof(self) weakSelf = self; + [[UIAlertController ea_actionSheetCustomWithTitle:nil buttonTitles:@[@"Pull"] destructiveTitle:@"删除本地 Repo" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { + [weakSelf pullRepo]; + }else if (index == 1){ + [weakSelf deleteRepo]; + } + }] showInView:self.view]; +} + +- (void)pullRepo{ + if (![_curURL.absoluteString isEqualToString:_curPro.localURL.absoluteString]) {//不是根目录不 pull,任性 + return; + } + __weak typeof(self) weakSelf = self; + MBProgressHUD *hud = [NSObject showHUDQueryStr:@"正在 pull..."]; + [_curPro gitPullBlock:^(BOOL result, NSString *tipStr) { + [NSObject hideHUDQuery]; + if (tipStr) { + [NSObject showHudTipStr:tipStr]; + }else{ + [NSObject showHudTipStr:@"已更新"]; + [weakSelf setupData]; + } + } progressBlock:^(const git_transfer_progress *progress, BOOL *stop) { + hud.detailsLabelText = [NSString stringWithFormat:@"%d / %d", progress->received_objects, progress->total_objects]; + }]; +} + +- (void)deleteRepo{ + [_curPro deleteLocalRepo]; + [NSObject showHudTipStr:@"已删除"]; + [self.navigationController popViewControllerAnimated:YES]; +} + +#pragma mark ScrollView Delegate +- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{ + if (scrollView == _myTableView) { + [self.mySearchBar resignFirstResponder]; + } +} +#pragma mark Table + +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ + return self.isSearching? 44.0: 0.0; +} + +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ + if (self.isSearching) { + UILabel *headerL = [UILabel labelWithSystemFontSize:14 textColorHexString:@"0xB5B5B5"]; + headerL.frame = CGRectMake(0, 0, kScreen_Width, 40); + headerL.backgroundColor = [UIColor whiteColor]; + headerL.textAlignment = NSTextAlignmentCenter; + headerL.text = [NSString stringWithFormat:@"共搜到 %lu 个与 \"%@\" 相关的文件", (unsigned long)self.searchedFileList.count, self.mySearchBar.text]; + [headerL doBorderWidth:kLine_MinHeight color:kColorDDD cornerRadius:0]; + return headerL; + }else{ + return [UIView new]; + } +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + return self.dataList.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + EALocalCodeListCell *cell = [tableView dequeueReusableCellWithIdentifier:[EALocalCodeListCell nameOfClass] forIndexPath:indexPath]; + cell.curURL = self.dataList[indexPath.row]; + cell.searchText = [_mySearchBar.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth hasSectionLine:NO]; + return cell; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ + return 44.0;; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + NSURL *itemURL = self.dataList[indexPath.row]; + NSDictionary *attributes = [itemURL resourceValuesForKeys:@[NSURLIsDirectoryKey] error:nil]; + BOOL isDir = [attributes[NSURLIsDirectoryKey] boolValue]; + if (isDir) { + EALocalCodeListViewController *vc = [EALocalCodeListViewController new]; + vc.curPro = _curPro; + vc.curRepo = _curRepo; + vc.curURL = itemURL; + [self.navigationController pushViewController:vc animated:YES]; + }else{ + EALocalCodeViewController *vc = [EALocalCodeViewController new]; + vc.curPro = _curPro; + vc.curRepo = _curRepo; + vc.curURL = itemURL; + [self.navigationController pushViewController:vc animated:YES]; + } +} + +#pragma mark UISearchBarDelegate + +- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{ + [self searchFileWithStr:searchText]; +} + +- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{ + [searchBar resignFirstResponder]; + [self searchFileWithStr:searchBar.text]; +} + +- (void)searchFileWithStr:(NSString *)string{ + if ([string isEmpty]) { + [self.myTableView reloadData]; + }else{ + NSString *strippedStr = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; + if (strippedStr.length > 0) { + [self updateFilteredContentForSearchString:strippedStr]; + } + } +} + +- (void)updateFilteredContentForSearchString:(NSString *)searchString{ + self.searchedFileList = [self.fileList filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(NSURL * _Nullable evaluatedObject, NSDictionary * _Nullable bindings) { + NSString *shortPath = evaluatedObject.lastPathComponent; + return ([shortPath rangeOfString:searchString options:NSCaseInsensitiveSearch].location != NSNotFound); + }]]; + [self.myTableView reloadData]; +} + +@end diff --git a/Coding_iOS/Controllers/EALocalCodeViewController.h b/Coding_iOS/Controllers/EALocalCodeViewController.h new file mode 100644 index 000000000..c3b1db2e8 --- /dev/null +++ b/Coding_iOS/Controllers/EALocalCodeViewController.h @@ -0,0 +1,16 @@ +// +// EALocalCodeViewController.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/28. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "BaseViewController.h" +#import "Project.h" + +@interface EALocalCodeViewController : BaseViewController +@property (strong, nonatomic) Project *curPro; +@property (strong, nonatomic) GTRepository *curRepo; +@property (strong, nonatomic) NSURL *curURL; +@end diff --git a/Coding_iOS/Controllers/EALocalCodeViewController.m b/Coding_iOS/Controllers/EALocalCodeViewController.m new file mode 100644 index 000000000..4178067e3 --- /dev/null +++ b/Coding_iOS/Controllers/EALocalCodeViewController.m @@ -0,0 +1,93 @@ +// +// EALocalCodeViewController.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/28. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "EALocalCodeViewController.h" +#import "WebContentManager.h" + +@interface EALocalCodeViewController () + +@property (strong, nonatomic) UIWebView *webContentView; +@property (strong, nonatomic) UIActivityIndicatorView *activityIndicator; + +@end + +@implementation EALocalCodeViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + self.title = _curURL.lastPathComponent; + {//用webView显示内容 + _webContentView = [[UIWebView alloc] initWithFrame:self.view.bounds]; + _webContentView.delegate = self; + _webContentView.backgroundColor = [UIColor clearColor]; + _webContentView.opaque = NO; + _webContentView.scalesPageToFit = YES; + [self.view addSubview:_webContentView]; + //webview加载指示 + _activityIndicator = [[UIActivityIndicatorView alloc] + initWithActivityIndicatorStyle: + UIActivityIndicatorViewStyleGray]; + _activityIndicator.hidesWhenStopped = YES; + [_activityIndicator setCenter:CGPointMake(CGRectGetWidth(_webContentView.frame)/2, CGRectGetHeight(_webContentView.frame)/2)]; + [_webContentView addSubview:_activityIndicator]; + [_webContentView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; + } + [self loadData]; +} + +- (void)loadData{ + if ([_curURL isTextData]) { + CodeFile *file = [CodeFile codeFileWithLocalURL:_curURL]; + NSString *codeStr = [WebContentManager codePatternedWithContent:file isEdit:NO]; + [self.webContentView loadHTMLString:codeStr baseURL:nil]; + }else{ + [self.webContentView loadRequest:[NSURLRequest requestWithURL:_curURL]]; + } +} + +#pragma mark - Orientations +- (BOOL)shouldAutorotate { + return YES; +} + +- (UIInterfaceOrientationMask)supportedInterfaceOrientations{ + return UIInterfaceOrientationMaskAllButUpsideDown; +} + +#pragma mark UIWebViewDelegate +- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ + DebugLog(@"strLink=[%@]",request.URL.absoluteString); + UIViewController *vc = [BaseViewController analyseVCFromLinkStr:request.URL.absoluteString]; + if (vc) { + [self.navigationController pushViewController:vc animated:YES]; + return NO; + } + return YES; +} +- (void)webViewDidStartLoad:(UIWebView *)webView{ + [_activityIndicator startAnimating]; +} +- (void)webViewDidFinishLoad:(UIWebView *)webView{ + [_activityIndicator stopAnimating]; +} + +- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{ + [_activityIndicator stopAnimating]; + if (error.code == NSURLErrorCancelled) { + NSLog(@"Canceled request: %@", webView.request.URL); + }else if ([error.domain isEqualToString:@"WebKitErrorDomain"] && (error.code == 102 || error.code == 204)) { + NSLog(@"ignore: %@", error); + }else { + [NSObject showError:error]; + } +} + +@end diff --git a/Coding_iOS/Controllers/EAPayViewController.h b/Coding_iOS/Controllers/EAPayViewController.h new file mode 100644 index 000000000..7f654731e --- /dev/null +++ b/Coding_iOS/Controllers/EAPayViewController.h @@ -0,0 +1,18 @@ +// +// EAPayViewController.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2017/11/29. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "BaseViewController.h" +#import "ShopOrder.h" + +@interface EAPayViewController : BaseViewController + +@property (strong, nonatomic) ShopOrder *shopOrder; + +- (void)handlePayURL:(NSURL *)url; + +@end diff --git a/Coding_iOS/Controllers/EAPayViewController.m b/Coding_iOS/Controllers/EAPayViewController.m new file mode 100644 index 000000000..a5cb6d918 --- /dev/null +++ b/Coding_iOS/Controllers/EAPayViewController.m @@ -0,0 +1,111 @@ +// +// EAPayViewController.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2017/11/29. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "EAPayViewController.h" + +#import +#import +#import + +#import "Coding_NetAPIManager.h" + +@interface EAPayViewController () + +@property (assign, nonatomic) NSInteger payMethod;//0 alipay, 1 wechat +@property (strong, nonatomic) NSDictionary *payDict; + +@end + +@implementation EAPayViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view from its nib. + self.title = @"支付"; + self.payMethod = 0; +} + +- (IBAction)methodBtnClicked:(UIButton *)sender { + self.payMethod = sender.tag; + if (self.payMethod == 1 && ![self p_canOpenWeiXin]){ + [NSObject showHudTipStr:@"您还没有安装「微信」"]; + return; + } + [NSObject showHUDQueryStr:@"请稍等..."]; + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_shop_payOrder:_shopOrder.orderNo method:_payMethod == 0? @"Alipay": @"Weixin" andBlock:^(NSDictionary *payDict, NSError *error) { + [NSObject hideHUDQuery]; + weakSelf.payDict = payDict; + if (weakSelf.payMethod == 0) { + [weakSelf aliPay]; + }else{ + [weakSelf weixinPay]; + } + }]; +} + +- (void)aliPay{ + __weak typeof(self) weakSelf = self; + [[AlipaySDK defaultService] payOrder:_payDict[@"url"] fromScheme:kCodingAppScheme callback:^(NSDictionary *resultDic) { + [weakSelf handleAliResult:resultDic]; + }]; +} + +- (void)weixinPay{ + PayReq *req = [PayReq new]; + NSDictionary *resultDict = _payDict; + + req.partnerId = resultDict[@"partnerId"]; + req.prepayId = resultDict[@"prepayId"]; + req.nonceStr = resultDict[@"nonceStr"]; + req.timeStamp = [resultDict[@"timestamp"] intValue]; + req.package = resultDict[@"package"]; + req.sign = resultDict[@"sign"]; + [WXApi sendReq:req]; +} + +- (void)handleAliResult:(NSDictionary *)resultDic{ + DebugLog(@"handleAliResult: %@", resultDic); + BOOL isPaySuccess = NO; + if (_payMethod == 0) { + isPaySuccess = ([resultDic[@"resultStatus"] integerValue] == 9000); + }else{ + NSInteger resultCode = [resultDic[@"ret"] intValue]; + isPaySuccess = (resultCode == 0); + } + [NSObject showHudTipStr:isPaySuccess? @"支付成功": @"支付失败"]; + if (isPaySuccess) { + [self.navigationController popViewControllerAnimated:YES]; + } +} + +- (void)handlePayURL:(NSURL *)url{ + if (_payMethod == 0) { + __weak typeof(self) weakSelf = self; + [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) { + [weakSelf handleAliResult:resultDic]; + }]; + }else{ + [self handleAliResult:[url queryParams]]; + } +} + +#pragma mark - app url +- (BOOL)p_canOpenWeiXin{ + return [self p_canOpen:@"weixin://"]; +} + +- (BOOL)p_canOpenAlipay{ + return [self p_canOpen:@"alipay://"]; +} + +- (BOOL)p_canOpen:(NSString*)url{ + return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:url]]; +} + +@end diff --git a/Coding_iOS/Controllers/EAPayViewController.xib b/Coding_iOS/Controllers/EAPayViewController.xib new file mode 100644 index 000000000..af6d9bcd6 --- /dev/null +++ b/Coding_iOS/Controllers/EAPayViewController.xib @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Coding_iOS/Controllers/EATerminalViewController.h b/Coding_iOS/Controllers/EATerminalViewController.h new file mode 100644 index 000000000..414581582 --- /dev/null +++ b/Coding_iOS/Controllers/EATerminalViewController.h @@ -0,0 +1,33 @@ +// +// EATerminalViewController.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/1/30. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "WebViewController.h" + +@interface EATerminalViewController : WebViewController + ++ (instancetype)terminalVC; + +@end + +@interface EATerminalButton : UIButton + +@property (strong, nonatomic) NSString *name; +@property (assign, nonatomic) BOOL isChoosed; + ++ (instancetype)terminalButtonWithName:(NSString *)name; ++ (instancetype)smallTerminalButtonWithName:(NSString *)name choosed:(BOOL)isChoosed; + +@end + +@interface EATerminalPopView : UIView + +@property (assign, nonatomic) NSInteger choosedIndex; +@property (assign, nonatomic, readonly) NSArray *choosedList; +@property (copy, nonatomic) void(^choosedIndexBlock)(NSArray *choosedList); + +@end diff --git a/Coding_iOS/Controllers/EATerminalViewController.m b/Coding_iOS/Controllers/EATerminalViewController.m new file mode 100644 index 000000000..b6f056ea6 --- /dev/null +++ b/Coding_iOS/Controllers/EATerminalViewController.m @@ -0,0 +1,306 @@ +// +// EATerminalViewController.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/1/30. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "EATerminalViewController.h" + +@interface EATerminalViewController () + +@property (strong, nonatomic) UIWindow *myToolWindow; +@property (strong, nonatomic) UIView *myToolBar; +@property (strong, nonatomic) EATerminalPopView *myPopView; + +@property (strong, nonatomic) NSArray *buttonList; +@end + +@implementation EATerminalViewController + ++ (instancetype)terminalVC{ + static NSInteger index = 0; + NSURL *curUrl = [NSURL URLWithString:(index % 2 == 0)? @"http://ide.xiayule.net/login": @"http://192.168.0.212:8060/"]; + index++; + return [[self alloc] initWithURL:curUrl]; +} + +- (void)setTitle:(NSString *)title{ + [super setTitle:@"Terminal"]; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardChange:) name:UIKeyboardWillChangeFrameNotification object:nil]; + [self.navigationItem setRightBarButtonItem:nil animated:NO]; + [self updateButtonList]; +} + +- (void)viewWillAppear:(BOOL)animated{ + [super viewWillAppear:animated]; + [self.navigationController setToolbarHidden:YES animated:animated]; +} + +- (void)dealloc{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; + self.myToolWindow.hidden = YES; + self.myToolWindow = nil; + self.myToolBar = nil; + [self.myPopView removeFromSuperview]; + self.myPopView = nil; +} + +- (UIWindow *)myToolWindow{ + if (!_myToolWindow) { + _myToolWindow = ({ + UIWindow *toolWindow = [[UIWindow alloc] initWithFrame:CGRectMake(0, kScreen_Height, kScreen_Width, 44)]; + toolWindow.backgroundColor = [UIColor clearColor]; + toolWindow.windowLevel = UIWindowLevelStatusBar; + toolWindow.hidden = NO; + toolWindow; + }); + } + return _myToolWindow; +} + +- (UIView *)myToolBar{ + if (!_myToolBar) { + _myToolBar = ({ + UIView *toolBar = [[UIView alloc] initWithFrame:self.myToolWindow.bounds]; + toolBar.backgroundColor = kColorWhite; + [self.myToolWindow addSubview:toolBar]; + toolBar; + }); + } + return _myToolBar; +} + +- (EATerminalPopView *)myPopView{ + if (!_myPopView) { + _myPopView = [EATerminalPopView new]; + _myPopView.frame = CGRectMake(kScreen_Width - _myPopView.width - 5, kScreen_Height, _myPopView.width, _myPopView.height); + _myPopView.hidden = YES; + [kKeyWindow addSubview:_myPopView]; + __weak typeof(self) weakSelf = self; + _myPopView.choosedIndexBlock = ^(NSArray *choosedList) { + [weakSelf updateButtonList]; + }; + } + return _myPopView; +} + +- (void)updateButtonList{ + NSMutableArray *buttonList = @[@"esc", @"ctrl", @"alt", @"->"].mutableCopy; + [buttonList addObjectsFromArray:self.myPopView.choosedList]; + [buttonList addObject:@"..."]; + self.buttonList = buttonList.copy; +} + +- (void)setButtonList:(NSArray *)buttonList{ + _buttonList = buttonList; + NSInteger buttonCount = MAX(1, _buttonList.count); + CGFloat lineW = 1.0; + CGFloat buttonW = (kScreen_Width - lineW * (buttonCount - 1))/ buttonCount; + if (_buttonList.count == self.myToolBar.subviews.count) { + for (EATerminalButton *button in self.myToolBar.subviews) { + NSInteger index = (NSInteger)((button.x)/ (buttonW + lineW)); + button.name = _buttonList[index]; + } + }else{ + [self.myToolBar.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; + for (NSInteger index = 0; index < _buttonList.count; index++) { + EATerminalButton *button = [EATerminalButton terminalButtonWithName:_buttonList[index]]; + button.frame = CGRectMake(index * (buttonW + lineW), 0, buttonW, self.myToolBar.height); + [button addTarget:self action:@selector(terminalButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; + [self.myToolBar addSubview:button]; + } + } +} + +- (void)terminalButtonClicked:(EATerminalButton *)sender{ + DebugLog(@"%@", sender.name); + if ([sender.name isEqualToString:@"..."]) { + self.myPopView.hidden = !self.myPopView.hidden; + }else{ + + } +} + +#pragma mark - KeyBoard Notification Handlers +- (void)keyboardChange:(NSNotification*)aNotification{ + NSDictionary* userInfo = [aNotification userInfo]; + NSTimeInterval animationDuration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; + UIViewAnimationCurve animationCurve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]; + CGRect keyboardEndFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; + [UIView animateWithDuration:animationDuration delay:0.0f options:[UIView animationOptionsForCurve:animationCurve] animations:^{ + CGFloat keyboardY = keyboardEndFrame.origin.y; + CGFloat footerToolBarY = keyboardY - ((keyboardY < kScreen_Height)? CGRectGetHeight(self.myToolWindow.frame): 0); + footerToolBarY += 44;//盖住原本的那个bar + self.myToolWindow.y = footerToolBarY; + self.myPopView.y = footerToolBarY - self.myPopView.height - 5; + if (keyboardY >= kScreen_Height) { + self.myPopView.hidden = YES; + } + } completion:^(BOOL finished) { + }]; +} + +@end + +#define kEATerminalButton_SelectMark @"" + +@interface EATerminalButton () +@property (assign, nonatomic) BOOL isSmall; +@end + +@implementation EATerminalButton + + ++ (instancetype)terminalButtonWithName:(NSString *)name{ + EATerminalButton *button = [EATerminalButton new]; + button.isSmall = NO; + button.titleLabel.font = [UIFont systemFontOfSize:15]; + [button setTitleColor:kColorDark2 forState:UIControlStateNormal]; + + button.backgroundColor = [UIColor colorWithHexString:@"0xBBC2CA"]; + button.name = name; + return button; +} + ++ (instancetype)smallTerminalButtonWithName:(NSString *)name choosed:(BOOL)isChoosed{ + EATerminalButton *button = [EATerminalButton new]; + button.isSmall = YES; + button.titleLabel.font = [UIFont systemFontOfSize:12]; + [button setTitleColor:kColorDark2 forState:UIControlStateNormal]; + + button.name = name; + button.isChoosed = isChoosed; + button.enabled = [name isEqualToString:kEATerminalButton_SelectMark]; + return button; +} + ++ (NSDictionary *)p_buttonImageDict{ + return @{@"->": @"terminal_tail", + @"...": @"terminal_more", + @"U": @"▲", + @"D": @"▼", + @"L": @"◀", + @"R": @"▶", + }; +} + +- (void)setName:(NSString *)name{ + _name = name; + NSString *imageName = [self.class p_buttonImageDict][name]; + UIImage *buttonImage = [UIImage imageNamed:imageName]; + if (buttonImage) { + [self setImage:buttonImage forState:UIControlStateNormal]; + [self setTitle:nil forState:UIControlStateNormal]; + }else if (imageName){ + self.titleLabel.font = [UIFont systemFontOfSize:_isSmall? 12: 18]; + [self setImage:nil forState:UIControlStateNormal]; + [self setTitle:imageName forState:UIControlStateNormal]; + }else{ + self.titleLabel.font = [UIFont systemFontOfSize:_isSmall? 12: 15]; + [self setImage:nil forState:UIControlStateNormal]; + [self setTitle:_name forState:UIControlStateNormal]; + } +} + +- (void)setIsChoosed:(BOOL)isChoosed{ + _isChoosed = isChoosed; + if ([_name isEqualToString:kEATerminalButton_SelectMark]) { + self.backgroundColor = [UIColor clearColor]; + [self setImage:[UIImage imageNamed:_isChoosed? @"terminal_box_selected": @"terminal_box_unselected"] forState:UIControlStateNormal]; + }else{ + self.backgroundColor = _isChoosed? [UIColor colorWithHexString:@"0xA7B0BD"]: kColorWhite; + } +} + +@end + +#define kEATerminalPopView_ChoosedIndex @"EATerminalPopView_ChoosedIndex" + +@interface EATerminalPopView () + +@end + +@implementation EATerminalPopView + +- (instancetype)init +{ + self = [super init]; + if (self) { + self.backgroundColor = [UIColor colorWithHexString:@"0xD4D6DD"]; + CGFloat buttonW = 33; + CGFloat buttonH = 31; + CGFloat lineW = 2; + CGFloat paddingW = 4; + NSArray *buttonA = self.p_buttonA; + NSInteger choosedIndex = self.choosedIndex; + __weak typeof(self) weakSelf = self; + for (NSInteger row = 0; row < buttonA.count; row++) { + NSArray *buttonInRow = buttonA[row]; + for (NSInteger col = 0; col < buttonInRow.count; col++) { + EATerminalButton *button = [EATerminalButton smallTerminalButtonWithName:buttonInRow[col] choosed:(row == choosedIndex)]; + button.frame = CGRectMake(paddingW + (lineW + buttonW)* col, paddingW + (lineW + buttonH)* row, buttonW, buttonH); + [self addSubview:button]; + if ([buttonInRow[col] isEqualToString:kEATerminalButton_SelectMark]) { + [button bk_addEventHandler:^(EATerminalButton *sender) { + NSInteger rowIndex = (NSInteger)((sender.y - paddingW) / (buttonH + lineW)); + weakSelf.choosedIndex = rowIndex; + } forControlEvents:UIControlEventTouchUpInside]; + } + } + } + self.frame = CGRectMake(0, 0, paddingW * 2 - lineW + (lineW + buttonW)* [buttonA.firstObject count], paddingW * 2 - lineW + (lineW + buttonH)* buttonA.count); + + UIImageView *arrowV = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"terminal_triangle"]]; + [self addSubview:arrowV]; + [arrowV mas_makeConstraints:^(MASConstraintMaker *make) { + make.size.mas_equalTo(CGSizeMake(15, 8)); + make.top.equalTo(self.mas_bottom); + make.right.offset(-(paddingW + (buttonW - 15)/ 2)); + }]; + } + return self; +} + +- (NSArray *)p_buttonA{ + return @[@[kEATerminalButton_SelectMark, @"/", @"-", @"|", @"@"], + @[kEATerminalButton_SelectMark, @"~", @".", @":", @";"], + @[kEATerminalButton_SelectMark, @"U", @"D", @"L", @"R"]]; +} + +- (NSArray *)choosedList{ + NSMutableArray *choosedList = [self.p_buttonA[self.choosedIndex] mutableCopy]; + [choosedList removeObject:kEATerminalButton_SelectMark]; + return choosedList.copy; +} + +- (NSInteger)choosedIndex{ + NSNumber *index = [[NSUserDefaults standardUserDefaults] objectForKey:kEATerminalPopView_ChoosedIndex]; + return index? MIN(index.integerValue, self.p_buttonA.count - 1): 2; +} + +- (void)setChoosedIndex:(NSInteger)choosedIndex{ + [[NSUserDefaults standardUserDefaults] setObject:@(choosedIndex) forKey:kEATerminalPopView_ChoosedIndex]; + [[NSUserDefaults standardUserDefaults] synchronize]; + + CGFloat buttonH = 31; + CGFloat lineW = 2; + CGFloat paddingW = 4; + for (UIView *subV in self.subviews) { + if ([subV isKindOfClass:[EATerminalButton class]]) { + NSInteger buttonRow = (NSInteger)((subV.y - paddingW) / (buttonH + lineW)); + ((EATerminalButton *)subV).isChoosed = (buttonRow == choosedIndex); + } + } + if (_choosedIndexBlock) { + _choosedIndexBlock(self.choosedList); + } +} + +@end diff --git a/Coding_iOS/Controllers/EditCodeViewController.m b/Coding_iOS/Controllers/EditCodeViewController.m index a8b23cc37..07b2f017c 100644 --- a/Coding_iOS/Controllers/EditCodeViewController.m +++ b/Coding_iOS/Controllers/EditCodeViewController.m @@ -11,6 +11,7 @@ #import "WebContentManager.h" #import "EaseMarkdownTextView.h" #import "WebViewController.h" +#import "UIViewController+BackButtonHandler.h" @interface EditCodeViewController () @property (strong, nonatomic) UISegmentedControl *segmentedControl; @@ -68,6 +69,32 @@ - (void)viewDidAppear:(BOOL)animated{ // if (self.curIndex == 0 && self.editView) { // [self.editView becomeFirstResponder]; // } + //禁用屏幕左滑返回手势 + if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) { + self.navigationController.interactivePopGestureRecognizer.enabled = NO; + } +} + +- (void)viewDidDisappear:(BOOL)animated { + [super viewDidDisappear:animated]; + //开启屏幕左滑返回手势 + if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) { + self.navigationController.interactivePopGestureRecognizer.enabled = YES; + } +} + +- (BOOL)navigationShouldPopOnBackButton{ + if (![_myCodeFile.editData isEqualToString:_myCodeFile.file.data]) { + __weak typeof(self) weakSelf = self; + [[UIAlertController ea_alertViewWithTitle:@"提示" message:@"如果不保存,更改将丢失,是否确认返回?" buttonTitles:@[@"确认返回"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { + [weakSelf.navigationController popViewControllerAnimated:YES]; + } + }] show]; + return NO; + }else{ + return YES; + } } #pragma mark UISegmentedControl @@ -176,7 +203,9 @@ - (void)saveBtnClicked{ [NSObject showHudTipStr:@"文件无改动"]; return; } + [NSObject showHUDQueryStr:@"正在保存..."]; [[Coding_NetAPIManager sharedManager] request_EditCodeFile:_myCodeFile withPro:_myProject andBlock:^(id data, NSError *error) { + [NSObject hideHUDQuery]; if (data) { if (self.savedSucessBlock) { self.savedSucessBlock(); diff --git a/Coding_iOS/Controllers/EditColorViewController.m b/Coding_iOS/Controllers/EditColorViewController.m index 1ad35236c..e7c87e84c 100644 --- a/Coding_iOS/Controllers/EditColorViewController.m +++ b/Coding_iOS/Controllers/EditColorViewController.m @@ -47,6 +47,9 @@ - (void)viewDidLoad { [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); } diff --git a/Coding_iOS/Controllers/EditLabelViewController.m b/Coding_iOS/Controllers/EditLabelViewController.m index 497a10be7..64371bd04 100644 --- a/Coding_iOS/Controllers/EditLabelViewController.m +++ b/Coding_iOS/Controllers/EditLabelViewController.m @@ -67,6 +67,9 @@ - (void)viewDidLoad { [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); [self sendRequest]; @@ -220,8 +223,8 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath - (NSArray *)rightButtons { NSMutableArray *rightUtilityButtons = [NSMutableArray new]; - [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:@"0xe6e6e6"] icon:[UIImage imageNamed:@"icon_file_cell_rename"]]; - [rightUtilityButtons sw_addUtilityButtonWithColor:kColorBrandRed icon:[UIImage imageNamed:@"icon_file_cell_delete"]]; + [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:@"0xF2F4F6"] icon:[UIImage imageNamed:@"icon_file_cell_rename"]]; + [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:@"0xF66262"] icon:[UIImage imageNamed:@"icon_file_cell_delete"]]; return rightUtilityButtons; } @@ -248,7 +251,7 @@ - (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerRightUtilityBut __weak typeof(self) weakSelf = self; ProjectTag *ptLabel = [_tagList objectAtIndex:indexPath.row]; NSString *tip = [NSString stringWithFormat:@"确定要删除标签:%@?", ptLabel.name]; - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:tip buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + UIAlertController *actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:tip buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf deleteBtnClick:indexPath.row]; } diff --git a/Coding_iOS/Controllers/EditMemberTypeProjectListViewController.h b/Coding_iOS/Controllers/EditMemberTypeProjectListViewController.h new file mode 100644 index 000000000..03dd0cee1 --- /dev/null +++ b/Coding_iOS/Controllers/EditMemberTypeProjectListViewController.h @@ -0,0 +1,16 @@ +// +// EditMemberTypeProjectListViewController.h +// Coding_Enterprise_iOS +// +// Created by Easeeeeeeeee on 2017/6/6. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "BaseViewController.h" +#import "Team.h" +#import "TeamMember.h" + +@interface EditMemberTypeProjectListViewController : BaseViewController +@property (strong, nonatomic) Team *curTeam; +@property (strong, nonatomic) TeamMember *curMember; +@end diff --git a/Coding_iOS/Controllers/EditMemberTypeProjectListViewController.m b/Coding_iOS/Controllers/EditMemberTypeProjectListViewController.m new file mode 100644 index 000000000..6632f7bd1 --- /dev/null +++ b/Coding_iOS/Controllers/EditMemberTypeProjectListViewController.m @@ -0,0 +1,104 @@ +// +// EditMemberTypeProjectListViewController.m +// Coding_Enterprise_iOS +// +// Created by Easeeeeeeeee on 2017/6/6. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "EditMemberTypeProjectListViewController.h" +#import "ODRefreshControl.h" +#import "Coding_NetAPIManager.h" +#import "ProjectListCell.h" +#import "ProjectRole.h" +#import "ValueListViewController.h" + +@interface EditMemberTypeProjectListViewController () +@property (strong, nonatomic) UITableView *myTableView; +@property (strong, nonatomic) ODRefreshControl *myRefreshControl; +@property (strong, nonatomic) NSArray *dataList; +@end + +@implementation EditMemberTypeProjectListViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + self.title = @"选择项目"; + _myTableView = ({ + UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; + tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + tableView.backgroundColor = kColorTableSectionBg; + tableView.tableFooterView = [UIView new]; + tableView.delegate = self; + tableView.dataSource = self; + [tableView registerClass:[ProjectListCell class] forCellReuseIdentifier:kCellIdentifier_ProjectList]; + [self.view addSubview:tableView]; + [tableView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; + tableView; + }); + _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; + [_myRefreshControl addTarget:self action:@selector(refresh) forControlEvents:UIControlEventValueChanged]; + [self refresh]; +} + +- (void)refresh{ + if (_dataList.count <= 0) { + [self.view beginLoading]; + } + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_ProjectRoleOfUser:_curMember.user.global_key andBlock:^(id data, NSError *error) { + [weakSelf.view endLoading]; + [weakSelf.myRefreshControl endRefreshing]; + if (data) { + weakSelf.dataList = data; + [weakSelf.myTableView reloadData]; + } + }]; +} + +#pragma mark Table +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + return _dataList.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + ProjectListCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_ProjectList forIndexPath:indexPath]; + ProjectRole *curR = _dataList[indexPath.row]; + [cell setProjectRole:curR]; + cell.backgroundColor = kColorTableBG; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; + return cell; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ + return [ProjectListCell cellHeight]; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + ProjectRole *curRole = _dataList[indexPath.row]; + __weak typeof(self) weakSelf = self; + __weak typeof(curRole) weakRole = curRole; + ValueListViewController *vc = [ValueListViewController new]; + NSMutableArray *valueList = @[@"受限成员", @"普通成员", @"管理员", @"无"].mutableCopy; + NSArray *typeRawList = @[@75, @80, @90, @(-1)]; + + [vc setTitle:@"设置项目权限" valueList:valueList defaultSelectIndex:[typeRawList indexOfObject:curRole.type] type:ValueListTypeProjectMemberType selectBlock:^(NSInteger index) { + NSNumber *editType = typeRawList[index]; + if (![weakRole.type isEqualToNumber:editType]) { + [[Coding_NetAPIManager sharedManager] request_EditTypeOfUser:weakSelf.curMember.user.global_key inProjects:@[weakRole.project_id] roles:@[editType] andBlock:^(id data, NSError *error) { + if (data) { + weakRole.type = editType; + [weakSelf.myTableView reloadData]; + } + }]; + } + }]; + [self.navigationController pushViewController:vc animated:YES]; +} + + +@end diff --git a/Coding_iOS/Controllers/EditTaskViewController.m b/Coding_iOS/Controllers/EditTaskViewController.m index 432dee343..2baea7ba5 100644 --- a/Coding_iOS/Controllers/EditTaskViewController.m +++ b/Coding_iOS/Controllers/EditTaskViewController.m @@ -23,6 +23,10 @@ #import "ProjectToChooseListViewController.h" #import "EditLabelViewController.h" #import "TaskResourceReferenceViewController.h" +#import "NProjectViewController.h" +#import "FunctionTipsManager.h" +#import "MartFunctionTipView.h" +#import "RATaskBoardListListViewController.h" @interface EditTaskViewController () @property (strong, nonatomic) UITableView *myTableView; @@ -54,10 +58,7 @@ - (void)viewDidLoad _myMsgInputView = [UIMessageInputView messageInputViewWithType:UIMessageInputViewContentTypeTask]; _myMsgInputView.isAlwaysShow = YES; _myMsgInputView.delegate = self; - - [self queryToRefreshTaskDetail]; } - [self configTitle]; _myTableView = ({ UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped]; @@ -75,6 +76,9 @@ - (void)viewDidLoad [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); if (_myMsgInputView) { @@ -88,10 +92,11 @@ - (void)viewDidLoad RAC(self.navigationItem.rightBarButtonItem, enabled) = [RACSignal combineLatest:@[RACObserve(self, myCopyTask.content), RACObserve(self, myCopyTask.owner), + RACObserve(self, myCopyTask.task_board_list), RACObserve(self, myCopyTask.priority), RACObserve(self, myCopyTask.status), RACObserve(self, myCopyTask.deadline), - RACObserve(self, myCopyTask.task_description.markdown)] reduce:^id (NSString *content, User *owner, NSNumber *priority, NSNumber *status, NSString *deadline){ + RACObserve(self, myCopyTask.task_description.markdown)] reduce:^id (NSString *content, EABoardTaskList *task_board_list, User *owner, NSNumber *priority, NSNumber *status, NSString *deadline){ @strongify(self); BOOL enabled = ![self.myCopyTask isSameToTask:self.myTask]; if (self.myCopyTask.handleType > TaskHandleTypeEdit) { @@ -107,7 +112,22 @@ - (void)configTitle{ if (_myCopyTask.handleType > TaskHandleTypeEdit) { self.title = @"创建任务"; }else{ - self.title = _myTask.project.name; + UILabel *titleL = [UILabel labelWithFont:[UIFont systemFontOfSize:kNavTitleFontSize] textColor:kColorNavTitle]; + titleL.text = _myTask.project.name; + titleL.userInteractionEnabled = YES; + __weak typeof(self) weakSelf = self; + [titleL bk_whenTapped:^{ + NProjectViewController *vc = [[NProjectViewController alloc] init]; + vc.myProject = weakSelf.myTask.project; + [weakSelf.navigationController pushViewController:vc animated:YES]; + }]; + [titleL sizeToFit]; + self.navigationItem.titleView = titleL; + if ([[FunctionTipsManager shareManager] needToTip:kFunctionTipStr_TaskTitleViewTap]) { + [MartFunctionTipView showText:@"点击标题可跳转到项目首页哦" direction:AMPopTipDirectionDown bubbleOffset:0 inView:self.view fromFrame:CGRectMake(kScreen_Width/ 2, 0, 0, 0) dismissHandler:^{ + [[FunctionTipsManager shareManager] markTiped:kFunctionTipStr_TaskTitleViewTap]; + }]; + } } } @@ -128,6 +148,12 @@ - (void)viewDidAppear:(BOOL)animated{ [_myMsgInputView prepareToShow]; } [self.myTableView reloadData]; + + if (_myCopyTask.handleType == TaskHandleTypeEdit && !_myCopyTask.activityList) { + [self queryToRefreshTaskDetail]; + }else{ + [self configTitle]; + } } - (void)didReceiveMemoryWarning @@ -144,7 +170,7 @@ - (void)messageInputView:(UIMessageInputView *)inputView sendText:(NSString *)te - (void)messageInputView:(UIMessageInputView *)inputView heightToBottomChenged:(CGFloat)heightToBottom{ [UIView animateWithDuration:0.25 delay:0.0f options:UIViewAnimationOptionTransitionFlipFromBottom animations:^{ UIEdgeInsets contentInsets= UIEdgeInsetsMake(0.0, 0.0, MAX(CGRectGetHeight(inputView.frame), heightToBottom), 0.0);; - CGFloat msgInputY = kScreen_Height - heightToBottom - 64; + CGFloat msgInputY = kScreen_Height - heightToBottom - (44 + kSafeArea_Top); self.myTableView.contentInset = contentInsets; self.myTableView.scrollIndicatorInsets = contentInsets; @@ -192,13 +218,15 @@ - (void)queryToRefreshTaskDetail{ } - (void)queryToRefreshResourceReference{ - __weak typeof(self) weakSelf = self; - [[Coding_NetAPIManager sharedManager] request_TaskResourceReference:_myTask andBlock:^(id data, NSError *error) { - if (data) { - _myTask.resourceReference = data; - [weakSelf.myTableView reloadData]; - } - }]; + if (_myCopyTask.handleType == TaskHandleTypeEdit) { + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_TaskResourceReference:_myTask andBlock:^(id data, NSError *error) { + if (data) { + _myTask.resourceReference = data; + [weakSelf.myTableView reloadData]; + } + }]; + } } #pragma mark Mine M - (void)doneBtnClicked{ @@ -312,6 +340,7 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger }else if (section == 1){ TaskHandleType handleType = self.myCopyTask.handleType; row = handleType == TaskHandleTypeEdit? 5: handleType == TaskHandleTypeAddWithProject? 4: 5; + row += 1;//加一个看板项 }else if (section == 2 && _myTask.resourceReference.itemList.count > 0){ row = 1; }else{ @@ -334,7 +363,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N }; cell.deleteBtnClickedBlock = ^(Task *toDelete){ [weakSelf.view endEditing:YES]; - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"删除此任务" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + UIAlertController *actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"删除此任务" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf deleteTask:toDelete]; } @@ -362,7 +391,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N TaskDescriptionCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_TaskDescriptionCell forIndexPath:indexPath]; NSString *titleStr; if (_myCopyTask.handleType > TaskHandleTypeEdit) { - titleStr = @"添加描述"; + titleStr = _myCopyTask.has_description.boolValue? @"查看描述": @"添加描述"; }else{ titleStr = _myCopyTask.has_description.boolValue? @"查看描述": @"补充描述"; } @@ -488,6 +517,34 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath [_self.myTableView reloadData]; } cellBtnBlock:nil]; [self.navigationController pushViewController:vc animated:YES]; + }else if (cellType == LeftImage_LRTextCellTypeTaskBoardList) { + if (_myCopyTask.project == nil) { + [NSObject showHudTipStr:@"需要选定所属项目先~"]; + return; + } + RATaskBoardListListViewController *vc = [RATaskBoardListListViewController new]; + vc.curPro = _myCopyTask.project; + vc.selectedBoardTL = _myCopyTask.task_board_list; + vc.needToShowDoneBoardTL = (_myCopyTask.handleType == TaskHandleTypeEdit); + vc.selectedBlock = ^(EABoardTaskList *selectedBoardTL) { + ESStrongSelf; + if (_self.myCopyTask.handleType == TaskHandleTypeEdit) {//看板只能单项修改 + [NSObject showStatusBarQueryStr:@"正在修改看板列表"]; + [[Coding_NetAPIManager sharedManager] request_PutTask:_self.myCopyTask toBoardTaskList:selectedBoardTL andBlock:^(id data, NSError *error) { + if (data) { + [NSObject showStatusBarSuccessStr:@"看板列表已修改"]; + _self.myCopyTask.task_board_list = _self.myTask.task_board_list = selectedBoardTL; + [_self.myTableView reloadData]; + }else{ + [NSObject showStatusBarError:error]; + } + }]; + }else{ + _self.myCopyTask.task_board_list = selectedBoardTL; + [_self.myTableView reloadData]; + } + }; + [self.navigationController pushViewController:vc animated:YES]; }else if (cellType == LeftImage_LRTextCellTypeTaskPriority){ ValueListViewController *vc = [[ValueListViewController alloc] init]; [vc setTitle:@"优先级" valueList:kTaskPrioritiesDisplay defaultSelectIndex:_myCopyTask.priority.intValue type:ValueListTypeTaskPriority selectBlock:^(NSInteger index) { @@ -624,7 +681,7 @@ - (void)doCommentToComment:(TaskComment *)toComment sender:(id)sender{ if (_toComment) { if ([Login isLoginUserGlobalKey:_toComment.owner.global_key]) { __weak typeof(self) weakSelf = self; - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"删除此评论" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + UIAlertController *actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"删除此评论" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf deleteComment:weakSelf.toComment]; } diff --git a/Coding_iOS/Controllers/EditTopicViewController.m b/Coding_iOS/Controllers/EditTopicViewController.m index aa5256d7b..7e8206692 100755 --- a/Coding_iOS/Controllers/EditTopicViewController.m +++ b/Coding_iOS/Controllers/EditTopicViewController.m @@ -258,6 +258,9 @@ - (void)loadPreview tableView.dataSource = self; tableView.separatorStyle = UITableViewCellSeparatorStyleNone; [tableView registerClass:[TopicPreviewCell class] forCellReuseIdentifier:kCellIdentifier_TopicPreviewCell]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); @@ -279,7 +282,8 @@ - (void)loadPreview - (void)addtitleBtnClick { EditLabelViewController *vc = [[EditLabelViewController alloc] init]; - vc.curProject = _curProTopic.project; +// vc.curProject = _curProTopic.project; + vc.curProject = _curProTopic.project ?: ({Project *p = [Project new]; p.id = _curProTopic.project_id; p;}); vc.orignalTags = _curProTopic.mdLabels; @weakify(self); vc.tagsSelectedBlock = ^(EditLabelViewController *vc, NSMutableArray *selectedTags){ diff --git a/Coding_iOS/Controllers/FileActivitiesViewController.m b/Coding_iOS/Controllers/FileActivitiesViewController.m index 37f4483f0..725b460fb 100644 --- a/Coding_iOS/Controllers/FileActivitiesViewController.m +++ b/Coding_iOS/Controllers/FileActivitiesViewController.m @@ -14,6 +14,7 @@ #import "ODRefreshControl.h" #import "FileCommentCell.h" #import "FileActivityCell.h" +#import "AddCommentCell.h" #import "UIView+PressMenu.h" @@ -25,7 +26,7 @@ @interface FileActivitiesViewController () 0 hasError:error != nil reloadButtonBlock:^(id sender) { + [self.view configBlankPage:EaseBlankPageTypeView hasData:YES hasError:error != nil reloadButtonBlock:^(id sender) { [self refresh]; }]; }]; } #pragma mark Table M + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ + return 2; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ + return 20.0; +} + +- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{ + UIView *view = [UIView new]; + view.backgroundColor = kColorTableSectionBg; + return view; +} + - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ - return _activityList.count; + return section == 0? _activityList.count: 1; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ - ProjectActivity *curActivity = [self.activityList objectAtIndex:indexPath.row]; - if ([curActivity.target_type isEqualToString:@"ProjectFileComment"]) { - FileComment *curComment = curActivity.projectFileComment; - curComment.created_at = curActivity.created_at; - FileCommentCell *cell; - if (curComment.htmlMedia.imageItems.count > 0) { - cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_FileCommentCell_Media forIndexPath:indexPath]; + if (indexPath.section == 0) { + ProjectActivity *curActivity = [self.activityList objectAtIndex:indexPath.row]; + if ([curActivity.target_type isEqualToString:@"ProjectFileComment"]) { + FileComment *curComment = curActivity.projectFileComment; + curComment.created_at = curActivity.created_at; + FileCommentCell *cell; + if (curComment.htmlMedia.imageItems.count > 0) { + cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_FileCommentCell_Media forIndexPath:indexPath]; + }else{ + cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_FileCommentCell forIndexPath:indexPath]; + } + cell.curComment = (TaskComment *)curComment; + cell.contentLabel.delegate = self; + cell.backgroundColor = kColorTableBG; + [cell configTop:(indexPath.row == 0) andBottom:(indexPath.row == _activityList.count - 1)]; + return cell; }else{ - cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_FileCommentCell forIndexPath:indexPath]; + FileActivityCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_FileActivityCell forIndexPath:indexPath]; + cell.curActivity = curActivity; + cell.backgroundColor = kColorTableBG; + [cell configTop:(indexPath.row == 0) andBottom:(indexPath.row == _activityList.count - 1)]; + return cell; } - cell.curComment = (TaskComment *)curComment; - cell.contentLabel.delegate = self; - cell.backgroundColor = kColorTableBG; - [cell configTop:(indexPath.row == 0) andBottom:(indexPath.row == _activityList.count - 1)]; - return cell; }else{ - FileActivityCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_FileActivityCell forIndexPath:indexPath]; - cell.curActivity = curActivity; - cell.backgroundColor = kColorTableBG; - [cell configTop:(indexPath.row == 0) andBottom:(indexPath.row == _activityList.count - 1)]; + AddCommentCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_AddCommentCell forIndexPath:indexPath]; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:50]; return cell; } } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ CGFloat cellHeight = 0; - ProjectActivity *curActivity = [self.activityList objectAtIndex:indexPath.row]; - if ([curActivity.target_type isEqualToString:@"ProjectFileComment"]) { - cellHeight = [FileCommentCell cellHeightWithObj:curActivity.projectFileComment]; + if (indexPath.section == 0) { + ProjectActivity *curActivity = [self.activityList objectAtIndex:indexPath.row]; + if ([curActivity.target_type isEqualToString:@"ProjectFileComment"]) { + cellHeight = [FileCommentCell cellHeightWithObj:curActivity.projectFileComment]; + }else{ + cellHeight = [FileActivityCell cellHeightWithObj:curActivity]; + } }else{ - cellHeight = [FileActivityCell cellHeightWithObj:curActivity]; + cellHeight = [AddCommentCell cellHeight]; } return cellHeight; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ [tableView deselectRowAtIndexPath:indexPath animated:YES]; - - ProjectActivity *curActivity = [self.activityList objectAtIndex:indexPath.row]; - if (![curActivity.target_type isEqualToString:@"ProjectFileComment"]) { - return; - } - UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; - if ([cell.contentView isMenuVCVisible]) { - [cell.contentView removePressMenu]; - return; - } - NSArray *menuTitles; - if ([curActivity.projectFileComment.owner.global_key isEqualToString:[Login curLoginUser].global_key]) { - menuTitles = @[@"拷贝文字", @"删除"]; + if (indexPath.section == 0) { + ProjectActivity *curActivity = [self.activityList objectAtIndex:indexPath.row]; + if (![curActivity.target_type isEqualToString:@"ProjectFileComment"]) { + return; + } + UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; + if ([cell.contentView isMenuVCVisible]) { + [cell.contentView removePressMenu]; + return; + } + NSArray *menuTitles; + if ([curActivity.projectFileComment.owner.global_key isEqualToString:[Login curLoginUser].global_key]) { + menuTitles = @[@"拷贝文字", @"删除"]; + }else{ + menuTitles = @[@"拷贝文字", @"回复"]; + } + __weak typeof(self) weakSelf = self; + [cell.contentView showMenuTitles:menuTitles menuClickedBlock:^(NSInteger index, NSString *title) { + if ([title hasPrefix:@"拷贝"]) { + [[UIPasteboard generalPasteboard] setString:curActivity.projectFileComment.content]; + }else if ([title isEqualToString:@"删除"]){ + [weakSelf deleteCommentOfActivity:curActivity]; + }else if ([title isEqualToString:@"回复"]){ + [weakSelf goToAddCommentVCToActivity:curActivity]; + } + }]; }else{ - menuTitles = @[@"拷贝文字", @"回复"]; + [self goToAddCommentVCToActivity:nil]; } - __weak typeof(self) weakSelf = self; - [cell.contentView showMenuTitles:menuTitles menuClickedBlock:^(NSInteger index, NSString *title) { - if ([title hasPrefix:@"拷贝"]) { - [[UIPasteboard generalPasteboard] setString:curActivity.projectFileComment.content]; - }else if ([title isEqualToString:@"删除"]){ - [weakSelf deleteCommentOfActivity:curActivity]; - }else if ([title isEqualToString:@"回复"]){ - [weakSelf goToAddCommentVCToActivity:curActivity]; - } - }]; } - #pragma mark Comment - (void)goToAddCommentVCToActivity:(ProjectActivity *)curActivity{ Project *curProject; diff --git a/Coding_iOS/Controllers/FileChangeDetailViewController.m b/Coding_iOS/Controllers/FileChangeDetailViewController.m index 419867f5b..ff60f0cf0 100644 --- a/Coding_iOS/Controllers/FileChangeDetailViewController.m +++ b/Coding_iOS/Controllers/FileChangeDetailViewController.m @@ -126,7 +126,7 @@ - (void)handleURL:(NSURL *)curURL{ NSMutableDictionary *params = [self getParamsFromURLStr:curURL.absoluteString]; if ([curURL.absoluteString hasPrefix:@"coding://line_note?"]) { NSString *title = [NSString stringWithFormat:@"Line %@", params[@"line"]]; - [[UIActionSheet bk_actionSheetCustomWithTitle:title buttonTitles:@[@"添加评论"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + [[UIAlertController ea_actionSheetCustomWithTitle:title buttonTitles:@[@"添加评论"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [self goToAddCommentWithParams:params]; } @@ -134,7 +134,7 @@ - (void)handleURL:(NSURL *)curURL{ }else if ([curURL.absoluteString hasPrefix:@"coding://line_note_comment?"]){ NSString *title = [NSString stringWithFormat:@"%@ 的评论", params[@"clicked_user_name"]]; BOOL belongToSelf = [params[@"clicked_user_name"] isEqualToString:[Login curLoginUser].global_key]; - [[UIActionSheet bk_actionSheetCustomWithTitle:title buttonTitles:@[belongToSelf? @"删除": @"回复"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + [[UIAlertController ea_actionSheetCustomWithTitle:title buttonTitles:@[belongToSelf? @"删除": @"回复"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { if (belongToSelf) { [self doDeleteCommentWithParams:params]; @@ -161,8 +161,9 @@ - (NSMutableDictionary *)getParamsFromURLStr:(NSString *)urlStr{ - (void)goToAddCommentWithParams:(NSMutableDictionary *)params{ AddMDCommentViewController *vc = [AddMDCommentViewController new]; vc.curProject = _curProject; - - NSString *requestPath = [[self.linkUrlStr componentsSeparatedByString:@"/git"] firstObject]; + vc.isLineNote = YES; + + NSString *requestPath = [[self.linkUrlStr componentsSeparatedByString:@"/git/"] firstObject]; requestPath = [requestPath stringByAppendingString:@"/git/line_notes"]; vc.requestPath = requestPath; @@ -191,7 +192,7 @@ - (void)goToAddCommentWithParams:(NSMutableDictionary *)params{ } - (void)doDeleteCommentWithParams:(NSMutableDictionary *)params{ - NSString *requestPath = [[self.linkUrlStr componentsSeparatedByString:@"/git"] firstObject]; + NSString *requestPath = [[self.linkUrlStr componentsSeparatedByString:@"/git/"] firstObject]; requestPath = [requestPath stringByAppendingFormat:@"/git/line_notes/%@", params[@"clicked_line_note_id"]]; [[Coding_NetAPIManager sharedManager] request_DeleteLineNoteWithPath:requestPath andBlock:^(id data, NSError *error) { [self refresh]; diff --git a/Coding_iOS/Controllers/FileEditViewController.m b/Coding_iOS/Controllers/FileEditViewController.m index 062a60390..b0caa4131 100644 --- a/Coding_iOS/Controllers/FileEditViewController.m +++ b/Coding_iOS/Controllers/FileEditViewController.m @@ -11,6 +11,7 @@ #import "WebContentManager.h" #import "EaseMarkdownTextView.h" #import "WebViewController.h" +#import "UIViewController+BackButtonHandler.h" @interface FileEditViewController () @property (strong, nonatomic) UISegmentedControl *segmentedControl; @@ -104,6 +105,22 @@ - (void)configContent{ }]; } + +- (BOOL)navigationShouldPopOnBackButton{ + BOOL hasChanged = ![self.content ?: @"" isEqualToString:_editView.text]; + if (hasChanged) { + __weak typeof(self) weakSelf = self; + [[UIAlertController ea_alertViewWithTitle:@"提示" message:@"如果不保存,更改将丢失,是否确认返回?" buttonTitles:@[@"确认返回"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { + [weakSelf.navigationController popViewControllerAnimated:YES]; + } + }] show]; + return NO; + }else{ + return YES; + } +} + #pragma mark UISegmentedControl - (void)segmentedControlSelected:(id)sender{ UISegmentedControl *segmentedControl = (UISegmentedControl *)sender; @@ -207,7 +224,9 @@ - (void)saveBtnClicked{ if ([self fileIsMD]) { edit_content = [edit_content aliasedString]; } + [NSObject showHUDQueryStr:@"正在保存..."]; [[Coding_NetAPIManager sharedManager] request_EditFile:_curFile withContent:edit_content andBlock:^(id data, NSError *error) { + [NSObject hideHUDQuery]; if (data) { if (self.completeBlock) { self.completeBlock(data); diff --git a/Coding_iOS/Controllers/FileListViewController.h b/Coding_iOS/Controllers/FileListViewController.h deleted file mode 100755 index 08b610f69..000000000 --- a/Coding_iOS/Controllers/FileListViewController.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// FileListViewController.h -// Coding_iOS -// -// Created by Ease on 14/11/14. -// Copyright (c) 2014年 Coding. All rights reserved. -// - -#import -#import "BaseViewController.h" -#import "ProjectFolder.h" -#import "ProjectFolders.h" - -@interface FileListViewController : BaseViewController -@property (strong, nonatomic) ProjectFolders *rootFolders; -@property (strong, nonatomic) ProjectFolder *curFolder; -@property (strong, nonatomic) Project *curProject; -@end diff --git a/Coding_iOS/Controllers/FileVersionsViewController.m b/Coding_iOS/Controllers/FileVersionsViewController.m index db2d22ceb..effb06899 100644 --- a/Coding_iOS/Controllers/FileVersionsViewController.m +++ b/Coding_iOS/Controllers/FileVersionsViewController.m @@ -55,6 +55,9 @@ - (void)viewDidLoad make.edges.equalTo(self.view); }]; tableView.allowsMultipleSelectionDuringEditing = YES; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); @@ -129,9 +132,9 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath #pragma mark Edit Table - (NSArray *)rightButtonsWithObj:(NSIndexPath *)indexPath{ NSMutableArray *rightUtilityButtons = [NSMutableArray new]; - [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:@"0xe6e6e6"] icon:[UIImage imageNamed:@"icon_file_cell_rename"]]; + [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:@"0xF2F4F6"] icon:[UIImage imageNamed:@"icon_file_cell_rename"]]; if (indexPath.row != 0) {//当前版本不能删除 - [rightUtilityButtons sw_addUtilityButtonWithColor:kColorBrandRed icon:[UIImage imageNamed:@"icon_file_cell_delete"]]; + [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:@"0xF66262"] icon:[UIImage imageNamed:@"icon_file_cell_delete"]]; } return rightUtilityButtons; } @@ -184,12 +187,12 @@ - (void)doRemarkFileVersion:(FileVersion *)curVersion withRemarkStr:(NSString *) - (void)deleteFileVersion:(FileVersion *)curVersion{ __weak typeof(self) weakSelf = self; - NSURL *fileUrl = [Coding_FileManager diskDownloadUrlForKey:curVersion.storage_key]; + NSURL *fileUrl = curVersion.diskFileUrl; Coding_DownloadTask *cDownloadTask = [Coding_FileManager cDownloadTaskForKey:curVersion.storage_key]; - UIActionSheet *actionSheet; + UIAlertController *actionSheet; if (fileUrl) { - actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"只是删除本地文件还是连同服务器版本一起删除?" buttonTitles:@[@"仅删除本地文件"] destructiveTitle:@"一起删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"只是删除本地文件还是连同服务器版本一起删除?" buttonTitles:@[@"仅删除本地文件"] destructiveTitle:@"一起删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { switch (index) { case 0: [weakSelf doDeleteFileVersion:curVersion fromDisk:YES]; @@ -202,7 +205,7 @@ - (void)deleteFileVersion:(FileVersion *)curVersion{ } }]; }else if (cDownloadTask){ - actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"确定将服务器上的该版本删除?" buttonTitles:@[@"只是取消下载"] destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"确定将服务器上的该版本删除?" buttonTitles:@[@"只是取消下载"] destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { switch (index) { case 0: [weakSelf doDeleteFileVersion:curVersion fromDisk:YES]; @@ -215,7 +218,7 @@ - (void)deleteFileVersion:(FileVersion *)curVersion{ } }]; }else{ - actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"确定将服务器上的该版本删除?" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"确定将服务器上的该版本删除?" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf doDeleteFileVersion:curVersion fromDisk:NO]; } @@ -231,7 +234,7 @@ - (void)doDeleteFileVersion:(FileVersion *)curVersion fromDisk:(BOOL)fromDisk{ [Coding_FileManager cancelCDownloadTaskForKey:curVersion.storage_key]; } // 删除本地文件 - NSURL *fileUrl = [Coding_FileManager diskDownloadUrlForKey:curVersion.storage_key]; + NSURL *fileUrl = curVersion.diskFileUrl; NSString *filePath = fileUrl.path; NSFileManager *fm = [NSFileManager defaultManager]; if ([fm fileExistsAtPath:filePath]) { diff --git a/Coding_iOS/Controllers/FileViewController.h b/Coding_iOS/Controllers/FileViewController.h index 4a2bf2de4..4d7d38375 100644 --- a/Coding_iOS/Controllers/FileViewController.h +++ b/Coding_iOS/Controllers/FileViewController.h @@ -7,8 +7,6 @@ // #import #import "BaseViewController.h" -#import "ProjectFolder.h" -#import "ProjectFolders.h" #import "ProjectFile.h" #import "FileVersion.h" diff --git a/Coding_iOS/Controllers/FileViewController.m b/Coding_iOS/Controllers/FileViewController.m index cfd7090c0..b84123cd2 100644 --- a/Coding_iOS/Controllers/FileViewController.m +++ b/Coding_iOS/Controllers/FileViewController.m @@ -35,6 +35,7 @@ @interface FileViewController () 0) { - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:nil buttonTitles:@[@"保存到相册", @"用其他应用打开"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + UIAlertController *actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:nil buttonTitles:@[@"保存到相册", @"用其他应用打开"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { switch (index) { case 0: [weakSelf saveCurImg]; @@ -299,6 +291,8 @@ - (void)rightNavBtnClicked{ } - (void)goToEditFile{ + [MobClick event:kUmeng_Event_File label:@"文件_点击编辑"]; + __weak typeof(self) weakSelf = self; FileEditViewController *vc = [FileEditViewController new]; vc.curFile = _curFile; @@ -313,9 +307,9 @@ - (void)goToEditFile{ - (void)goToShareFileLink{ __weak typeof(self) weakSelf = self; - UIActionSheet *actionSheet; + UIAlertController *actionSheet; if (_curFile.share) { - actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"该链接适用于所有人,无需登录" buttonTitles:@[@"拷贝链接", @"关闭共享"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"该链接适用于所有人,无需登录" buttonTitles:@[@"拷贝链接"] destructiveTitle:@"关闭共享" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf doCopyShareUrl]; }else if (index == 1) { @@ -323,7 +317,7 @@ - (void)goToShareFileLink{ } }]; }else{ - actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"当前未开启共享,请先创建公开链接" buttonTitles:@[@"开启共享并拷贝链接"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"当前未开启共享,请先创建公开链接" buttonTitles:@[@"开启共享并拷贝链接"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf doOpenAndCopyShareUrl]; } @@ -354,7 +348,7 @@ - (void)doOpenAndCopyShareUrl{ - (void)doCloseShareUrl{ NSString *hashStr = [[_curFile.share.url componentsSeparatedByString:@"/"] lastObject]; __weak typeof(self) weakSelf = self; - [[Coding_NetAPIManager sharedManager] request_CloseShareHash:hashStr andBlock:^(id data, NSError *error) { + [[Coding_NetAPIManager sharedManager] request_CloseFileShareHash:hashStr andBlock:^(id data, NSError *error) { if (data) { weakSelf.curFile.share = nil; [NSObject showHudTipStr:@"共享链接已关闭"]; @@ -369,12 +363,12 @@ - (void)goToFileInfo{ } - (void)deleteCurFile{ - UIActionSheet *actionSheet; - NSURL *fileUrl = [_curFile hasBeenDownload]; + UIAlertController *actionSheet; + NSURL *fileUrl = [_curFile diskFileUrl]; Coding_DownloadTask *cDownloadTask = [_curFile cDownloadTask]; - + if (fileUrl) { - actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"只是删除本地文件还是连同服务器文件一起删除?" buttonTitles:@[@"仅删除本地文件"] destructiveTitle:@"一起删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"只是删除本地文件还是连同服务器文件一起删除?" buttonTitles:@[@"仅删除本地文件"] destructiveTitle:@"一起删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { switch (index) { case 0: [self doDeleteCurFile:self.curFile fromDisk:YES]; @@ -387,7 +381,7 @@ - (void)deleteCurFile{ } }]; }else if (cDownloadTask){ - actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"确定将服务器上的该文件删除?" buttonTitles:@[@"只是取消下载"] destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"确定将服务器上的该文件删除?" buttonTitles:@[@"只是取消下载"] destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { switch (index) { case 0: [self doDeleteCurFile:self.curFile fromDisk:YES]; @@ -400,7 +394,7 @@ - (void)deleteCurFile{ } }]; }else{ - actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"确定将服务器上的该文件删除?" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"确定将服务器上的该文件删除?" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [self doDeleteCurFile:self.curFile fromDisk:NO]; } @@ -416,7 +410,7 @@ - (void)doDeleteCurFile:(ProjectFile *)file fromDisk:(BOOL)fromDisk{ [Coding_FileManager cancelCDownloadTaskForKey:file.storage_key]; } // 删除本地文件 - NSURL *fileUrl = [file hasBeenDownload]; + NSURL *fileUrl = [file diskFileUrl]; NSString *filePath = fileUrl.path; NSFileManager *fm = [NSFileManager defaultManager]; if ([fm fileExistsAtPath:filePath]) { @@ -451,18 +445,18 @@ - (void)openByOtherApp{ } - (void)saveCurImg{ - SEL selectorToCall = @selector(imageWasSavedSuccessfully:didFinishSavingWithError:contextInfo:); - - UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:self.fileUrl]]; - if (!image) { - [NSObject showHudTipStr:@"提取图片失败"]; - return; - } - UIImageWriteToSavedPhotosAlbum(image, self, selectorToCall, NULL); + __weak typeof(self) weakSelf = self; + [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ + [[PHAssetCreationRequest creationRequestForAsset] addResourceWithType:PHAssetResourceTypePhoto fileURL:weakSelf.fileUrl options:nil]; + } completionHandler:^(BOOL success, NSError * _Nullable error) { + dispatch_async(dispatch_get_main_queue(), ^{ + [weakSelf saveImageHappenedError:error]; + }); + }]; } -- (void) imageWasSavedSuccessfully:(UIImage *)paramImage didFinishSavingWithError:(NSError *)paramError contextInfo:(void *)paramContextInfo{ - if (paramError == nil){ +- (void)saveImageHappenedError:(NSError *)error{ + if (error == nil){ [NSObject showHudTipStr:@"成功保存到相册"]; } else { [NSObject showHudTipStr:@"保存失败"]; @@ -511,29 +505,34 @@ - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{ #pragma mark EaseToolBarDelegate - (void)easeToolBar:(EaseToolBar *)toolBar didClickedIndex:(NSInteger)index{ - EaseToolBarItem *item = [toolBar itemOfIndex:index]; - NSString *tipStr = nil; if (index == 0) { + [MobClick event:kUmeng_Event_File label:@"文件_点击文件动态"]; + FileActivitiesViewController *vc = [FileActivitiesViewController vcWithFile:_curFile]; [self.navigationController pushViewController:vc animated:YES]; - tipStr = kFunctionTipStr_File_2V_Activity; }else if (index == 1){ + [MobClick event:kUmeng_Event_File label:@"文件_点击历史版本"]; + FileVersionsViewController *vc = [FileVersionsViewController vcWithFile:_curFile]; [self.navigationController pushViewController:vc animated:YES]; - tipStr = kFunctionTipStr_File_2V_Version; - } - if ([[FunctionTipsManager shareManager] needToTip:tipStr]) { - [[FunctionTipsManager shareManager] markTiped:tipStr]; - [item removeTipIcon]; } } #pragma mark Data Value -- (NSURL *)hasBeenDownload{ +- (BOOL)p_isTextContent{ + if ([self.fileType isEqualToString:@"md"] + || [self.fileType isEqualToString:@"html"] + || [self.fileType isEqualToString:@"txt"] + || [self.fileType isEqualToString:@"plist"]){ + return YES; + } + return NO; +} +- (NSURL *)diskFileUrl{ NSURL *fileUrl; if (self.curVersion) { - fileUrl = [self.curVersion hasBeenDownload]; + fileUrl = [self.curVersion diskFileUrl]; }else{ - fileUrl = [self.curFile hasBeenDownload]; + fileUrl = [self.curFile diskFileUrl]; } return fileUrl; } @@ -573,6 +572,50 @@ - (BOOL)fileCanEdit{ return NO; } } +#pragma mark download TextContent +- (void)p_startDownload{ + NSURL *fileUrl = _curVersion.diskFileUrl ?: _curFile.diskFileUrl; + Coding_DownloadTask *cDownloadTask = _curVersion? _curVersion.cDownloadTask : _curFile.cDownloadTask; + if (!fileUrl) { + if (cDownloadTask) {//重新开始 + if (cDownloadTask.task.state == NSURLSessionTaskStateSuspended) { + [cDownloadTask.task resume]; + } + }else{//新建下载 + if (!(_curVersion.project_id ?: _curFile.project_id)) { + [NSObject showHudTipStr:@"下载失败~"]; + }else{ + __weak typeof(self) weakSelf = self; + cDownloadTask = [[Coding_FileManager sharedManager] addDownloadTaskForObj:_curVersion ?: _curFile completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) { + [weakSelf.view endLoading]; + if (error) { + [NSObject showError:error]; + DebugLog(@"ERROR:%@", error.description); + }else{ + DebugLog(@"File downloaded to: %@", filePath); + } + }]; + } + } + self.progress = cDownloadTask.progress; + } +} + +- (void)setProgress:(NSProgress *)progress{ + _progress = progress; + __weak typeof(self) weakSelf = self; + if (_progress && _progress.fractionCompleted < 0.999) { + [self.view beginLoading]; + [[RACObserve(self, progress.fractionCompleted) takeUntil:self.rac_willDeallocSignal] subscribeNext:^(NSNumber *fractionCompleted) { + if (fractionCompleted.doubleValue > 0.999) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [weakSelf configContent]; + }); + } + }]; + } +} + @end diff --git a/Coding_iOS/Controllers/FolderToMoveViewController.h b/Coding_iOS/Controllers/FolderToMoveViewController.h index 454630a6a..56bc645ef 100755 --- a/Coding_iOS/Controllers/FolderToMoveViewController.h +++ b/Coding_iOS/Controllers/FolderToMoveViewController.h @@ -7,18 +7,14 @@ // #import "BaseViewController.h" -#import "ProjectFolder.h" -#import "ProjectFolders.h" #import "ProjectFile.h" +#import "Project.h" @interface FolderToMoveViewController : BaseViewController - -@property (strong, nonatomic) ProjectFolders *rootFolders; @property (strong, nonatomic) Project *curProject; -@property (strong, nonatomic) ProjectFolder *curFolder, *fromFolder; +@property (strong, nonatomic) ProjectFile *curFolder, *fromFolder; @property (strong, nonatomic) NSArray *toMovedIdList; @property (assign, nonatomic) BOOL isMoveFolder; - -@property (copy, nonatomic) void(^moveToFolderBlock)(ProjectFolder *curFolder, NSArray *toMovedIdList); +@property (copy, nonatomic) void(^moveToFolderBlock)(ProjectFile *curFolder, NSArray *toMovedIdList); @end diff --git a/Coding_iOS/Controllers/FolderToMoveViewController.m b/Coding_iOS/Controllers/FolderToMoveViewController.m index ed9506c3a..31d546214 100755 --- a/Coding_iOS/Controllers/FolderToMoveViewController.m +++ b/Coding_iOS/Controllers/FolderToMoveViewController.m @@ -7,13 +7,15 @@ // #import "FolderToMoveViewController.h" -#import "ProjectFolderListCell.h" +#import "FileListFolderCell.h" #import "EaseToolBar.h" #import "SettingTextViewController.h" #import "Coding_NetAPIManager.h" +#import "ODRefreshControl.h" @interface FolderToMoveViewController () @property (nonatomic, strong) UITableView *myTableView; +@property (nonatomic, strong) ODRefreshControl *refreshControl; @property (nonatomic, strong) EaseToolBar *myToolBar; @property (strong, nonatomic) NSMutableArray *dataList; @end @@ -27,10 +29,11 @@ - (void)viewDidLoad self.title = self.curFolder.name; }else if (self.curProject){ self.title = self.curProject.name; + self.curFolder = [[ProjectFile alloc] initWithFileId:@0 inProject:self.curProject.name ofUser:self.curProject.owner_user_name]; }else{ self.title = @"选择目标文件夹"; } - + [self.navigationItem setRightBarButtonItem:[UIBarButtonItem itemWithBtnTitle:@"取消" target:self action:@selector(dismissSelf)] animated:YES]; // 添加myTableView _myTableView = ({ UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; @@ -38,28 +41,40 @@ - (void)viewDidLoad tableView.dataSource = self; tableView.delegate = self; tableView.separatorStyle = UITableViewCellSeparatorStyleNone; - [tableView registerClass:[ProjectFolderListCell class] forCellReuseIdentifier:kCellIdentifier_ProjectFolderList]; + [tableView registerClass:[FileListFolderCell class] forCellReuseIdentifier:kCellIdentifier_FileListFolder]; [self.view addSubview:tableView]; [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; tableView; }); - - [self configToolBar]; - - [self.navigationItem setRightBarButtonItem:[UIBarButtonItem itemWithBtnTitle:@"取消" target:self action:@selector(dismissSelf)] animated:YES]; + _refreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; + [_refreshControl addTarget:self action:@selector(refresh) forControlEvents:UIControlEventValueChanged]; + [self refresh]; +} + +- (void)refresh{ + if (self.dataList.count <= 0) { + [self.view beginLoading]; + } + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_FoldersInFolder:_curFolder andBlock:^(id data, NSError *error) { + [weakSelf.view endLoading]; + [weakSelf.refreshControl endRefreshing]; + if (data) { + weakSelf.dataList = data; + [weakSelf.myTableView reloadData]; + [weakSelf configToolBar]; + } + }]; } - (void)configToolBar{ //添加底部ToolBar if (!_myToolBar) { //添加底部ToolBar - EaseToolBarItem *item1 = [EaseToolBarItem easeToolBarItemWithTitle:@" 新建文件夹" image:@"button_file_createFolder_enable" disableImage:@"button_file_createFolder_unable"]; - EaseToolBarItem *item2 = [EaseToolBarItem easeToolBarItemWithTitle:@" 移动到这里" image:@"button_file_move_enable" disableImage:@"button_file_move_unable"]; - item1.enabled = [self canCreatNewFolder]; - item2.enabled = [self canMovedHere]; - + EaseToolBarItem *item1 = [EaseToolBarItem easeToolBarItemWithTitle:@"新建文件夹" image:@"button_file_createFolder_enable" disableImage:@"button_file_createFolder_unable"]; + EaseToolBarItem *item2 = [EaseToolBarItem easeToolBarItemWithTitle:@"移动到这里" image:@"button_file_move_enable" disableImage:@"button_file_move_unable"]; _myToolBar = [EaseToolBar easeToolBarWithItems:@[item1, item2]]; _myToolBar.delegate = self; [self.view addSubview:_myToolBar]; @@ -67,13 +82,7 @@ - (void)configToolBar{ make.bottom.equalTo(self.view.mas_bottom); make.size.mas_equalTo(_myToolBar.frame.size); }]; - }else{ - EaseToolBarItem *item1 = [_myToolBar itemOfIndex:0]; - EaseToolBarItem *item2 = [_myToolBar itemOfIndex:1]; - item1.enabled = [self canCreatNewFolder]; - item2.enabled = [self canMovedHere]; } - UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0,CGRectGetHeight(_myToolBar.frame), 0.0); self.myTableView.contentInset = contentInsets; self.myTableView.scrollIndicatorInsets = contentInsets; @@ -84,76 +93,46 @@ - (void)dismissSelf{ [self dismissViewControllerAnimated:YES completion:nil]; } #pragma mark Data Thing -- (NSMutableArray *)dataList{ - if (!_dataList) { - if (self.curFolder) { - _dataList = _isMoveFolder? nil: self.curFolder.sub_folders; - }else{ - _dataList = _rootFolders.list.mutableCopy; - [_dataList removeObjectAtIndex:0];//移除「分享中」文件夹 - if (_isMoveFolder) { - ProjectFolder *outFolder = [ProjectFolder outFolder]; - [_dataList replaceObjectAtIndex:0 withObject:outFolder]; - } - } - if (_dataList.count > 0) { - //移除 fromFolder - ProjectFolder *folderToRemove = _fromFolder ?: [ProjectFolder defaultFolder]; - folderToRemove = [_dataList filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"file_id = %@", folderToRemove.file_id]].firstObject; + +- (void)setDataList:(NSMutableArray *)dataList{ + if (dataList.count > 0 && _isMoveFolder) { + for (NSNumber *folderId in _toMovedIdList) { + ProjectFile *folderToRemove = [dataList filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"file_id = %@", folderId]].firstObject; if (folderToRemove) { - [_dataList removeObject:folderToRemove]; - } - if (_isMoveFolder) {//移除 要移动的 Folder - for (NSNumber *folderId in _toMovedIdList) { - folderToRemove = [_dataList filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"file_id = %@", folderId]].firstObject; - if (folderToRemove) { - [_dataList removeObject:folderToRemove]; - } - } + [dataList removeObject:folderToRemove]; } } } - return _dataList; -} -- (BOOL)canMovedHere{ - return (self.curFolder != nil); -} -- (BOOL)canCreatNewFolder{ - return (self.curFolder == nil || (!_isMoveFolder && self.curFolder.parent_id.intValue == 0 && self.curFolder.file_id.intValue != 0)); + _dataList = dataList; } #pragma mark Table - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ - NSInteger row = 0; - if ([self dataList]) { - row = [[self dataList] count]; - } - return row; + return self.dataList.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ - ProjectFolderListCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_ProjectFolderList forIndexPath:indexPath]; - cell.useToMove = YES; - ProjectFolder *folder = [[self dataList] objectAtIndex:indexPath.row]; + FileListFolderCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_FileListFolder forIndexPath:indexPath]; + ProjectFile *folder = [[self dataList] objectAtIndex:indexPath.row]; cell.folder = folder; [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; return cell; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ - return [ProjectFolderListCell cellHeight]; + return [FileListFolderCell cellHeight]; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ [tableView deselectRowAtIndexPath:indexPath animated:YES]; - ProjectFolder *clickedFolder = [[self dataList] objectAtIndex:indexPath.row]; - + ProjectFile *clickedFolder = [[self dataList] objectAtIndex:indexPath.row]; + FolderToMoveViewController *vc = [[FolderToMoveViewController alloc] init]; vc.isMoveFolder = _isMoveFolder; vc.toMovedIdList = self.toMovedIdList; vc.curProject = self.curProject; - vc.rootFolders = self.rootFolders; vc.curFolder = clickedFolder; + vc.fromFolder = self.fromFolder; vc.moveToFolderBlock = self.moveToFolderBlock; [self.navigationController pushViewController:vc animated:YES]; } @@ -169,11 +148,7 @@ - (void)easeToolBar:(EaseToolBar *)toolBar didClickedIndex:(NSInteger)index{ DebugLog(@"%@", textValue); [[Coding_NetAPIManager sharedManager] request_CreatFolder:textValue inFolder:weakSelf.curFolder inProject:weakSelf.curProject andBlock:^(id data, NSError *error) { if (data) { - if (weakSelf.curFolder) { - [weakSelf.curFolder.sub_folders insertObject:data atIndex:0]; - }else{ - [weakSelf.rootFolders.list insertObject:data atIndex:1]; - } + [weakSelf.dataList insertObject:data atIndex:0]; [weakSelf.myTableView reloadData]; [NSObject showHudTipStr:@"创建文件夹成功"]; } diff --git a/Coding_iOS/Controllers/ForkTreeViewController.m b/Coding_iOS/Controllers/ForkTreeViewController.m index c878aa8e0..e8734bbcc 100644 --- a/Coding_iOS/Controllers/ForkTreeViewController.m +++ b/Coding_iOS/Controllers/ForkTreeViewController.m @@ -37,6 +37,9 @@ - (void)viewDidLoad{ [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; diff --git a/Coding_iOS/Controllers/HelpViewController.m b/Coding_iOS/Controllers/HelpViewController.m index 7555cf570..a84be74d4 100644 --- a/Coding_iOS/Controllers/HelpViewController.m +++ b/Coding_iOS/Controllers/HelpViewController.m @@ -12,7 +12,12 @@ @implementation HelpViewController + (instancetype)vcWithHelpStr{ - NSString *curUrlStr = @"/help/doc/mobile/index.html"; + NSString *curUrlStr; + if (kTarget_Enterprise) { + curUrlStr = @"help"; + }else{ + curUrlStr = @"/help/doc/mobile"; + } NSURL *curUrl = [NSURL URLWithString:curUrlStr relativeToURL:[NSURL URLWithString:[NSObject baseURLStr]]]; return [[self alloc] initWithURL:curUrl]; } @@ -23,8 +28,9 @@ - (void)setTitle:(NSString *)title{ - (void)viewDidLoad{ [super viewDidLoad]; - - [self.navigationItem setRightBarButtonItem:[[UIBarButtonItem alloc] initWithTitle:@"反馈" style:UIBarButtonItemStylePlain target:self action:@selector(goToFeedBack)] animated:YES]; + if (!kTarget_Enterprise) { + [self.navigationItem setRightBarButtonItem:[[UIBarButtonItem alloc] initWithTitle:@"反馈" style:UIBarButtonItemStylePlain target:self action:@selector(goToFeedBack)] animated:YES]; + } } - (void)goToFeedBack{ diff --git a/Coding_iOS/Controllers/LikersViewController.m b/Coding_iOS/Controllers/LikersViewController.m index 71669d0ee..7c37c1654 100755 --- a/Coding_iOS/Controllers/LikersViewController.m +++ b/Coding_iOS/Controllers/LikersViewController.m @@ -52,6 +52,9 @@ - (void)viewDidLoad [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); @@ -125,9 +128,15 @@ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPa - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ [tableView deselectRowAtIndexPath:indexPath animated:YES]; User *user = [_like_reward_users objectAtIndex:indexPath.row]; - UserInfoViewController *vc = [[UserInfoViewController alloc] init]; - vc.curUser = user; - [self.navigationController pushViewController:vc animated:YES]; + if (kTarget_Enterprise) { + UserInfoDetailViewController *vc = [[UserInfoDetailViewController alloc] init]; + vc.curUser = user; + [self.navigationController pushViewController:vc animated:YES]; + }else{ + UserInfoViewController *vc = [[UserInfoViewController alloc] init]; + vc.curUser = user; + [self.navigationController pushViewController:vc animated:YES]; + } } - (void)dealloc diff --git a/Coding_iOS/Controllers/LocalFilesViewController.m b/Coding_iOS/Controllers/LocalFilesViewController.m index deb42158c..111c2c726 100644 --- a/Coding_iOS/Controllers/LocalFilesViewController.m +++ b/Coding_iOS/Controllers/LocalFilesViewController.m @@ -36,6 +36,9 @@ - (void)viewDidLoad{ make.edges.equalTo(self.view); }]; tableView.allowsMultipleSelectionDuringEditing = YES; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); [self changeEditStateToEditing:NO]; @@ -86,7 +89,7 @@ - (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerRightUtilityBut NSIndexPath *indexPath = [self.myTableView indexPathForCell:cell]; NSURL *fileUrl = self.fileList[indexPath.row]; __weak typeof(self) weakSelf = self; - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"确定要删除本地文件吗?" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + UIAlertController *actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"确定要删除本地文件吗?" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf deleteFilesWithUrlList:@[fileUrl]]; } @@ -99,16 +102,18 @@ - (void)changeEditStateToEditing:(BOOL)isEditing{ [_myTableView setEditing:isEditing animated:YES]; NSArray *rightBarButtonItems; if (isEditing) { - UIBarButtonItem *item1 = [UIBarButtonItem itemWithBtnTitle:@"完成" target:self action:@selector(changeEditState)]; - UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; - spaceItem.width = 20; - UIBarButtonItem *item2 = [UIBarButtonItem itemWithBtnTitle:@"反选" target:self action:@selector(reverseSelect)]; - rightBarButtonItems = @[item1, spaceItem, item2]; +// UIBarButtonItem *item1 = [UIBarButtonItem itemWithBtnTitle:@"完成" target:self action:@selector(changeEditState)]; +// UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; +// spaceItem.width = 20; +// UIBarButtonItem *item2 = [UIBarButtonItem itemWithBtnTitle:@"反选" target:self action:@selector(reverseSelect)]; +// rightBarButtonItems = @[item1, spaceItem, item2]; + UIBarButtonItem *item1 = [UIBarButtonItem itemWithBtnTitle:@"取消" target:self action:@selector(changeEditState)]; + rightBarButtonItems = @[item1]; }else{ UIBarButtonItem *item1 = [UIBarButtonItem itemWithBtnTitle:@"编辑" target:self action:@selector(changeEditState)]; rightBarButtonItems = @[item1]; } - [self.navigationItem setRightBarButtonItems:rightBarButtonItems animated:YES]; + [self.navigationItem setRightBarButtonItems:_fileList.count > 0? rightBarButtonItems: nil animated:YES]; [self configToolBar]; [self.myTableView performSelector:@selector(reloadData) withObject:nil afterDelay:0.3]; } @@ -138,7 +143,7 @@ - (void)reverseSelect{ - (void)configToolBar{ //添加底部ToolBar if (!_myEditToolBar) { - EaseToolBarItem *item = [EaseToolBarItem easeToolBarItemWithTitle:@" 删除" image:@"button_file_denete_enable" disableImage:nil]; + EaseToolBarItem *item = [EaseToolBarItem easeToolBarItemWithTitle:@"删除" image:@"button_file_denete_enable" disableImage:nil]; _myEditToolBar = [EaseToolBar easeToolBarWithItems:@[item]]; _myEditToolBar.delegate = self; [self.view addSubview:_myEditToolBar]; @@ -161,7 +166,7 @@ - (void)easeToolBar:(EaseToolBar *)toolBar didClickedIndex:(NSInteger)index{ if (toolBar == _myEditToolBar) { if (index == 0) { __weak typeof(self) weakSelf = self; - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"确定要删除选中的本地文件吗?" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + UIAlertController *actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"确定要删除选中的本地文件吗?" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf deleteSelectedFiles]; } diff --git a/Coding_iOS/Controllers/LocalFoldersViewController.m b/Coding_iOS/Controllers/LocalFoldersViewController.m index 9d33be5a5..42531954c 100644 --- a/Coding_iOS/Controllers/LocalFoldersViewController.m +++ b/Coding_iOS/Controllers/LocalFoldersViewController.m @@ -44,6 +44,9 @@ - (void)viewDidLoad{ make.edges.equalTo(self.view); }]; tableView.allowsMultipleSelectionDuringEditing = YES; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; @@ -58,7 +61,7 @@ - (void)viewWillAppear:(BOOL)animated{ - (void)refresh{ BOOL hasData = [self findLocalFile]; - [self.view configBlankPage:EaseBlankPageTypeView hasData:hasData hasError:NO reloadButtonBlock:nil]; + [self.view configBlankPage:EaseBlankPageTypeFile hasData:hasData hasError:NO reloadButtonBlock:nil]; if (!hasData) { [self.myRefreshControl endRefreshing]; return; @@ -112,6 +115,7 @@ - (BOOL)findLocalFile{ } } [self.myTableView reloadData]; + [self changeEditStateToEditing:self.myTableView.isEditing]; return localFileUrlList.count > 0; } @@ -181,7 +185,7 @@ - (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerRightUtilityBut NSString *projectId = _projectId_list[indexPath.row]; __weak typeof(self) weakSelf = self; - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"确定要删除该文件夹内所有本地文件吗?" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + UIAlertController *actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"确定要删除该文件夹内所有本地文件吗?" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf deleteFilesWithProjectIdList:@[projectId]]; } @@ -194,16 +198,18 @@ - (void)changeEditStateToEditing:(BOOL)isEditing{ [_myTableView setEditing:isEditing animated:YES]; NSArray *rightBarButtonItems; if (isEditing) { - UIBarButtonItem *item1 = [UIBarButtonItem itemWithBtnTitle:@"完成" target:self action:@selector(changeEditState)]; - UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; - spaceItem.width = 20; - UIBarButtonItem *item2 = [UIBarButtonItem itemWithBtnTitle:@"反选" target:self action:@selector(reverseSelect)]; - rightBarButtonItems = @[item1, spaceItem, item2]; +// UIBarButtonItem *item1 = [UIBarButtonItem itemWithBtnTitle:@"完成" target:self action:@selector(changeEditState)]; +// UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; +// spaceItem.width = 20; +// UIBarButtonItem *item2 = [UIBarButtonItem itemWithBtnTitle:@"反选" target:self action:@selector(reverseSelect)]; +// rightBarButtonItems = @[item1, spaceItem, item2]; + UIBarButtonItem *item1 = [UIBarButtonItem itemWithBtnTitle:@"取消" target:self action:@selector(changeEditState)]; + rightBarButtonItems = @[item1]; }else{ UIBarButtonItem *item1 = [UIBarButtonItem itemWithBtnTitle:@"编辑" target:self action:@selector(changeEditState)]; rightBarButtonItems = @[item1]; } - [self.navigationItem setRightBarButtonItems:rightBarButtonItems animated:YES]; + [self.navigationItem setRightBarButtonItems:_projectId_list.count > 0? rightBarButtonItems: nil animated:YES]; [self configToolBar]; [self.myTableView performSelector:@selector(reloadData) withObject:nil afterDelay:0.3]; } @@ -233,7 +239,7 @@ - (void)reverseSelect{ - (void)configToolBar{ //添加底部ToolBar if (!_myEditToolBar) { - EaseToolBarItem *item = [EaseToolBarItem easeToolBarItemWithTitle:@" 删除" image:@"button_file_denete_enable" disableImage:nil]; + EaseToolBarItem *item = [EaseToolBarItem easeToolBarItemWithTitle:@"删除" image:@"button_file_denete_enable" disableImage:nil]; _myEditToolBar = [EaseToolBar easeToolBarWithItems:@[item]]; _myEditToolBar.delegate = self; [self.view addSubview:_myEditToolBar]; @@ -256,7 +262,7 @@ - (void)easeToolBar:(EaseToolBar *)toolBar didClickedIndex:(NSInteger)index{ if (toolBar == _myEditToolBar) { if (index == 0) { __weak typeof(self) weakSelf = self; - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"确定要删除选中文件夹内所有本地文件吗?" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + UIAlertController *actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"确定要删除选中文件夹内所有本地文件吗?" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf deleteSelectedFolders]; } diff --git a/Coding_iOS/Controllers/Login/ActivateViewController.m b/Coding_iOS/Controllers/Login/ActivateViewController.m index 990125505..73ef0d114 100644 --- a/Coding_iOS/Controllers/Login/ActivateViewController.m +++ b/Coding_iOS/Controllers/Login/ActivateViewController.m @@ -36,6 +36,9 @@ - (void)viewDidLoad { [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); self.myTableView.tableHeaderView = [self customHeaderView]; @@ -55,7 +58,7 @@ - (UIView *)customHeaderView{ headerLabel.textColor = kColor999; headerLabel.numberOfLines = 0; headerLabel.textAlignment = NSTextAlignmentCenter; - headerLabel.text = @"您还未设置过用户名(个性后缀)\n设置后才能正常登录!"; + headerLabel.text = @"您还未设置过用户名\n设置后才能正常登录!"; [headerLabel setCenter:headerV.center]; [headerV addSubview:headerLabel]; return headerV; @@ -89,7 +92,7 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ Input_OnlyText_Cell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_Input_OnlyText_Cell_Text forIndexPath:indexPath]; __weak typeof(self) weakSelf = self; - [cell setPlaceholder:@" 用户名(个性后缀)" value:self.global_key]; + [cell setPlaceholder:@" 用户名" value:self.global_key]; cell.textValueChangedBlock = ^(NSString *valueStr){ weakSelf.global_key = valueStr; }; @@ -98,6 +101,6 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ - return 44.0; + return 50; } @end diff --git a/Coding_iOS/Controllers/Login/CannotLoginViewController.m b/Coding_iOS/Controllers/Login/CannotLoginViewController.m index cecc8d4c0..d92cb8d67 100644 --- a/Coding_iOS/Controllers/Login/CannotLoginViewController.m +++ b/Coding_iOS/Controllers/Login/CannotLoginViewController.m @@ -10,13 +10,15 @@ #import "TPKeyboardAvoidingTableView.h" #import "Input_OnlyText_Cell.h" +#ifdef Target_Enterprise + @interface CannotLoginViewController () @property (nonatomic, assign) CannotLoginMethodType medthodType; @property (nonatomic, assign) NSUInteger stepIndex; @property (strong, nonatomic) NSString *userStr, *phoneCode, *password, *confirm_password, *j_captcha; @property (strong, nonatomic) TPKeyboardAvoidingTableView *myTableView; -@property (strong, nonatomic) UIButton *footerBtn; +@property (strong, nonatomic) UIButton *footerBtn, *backBtn; @property (strong, nonatomic) NSString *phoneCodeCellIdentifier; @end @@ -42,7 +44,7 @@ - (void)viewDidLoad [tableView registerClass:[Input_OnlyText_Cell class] forCellReuseIdentifier:kCellIdentifier_Input_OnlyText_Cell_Text]; [tableView registerClass:[Input_OnlyText_Cell class] forCellReuseIdentifier:kCellIdentifier_Input_OnlyText_Cell_Captcha]; [tableView registerClass:[Input_OnlyText_Cell class] forCellReuseIdentifier:self.phoneCodeCellIdentifier]; - tableView.backgroundColor = kColorTableSectionBg; + tableView.backgroundColor = [UIColor whiteColor]; tableView.dataSource = self; tableView.delegate = self; tableView.separatorStyle = UITableViewCellSeparatorStyleNone; @@ -54,8 +56,20 @@ - (void)viewDidLoad }); self.myTableView.tableFooterView=[self customFooterView]; self.myTableView.tableHeaderView = [self customHeaderView]; - - [self addChangeBaseURLGesture]; + [self setupBackBtn]; +} + +- (void)setupBackBtn{ + if (!_backBtn) { + _backBtn = ({ + UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, kSafeArea_Top, 44, 44)]; + button.tintColor = kColorLightBlue; + [button setImage:[[UIImage imageNamed:@"back_green_Nav"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal]; + [button addTarget:self.navigationController action:@selector(popViewControllerAnimated:) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:button]; + button; + }); + } } - (void)viewWillDisappear:(BOOL)animated{ @@ -63,55 +77,42 @@ - (void)viewWillDisappear:(BOOL)animated{ [self.view endEditing:YES]; } -- (void)addChangeBaseURLGesture{ - @weakify(self); - UITapGestureRecognizer *tapGR = [UITapGestureRecognizer bk_recognizerWithHandler:^(UIGestureRecognizer *sender, UIGestureRecognizerState state, CGPoint location) { - @strongify(self); - if (state == UIGestureRecognizerStateRecognized) { - [self changeBaseURLTip]; - } - }]; - tapGR.numberOfTapsRequired = 10.0; - [self.view addGestureRecognizer:tapGR]; -} - -- (void)changeBaseURLTip{ - if ([UIDevice currentDevice].systemVersion.integerValue < 8) { - [NSObject showHudTipStr:@"需要 8.0 以上系统才能切换服务器地址"]; - return; - } - UIAlertController *alertCtrl = [UIAlertController alertControllerWithTitle:@"更改服务器 URL" message:@"空白值可切换回生产环境\n(地址末尾务必加上「/」)" preferredStyle:UIAlertControllerStyleAlert]; - - UIAlertAction *cancelA = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]; - UIAlertAction *confirmA = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) { - [NSObject changeBaseURLStrTo:alertCtrl.textFields[0].text]; - }]; - [alertCtrl addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { - textField.placeholder = @"Coding 服务器地址"; - textField.text = [NSObject baseURLStr]; - }]; - [alertCtrl addAction:cancelA]; - [alertCtrl addAction:confirmA]; - [self presentViewController:alertCtrl animated:YES completion:nil]; - -} - - (void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; - [self.navigationController setNavigationBarHidden:NO animated:YES]; } #pragma mark - Table view Header Footer - (UIView *)customHeaderView{ - UIView *headerV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 60)]; - headerV.backgroundColor = [UIColor clearColor]; + UIView *headerV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 44 + 60)]; + + UILabel *headerL = [UILabel labelWithSystemFontSize:28 textColorHexString:@"0x272C33"]; + headerL.text = @"找回密码"; + [headerV addSubview:headerL]; + [headerL mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(headerV).offset(20); + make.bottom.equalTo(headerV); + make.height.mas_equalTo(40); + }]; return headerV; } - (UIView *)customFooterView{ UIView *footerV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 150)]; - _footerBtn = [UIButton buttonWithStyle:StrapSuccessStyle andTitle:[self footerBtnTitle] andFrame:CGRectMake(kLoginPaddingLeftWidth, 20, kScreen_Width-kLoginPaddingLeftWidth*2, 45) target:self action:@selector(footerBtnClicked:)]; - [footerV addSubview:_footerBtn]; + _footerBtn = ({ + UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(kLoginPaddingLeftWidth, 25, kScreen_Width-kLoginPaddingLeftWidth*2, 50)]; + button.backgroundColor = kColorDark4; + button.titleLabel.font = [UIFont systemFontOfSize:17 weight:UIFontWeightMedium]; + [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [button setTitle:[self footerBtnTitle] forState:UIControlStateNormal]; + button.layer.masksToBounds = YES; + button.layer.cornerRadius = 2.0; + [button addTarget:self action:@selector(footerBtnClicked:) forControlEvents:UIControlEventTouchUpInside]; + button; + }); + [footerV addSubview:_footerBtn]; + [RACObserve(self, footerBtn.enabled) subscribeNext:^(NSNumber *x) { + [self.footerBtn setTitleColor:[UIColor colorWithWhite:1.0 alpha:x.boolValue? 1.0: .5] forState:UIControlStateNormal]; + }]; if (_stepIndex == 0) { RAC(self, footerBtn.enabled) = [RACSignal combineLatest:@[RACObserve(self, userStr)] reduce:^id(NSString *userStr){ @@ -167,7 +168,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } } Input_OnlyText_Cell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath]; - + cell.isBottomLineShow = YES; __weak typeof(self) weakSelf = self; if (indexPath.row == 0) { [cell setPlaceholder:(_stepIndex == 0? @" 手机/邮箱": _medthodType == CannotLoginMethodPhone? @" 手机号": @" 邮箱") value:self.userStr]; @@ -196,7 +197,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N weakSelf.phoneCode = valueStr; }; cell.phoneCodeBtnClckedBlock = ^(PhoneCodeButton *btn){ - [weakSelf phoneCodeBtnClicked:btn]; + [weakSelf phoneCodeBtnClicked:btn withCaptcha:nil]; }; } }else{ @@ -207,31 +208,90 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } } - [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kLoginPaddingLeftWidth]; return cell; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ - return 44.0; + return 65.0; } #pragma mark Btn Clicked -- (void)phoneCodeBtnClicked:(PhoneCodeButton *)sender{ +- (void)phoneCodeBtnClicked:(PhoneCodeButton *)sender withCaptcha:(NSString *)captcha{ if (![_userStr isPhoneNo]) { [NSObject showHudTipStr:@"手机号码格式有误"]; return; } sender.enabled = NO; - [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:@"api/account/password/forget" withParams:@{@"account": _userStr} withMethodType:Post andBlock:^(id data, NSError *error) { + NSMutableDictionary *params = @{@"account": _userStr, + @"phoneCountryCode": @"+86"}.mutableCopy; + if (captcha.length > 0) { + params[@"j_captcha"] = captcha; + } + __weak typeof(self) weakSelf = self; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:@"api/account/password/forget" withParams:params withMethodType:Post autoShowError:captcha.length > 0 andBlock:^(id data, NSError *error) { if (data) { [NSObject showHudTipStr:@"验证码发送成功"]; [sender startUpTimer]; }else{ [sender invalidateTimer]; + if (error && error.userInfo[@"msg"] && [[error.userInfo[@"msg"] allKeys] containsObject:@"j_captcha_error"]) { + [weakSelf p_showCaptchaAlert:sender]; + }else if (captcha.length <= 0){ + [NSObject showError:error]; + } + } + }]; +} + +- (void)p_showCaptchaAlert:(PhoneCodeButton *)sender{ + SDCAlertController *alertV = [SDCAlertController alertControllerWithTitle:@"提示" message:@"请输入图片验证码" preferredStyle:SDCAlertControllerStyleAlert]; + UITextField *textF = [UITextField new]; + textF.layer.sublayerTransform = CATransform3DMakeTranslation(5, 0, 0); + textF.backgroundColor = [UIColor whiteColor]; + [textF doBorderWidth:0.5 color:nil cornerRadius:2.0]; + UIImageView *imageV = [YLImageView new]; + imageV.backgroundColor = [UIColor lightGrayColor]; + imageV.contentMode = UIViewContentModeScaleAspectFit; + imageV.clipsToBounds = YES; + imageV.userInteractionEnabled = YES; + [textF doBorderWidth:0.5 color:nil cornerRadius:2.0]; + NSURL *imageURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@api/getCaptcha", [NSObject baseURLStr]]]; + [imageV sd_setImageWithURL:imageURL placeholderImage:nil options:(SDWebImageRetryFailed | SDWebImageRefreshCached | SDWebImageHandleCookies)]; + + [alertV.contentView addSubview:textF]; + [alertV.contentView addSubview:imageV]; + [textF mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(alertV.contentView).offset(15); + make.height.mas_equalTo(25); + make.bottom.equalTo(alertV.contentView).offset(-10); + }]; + [imageV mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.equalTo(alertV.contentView).offset(-15); + make.left.equalTo(textF.mas_right).offset(10); + make.width.mas_equalTo(60); + make.height.mas_equalTo(25); + make.centerY.equalTo(textF); + }]; + //Action + __weak typeof(imageV) weakImageV = imageV; + [imageV bk_whenTapped:^{ + [weakImageV sd_setImageWithURL:imageURL placeholderImage:nil options:(SDWebImageRetryFailed | SDWebImageRefreshCached | SDWebImageHandleCookies)]; + }]; + __weak typeof(self) weakSelf = self; + [alertV addAction:[SDCAlertAction actionWithTitle:@"取消" style:SDCAlertActionStyleCancel handler:nil]]; + [alertV addAction:[SDCAlertAction actionWithTitle:@"确定" style:SDCAlertActionStyleDefault handler:nil]]; + alertV.shouldDismissBlock = ^BOOL (SDCAlertAction *action){ + if (![action.title isEqualToString:@"取消"]) { + [weakSelf phoneCodeBtnClicked:sender withCaptcha:textF.text]; } + return YES; + }; + [alertV presentWithCompletion:^{ + [textF becomeFirstResponder]; }]; } + - (void)footerBtnClicked:(id)sender{ if (_stepIndex == 0) { CannotLoginViewController *vc = [CannotLoginViewController vcWithMethodType:[_userStr isPhoneNo]? CannotLoginMethodPhone: CannotLoginMethodEamil stepIndex:1 userStr:_userStr]; @@ -269,3 +329,394 @@ - (void)footerBtnClicked:(id)sender{ } @end + +#else + +@interface CannotLoginViewController () +@property (nonatomic, assign) CannotLoginMethodType medthodType; +@property (nonatomic, assign) NSUInteger stepIndex; +@property (strong, nonatomic) NSString *userStr, *phoneCode, *password, *confirm_password, *j_captcha; + +@property (strong, nonatomic) TPKeyboardAvoidingTableView *myTableView; +@property (strong, nonatomic) UIButton *footerBtn; +@property (strong, nonatomic) NSString *phoneCodeCellIdentifier; +@end + +@implementation CannotLoginViewController ++ (instancetype)vcWithMethodType:(CannotLoginMethodType)methodType stepIndex:(NSUInteger)stepIndex userStr:(NSString *)userStr{ + CannotLoginViewController *vc = [self new]; + vc.medthodType = methodType; + vc.stepIndex = stepIndex; + vc.userStr = userStr; + return vc; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + self.phoneCodeCellIdentifier = [Input_OnlyText_Cell randomCellIdentifierOfPhoneCodeType]; + if ([Login isLogin] && self.userStr.length <= 0) { + self.userStr = (self.medthodType == CannotLoginMethodEamil? [Login curLoginUser].email: [Login curLoginUser].phone); + } + + // 添加myTableView + _myTableView = ({ + TPKeyboardAvoidingTableView *tableView = [[TPKeyboardAvoidingTableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; + tableView.backgroundColor = [Login isLogin]? kColorTableSectionBg: kColorWhite; + [tableView registerClass:[Input_OnlyText_Cell class] forCellReuseIdentifier:kCellIdentifier_Input_OnlyText_Cell_Text]; + [tableView registerClass:[Input_OnlyText_Cell class] forCellReuseIdentifier:kCellIdentifier_Input_OnlyText_Cell_Captcha]; + [tableView registerClass:[Input_OnlyText_Cell class] forCellReuseIdentifier:self.phoneCodeCellIdentifier]; + tableView.dataSource = self; + tableView.delegate = self; + tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + [self.view addSubview:tableView]; + [tableView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; + tableView; + }); + self.myTableView.tableFooterView=[self customFooterView]; + self.myTableView.tableHeaderView = [self customHeaderView]; + + [self addChangeBaseURLGesture]; +} + +- (void)viewWillDisappear:(BOOL)animated{ + [super viewWillDisappear:animated]; + [self.view endEditing:YES]; +} + +- (void)addChangeBaseURLGesture{ + @weakify(self); + UITapGestureRecognizer *tapGR = [UITapGestureRecognizer bk_recognizerWithHandler:^(UIGestureRecognizer *sender, UIGestureRecognizerState state, CGPoint location) { + @strongify(self); + if (state == UIGestureRecognizerStateRecognized) { + [self changeBaseURLTip]; + } + }]; + tapGR.numberOfTapsRequired = 10.0; + [self.view addGestureRecognizer:tapGR]; +} + +- (void)changeBaseURLTip{ + if ([UIDevice currentDevice].systemVersion.integerValue < 8) { + [NSObject showHudTipStr:@"需要 8.0 以上系统才能切换服务器地址"]; + return; + } + UIAlertController *alertCtrl = [UIAlertController alertControllerWithTitle:@"更改服务器 URL" message:@"空白值可切换回生产环境\n" preferredStyle:UIAlertControllerStyleAlert]; + + UIAlertAction *cancelA = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]; + UIAlertAction *confirmA = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) { + NSString *newBaseURLStr = alertCtrl.textFields[0].text; + if ([newBaseURLStr.uppercaseString isEqualToString:@"S"]) { + newBaseURLStr = @"http://coding.codingprod.net/"; + }else if ([newBaseURLStr.uppercaseString isEqualToString:@"T"]){ + newBaseURLStr = @"http://coding.t.codingprod.net/"; + } + [NSObject changeBaseURLStrTo:newBaseURLStr]; + }]; + [alertCtrl addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { + textField.placeholder = @"CODING 服务器地址"; + textField.text = [NSObject baseURLStr]; + }]; + [alertCtrl addAction:cancelA]; + [alertCtrl addAction:confirmA]; + [self presentViewController:alertCtrl animated:YES completion:nil]; + +} + +- (void)viewWillAppear:(BOOL)animated{ + [super viewWillAppear:animated]; + [self.navigationController setNavigationBarHidden:NO animated:YES]; +} + +#pragma mark - Table view Header Footer +- (UIView *)customHeaderView{ + UIView *headerV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, [Login isLogin]? 20: 60)]; + if (![Login isLogin]) { + self.title = nil; + UILabel *headerL = [UILabel labelWithFont:[UIFont systemFontOfSize:30] textColor:kColorDark2]; + headerL.text = [self p_titleStr]; + [headerV addSubview:headerL]; + [headerL mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.offset(kPaddingLeftWidth); + make.bottom.offset(0); + make.height.mas_equalTo(42); + }]; + }else{ + self.title = [self p_titleStr]; + } + return headerV; +} + +- (NSString *)p_titleStr{ + return self.medthodType == CannotLoginMethodEamil? @"重置密码": self.stepIndex > 0? @"重置密码": @"找回密码"; +} + +- (UIView *)customFooterView{ + UIView *footerV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 150)]; + _footerBtn = [UIButton buttonWithStyle:StrapSuccessStyle andTitle:[self footerBtnTitle] andFrame:CGRectMake(kLoginPaddingLeftWidth, 20, kScreen_Width-kLoginPaddingLeftWidth*2, [Login isLogin]? 45: 50) target:self action:@selector(footerBtnClicked:)]; + [footerV addSubview:_footerBtn]; + + if (_medthodType == CannotLoginMethodEamil) { + RAC(self, footerBtn.enabled) = [RACSignal combineLatest:@[RACObserve(self, userStr), + RACObserve(self, j_captcha)] + reduce:^id(NSString *userStr, NSString *j_captcha){ + return @([userStr isEmail] && j_captcha.length > 0); + }]; + }else{ + if (_stepIndex == 0) { + RAC(self, footerBtn.enabled) = [RACSignal combineLatest:@[RACObserve(self, userStr), + RACObserve(self, phoneCode)] + reduce:^id(NSString *userStr, NSString *phoneCode){ + return @([userStr isPhoneNo] && phoneCode.length > 0); + }]; + }else{ + RAC(self, footerBtn.enabled) = [RACSignal combineLatest:@[RACObserve(self, userStr), + RACObserve(self, phoneCode), + RACObserve(self, password), + RACObserve(self, confirm_password)] + reduce:^id(NSString *userStr, NSString *phoneCode, NSString *password, NSString *confirm_password){ + return @([userStr isPhoneNo] && phoneCode.length > 0 && password.length > 0 && confirm_password.length > 0); + }]; + } + } + if (_medthodType == CannotLoginMethodPhone && _stepIndex <= 0 && + (![Login isLogin] || [Login curLoginUser].email.length > 0)) { + UIButton *emailBtn = ({ + UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 120, 30)]; + [button.titleLabel setFont:[UIFont systemFontOfSize:15]]; + [button setTitleColor:kColorDark2 forState:UIControlStateNormal]; + [button setTitle:@"使用邮箱找回" forState:UIControlStateNormal]; + [footerV addSubview:button]; + [button mas_makeConstraints:^(MASConstraintMaker *make) { + make.size.mas_equalTo(CGSizeMake(120, 30)); + make.top.equalTo(_footerBtn.mas_bottom).offset(30); + make.centerX.equalTo(footerV); + }]; + button; + }); + __weak typeof(self) weakSelf = self; + [emailBtn bk_addEventHandler:^(id sender) { + CannotLoginViewController *vc = [CannotLoginViewController vcWithMethodType:CannotLoginMethodEamil stepIndex:0 userStr:nil]; + [weakSelf.navigationController pushViewController:vc animated:YES]; + } forControlEvents:UIControlEventTouchUpInside]; + } + return footerV; +} + +- (NSString *)footerBtnTitle{ + NSString *curStr = @""; + if (_medthodType == CannotLoginMethodEamil) { + curStr = @"发送重置密码邮件"; + }else{ + curStr = _stepIndex == 0? @"下一步": @"完成"; + } + return curStr; +} +#pragma mark - Table view data source +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + return 2; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + NSString *cellIdentifier; + if (_medthodType == CannotLoginMethodEamil) { + cellIdentifier = indexPath.row == 0? kCellIdentifier_Input_OnlyText_Cell_Text: kCellIdentifier_Input_OnlyText_Cell_Captcha; + }else if (_stepIndex <= 0){ + cellIdentifier = indexPath.row == 0? kCellIdentifier_Input_OnlyText_Cell_Text: self.phoneCodeCellIdentifier; + }else{ + cellIdentifier = kCellIdentifier_Input_OnlyText_Cell_Text; + } + Input_OnlyText_Cell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath]; + cell.isBottomLineShow = ![Login isLogin]; + + __weak typeof(self) weakSelf = self; + if (_medthodType == CannotLoginMethodEamil) { + if (indexPath.row == 0) { + [cell setPlaceholder:@" 电子邮箱" value:self.userStr]; + cell.textField.keyboardType = UIKeyboardTypeEmailAddress; + cell.textValueChangedBlock = ^(NSString *valueStr){ + weakSelf.userStr = valueStr; + }; + }else{ + [cell setPlaceholder:@" 验证码" value:self.j_captcha]; + cell.textValueChangedBlock = ^(NSString *valueStr){ + weakSelf.j_captcha = valueStr; + }; + } + }else if (_stepIndex <= 0){ + if (indexPath.row == 0) { + [cell setPlaceholder:@" 手机号码" value:self.userStr]; + cell.textField.keyboardType = UIKeyboardTypeNumberPad; + cell.textValueChangedBlock = ^(NSString *valueStr){ + weakSelf.userStr = valueStr; + }; + }else{ + cell.textField.keyboardType = UIKeyboardTypeNumberPad; + [cell setPlaceholder:@" 验证码" value:self.phoneCode]; + cell.textValueChangedBlock = ^(NSString *valueStr){ + weakSelf.phoneCode = valueStr; + }; + cell.phoneCodeBtnClckedBlock = ^(PhoneCodeButton *btn){ + [weakSelf phoneCodeBtnClicked:btn withCaptcha:nil]; + }; + } + }else{ + if (indexPath.row == 0) { + cell.textField.secureTextEntry = YES; + [cell setPlaceholder:@" 设置密码" value:self.password]; + cell.textValueChangedBlock = ^(NSString *valueStr){ + weakSelf.password = valueStr; + }; + }else{ + cell.textField.secureTextEntry = YES; + [cell setPlaceholder:@" 重复密码" value:self.confirm_password]; + cell.textValueChangedBlock = ^(NSString *valueStr){ + weakSelf.confirm_password = valueStr; + }; + } + } + if ([Login isLogin]) { + cell.backgroundColor = kColorWhite; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; + } + return cell; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ + return [Login isLogin]? 50: 65.0; +} + +#pragma mark Btn Clicked +- (void)phoneCodeBtnClicked:(PhoneCodeButton *)sender withCaptcha:(NSString *)captcha{ + if (![_userStr isPhoneNo]) { + [NSObject showHudTipStr:@"手机号码格式有误"]; + return; + } + sender.enabled = NO; + NSMutableDictionary *params = @{@"account": _userStr, + @"phoneCountryCode": @"+86"}.mutableCopy; + if (captcha.length > 0) { + params[@"j_captcha"] = captcha; + } + __weak typeof(self) weakSelf = self; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:@"api/account/password/forget" withParams:params withMethodType:Post autoShowError:captcha.length > 0 andBlock:^(id data, NSError *error) { + if (data) { + [NSObject showHudTipStr:@"验证码发送成功"]; + [sender startUpTimer]; + }else{ + [sender invalidateTimer]; + if (error && error.userInfo[@"msg"] && [[error.userInfo[@"msg"] allKeys] containsObject:@"j_captcha_error"]) { + [weakSelf p_showCaptchaAlert:sender]; + }else if (captcha.length <= 0){ + [NSObject showError:error]; + } + } + }]; +} + +- (void)p_showCaptchaAlert:(PhoneCodeButton *)sender{ + SDCAlertController *alertV = [SDCAlertController alertControllerWithTitle:@"提示" message:@"请输入图片验证码" preferredStyle:SDCAlertControllerStyleAlert]; + UITextField *textF = [UITextField new]; + textF.layer.sublayerTransform = CATransform3DMakeTranslation(5, 0, 0); + textF.backgroundColor = [UIColor whiteColor]; + [textF doBorderWidth:0.5 color:nil cornerRadius:2.0]; + UIImageView *imageV = [YLImageView new]; + imageV.backgroundColor = [UIColor lightGrayColor]; + imageV.contentMode = UIViewContentModeScaleAspectFit; + imageV.clipsToBounds = YES; + imageV.userInteractionEnabled = YES; + [textF doBorderWidth:0.5 color:nil cornerRadius:2.0]; + NSURL *imageURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@api/getCaptcha", [NSObject baseURLStr]]]; + [imageV sd_setImageWithURL:imageURL placeholderImage:nil options:(SDWebImageRetryFailed | SDWebImageRefreshCached | SDWebImageHandleCookies)]; + + [alertV.contentView addSubview:textF]; + [alertV.contentView addSubview:imageV]; + [textF mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(alertV.contentView).offset(15); + make.height.mas_equalTo(25); + make.bottom.equalTo(alertV.contentView).offset(-10); + }]; + [imageV mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.equalTo(alertV.contentView).offset(-15); + make.left.equalTo(textF.mas_right).offset(10); + make.width.mas_equalTo(60); + make.height.mas_equalTo(25); + make.centerY.equalTo(textF); + }]; + //Action + __weak typeof(imageV) weakImageV = imageV; + [imageV bk_whenTapped:^{ + [weakImageV sd_setImageWithURL:imageURL placeholderImage:nil options:(SDWebImageRetryFailed | SDWebImageRefreshCached | SDWebImageHandleCookies)]; + }]; + __weak typeof(self) weakSelf = self; + [alertV addAction:[SDCAlertAction actionWithTitle:@"取消" style:SDCAlertActionStyleCancel handler:nil]]; + [alertV addAction:[SDCAlertAction actionWithTitle:@"确定" style:SDCAlertActionStyleDefault handler:nil]]; + alertV.shouldDismissBlock = ^BOOL (SDCAlertAction *action){ + if (![action.title isEqualToString:@"取消"]) { + [weakSelf phoneCodeBtnClicked:sender withCaptcha:textF.text]; + } + return YES; + }; + [alertV presentWithCompletion:^{ + [textF becomeFirstResponder]; + }]; +} + + +- (void)footerBtnClicked:(id)sender{ + __weak typeof(self) weakSelf = self; + if (_medthodType == CannotLoginMethodEamil) { + [self.footerBtn startQueryAnimate]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:@"api/account/password/forget" withParams:@{@"account": _userStr, @"j_captcha": _j_captcha} withMethodType:Post andBlock:^(id data, NSError *error) { + [weakSelf.footerBtn stopQueryAnimate]; + if (data) { + [NSObject showHudTipStr:@"重置密码邮件已经发送,请尽快去邮箱查看"]; + [weakSelf.navigationController popToRootViewControllerAnimated:YES]; + }else{ + [weakSelf.myTableView reloadData];//主要是为了 刷新一下图片验证码 + } + }]; + }else if (_stepIndex == 0){ + [self.footerBtn startQueryAnimate]; + NSDictionary *params = @{@"phone": _userStr, + @"code": _phoneCode, + @"phoneCountryCode": @"+86", + @"type": @"reset"}; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:@"api/account/phone/code/check" withParams:params withMethodType:Post andBlock:^(id data, NSError *error) { + [self.footerBtn stopQueryAnimate]; + if (!error) { + //通过校验 + CannotLoginViewController *vc = [CannotLoginViewController vcWithMethodType:CannotLoginMethodPhone stepIndex:1 userStr:_userStr]; + vc.phoneCode = weakSelf.phoneCode; + [weakSelf.navigationController pushViewController:vc animated:YES]; + } + }]; + }else{ + if (![_password isEqualToString:_confirm_password]) { + [NSObject showHudTipStr:@"两次输入密码不一致"]; + return; + } + [self.footerBtn startQueryAnimate]; + NSMutableDictionary *params = @{@"account": _userStr, + @"password": [_password sha1Str], + @"confirm": [_confirm_password sha1Str], + @"code": _phoneCode}.mutableCopy; + params[@"j_captcha"] = _j_captcha; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:@"api/account/password/reset" withParams:params withMethodType:Post andBlock:^(id data, NSError *error) { + [weakSelf.footerBtn stopQueryAnimate]; + if (data) { + [NSObject showHudTipStr:@"密码设置成功"]; + [weakSelf.navigationController popToRootViewControllerAnimated:YES]; + } + }]; + } +} + +@end + +#endif diff --git a/Coding_iOS/Controllers/Login/Close2FAViewController.m b/Coding_iOS/Controllers/Login/Close2FAViewController.m index 96a91ccc9..4ba4c2053 100644 --- a/Coding_iOS/Controllers/Login/Close2FAViewController.m +++ b/Coding_iOS/Controllers/Login/Close2FAViewController.m @@ -47,6 +47,9 @@ - (void)viewDidLoad { [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); self.myTableView.tableHeaderView = [self customHeaderView]; @@ -106,7 +109,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N weakSelf.phoneCode = valueStr; }; cell.phoneCodeBtnClckedBlock = ^(PhoneCodeButton *btn){ - [weakSelf phoneCodeBtnClicked:btn]; + [weakSelf phoneCodeBtnClicked:btn withCaptcha:nil]; }; } [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kLoginPaddingLeftWidth]; @@ -114,21 +117,74 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } #pragma mark Btn Clicked -- (void)phoneCodeBtnClicked:(PhoneCodeButton *)sender{ +- (void)phoneCodeBtnClicked:(PhoneCodeButton *)sender withCaptcha:(NSString *)captcha{ if (![_phone isPhoneNo]) { [NSObject showHudTipStr:@"手机号码格式有误"]; return; } sender.enabled = NO; - [[Coding_NetAPIManager sharedManager] post_Close2FAGeneratePhoneCode:self.phone block:^(id data, NSError *error) { + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] post_Close2FAGeneratePhoneCode:self.phone withCaptcha:captcha block:^(id data, NSError *error) { if (data) { [NSObject showHudTipStr:@"验证码发送成功"]; [sender startUpTimer]; }else{ [sender invalidateTimer]; + if (error && error.userInfo[@"msg"] && [[error.userInfo[@"msg"] allKeys] containsObject:@"j_captcha_error"]) { + [weakSelf p_showCaptchaAlert:sender]; + } + } + }]; +} + +- (void)p_showCaptchaAlert:(PhoneCodeButton *)sender{ + SDCAlertController *alertV = [SDCAlertController alertControllerWithTitle:@"提示" message:@"请输入图片验证码" preferredStyle:SDCAlertControllerStyleAlert]; + UITextField *textF = [UITextField new]; + textF.layer.sublayerTransform = CATransform3DMakeTranslation(5, 0, 0); + textF.backgroundColor = [UIColor whiteColor]; + [textF doBorderWidth:0.5 color:nil cornerRadius:2.0]; + UIImageView *imageV = [YLImageView new]; + imageV.backgroundColor = [UIColor lightGrayColor]; + imageV.contentMode = UIViewContentModeScaleAspectFit; + imageV.clipsToBounds = YES; + imageV.userInteractionEnabled = YES; + [textF doBorderWidth:0.5 color:nil cornerRadius:2.0]; + NSURL *imageURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@api/getCaptcha", [NSObject baseURLStr]]]; + [imageV sd_setImageWithURL:imageURL placeholderImage:nil options:(SDWebImageRetryFailed | SDWebImageRefreshCached | SDWebImageHandleCookies)]; + + [alertV.contentView addSubview:textF]; + [alertV.contentView addSubview:imageV]; + [textF mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(alertV.contentView).offset(15); + make.height.mas_equalTo(25); + make.bottom.equalTo(alertV.contentView).offset(-10); + }]; + [imageV mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.equalTo(alertV.contentView).offset(-15); + make.left.equalTo(textF.mas_right).offset(10); + make.width.mas_equalTo(60); + make.height.mas_equalTo(25); + make.centerY.equalTo(textF); + }]; + //Action + __weak typeof(imageV) weakImageV = imageV; + [imageV bk_whenTapped:^{ + [weakImageV sd_setImageWithURL:imageURL placeholderImage:nil options:(SDWebImageRetryFailed | SDWebImageRefreshCached | SDWebImageHandleCookies)]; + }]; + __weak typeof(self) weakSelf = self; + [alertV addAction:[SDCAlertAction actionWithTitle:@"取消" style:SDCAlertActionStyleCancel handler:nil]]; + [alertV addAction:[SDCAlertAction actionWithTitle:@"确定" style:SDCAlertActionStyleDefault handler:nil]]; + alertV.shouldDismissBlock = ^BOOL (SDCAlertAction *action){ + if (![action.title isEqualToString:@"取消"]) { + [weakSelf phoneCodeBtnClicked:sender withCaptcha:textF.text]; } + return YES; + }; + [alertV presentWithCompletion:^{ + [textF becomeFirstResponder]; }]; } + - (void)footerBtnClicked:(id)sender{ [self.footerBtn startQueryAnimate]; [[Coding_NetAPIManager sharedManager] post_Close2FAWithPhone:self.phone code:self.phoneCode block:^(id data, NSError *error) { diff --git a/Coding_iOS/Controllers/Login/IntroductionViewController.h b/Coding_iOS/Controllers/Login/IntroductionViewController.h index 87992e691..853fdac7a 100644 --- a/Coding_iOS/Controllers/Login/IntroductionViewController.h +++ b/Coding_iOS/Controllers/Login/IntroductionViewController.h @@ -6,8 +6,39 @@ // Copyright (c) 2015年 Coding. All rights reserved. // +#ifdef Target_Enterprise + +#import "BaseViewController.h" + +@class IntroductionItem, IntroductionHomePage, IntroductionIndexPage; + +@interface IntroductionViewController : BaseViewController + +- (void)presentLoginUI; + +@end + +@interface IntroductionHomePage : UIView +@property (strong, nonatomic) IntroductionItem *curItem; + +@end + +@interface IntroductionIndexPage : UIView +@property (strong, nonatomic) IntroductionItem *curItem; +@end + +@interface IntroductionItem : NSObject ++ (instancetype)itemWithTitle:(NSString *)title content:(NSString *)content imagePrefix:(NSString *)imagePrefix; +@property (strong, nonatomic) NSString *title, *content, *imagePrefix; +@property (assign, nonatomic) BOOL isHomePage; +@end + +#else + #import @interface IntroductionViewController : IFTTTAnimatedPagingScrollViewController @end + +#endif diff --git a/Coding_iOS/Controllers/Login/IntroductionViewController.m b/Coding_iOS/Controllers/Login/IntroductionViewController.m index 9421647e6..853dbe09c 100644 --- a/Coding_iOS/Controllers/Login/IntroductionViewController.m +++ b/Coding_iOS/Controllers/Login/IntroductionViewController.m @@ -6,6 +6,476 @@ // Copyright (c) 2015年 Coding. All rights reserved. // + +#ifdef Target_Enterprise + +#define kIntroductionView_AnimateDuration .6 + +#import "IntroductionViewController.h" +#import "LoginViewController.h" +#import "YLImageView.h" +#import "YLGIFImage.h" +#import "SMPageControl.h" +#import + +@interface IntroductionViewController () +@property (strong, nonatomic) UIButton *loginEnterpriseBtn, *loginPrivateCloudBtn; +@property (strong, nonatomic) SMPageControl *pageControl; +@property (strong, nonatomic) IntroductionHomePage *homePage; +@property (strong, nonatomic) IntroductionIndexPage *indexPage; + +@property (strong, nonatomic) NSMutableArray *pageItems; +@property (strong, nonatomic) IntroductionItem *curItem; +@end + +@implementation IntroductionViewController +- (void)viewDidLoad{ + [super viewDidLoad]; + + self.view.backgroundColor = [UIColor whiteColor]; + {//Data + _pageItems = @[].mutableCopy; + IntroductionItem *homeItem = [IntroductionItem itemWithTitle:@"欢迎来到\nCoding Enterprise" content:@"CODING Enterprise 是 CODING 专为企业打造的软件开发协作平台,让企业更好地管理项目成员,便捷而深入地把握开发进度,让开发流程更高效。" imagePrefix:nil]; + homeItem.isHomePage = YES; + [_pageItems addObject:homeItem]; + [_pageItems addObject:[IntroductionItem itemWithTitle:@"任务协作" content:@"任务进度与代码仓库无缝衔接" imagePrefix:@"intro_icon_task"]]; + [_pageItems addObject:[IntroductionItem itemWithTitle:@"文件管理" content:@"云端共享,支持在线预览、编辑、评论" imagePrefix:@"intro_icon_file"]]; + [_pageItems addObject:[IntroductionItem itemWithTitle:@"Wiki 知识库" content:@"文档书写,记录整个项目的来龙去脉" imagePrefix:@"intro_icon_wiki"]]; + [_pageItems addObject:[IntroductionItem itemWithTitle:@"代码托管" content:@"提交代码、合并请求一步到位" imagePrefix:@"intro_icon_code"]]; + } + + [self configureButtonsAndPageControl]; + self.curItem = _pageItems.firstObject; + [self addGesture]; +} + +- (void)viewWillAppear:(BOOL)animated{ + [super viewWillAppear:animated]; + [[UIApplication sharedApplication] setStatusBarHidden:YES]; +} + +- (void)viewWillDisappear:(BOOL)animated{ + [super viewWillDisappear:animated]; + [[UIApplication sharedApplication] setStatusBarHidden:NO]; +} + +- (void)configureButtonsAndPageControl{ + // PageControl + UIImage *pageIndicatorImage = [UIImage imageNamed:@"intro_dot_light_unselected"]; + UIImage *currentPageIndicatorImage = [UIImage imageNamed:@"intro_dot_light_selected"]; + self.pageControl = ({ + SMPageControl *pageControl = [[SMPageControl alloc] init]; + pageControl.numberOfPages = self.pageItems.count; + pageControl.userInteractionEnabled = NO; + pageControl.pageIndicatorImage = pageIndicatorImage; + pageControl.currentPageIndicatorImage = currentPageIndicatorImage; + [pageControl sizeToFit]; + pageControl.currentPage = 0; + pageControl; + }); + [self.view addSubview:self.pageControl]; + [self.pageControl mas_makeConstraints:^(MASConstraintMaker *make) { + make.size.mas_equalTo(CGSizeMake(kScreen_Width, 20)); + make.centerX.equalTo(self.view); + make.bottom.equalTo(self.view.mas_bottom).offset(kDevice_Use_iPhone4_Layout? -10: kDevice_Is_iPhone5? -30: -(50 + kSafeArea_Bottom)); + }]; + // Button + self.loginPrivateCloudBtn = ({ + UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; + [button addTarget:self action:@selector(loginPrivateCloudBtnClicked) forControlEvents:UIControlEventTouchUpInside]; + button.backgroundColor = [UIColor clearColor]; + button.titleLabel.font = [UIFont systemFontOfSize:17 weight:UIFontWeightRegular]; + [button setTitleColor:kColorDark2 forState:UIControlStateNormal]; + [button setTitle:@"私有部署账号登录" forState:UIControlStateNormal]; + [button doBorderWidth:1.0 color:kColorDark2 cornerRadius:2.0]; + button; + }); + [self.view addSubview:self.loginPrivateCloudBtn]; + [self.loginPrivateCloudBtn mas_makeConstraints:^(MASConstraintMaker *make) { + CGFloat padding = (MIN(kScreen_Width, 350) - 270)/ 2; + make.height.mas_equalTo(56); + make.left.equalTo(self.view).offset(padding); + make.right.equalTo(self.view).offset(-padding); + make.centerX.equalTo(self.view); + make.bottom.equalTo(_pageControl.mas_top).offset(kDevice_Use_iPhone4_Layout? -10: kDevice_Is_iPhone5? -20 : -50); + }]; + + self.loginEnterpriseBtn = ({ + UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; + [button addTarget:self action:@selector(loginEnterpriseBtnClicked) forControlEvents:UIControlEventTouchUpInside]; + button.backgroundColor = kColorDark4; + button.titleLabel.font = [UIFont systemFontOfSize:17 weight:UIFontWeightMedium]; + [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [button setTitle:@"企业账号登录" forState:UIControlStateNormal]; + button.layer.masksToBounds = YES; + button.layer.cornerRadius = 2.0; + button.hidden = true; + button; + }); + [self.view addSubview:self.loginEnterpriseBtn]; + [self.loginEnterpriseBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.size.centerX.equalTo(self.loginPrivateCloudBtn); + make.bottom.equalTo(self.loginPrivateCloudBtn.mas_top).offset(-10); + }]; +} + +- (void)addGesture{ + {//Left + UISwipeGestureRecognizer *swipeG = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeGesture:)]; + swipeG.direction = UISwipeGestureRecognizerDirectionLeft; + [self.view addGestureRecognizer:swipeG]; + } + {//Right + UISwipeGestureRecognizer *swipeG = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeGesture:)]; + swipeG.direction = UISwipeGestureRecognizerDirectionRight; + [self.view addGestureRecognizer:swipeG]; + } +} + +- (void)handleSwipeGesture:(UISwipeGestureRecognizer *)swipeG{ + if (swipeG.state == UIGestureRecognizerStateRecognized) { + NSInteger index = [self.pageItems indexOfObject:self.curItem]; + if (index == NSNotFound) { + index = 0; + }else if (swipeG.direction & UISwipeGestureRecognizerDirectionLeft) {// +1 + index = MIN(++index, self.pageItems.count - 1); + }else if (swipeG.direction & UISwipeGestureRecognizerDirectionRight){// - 1 + index = MAX(--index, 0); + } + self.curItem = self.pageItems[index]; + } +} + +- (void)setCurItem:(IntroductionItem *)curItem{ + static BOOL isAnimating = NO; + if (isAnimating) { + return; + } + if (_curItem == curItem) { + return; + } + BOOL isHomeOrIndexNeedChange = (_curItem.isHomePage != curItem.isHomePage); + isAnimating = YES; + YLGIFImage *preImage = (YLGIFImage *)[YLGIFImage imageNamed:[NSString stringWithFormat:@"%@_down.gif", _curItem.imagePrefix]]; + YLGIFImage *nextImage = (YLGIFImage *)[YLGIFImage imageNamed:[NSString stringWithFormat:@"%@_up.gif", curItem.imagePrefix]]; + NSTimeInterval animateDuration = preImage.totalDuration + nextImage.totalDuration;//这里有点傻,不过,就这样吧 + animateDuration += isHomeOrIndexNeedChange? kIntroductionView_AnimateDuration: 0; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(animateDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + isAnimating = NO; + }); + + _curItem = curItem; + + if (isHomeOrIndexNeedChange) { + UIImage *pageIndicatorImage = [UIImage imageNamed:[NSString stringWithFormat:@"intro_dot_%@_unselected", _curItem.isHomePage? @"light": @"dark"]]; + UIImage *currentPageIndicatorImage = [UIImage imageNamed:[NSString stringWithFormat:@"intro_dot_%@_selected", _curItem.isHomePage? @"light": @"dark"]]; + _pageControl.pageIndicatorImage = pageIndicatorImage; + _pageControl.currentPageIndicatorImage = currentPageIndicatorImage; + } + self.homePage.curItem = self.indexPage.curItem = _curItem; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(MAX(preImage.totalDuration, kIntroductionView_AnimateDuration) * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + _pageControl.currentPage = [_pageItems indexOfObject:_curItem]; + }); +} + +- (IntroductionHomePage *)homePage{ + if (!_homePage) { + _homePage = [IntroductionHomePage new]; + [self.view insertSubview:_homePage atIndex:0]; + [_homePage mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; + } + return _homePage; +} + +- (IntroductionIndexPage *)indexPage{ + if (!_indexPage) { + _indexPage = [IntroductionIndexPage new]; + [self.view insertSubview:_indexPage atIndex:0]; + [_indexPage mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; + } + return _indexPage; +} + +#pragma mark Action +- (void)loginEnterpriseBtnClicked{ + [NSObject setupIsPrivateCloud:@(NO)]; + [self presentLoginAnimated:YES]; +} + +- (void)loginPrivateCloudBtnClicked{ + [NSObject setupIsPrivateCloud:@(YES)]; + [self presentLoginAnimated:YES]; +} + +- (void)presentLoginAnimated:(BOOL)animated{ + LoginViewController *vc = [[LoginViewController alloc] init]; + vc.showDismissButton = YES; + UINavigationController *nav = [[BaseNavigationController alloc] initWithRootViewController:vc]; + [self presentViewController:nav animated:animated completion:nil]; +} + +- (void)presentLoginUI{ + [self presentLoginAnimated:NO]; +} + +@end + +@interface IntroductionHomePage () +@property (strong, nonatomic) UILabel *titleL, *contentL; +@property (strong, nonatomic) UIView *blurView; +@property (strong, nonatomic) NSMutableArray *circleList; +@end + +@implementation IntroductionHomePage + +- (instancetype)init{ + self = [super init]; + if (self) { + self.alpha = 0; + [self setupBlurView]; + _titleL = [UILabel labelWithFont:[UIFont systemFontOfSize:30] textColor:kColorDark4]; + _contentL = [UILabel labelWithFont:[UIFont systemFontOfSize:kDevice_Is_iPhone6Plus? 17: 15] textColor:kColorDark4]; + _titleL.numberOfLines = _contentL.numberOfLines = 0; + [self addSubview:_titleL]; + [self addSubview:_contentL]; + [_titleL mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self).offset(kDevice_Use_iPhone4_Layout? 64: 90); + make.left.equalTo(self).offset(30); + make.right.equalTo(self).offset(-30); + }]; + [_contentL mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.equalTo(_titleL); + make.top.equalTo(_titleL.mas_bottom).offset((kDevice_Use_iPhone4_Layout || kDevice_Is_iPhone5)? 20: 40); + }]; + } + return self; +} + +- (void)setupBlurView{ + for (NSInteger index = 0; index < 4; index++) { + [self addCircleIndex:index]; + } + UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:self.bounds]; + [toolbar setBarStyle:UIBarStyleDefault]; + [self addSubview:toolbar]; + [toolbar mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self); + }]; + _blurView = toolbar; +} + +- (void)addCircleIndex:(NSInteger)index{ + static NSArray *colorList; + static NSArray *pointList; + if (!colorList) {//背景色列表 + CGFloat alpha = .9; + colorList = @[ + [UIColor colorWithHexString:@"0xC9F1DD" andAlpha:alpha], + [UIColor colorWithHexString:@"0x43CD87" andAlpha:alpha], + [UIColor colorWithHexString:@"0x76A6D9" andAlpha:alpha], + // [UIColor colorWithHexString:@"0x7991B2" andAlpha:alpha], + ]; + } + if (!pointList) {//center 列表 + pointList = @[ + [NSValue valueWithCGPoint:CGPointMake(kScreen_Width * .4, kScreen_Height * .2)], + [NSValue valueWithCGPoint:CGPointMake(kScreen_Width * .2, kScreen_Height * .6)], + [NSValue valueWithCGPoint:CGPointMake(kScreen_Width * .9, kScreen_Height * .5)], + // [NSValue valueWithCGPoint:CGPointMake(kScreen_Width * .7, kScreen_Height * .9)], + ]; + } + if (index < 0 || index >= MIN(colorList.count, pointList.count)) { + return; + } + if (!_circleList) { + _circleList = @[].mutableCopy; + } + CGFloat circleWidth = kScreen_Width; + UIView *circleV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, circleWidth, circleWidth)]; + circleV.backgroundColor = colorList[index]; + circleV.clipsToBounds = YES; + circleV.layer.cornerRadius = circleWidth / 2; + [self addSubview:circleV]; + [_circleList addObject:circleV]; + + CGFloat animationWidth = kScreen_Width * .3; + UIBezierPath *bezierPath = [UIBezierPath new]; + CGPoint originP = pointList[index].CGPointValue; + originP.y += kScreen_Height * .4; + [bezierPath moveToPoint:originP]; + [bezierPath addLineToPoint:CGPointMake(originP.x + animationWidth, originP.y)]; + [bezierPath addLineToPoint:CGPointMake(originP.x + animationWidth, originP.y + animationWidth)]; + [bezierPath addLineToPoint:CGPointMake(originP.x, originP.y + animationWidth)]; + [bezierPath addLineToPoint:CGPointMake(originP.x, originP.y)]; + + CAKeyframeAnimation *animation = [CAKeyframeAnimation animation]; + animation.keyPath = @"position"; + animation.duration = 15.0; + animation.path = bezierPath.CGPath; + animation.repeatCount = INFINITY; + animation.timeOffset = ((CGFloat)index)/ (colorList.count) * animation.duration; + [circleV.layer addAnimation:animation forKey:nil]; +} + +- (void)setCurItem:(IntroductionItem *)curItem{ + if (_curItem == curItem) { + return; + } + if (!_curItem.isHomePage && !curItem.isHomePage) { + _curItem = curItem; + }else{ + YLGIFImage *preImage = (YLGIFImage *)[YLGIFImage imageNamed:[NSString stringWithFormat:@"%@_down.gif", _curItem.imagePrefix]]; + _curItem = curItem; + if (_curItem.isHomePage) { + _titleL.attributedText = self.attrTitle; + _contentL.attributedText = self.attrContent; + } + CGFloat nextAlpha = _curItem.isHomePage? 1.0: 0; + if (fabs(self.alpha - nextAlpha) > .1) { + CGFloat circleDuration = .3; + if (nextAlpha > .1) { + self.alpha = nextAlpha; + [UIView animateWithDuration:kIntroductionView_AnimateDuration - circleDuration delay:preImage.totalDuration options:UIViewAnimationOptionCurveEaseInOut animations:^{ + _titleL.alpha = _contentL.alpha = _blurView.alpha = nextAlpha; + } completion:^(BOOL finished) { + [UIView animateWithDuration:circleDuration animations:^{ + [_circleList setValue:@(nextAlpha) forKey:@"alpha"]; + }]; + }]; + }else{ + [UIView animateWithDuration:circleDuration animations:^{ + [_circleList setValue:@(nextAlpha) forKey:@"alpha"]; + } completion:^(BOOL finished) { + [UIView animateWithDuration:kIntroductionView_AnimateDuration - circleDuration animations:^{ + _titleL.alpha = _contentL.alpha = _blurView.alpha = nextAlpha; + } completion:^(BOOL finished) { + self.alpha = nextAlpha; + }]; + }]; + } + } + } +} + +- (NSAttributedString *)attrTitle{ + NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:_curItem.title]; + NSString *colorStr = [_curItem.title componentsSeparatedByString:@"\n"].lastObject; + [attrStr addAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:(kDevice_Use_iPhone4_Layout || kDevice_Is_iPhone5)? 30: 34], + NSForegroundColorAttributeName : kColorLightBlue} + range:[_curItem.title rangeOfString:colorStr]]; + NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; + paragraphStyle.minimumLineHeight = paragraphStyle.maximumLineHeight = 45; + paragraphStyle.alignment = NSTextAlignmentJustified; + [attrStr addAttributes:@{NSParagraphStyleAttributeName : paragraphStyle} + range:NSMakeRange(0, _curItem.title.length)]; + return attrStr; +} + +- (NSAttributedString *)attrContent{ + NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:_curItem.content]; + NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; + paragraphStyle.minimumLineHeight = paragraphStyle.maximumLineHeight = 28; + paragraphStyle.alignment = NSTextAlignmentJustified; + [attrStr addAttributes:@{NSParagraphStyleAttributeName : paragraphStyle} + range:NSMakeRange(0, _curItem.content.length)]; + return attrStr; +} + +@end + +@interface IntroductionIndexPage () +@property (strong, nonatomic) UILabel *titleL, *contentL; +@property (strong, nonatomic) YLImageView *imageV; +@end + +@implementation IntroductionIndexPage + +- (instancetype)init{ + self = [super init]; + if (self) { + self.alpha = 0; + _imageV = [YLImageView new]; + _titleL = [UILabel labelWithFont:[UIFont systemFontOfSize:21 weight:UIFontWeightMedium] textColor:kColorDark4]; + _contentL = [UILabel labelWithFont:[UIFont systemFontOfSize:(kDevice_Use_iPhone4_Layout || kDevice_Is_iPhone5)? 15: 17] textColor:kColorDark4]; + [self addSubview:_imageV]; + [self addSubview:_titleL]; + [self addSubview:_contentL]; + [_imageV mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self).offset(60); + make.centerX.equalTo(self); + make.size.mas_equalTo(CGSizeMake((462 / 2.0) * (kScreen_Height / 667), (390 / 2.0) * (kScreen_Height / 667))); + }]; + [_titleL mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(_imageV.mas_bottom).offset(0); + make.centerX.equalTo(self); + }]; + [_contentL mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(_titleL.mas_bottom).offset(10); + make.centerX.equalTo(self); + }]; + } + return self; +} + +- (void)setCurItem:(IntroductionItem *)curItem{ + if (_curItem == curItem) { + return; + } + YLGIFImage *preImage = (YLGIFImage *)[YLGIFImage imageNamed:[NSString stringWithFormat:@"%@_down.gif", _curItem.imagePrefix]]; + YLGIFImage *nextImage = (YLGIFImage *)[YLGIFImage imageNamed:[NSString stringWithFormat:@"%@_up.gif", curItem.imagePrefix]]; + preImage.loopCount = nextImage.loopCount = 1; + BOOL isHomeOrIndexNeedChange = (_curItem.isHomePage != curItem.isHomePage); + + _curItem = curItem; + + if (isHomeOrIndexNeedChange) {//Index 和 Home Page 之间的切换 + YLGIFImage *gifImage = preImage ?: nextImage; + CGFloat nextAlpha = _curItem.isHomePage? 0: 1.0; + if (!_curItem.isHomePage) { + _titleL.text = _curItem.title; + _contentL.text = _curItem.content; + } + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)((nextAlpha > .1? kIntroductionView_AnimateDuration: 0) * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + _imageV.image = gifImage; + }); + [UIView animateWithDuration:gifImage.totalDuration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ + self.alpha = nextAlpha; + } completion:nil]; + }else{ + _imageV.image = preImage; + [UIView animateWithDuration:preImage.totalDuration animations:^{ + _titleL.alpha = _contentL.alpha = 0; + } completion:^(BOOL finished) { + _imageV.image = nextImage; + _titleL.text = _curItem.title; + _contentL.text = _curItem.content; + [UIView animateWithDuration:nextImage.totalDuration animations:^{ + _titleL.alpha = _contentL.alpha = 1.0; + }]; + }]; + } +} + +@end + +@implementation IntroductionItem + ++ (instancetype)itemWithTitle:(NSString *)title content:(NSString *)content imagePrefix:(NSString *)imagePrefix{ + IntroductionItem *item = [self new]; + item.title = title; + item.content = content; + item.imagePrefix = imagePrefix; + return item; +} + +@end + +#else + #import "IntroductionViewController.h" #import "LoginViewController.h" #import "RegisterViewController.h" @@ -47,13 +517,13 @@ - (instancetype)init @"6_image" : @"intro_tip_5", } mutableCopy]; -// _iconsDict = [NSMutableDictionary new]; -// _tipsDict = [NSMutableDictionary new]; -// for (int i = 0; i < self.numberOfPages; i++) { -// NSString *imageKey = [self imageKeyForIndex:i]; -// [_iconsDict setObject:[NSString stringWithFormat:@"intro_icon_%d", i] forKey:imageKey]; -// [_tipsDict setObject:[NSString stringWithFormat:@"intro_tip_%d", i] forKey:imageKey]; -// } + // _iconsDict = [NSMutableDictionary new]; + // _tipsDict = [NSMutableDictionary new]; + // for (int i = 0; i < self.numberOfPages; i++) { + // NSString *imageKey = [self imageKeyForIndex:i]; + // [_iconsDict setObject:[NSString stringWithFormat:@"intro_icon_%d", i] forKey:imageKey]; + // [_tipsDict setObject:[NSString stringWithFormat:@"intro_tip_%d", i] forKey:imageKey]; + // } } return self; @@ -71,7 +541,7 @@ - (NSString *)viewKeyForIndex:(NSInteger)index{ - (void)viewDidLoad { [super viewDidLoad]; - + self.view.backgroundColor = [UIColor colorWithHexString:@"0xf1f1f1"]; [self configureViews]; @@ -89,7 +559,7 @@ - (void)viewWillDisappear:(BOOL)animated{ #pragma mark - Orientations - (BOOL)shouldAutorotate{ - return UIInterfaceOrientationIsLandscape(self.interfaceOrientation); + return UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication.statusBarOrientation); } - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { @@ -115,13 +585,13 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView #pragma Views - (void)configureViews{ [self configureButtonsAndPageControl]; - + CGFloat scaleFactor = 1.0; CGFloat desginHeight = 667.0;//iPhone6 的设计尺寸 - if (!kDevice_Is_iPhone6 && !kDevice_Is_iPhone6Plus) { + if (!kDevice_Is_iPhone6 && !kDevice_Is_iPhone6Plus && !kDevice_Is_FullScreen) { scaleFactor = kScreen_Height/desginHeight; } - + for (int i = 0; i < self.numberOfPages; i++) { NSString *imageKey = [self imageKeyForIndex:i]; NSString *viewKey = [self viewKeyForIndex:i]; @@ -151,12 +621,12 @@ - (void)configureViews{ } - (void)configureButtonsAndPageControl{ -// Button - UIColor *darkColor = kColorBrandGreen; + // Button + UIColor *darkColor = kColorBrandBlue; CGFloat buttonWidth = kScreen_Width * 0.4; CGFloat buttonHeight = kScaleFrom_iPhone5_Desgin(38); CGFloat paddingToCenter = kScaleFrom_iPhone5_Desgin(10); - CGFloat paddingToBottom = kScaleFrom_iPhone5_Desgin(20); + CGFloat paddingToBottom = kScaleFrom_iPhone5_Desgin(20) + kSafeArea_Bottom; self.registerBtn = ({ UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; @@ -201,10 +671,10 @@ - (void)configureButtonsAndPageControl{ make.bottom.equalTo(self.view).offset(-paddingToBottom); }]; -// PageControl + // PageControl UIImage *pageIndicatorImage = [UIImage imageNamed:@"intro_dot_unselected"]; UIImage *currentPageIndicatorImage = [UIImage imageNamed:@"intro_dot_selected"]; - + if (!kDevice_Is_iPhone6 && !kDevice_Is_iPhone6Plus) { CGFloat desginWidth = 375.0;//iPhone6 的设计尺寸 CGFloat scaleFactor = kScreen_Width/desginWidth; @@ -265,7 +735,7 @@ - (void)configureTipAndTitleViewAnimations{ } if (tipView) { [self keepView:tipView onPages:@[@(index +1), @(index), @(index-1)] atTimes:@[@(index - 1), @(index), @(index +1)]]; - + IFTTTAlphaAnimation *tipAlphaAnimation = [IFTTTAlphaAnimation animationWithView:tipView]; [tipAlphaAnimation addKeyframeForTime:index -0.5 alpha:0.f]; [tipAlphaAnimation addKeyframeForTime:index alpha:1.f]; @@ -283,15 +753,18 @@ - (void)configureTipAndTitleViewAnimations{ #pragma mark Action - (void)registerBtnClicked{ RegisterViewController *vc = [RegisterViewController vcWithMethodType:RegisterMethodPhone registerObj:nil]; - UINavigationController *nav = [[BaseNavigationController alloc] initWithRootViewController:vc]; + UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc]; [self presentViewController:nav animated:YES completion:nil]; } - (void)loginBtnClicked{ LoginViewController *vc = [[LoginViewController alloc] init]; vc.showDismissButton = YES; - UINavigationController *nav = [[BaseNavigationController alloc] initWithRootViewController:vc]; + UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc]; [self presentViewController:nav animated:YES completion:nil]; } @end + +#endif + diff --git a/Coding_iOS/Controllers/Login/LoginViewController.m b/Coding_iOS/Controllers/Login/LoginViewController.m index a44cf87dd..27ad9aaa6 100644 --- a/Coding_iOS/Controllers/Login/LoginViewController.m +++ b/Coding_iOS/Controllers/Login/LoginViewController.m @@ -23,6 +23,473 @@ #import "Ease_2FA.h" #import "Login2FATipCell.h" +#import + +#ifdef Target_Enterprise + +typedef NS_ENUM(NSUInteger, LoginStep) { + LoginStepCompany = 0, + LoginStepPassword, + LoginStep2FA, +}; + +@interface LoginViewController () +@property (strong, nonatomic) TPKeyboardAvoidingTableView *myTableView; +@property (strong, nonatomic) UIButton *backBtn, *rightNavBtn, *nextBtn, *cannotLoginBtn; +@property (strong, nonatomic) UIActivityIndicatorView *activityIndicator; + +@property (assign, nonatomic) LoginStep step; +@property (nonatomic, strong) Login *myLogin; +@property (strong, nonatomic) NSString *otpCode; +@property (assign, nonatomic) BOOL captchaNeeded; +@property (assign, nonatomic, readonly) BOOL isPrivateCloud; +@end + + +@implementation LoginViewController + +#pragma mark Life +- (void)viewDidLoad{ + [super viewDidLoad]; + // Do any additional setup after loading the view. + self.title = @"登录"; + if (_step == LoginStepCompany) { + self.myLogin.company = self.isPrivateCloud? [NSObject privateCloud]: ([Login curLoginCompany].global_key ?: [NSObject baseCompany]); + [self addChangeBaseURLGesture]; + }else if (_step == LoginStepPassword){ + self.myLogin.email = [Login preUserEmail]; + [self refreshCaptchaNeeded]; + }else if (_step == LoginStep2FA){ + self.otpCode = [OTPListViewController otpCodeWithGK:self.myLogin.email]; + if (self.otpCode) {//发送登录请求 + [self loginBtnClicked]; + } + } + self.myTableView.tableHeaderView = [self customHeaderView]; + self.myTableView.tableFooterView=[self customFooterView]; + [self.navigationController addFullscreenPopGesture]; + [self setupNavBtn]; + +#if DEBUG + if (self.isPrivateCloud) { + self.myLogin.email = @"ce-admin"; + self.myLogin.company = @"http://pd.codingprod.net"; + self.myLogin.password = @"123123"; + } +#endif +} + + + +- (void)viewWillAppear:(BOOL)animated{ + [super viewWillAppear:animated]; + [self.myTableView reloadData]; + [self.navigationController setNavigationBarHidden:YES animated:YES]; +} + +- (void)viewWillDisappear:(BOOL)animated{ + [super viewWillDisappear:animated]; + [self.view endEditing:YES]; +} + +- (void)setupNavBtn{ + if (_step > LoginStepCompany || self.showDismissButton) { + [self backBtn]; + } + [self rightNavBtn]; +} + +- (void)refreshCaptchaNeeded{ + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_CaptchaNeededWithPath:@"api/captcha/login" andBlock:^(id data, NSError *error) { + if (data) { + weakSelf.captchaNeeded = ((NSNumber *)data).boolValue; + } + }]; +} + +#pragma mark Get Set +- (Login *)myLogin{ + if (!_myLogin) { + _myLogin = [Login new]; + } + return _myLogin; +} + +- (BOOL)isPrivateCloud{ + return [NSObject isPrivateCloud].boolValue; +} + +- (void)setCaptchaNeeded:(BOOL)captchaNeeded{ + _captchaNeeded = captchaNeeded; + if (!captchaNeeded) { + self.myLogin.j_captcha = nil; + } + [self.myTableView reloadData]; +} + +- (TPKeyboardAvoidingTableView *)myTableView{ + if (!_myTableView) { + _myTableView = ({ + TPKeyboardAvoidingTableView *tableView = [[TPKeyboardAvoidingTableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; + [tableView registerClass:[Login2FATipCell class] forCellReuseIdentifier:kCellIdentifier_Login2FATipCell]; + [tableView registerClass:[Input_OnlyText_Cell class] forCellReuseIdentifier:kCellIdentifier_Input_OnlyText_Cell_Text]; + [tableView registerClass:[Input_OnlyText_Cell class] forCellReuseIdentifier:kCellIdentifier_Input_OnlyText_Cell_Captcha]; + [tableView registerClass:[Input_OnlyText_Cell class] forCellReuseIdentifier:kCellIdentifier_Input_OnlyText_Cell_Company]; + tableView.backgroundColor = [UIColor whiteColor]; + tableView.dataSource = self; + tableView.delegate = self; + tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + [self.view addSubview:tableView]; + [tableView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; + tableView; + }); + } + return _myTableView; +} + +- (UIButton *)backBtn{ + if (!_backBtn) { + _backBtn = ({ + UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, kSafeArea_Top, 44, 44)]; + [button setImage:[UIImage imageNamed:@"back_green_Nav"] forState:UIControlStateNormal]; + button.tintColor = kColorLightBlue; + [button setImage:[[UIImage imageNamed:@"back_green_Nav"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal]; + [button addTarget:self action:@selector(backBtnClicked) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:button]; + button; + }); + } + return _backBtn; +} + +- (UIButton *)rightNavBtn{ + if (!_rightNavBtn) { + if (!_rightNavBtn) { + _rightNavBtn = ({ + UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(kScreen_Width - 130, kSafeArea_Top, 120, 50)]; + button.backgroundColor = [UIColor whiteColor]; + [button.titleLabel setFont:[UIFont systemFontOfSize:15]]; + [button setTitleColor:kColorLightBlue forState:UIControlStateNormal]; + [button setTitleColor:[UIColor colorWithHexString:@"0x0060FF" andAlpha:.5] forState:UIControlStateHighlighted]; + button.tintColor = kColorBrandBlue; + [button addTarget:self action:@selector(rightNavBtnClicked) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:button]; + button; + }); + } + if (_step == LoginStep2FA) { + [_rightNavBtn setTitle:@"关闭两步验证" forState:UIControlStateNormal]; + [_rightNavBtn setImage:nil forState:UIControlStateNormal]; + _rightNavBtn.hidden = [NSObject isPrivateCloud].boolValue; + }else{ + [_rightNavBtn setTitle:@" 两步验证" forState:UIControlStateNormal]; + [_rightNavBtn setImage:[[UIImage imageNamed:@"twoFABtn_Nav"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal]; + } + } + return _rightNavBtn; +} + +- (UIActivityIndicatorView *)activityIndicator{ + if (!_activityIndicator) { + _activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleWhite]; + _activityIndicator.hidesWhenStopped = YES; + [_nextBtn addSubview:_activityIndicator]; + } + [_activityIndicator setCenter:CGPointMake(_nextBtn.width/2 - 40, _nextBtn.height/2)]; + return _activityIndicator; +} + +#pragma mark - Table Header Footer +- (UIView *)customHeaderView{ + UIView *headerV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 44 + (_step == LoginStepPassword? 100: 60))]; + UILabel *headerL = [UILabel labelWithSystemFontSize:28 textColorHexString:@"0x272C33"]; + if (_step == LoginStepPassword) { + [headerL ea_setText:[NSString stringWithFormat:@"登录到\n%@", [NSURL URLWithString:[NSObject baseURLStr]].host] lineSpacing:5]; + }else{ + headerL.text = (_step == LoginStepCompany? (self.isPrivateCloud? @"私有部署账号登录": + @"企业账号登录"): + @"两步验证"); + } + [headerV addSubview:headerL]; + [headerL mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(headerV).offset(20); + make.bottom.equalTo(headerV); + make.height.mas_equalTo(_step == LoginStepPassword? 80: 40); + }]; + return headerV; +} + +- (UIView *)customFooterView{ + UIView *footerV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 100)]; + _nextBtn = ({ + UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(kLoginPaddingLeftWidth, (_step == LoginStepPassword? 50: 25), kScreen_Width-kLoginPaddingLeftWidth*2, 50)]; + button.backgroundColor = kColorDark4; + button.titleLabel.font = [UIFont systemFontOfSize:17 weight:UIFontWeightMedium]; + [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [button setTitle:(_step == LoginStepCompany? @"下一步": @"登录") forState:UIControlStateNormal]; + button.layer.masksToBounds = YES; + button.layer.cornerRadius = 2.0; + [button addTarget:self action:@selector(loginBtnClicked) forControlEvents:UIControlEventTouchUpInside]; + [footerV addSubview:button]; + button; + }); + [RACObserve(self, nextBtn.enabled) subscribeNext:^(NSNumber *x) { + [self.nextBtn setTitleColor:[UIColor colorWithWhite:1.0 alpha:x.boolValue? 1.0: .5] forState:UIControlStateNormal]; + }]; + RAC(self, nextBtn.alpha) = [RACObserve(self, nextBtn.enabled) map:^id(NSNumber *value) { + return @(value.boolValue? 1.0: .99); + }]; + if (_step == LoginStepCompany) { + RAC(self, nextBtn.enabled) = [RACObserve(self, myLogin.company) map:^id(NSString *value) { + return @(value.length > 0); + }]; + }else if (_step == LoginStepPassword){ + _cannotLoginBtn = ({ + UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(kScreen_Width - 120, 10, 100, 30)]; + button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight; + [button.titleLabel setFont:[UIFont systemFontOfSize:14]]; + [button setTitleColor:kColorLightBlue forState:UIControlStateNormal]; + [button setTitle:@"忘记密码?" forState:UIControlStateNormal]; + [button addTarget:self action:@selector(cannotLoginBtnClicked) forControlEvents:UIControlEventTouchUpInside]; + [footerV addSubview:button]; + button; + }); + RAC(self, nextBtn.enabled) = [RACSignal combineLatest:@[RACObserve(self, myLogin.email), + RACObserve(self, myLogin.password), + RACObserve(self, myLogin.j_captcha), + RACObserve(self, captchaNeeded)] + reduce:^id(NSString *email, + NSString *password, + NSString *j_captcha, + NSNumber *captchaNeeded){ + return @(email.length > 0 && password.length > 0 && (j_captcha.length > 0 || !captchaNeeded.boolValue)); + }]; + }else if (_step == LoginStep2FA){ + RAC(self, nextBtn.enabled) = [RACObserve(self, otpCode) map:^id(NSString *value) { + return @(value.length > 0); + }]; + } + return footerV; +} + +#pragma mark - Table Data +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + return (_step == LoginStepCompany? 1: + _step == LoginStepPassword? (_captchaNeeded? 3: 2): + _step == LoginStep2FA? 2: + 0); +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + NSInteger row = indexPath.row; + if (_step == LoginStep2FA && row == 0) { + Login2FATipCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_Login2FATipCell forIndexPath:indexPath]; + cell.tipLabel.text = @"您的账户开启了两步验证,请输入动态验证码登录"; + return cell; + }else{ + NSString *identifier = (_step == LoginStepCompany? (self.isPrivateCloud? kCellIdentifier_Input_OnlyText_Cell_Text: + kCellIdentifier_Input_OnlyText_Cell_Company): + _step == LoginStepPassword? (row < 2? kCellIdentifier_Input_OnlyText_Cell_Text: + kCellIdentifier_Input_OnlyText_Cell_Captcha): + kCellIdentifier_Input_OnlyText_Cell_Text); + Input_OnlyText_Cell *cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath]; + cell.isBottomLineShow = YES; + __weak typeof(self) weakSelf = self; + if (_step == LoginStepCompany) { + [cell setPlaceholder:self.isPrivateCloud? @" 请输入私有部署域名": @" 请输入企业域名前缀" value:self.myLogin.company]; + if (!self.isPrivateCloud) { + cell.companySuffixL.text = [NSString stringWithFormat:@".%@", [NSObject baseCompanySuffixStr]]; + }else{ + cell.textField.keyboardType = UIKeyboardTypeURL; + } + cell.textValueChangedBlock = ^(NSString *valueStr){ + weakSelf.myLogin.company = valueStr; + }; + }else if (_step == LoginStepPassword){ + if (row == 0) { + cell.textField.keyboardType = UIKeyboardTypeEmailAddress; + [cell setPlaceholder:@" 邮箱或用户名" value:self.myLogin.email]; + cell.textValueChangedBlock = ^(NSString *valueStr){ + weakSelf.myLogin.email = valueStr; + }; + }else if (row == 1){ + [cell setPlaceholder:@" 密码" value:self.myLogin.password]; + cell.textField.secureTextEntry = YES; + cell.textValueChangedBlock = ^(NSString *valueStr){ + weakSelf.myLogin.password = valueStr; + }; + }else{ + [cell setPlaceholder:@" 验证码" value:self.myLogin.j_captcha]; + cell.textValueChangedBlock = ^(NSString *valueStr){ + weakSelf.myLogin.j_captcha = valueStr; + }; + } + }else if (_step == LoginStep2FA){ + cell.textField.keyboardType = UIKeyboardTypeNumberPad; + [cell setPlaceholder:@" 动态验证码" value:self.otpCode]; + cell.textValueChangedBlock = ^(NSString *valueStr){ + weakSelf.otpCode = valueStr; + }; + } + return cell; + } +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ + return 65.0; +} + +#pragma mark Btn Clicked + +- (void)backBtnClicked{ + if (self.navigationController.viewControllers.count > 1) { + [self.navigationController popViewControllerAnimated:YES]; + }else{ + [self dismissViewControllerAnimated:YES completion:nil]; + } +} + +- (void)rightNavBtnClicked{ + if (_step == LoginStep2FA) { + __weak typeof(self) weakSelf = self; + UIViewController *vc = [Close2FAViewController vcWithPhone:self.myLogin.email sucessBlock:^(UIViewController *vc) { + [weakSelf.navigationController popToViewController:weakSelf.navigationController.viewControllers[1] animated:YES]; + }]; + [self.navigationController pushViewController:vc animated:YES]; + }else{ + OTPListViewController *vc = [OTPListViewController new]; + [self.navigationController pushViewController:vc animated:YES]; + } +} + +- (void)cannotLoginBtnClicked{ + UIViewController *vc = [CannotLoginViewController vcWithMethodType:CannotLoginMethodEamil stepIndex:1 userStr:[self.myLogin.email isEmail]? self.myLogin.email: nil]; + [self.navigationController pushViewController:vc animated:YES]; +} + +- (void)loginBtnClicked{ + [self.view endEditing:YES]; + [self.activityIndicator startAnimating]; + _nextBtn.enabled = NO; + __weak typeof(self) weakSelf = self; + void (^endLoadingBlock)() = ^(){ + [weakSelf.activityIndicator stopAnimating]; + weakSelf.nextBtn.enabled = YES; + }; + if (_step == LoginStepCompany) { + [NSObject changeBaseCompanyTo:self.myLogin.company]; + [[Coding_NetAPIManager sharedManager] request_CompanyExist:[NSObject baseCompany] andBlock:^(id data, NSError *error) { + endLoadingBlock(); + if (error) { + if (error.code == 1){//企业不存在 + [NSObject showHudTipStr:weakSelf.isPrivateCloud? @"请正确填写私有部署域名": @"请正确填写企业域名"]; + }else{ + [NSObject showError:error]; + } + }else{ + NSDictionary *dataBody = [data objectForKey:@"data"]; + NSDictionary *settings = [dataBody objectForKey:@"settings"]; + BOOL ssoEnabled = [[settings objectForKey:@"ssoEnabled"] boolValue]; + NSString *ssoType = [settings objectForKey:@"ssoType"]; + self.myLogin.ssoType = ssoType; + self.myLogin.ssoEnabled = ssoEnabled; + [weakSelf goToNextStep]; + } + }]; + }else if (_step == LoginStepPassword){ + [[Coding_NetAPIManager sharedManager] request_Login_WithPath:[self.myLogin toPath] Params:[self.myLogin toParams] andBlock:^(id data, NSError *error) { + endLoadingBlock(); + if (data) { + [Login setPreUserEmail:weakSelf.myLogin.email];//记住登录账号 + [((AppDelegate *)[UIApplication sharedApplication].delegate) setupTabViewController]; + }else{ + NSString *global_key = error.userInfo[@"msg"][@"two_factor_auth_code_not_empty"]; + if (global_key.length > 0) { + weakSelf.myLogin.email = global_key; + [weakSelf goToNextStep]; + }else if (error.userInfo[@"msg"][@"user_need_activate"]){ + [NSObject showError:error]; + ActivateViewController *vc = [ActivateViewController new]; + [self.navigationController pushViewController:vc animated:YES]; + }else{ + [NSObject showError:error]; + [weakSelf refreshCaptchaNeeded]; + } + } + }]; + }else if (_step == LoginStep2FA){ + [[Coding_NetAPIManager sharedManager] request_Login_With2FA:self.otpCode andBlock:^(id data, NSError *error) { + endLoadingBlock(); + if (data) { + [Login setPreUserEmail:self.myLogin.email];//记住登录账号 + [((AppDelegate *)[UIApplication sharedApplication].delegate) setupTabViewController]; + }else{ + NSString *status_expired = error.userInfo[@"msg"][@"user_login_status_expired"]; + if (status_expired.length > 0) {//登录状态过期了,返回上个页面重新密码登录 + [weakSelf.navigationController popViewControllerAnimated:YES]; + } + } + }]; + }else{ + endLoadingBlock(); + } +} + +- (void)goToNextStep{ + LoginViewController *vc = [LoginViewController new]; + vc.myLogin = _myLogin; + vc.step = _step + 1; + [self.navigationController pushViewController:vc animated:YES]; +} + +#pragma mark 切换服务器手势 - 不停地 tap + +- (void)addChangeBaseURLGesture{ + @weakify(self); + UITapGestureRecognizer *tapGR = [UITapGestureRecognizer bk_recognizerWithHandler:^(UIGestureRecognizer *sender, UIGestureRecognizerState state, CGPoint location) { + @strongify(self); + if (state == UIGestureRecognizerStateRecognized) { + [self changeBaseURLTip]; + } + }]; + tapGR.numberOfTapsRequired = 10.0; + [self.view addGestureRecognizer:tapGR]; +} + +- (void)changeBaseURLTip{ + if ([UIDevice currentDevice].systemVersion.integerValue < 8) { + [NSObject showHudTipStr:@"需要 8.0 以上系统才能切换服务器地址"]; + return; + } + UIAlertController *alertCtrl = [UIAlertController alertControllerWithTitle:@"更改服务器 URL" message:@"空白值可切换回生产环境\n" preferredStyle:UIAlertControllerStyleAlert]; + + UIAlertAction *cancelA = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]; + __weak typeof(self) weakSelf = self; + UIAlertAction *confirmA = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) { + NSString *newBaseCompanySuffixStr = alertCtrl.textFields[0].text; + if ([newBaseCompanySuffixStr.uppercaseString isEqualToString:@"S"]) { + newBaseCompanySuffixStr = @"coding.codingprod.net"; + } + [NSObject changeBaseCompanySuffixStrTo:newBaseCompanySuffixStr]; + [weakSelf.myTableView reloadData]; + }]; + [alertCtrl addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { + textField.placeholder = @"CODING 服务器地址"; + textField.text = [NSObject baseCompanySuffixStr]; + }]; + [alertCtrl addAction:cancelA]; + [alertCtrl addAction:confirmA]; + [self presentViewController:alertCtrl animated:YES completion:nil]; +} + +@end + +#else + + @interface LoginViewController () @property (nonatomic, strong) Login *myLogin; @@ -31,9 +498,9 @@ @interface LoginViewController () @property (assign, nonatomic) BOOL captchaNeeded; -@property (strong, nonatomic) UIButton *loginBtn, *buttonFor2FA, *cannotLoginBtn; +@property (strong, nonatomic) UIButton *loginBtn, *buttonFor2FA, *underLoginBtn; @property (strong, nonatomic) UIActivityIndicatorView *activityIndicator; -@property (strong, nonatomic) UIImageView *iconUserView, *bgBlurredView; +//@property (strong, nonatomic) UIImageView *iconUserView, *bgBlurredView; @property (strong, nonatomic) EaseInputTipsView *inputTipsView; @property (strong, nonatomic) UIButton *dismissButton; @@ -56,26 +523,31 @@ - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. - + self.myLogin = [[Login alloc] init]; self.myLogin.email = [Login preUserEmail]; _captchaNeeded = NO; - + self.view.backgroundColor = kColorWhite; + [self.navigationController.navigationBar setupClearBGStyle]; + // 添加myTableView _myTableView = ({ TPKeyboardAvoidingTableView *tableView = [[TPKeyboardAvoidingTableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; [tableView registerClass:[Login2FATipCell class] forCellReuseIdentifier:kCellIdentifier_Login2FATipCell]; [tableView registerClass:[Input_OnlyText_Cell class] forCellReuseIdentifier:kCellIdentifier_Input_OnlyText_Cell_Text]; [tableView registerClass:[Input_OnlyText_Cell class] forCellReuseIdentifier:kCellIdentifier_Input_OnlyText_Cell_Captcha]; - - tableView.backgroundView = self.bgBlurredView; + + // tableView.backgroundView = self.bgBlurredView; tableView.dataSource = self; tableView.delegate = self; tableView.separatorStyle = UITableViewCellSeparatorStyleNone; [self.view addSubview:tableView]; [tableView mas_makeConstraints:^(MASConstraintMaker *make) { - make.edges.equalTo(self.view); + make.edges.equalTo(self.view).insets(UIEdgeInsetsMake(kSafeArea_Top, 0, 0, 0)); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); @@ -86,19 +558,19 @@ - (void)viewDidLoad [self buttonFor2FA]; [self refreshCaptchaNeeded]; - [self refreshIconUserImage]; + // [self refreshIconUserImage]; } - (UIButton *)buttonFor2FA{ if (!_buttonFor2FA) { _buttonFor2FA = ({ - UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(kScreen_Width - 100, 20, 90, 50)]; - [button.titleLabel setFont:[UIFont systemFontOfSize:13]]; - [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; - [button setTitleColor:[UIColor colorWithWhite:1.0 alpha:0.5] forState:UIControlStateHighlighted]; - + UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(kScreen_Width - 115, kSafeArea_Top, 100, 50)]; + [button.titleLabel setFont:[UIFont systemFontOfSize:15]]; + [button setTitleColor:kColorBrandBlue forState:UIControlStateNormal]; + [button setTitleColor:[UIColor colorWithHexString:@"0x0060FF" andAlpha:.5] forState:UIControlStateHighlighted]; + button.tintColor = kColorBrandBlue; [button setTitle:@" 两步验证" forState:UIControlStateNormal]; - [button setImage:[UIImage imageNamed:@"twoFABtn_Nav"] forState:UIControlStateNormal]; + [button setImage:[[UIImage imageNamed:@"twoFABtn_Nav"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal]; button; }); [_buttonFor2FA addTarget:self action:@selector(goTo2FAVC) forControlEvents:UIControlEventTouchUpInside]; @@ -114,29 +586,29 @@ - (void)setCaptchaNeeded:(BOOL)captchaNeeded{ } } -- (UIImageView *)bgBlurredView{ - if (!_bgBlurredView) { - //背景图片 - UIImageView *bgView = [[UIImageView alloc] initWithFrame:kScreen_Bounds]; - bgView.contentMode = UIViewContentModeScaleAspectFill; - UIImage *bgImage = [[StartImagesManager shareManager] curImage].image; - - CGSize bgImageSize = bgImage.size, bgViewSize = bgView.frame.size; - if (bgImageSize.width > bgViewSize.width && bgImageSize.height > bgViewSize.height) { - bgImage = [bgImage scaleToSize:bgViewSize usingMode:NYXResizeModeAspectFill]; - } - bgImage = [bgImage applyLightEffectAtFrame:CGRectMake(0, 0, bgImage.size.width, bgImage.size.height)]; - bgView.image = bgImage; - //黑色遮罩 - UIColor *blackColor = [UIColor blackColor]; - [bgView addGradientLayerWithColors:@[(id)[blackColor colorWithAlphaComponent:0.3].CGColor, - (id)[blackColor colorWithAlphaComponent:0.3].CGColor] - locations:nil - startPoint:CGPointMake(0.5, 0.0) endPoint:CGPointMake(0.5, 1.0)]; - _bgBlurredView = bgView; - } - return _bgBlurredView; -} +//- (UIImageView *)bgBlurredView{ +// if (!_bgBlurredView) { +// //背景图片 +// UIImageView *bgView = [[UIImageView alloc] initWithFrame:kScreen_Bounds]; +// bgView.contentMode = UIViewContentModeScaleAspectFill; +// UIImage *bgImage = [[StartImagesManager shareManager] curImage].image; +// +// CGSize bgImageSize = bgImage.size, bgViewSize = bgView.frame.size; +// if (bgImageSize.width > bgViewSize.width && bgImageSize.height > bgViewSize.height) { +// bgImage = [bgImage scaleToSize:bgViewSize usingMode:NYXResizeModeAspectFill]; +// } +// bgImage = [bgImage applyLightEffectAtFrame:CGRectMake(0, 0, bgImage.size.width, bgImage.size.height)]; +// bgView.image = bgImage; +// //黑色遮罩 +// UIColor *blackColor = [UIColor blackColor]; +// [bgView addGradientLayerWithColors:@[(id)[blackColor colorWithAlphaComponent:0.3].CGColor, +// (id)[blackColor colorWithAlphaComponent:0.3].CGColor] +// locations:nil +// startPoint:CGPointMake(0.5, 0.0) endPoint:CGPointMake(0.5, 1.0)]; +// _bgBlurredView = bgView; +// } +// return _bgBlurredView; +//} - (void)refreshCaptchaNeeded{ @@ -168,11 +640,11 @@ - (void)viewDidAppear:(BOOL)animated{ tipsView.selectedStringBlock = ^(NSString *valueStr){ [weakSelf.view endEditing:YES]; weakSelf.myLogin.email = valueStr; - [weakSelf refreshIconUserImage]; + // [weakSelf refreshIconUserImage]; [weakSelf.myTableView reloadData]; }; UITableViewCell *cell = [_myTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; - [tipsView setY:CGRectGetMaxY(cell.frame) - 0.5]; + [tipsView setY:CGRectGetMaxY(cell.frame)]; [_myTableView addSubview:tipsView]; tipsView; @@ -188,8 +660,9 @@ - (void)viewWillDisappear:(BOOL)animated{ - (void)showdismissButton:(BOOL)willShow{ self.dismissButton.hidden = !willShow; if (!self.dismissButton && willShow) { - self.dismissButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 20, 50, 50)]; - [self.dismissButton setImage:[UIImage imageNamed:@"dismissBtn_Nav"] forState:UIControlStateNormal]; + self.dismissButton = [[UIButton alloc] initWithFrame:CGRectMake(0, kSafeArea_Top, 50, 50)]; + self.dismissButton.tintColor = kColorBrandBlue; + [self.dismissButton setImage:[[UIImage imageNamed:@"back_green_Nav"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal]; [self.dismissButton addTarget:self action:@selector(dismissButtonClicked) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:self.dismissButton]; } @@ -211,13 +684,12 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N { if (self.is2FAUI && indexPath.row == 0) { Login2FATipCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_Login2FATipCell forIndexPath:indexPath]; - cell.tipLabel.text = @" 您的账户开启了两步验证,请输入动态验证码登录 "; return cell; } Input_OnlyText_Cell *cell = [tableView dequeueReusableCellWithIdentifier:(indexPath.row > 1? kCellIdentifier_Input_OnlyText_Cell_Captcha: kCellIdentifier_Input_OnlyText_Cell_Text) forIndexPath:indexPath]; - cell.isForLoginVC = YES; - + // cell.isForLoginVC = YES; + cell.isBottomLineShow = YES; __weak typeof(self) weakSelf = self; if (self.is2FAUI) { cell.textField.keyboardType = UIKeyboardTypeNumberPad; @@ -228,12 +700,12 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N }else{ if (indexPath.row == 0) { cell.textField.keyboardType = UIKeyboardTypeEmailAddress; - [cell setPlaceholder:@" 手机号码/电子邮箱/个性后缀" value:self.myLogin.email]; + [cell setPlaceholder:@" 手机 / 邮箱 / 用户名" value:self.myLogin.email]; cell.textValueChangedBlock = ^(NSString *valueStr){ weakSelf.inputTipsView.valueStr = valueStr; weakSelf.inputTipsView.active = YES; weakSelf.myLogin.email = valueStr; - [weakSelf refreshIconUserImage]; + // [weakSelf refreshIconUserImage]; }; cell.editDidBeginBlock = ^(NSString *valueStr){ weakSelf.inputTipsView.valueStr = valueStr; @@ -258,51 +730,42 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N return cell; } -- (void)refreshIconUserImage{ - NSString *textStr = self.myLogin.email; - if (textStr) { - User *curUser = [Login userWithGlobaykeyOrEmail:textStr]; - if (curUser && curUser.avatar) { - [self.iconUserView sd_setImageWithURL:[curUser.avatar urlImageWithCodePathResizeToView:self.iconUserView] placeholderImage:[UIImage imageNamed:@"icon_user_monkey"]]; - return; - } +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ + if (self.is2FAUI && indexPath.row == 0) { + return 40; } - [self.iconUserView setImage:[UIImage imageNamed:@"icon_user_monkey"]]; + return 65; } +//- (void)refreshIconUserImage{ +// NSString *textStr = self.myLogin.email; +// if (textStr) { +// User *curUser = [Login userWithGlobaykeyOrEmail:textStr]; +// if (curUser && curUser.avatar) { +// [self.iconUserView sd_setImageWithURL:[curUser.avatar urlImageWithCodePathResizeToView:self.iconUserView] placeholderImage:[UIImage imageNamed:@"icon_user_monkey"]]; +// return; +// } +// } +// [self.iconUserView setImage:[UIImage imageNamed:@"icon_user_monkey"]]; +//} + #pragma mark - Table view Header Footer - (UIView *)customHeaderView{ - CGFloat iconUserViewWidth; - if (kDevice_Is_iPhone6Plus) { - iconUserViewWidth = 100; - }else if (kDevice_Is_iPhone6){ - iconUserViewWidth = 90; - }else{ - iconUserViewWidth = 75; - } - - UIView *headerV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, kScreen_Height/3)]; - - _iconUserView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, iconUserViewWidth, iconUserViewWidth)]; - _iconUserView.contentMode = UIViewContentModeScaleAspectFit; - _iconUserView.layer.masksToBounds = YES; - _iconUserView.layer.cornerRadius = _iconUserView.frame.size.width/2; - _iconUserView.layer.borderWidth = 2; - _iconUserView.layer.borderColor = [UIColor whiteColor].CGColor; - - [headerV addSubview:_iconUserView]; - [_iconUserView mas_makeConstraints:^(MASConstraintMaker *make) { - make.size.mas_equalTo(CGSizeMake(iconUserViewWidth, iconUserViewWidth)); - make.centerX.equalTo(headerV); - make.centerY.equalTo(headerV).offset(30); + UIView *headerV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 110)]; + UILabel *headerL = [UILabel labelWithFont:[UIFont systemFontOfSize:30] textColor:kColorDark2]; + headerL.text = self.is2FAUI? @"两步验证": @"登录"; + [headerV addSubview:headerL]; + [headerL mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.offset(kPaddingLeftWidth); + make.bottom.offset(0); + make.height.mas_equalTo(42); }]; - [_iconUserView setImage:[UIImage imageNamed:@"icon_user_monkey"]]; return headerV; } - (UIView *)customFooterView{ - UIView *footerV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 150)]; - _loginBtn = [UIButton buttonWithStyle:StrapSuccessStyle andTitle:@"登录" andFrame:CGRectMake(kLoginPaddingLeftWidth, 20, kScreen_Width-kLoginPaddingLeftWidth*2, 45) target:self action:@selector(sendLogin)]; + UIView *footerV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 200)]; + _loginBtn = [UIButton buttonWithStyle:StrapSuccessStyle andTitle:@"登录" andFrame:CGRectMake(kLoginPaddingLeftWidth, 55, kScreen_Width-kLoginPaddingLeftWidth*2, 50) target:self action:@selector(sendLogin)]; [footerV addSubview:_loginBtn]; RAC(self, loginBtn.enabled) = [RACSignal combineLatest:@[RACObserve(self, myLogin.email), RACObserve(self, myLogin.password), @@ -326,13 +789,14 @@ - (UIView *)customFooterView{ } } }]; - _cannotLoginBtn = ({ + _underLoginBtn = ({ UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100, 30)]; [button.titleLabel setFont:[UIFont systemFontOfSize:14]]; - [button setTitleColor:[UIColor colorWithWhite:1.0 alpha:0.5] forState:UIControlStateNormal]; - [button setTitleColor:[UIColor colorWithWhite:0.5 alpha:0.5] forState:UIControlStateHighlighted]; + [button setTitleColor:kColorDark2 forState:UIControlStateNormal]; + button.tintColor = kColorDark2; + [button setTitle:@" 微信登录" forState:UIControlStateNormal]; + [button setImage:[UIImage imageNamed:@"login_wechat"] forState:UIControlStateNormal]; - [button setTitle:@"找回密码" forState:UIControlStateNormal]; [footerV addSubview:button]; [button mas_makeConstraints:^(MASConstraintMaker *make) { make.size.mas_equalTo(CGSizeMake(100, 30)); @@ -341,7 +805,25 @@ - (UIView *)customFooterView{ }]; button; }); - [_cannotLoginBtn addTarget:self action:@selector(cannotLoginBtnClicked:) forControlEvents:UIControlEventTouchUpInside]; + [_underLoginBtn addTarget:self action:@selector(underLoginBtnClicked:) forControlEvents:UIControlEventTouchUpInside]; + + _underLoginBtn.hidden = ![self p_canOpenWeiXin]; + + UIButton *cannotLoginBtn = ({ + UIButton *button = [UIButton new]; + [button.titleLabel setFont:[UIFont systemFontOfSize:14]]; + [button setTitleColor:kColorDark4 forState:UIControlStateNormal]; + + [button setTitle:@"忘记密码?" forState:UIControlStateNormal]; + [footerV addSubview:button]; + [button mas_makeConstraints:^(MASConstraintMaker *make) { + make.size.mas_equalTo(CGSizeMake(90, 30)); + make.top.offset(15); + make.right.offset(-kPaddingLeftWidth); + }]; + button; + }); + [cannotLoginBtn addTarget:self action:@selector(cannotLoginBtnClicked:) forControlEvents:UIControlEventTouchUpInside]; return footerV; } @@ -349,25 +831,30 @@ - (UIView *)customFooterView{ #pragma mark BottomView - (void)configBottomView{ if (!_bottomView) { - _bottomView = [[UIView alloc] initWithFrame:CGRectMake(0, kScreen_Height - 55, kScreen_Width, 55)]; - _bottomView.backgroundColor = [UIColor clearColor]; + _bottomView = [UIView new]; + UIButton *registerBtn = ({ UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100, 30)]; - [button.titleLabel setFont:[UIFont systemFontOfSize:14]]; - [button setTitleColor:[UIColor colorWithWhite:1.0 alpha:0.5] forState:UIControlStateNormal]; - [button setTitleColor:[UIColor colorWithWhite:0.5 alpha:0.5] forState:UIControlStateHighlighted]; + [button.titleLabel setFont:[UIFont systemFontOfSize:15]]; + [button setTitleColor:kColorDark2 forState:UIControlStateNormal]; - [button setTitle:@"去注册" forState:UIControlStateNormal]; + [button setTitle:@"注册新账号" forState:UIControlStateNormal]; [_bottomView addSubview:button]; [button mas_makeConstraints:^(MASConstraintMaker *make) { make.size.mas_equalTo(CGSizeMake(100, 30)); - make.centerX.equalTo(_bottomView); make.top.equalTo(_bottomView); + make.centerX.equalTo(_bottomView); }]; button; }); [registerBtn addTarget:self action:@selector(goRegisterVC:) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:_bottomView]; + [_bottomView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.equalTo(self.view); + make.bottom.offset(-kSafeArea_Bottom); + make.height.mas_equalTo(55); + }]; } } @@ -436,16 +923,11 @@ - (void)sendLogin{ - (void)doSomethingAfterLogin{ User *curUser = [Login curLoginUser]; if (curUser.email.length > 0 && !curUser.email_validation.boolValue) { - UIAlertView *alertView = [UIAlertView bk_alertViewWithTitle:@"激活邮箱" message:@"该邮箱尚未激活,请尽快去邮箱查收邮件并激活账号。如果在收件箱中没有看到,请留意一下垃圾邮件箱子(T_T)"]; - [alertView bk_setCancelButtonWithTitle:@"取消" handler:nil]; - [alertView bk_addButtonWithTitle:@"重发激活邮件" handler:nil]; - [alertView bk_setDidDismissBlock:^(UIAlertView *alert, NSInteger index) { - if (index == 1) { + [[UIAlertController ea_alertViewWithTitle:@"激活邮箱" message:@"该邮箱尚未激活,请尽快去邮箱查收邮件并激活账号。如果在收件箱中没有看到,请留意一下垃圾邮件箱子(T_T)" buttonTitles:@[@"重发激活邮件"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { [self sendActivateEmail]; } - }]; - [alertView show]; - + }] show]; } } - (void)sendActivateEmail{ @@ -457,28 +939,28 @@ - (void)sendActivateEmail{ } - (IBAction)cannotLoginBtnClicked:(id)sender { - UIViewController *vc; - if (_is2FAUI) { - vc = [Close2FAViewController vcWithPhone:self.myLogin.email sucessBlock:^(UIViewController *vc) { - self.is2FAUI = NO; - [self.navigationController popToRootViewControllerAnimated:YES]; - }]; - }else{ - vc = [CannotLoginViewController vcWithMethodType:0 stepIndex:0 userStr:(([self.myLogin.email isPhoneNo] || [self.myLogin.email isEmail])? self.myLogin.email: nil)]; - } + CannotLoginViewController *vc = [CannotLoginViewController vcWithMethodType:CannotLoginMethodPhone stepIndex:0 userStr:([self.myLogin.email isPhoneNo]? self.myLogin.email: nil)]; [self.navigationController pushViewController:vc animated:YES]; } - (IBAction)goRegisterVC:(id)sender { - RegisterViewController *vc = [RegisterViewController vcWithMethodType:RegisterMethodPhone registerObj:nil]; - [self.navigationController pushViewController:vc animated:YES]; + if (self.navigationController.viewControllers.count > 1) { + [self.navigationController popToRootViewControllerAnimated:YES]; + }else{ + RegisterViewController *vc = [RegisterViewController vcWithMethodType:RegisterMethodPhone registerObj:nil]; + [self.navigationController pushViewController:vc animated:YES]; + } } - (void)dismissButtonClicked{ if (self.is2FAUI) { self.is2FAUI = NO; }else{ - [self dismissViewControllerAnimated:YES completion:nil]; + if (self.navigationController.viewControllers.count > 1) { + [self.navigationController popViewControllerAnimated:YES]; + }else{ + [self dismissViewControllerAnimated:YES completion:nil]; + } } } @@ -493,14 +975,16 @@ - (void)changeUITo2FAWithGK:(NSString *)global_key{ - (void)setIs2FAUI:(BOOL)is2FAUI{ _is2FAUI = is2FAUI; + UILabel *headerL = self.myTableView.tableHeaderView.subviews.firstObject; + headerL.text = self.is2FAUI? @"两步验证": @"登录"; if (!_is2FAUI) { self.otpCode = nil; - [self.dismissButton setImage:[UIImage imageNamed:@"dismissBtn_Nav"] forState:UIControlStateNormal]; + [_buttonFor2FA setTitle:@" 两步验证" forState:UIControlStateNormal]; + [_buttonFor2FA setImage:[[UIImage imageNamed:@"twoFABtn_Nav"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal]; }else{ - [self.dismissButton setImage:[UIImage imageNamed:@"backBtn_Nav"] forState:UIControlStateNormal]; + [_buttonFor2FA setTitle:@"关闭两步验证" forState:UIControlStateNormal]; + [_buttonFor2FA setImage:nil forState:UIControlStateNormal]; } - [_cannotLoginBtn setTitle:_is2FAUI? @"关闭两步验证": @"找回密码" forState:UIControlStateNormal]; - [self.myTableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:_is2FAUI? UITableViewRowAnimationLeft: UITableViewRowAnimationRight]; } @@ -515,7 +999,65 @@ - (NSString *)loginTipFor2FA{ } - (void)goTo2FAVC{ - OTPListViewController *vc = [OTPListViewController new]; - [self.navigationController pushViewController:vc animated:YES]; + if (_is2FAUI) { + Close2FAViewController *vc = [Close2FAViewController vcWithPhone:self.myLogin.email sucessBlock:^(UIViewController *vc) { + self.is2FAUI = NO; + [self.navigationController popToRootViewControllerAnimated:YES]; + }]; + [self.navigationController pushViewController:vc animated:YES]; + }else{ + OTPListViewController *vc = [OTPListViewController new]; + [self.navigationController pushViewController:vc animated:YES]; + } +} + +#pragma mark thridPlatform +- (void)underLoginBtnClicked:(UIButton *)sender { + UMSocialPlatformType platformType = UMSocialPlatformType_WechatSession; + if (platformType != UMSocialPlatformType_UnKnown) { + __weak typeof(self) weakSelf = self; + [[UMSocialManager defaultManager] getUserInfoWithPlatform:platformType currentViewController:self completion:^(id result, NSError *error) { + UMSocialResponse *resp = result; + if (!error) { + [weakSelf p_thridPlatformLogin:resp]; + }else if (error){ + [NSObject showHudTipStr:@"授权失败"]; + DebugLog(@"%@", error); + } + }]; + } } + +- (void)p_thridPlatformLogin:(UMSocialResponse *)resp{ + [self.view endEditing:YES]; + + __weak typeof(self) weakSelf = self; + [NSObject showHUDQueryStr:@"正在登录..."]; + [[Coding_NetAPIManager sharedManager] request_Login_With_UMSocialResponse:resp andBlock:^(id data, NSError *error) { + [NSObject hideHUDQuery]; + if (data) { + [((AppDelegate *)[UIApplication sharedApplication].delegate) setupTabViewController]; + [weakSelf doSomethingAfterLogin]; + }else if (error){ + if (error.userInfo[@"msg"][@"oauth_account_not_bound"]) { + kTipAlert(@"抱歉,你还未绑定微信,请前往 Coding 主站完成微信绑定操作"); + }else{ + [NSObject showError:error]; + } + } + }]; +} + +#pragma mark - app url +- (BOOL)p_canOpenWeiXin{ + return [self p_canOpen:@"weixin://"]; +} + +- (BOOL)p_canOpen:(NSString*)url{ + return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:url]]; +} + @end + +#endif + diff --git a/Coding_iOS/Controllers/Login/PasswordViewController.m b/Coding_iOS/Controllers/Login/PasswordViewController.m index e0920605c..c8530329b 100644 --- a/Coding_iOS/Controllers/Login/PasswordViewController.m +++ b/Coding_iOS/Controllers/Login/PasswordViewController.m @@ -43,6 +43,9 @@ - (void)viewDidLoad [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); self.myTableView.tableFooterView=[self customFooterView]; @@ -133,7 +136,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ - return 44.0; + return 50; } #pragma mark Btn Clicked diff --git a/Coding_iOS/Controllers/Login/RegisterViewController.m b/Coding_iOS/Controllers/Login/RegisterViewController.m index 5e1006528..de6beaba9 100755 --- a/Coding_iOS/Controllers/Login/RegisterViewController.m +++ b/Coding_iOS/Controllers/Login/RegisterViewController.m @@ -17,6 +17,7 @@ #import "CannotLoginViewController.h" #import "EaseInputTipsView.h" #import "CountryCodeListViewController.h" +#import "LoginViewController.h" @interface RegisterViewController () @property (nonatomic, assign) RegisterMethodType medthodType; @@ -32,6 +33,8 @@ @interface RegisterViewController () 1) { + [weakSelf.navigationController popToRootViewControllerAnimated:YES]; + }else{ + LoginViewController *vc = [[LoginViewController alloc] init]; + vc.showDismissButton = YES; + [weakSelf.navigationController pushViewController:vc animated:YES]; + } + } forControlEvents:UIControlEventTouchUpInside]; button; }); - [bottomView addSubview:bottomBtn]; [bottomBtn mas_makeConstraints:^(MASConstraintMaker *make) { - make.edges.equalTo(bottomView).insets(UIEdgeInsetsMake(0, 0, 30, 0)); + make.left.top.right.equalTo(bottomView); + make.height.mas_equalTo(25); }]; - [self.view addSubview:bottomView]; [bottomView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.bottom.equalTo(self.view); - make.height.mas_equalTo(50); + make.height.mas_equalTo(50 + kSafeArea_Bottom); }]; } @@ -167,22 +197,21 @@ - (void)changeMethodType{ } } - (UIView *)customHeaderView{ - UIView *headerV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 0.15*kScreen_Height)]; - headerV.backgroundColor = [UIColor clearColor]; - UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 50)]; - headerLabel.backgroundColor = [UIColor clearColor]; - headerLabel.font = [UIFont boldSystemFontOfSize:18]; - headerLabel.textColor = kColor222; - headerLabel.textAlignment = NSTextAlignmentCenter; - headerLabel.text = @"加入Coding,体验云端开发之美!"; - [headerLabel setCenter:headerV.center]; - [headerV addSubview:headerLabel]; + UIView *headerV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 60)]; + UILabel *headerL = [UILabel labelWithFont:[UIFont systemFontOfSize:30] textColor:kColorDark2]; + headerL.text = self.step > 0? @"设置密码": @"注册"; + [headerV addSubview:headerL]; + [headerL mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.offset(kPaddingLeftWidth); + make.bottom.offset(0); + make.height.mas_equalTo(42); + }]; return headerV; } - (UIView *)customFooterView{ UIView *footerV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 150)]; //button - _footerBtn = [UIButton buttonWithStyle:StrapSuccessStyle andTitle:@"注册" andFrame:CGRectMake(kLoginPaddingLeftWidth, 20, kScreen_Width-kLoginPaddingLeftWidth*2, 45) target:self action:@selector(sendRegister)]; + _footerBtn = [UIButton buttonWithStyle:StrapSuccessStyle andTitle:self.step > 0? @"注册": @"下一步" andFrame:CGRectMake(kLoginPaddingLeftWidth, 20, kScreen_Width-kLoginPaddingLeftWidth*2, 50) target:self action:@selector(sendRegister)]; [footerV addSubview:_footerBtn]; __weak typeof(self) weakSelf = self; @@ -190,6 +219,7 @@ - (UIView *)customFooterView{ RACObserve(self, myRegister.phone), RACObserve(self, myRegister.email), RACObserve(self, myRegister.password), + RACObserve(self, myRegister.confirm_password), RACObserve(self, myRegister.code), RACObserve(self, myRegister.j_captcha), RACObserve(self, captchaNeeded)] @@ -197,33 +227,47 @@ - (UIView *)customFooterView{ NSString *phone, NSString *email, NSString *password, + NSString *confirm_password, NSString *code, NSString *j_captcha, NSNumber *captchaNeeded){ - BOOL enabled = (global_key.length > 0 && - password.length > 0 && - (!captchaNeeded.boolValue || j_captcha.length > 0) && - ((weakSelf.medthodType == RegisterMethodEamil && email.length > 0) || - (weakSelf.medthodType == RegisterMethodPhone && phone.length > 0 && code.length > 0))); + BOOL enabled; + if (weakSelf.medthodType == RegisterMethodEamil) { + enabled = (global_key.length > 0 && + password.length > 0 && + (!captchaNeeded.boolValue || j_captcha.length > 0) && + email.length > 0); + }else if (weakSelf.step > 0){ + enabled = (global_key.length > 0 && + password.length > 0 && + confirm_password.length > 0 && +// [confirm_password isEqualToString:password] && + (!captchaNeeded.boolValue || j_captcha.length > 0) && + (phone.length > 0 && code.length > 0)); + }else{ + enabled = (global_key.length > 0 && + (!captchaNeeded.boolValue || j_captcha.length > 0) && + (phone.length > 0 && code.length > 0)); + } return @(enabled); }]; //label UITTTAttributedLabel *lineLabel = ({ - UITTTAttributedLabel *label = [[UITTTAttributedLabel alloc] init]; + UITTTAttributedLabel *label = [[UITTTAttributedLabel alloc] initWithFrame:CGRectZero]; label.textAlignment = NSTextAlignmentCenter; - label.font = [UIFont systemFontOfSize:12]; - label.textColor = kColor999; + label.font = [UIFont systemFontOfSize:14]; + label.textColor = kColorDark2; label.numberOfLines = 0; label.linkAttributes = kLinkAttributes; label.activeLinkAttributes = kLinkAttributesActive; label.delegate = self; label; }); - NSString *tipStr = @"注册 Coding 账号表示您已同意《Coding 服务条款》"; + NSString *tipStr = @"点击注册,即同意《Coding 服务条款》"; lineLabel.text = tipStr; [lineLabel addLinkToTransitInformation:@{@"actionStr" : @"gotoServiceTermsVC"} withRange:[tipStr rangeOfString:@"《Coding 服务条款》"]]; CGRect footerBtnFrame = _footerBtn.frame; - lineLabel.frame = CGRectMake(CGRectGetMinX(footerBtnFrame), CGRectGetMaxY(footerBtnFrame) +12, CGRectGetWidth(footerBtnFrame), 12); + lineLabel.frame = CGRectMake(CGRectGetMinX(footerBtnFrame), CGRectGetMaxY(footerBtnFrame) +15, CGRectGetWidth(footerBtnFrame), 15); [footerV addSubview:lineLabel]; return footerV; @@ -231,7 +275,7 @@ - (UIView *)customFooterView{ #pragma mark - Table view data source - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ - NSInteger num = _medthodType == RegisterMethodEamil? 3: 4; + NSInteger num = _medthodType == RegisterMethodEamil? 3: _step > 0? 2: 3; return _captchaNeeded? num +1 : num; } @@ -242,20 +286,24 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N indexPath.row == 2? kCellIdentifier_Input_OnlyText_Cell_Password: kCellIdentifier_Input_OnlyText_Cell_Text); }else{ - cellIdentifier = (indexPath.row == 4? kCellIdentifier_Input_OnlyText_Cell_Captcha: - indexPath.row == 3? self.phoneCodeCellIdentifier: - indexPath.row == 2? kCellIdentifier_Input_OnlyText_Cell_Password: - indexPath.row == 1? kCellIdentifier_Input_OnlyText_Cell_Phone: - kCellIdentifier_Input_OnlyText_Cell_Text); + if (_step > 0) { + cellIdentifier = (indexPath.row == 2? kCellIdentifier_Input_OnlyText_Cell_Captcha: + kCellIdentifier_Input_OnlyText_Cell_Text); + }else{ + cellIdentifier = (indexPath.row == 2? self.phoneCodeCellIdentifier: + indexPath.row == 1? kCellIdentifier_Input_OnlyText_Cell_Phone: + kCellIdentifier_Input_OnlyText_Cell_Text); + } } Input_OnlyText_Cell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath]; + cell.isBottomLineShow = YES; __weak typeof(self) weakSelf = self; if (_medthodType == RegisterMethodEamil) { if (indexPath.row == 0) { - [cell setPlaceholder:@" 用户名(个性后缀)" value:self.myRegister.global_key]; + [cell setPlaceholder:@" 用户名" value:self.myRegister.global_key]; cell.textValueChangedBlock = ^(NSString *valueStr){ - weakSelf.myRegister.global_key = valueStr; + weakSelf.myRegister.global_key = [valueStr trimWhitespace]; }; }else if (indexPath.row == 1){ cell.textField.keyboardType = UIKeyboardTypeEmailAddress; @@ -280,53 +328,58 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N }; } }else{ - if (indexPath.row == 0) { - [cell setPlaceholder:@" 用户名(个性后缀)" value:self.myRegister.global_key]; - cell.textValueChangedBlock = ^(NSString *valueStr){ - weakSelf.myRegister.global_key = valueStr; - }; - }else if (indexPath.row == 1){ - if (!_countryCodeDict) { - _countryCodeDict = @{@"country": @"China", - @"country_code": @"86", - @"iso_code": @"cn"}; + if (_step > 0) { + if (indexPath.row == 0){ + [cell setPlaceholder:@" 设置密码" value:self.myRegister.password]; + cell.textField.secureTextEntry = YES; + cell.textValueChangedBlock = ^(NSString *valueStr){ + weakSelf.myRegister.password = valueStr; + }; + }else if (indexPath.row == 1){ + [cell setPlaceholder:@" 重复密码" value:self.myRegister.password]; + cell.textField.secureTextEntry = YES; + cell.textValueChangedBlock = ^(NSString *valueStr){ + weakSelf.myRegister.confirm_password = valueStr; + }; + }else{ + [cell setPlaceholder:@" 验证码" value:self.myRegister.j_captcha]; + cell.textValueChangedBlock = ^(NSString *valueStr){ + weakSelf.myRegister.j_captcha = valueStr; + }; } - cell.textField.keyboardType = UIKeyboardTypeNumberPad; - [cell setPlaceholder:@" 手机号" value:self.myRegister.phone]; - cell.countryCodeL.text = [NSString stringWithFormat:@"+%@", _countryCodeDict[@"country_code"]]; - cell.countryCodeBtnClickedBlock = ^(){ - [weakSelf goToCountryCodeVC]; - }; - cell.textValueChangedBlock = ^(NSString *valueStr){ - weakSelf.myRegister.phone = valueStr; - }; - }else if (indexPath.row == 2){ - [cell setPlaceholder:@" 设置密码" value:self.myRegister.password]; - cell.textValueChangedBlock = ^(NSString *valueStr){ - weakSelf.myRegister.password = valueStr; - }; - }else if (indexPath.row == 3){ - cell.textField.keyboardType = UIKeyboardTypeNumberPad; - [cell setPlaceholder:@" 手机验证码" value:self.myRegister.code]; - cell.textValueChangedBlock = ^(NSString *valueStr){ - weakSelf.myRegister.code = valueStr; - }; - cell.phoneCodeBtnClckedBlock = ^(PhoneCodeButton *btn){ - [weakSelf phoneCodeBtnClicked:btn]; - }; }else{ - [cell setPlaceholder:@" 验证码" value:self.myRegister.j_captcha]; - cell.textValueChangedBlock = ^(NSString *valueStr){ - weakSelf.myRegister.j_captcha = valueStr; - }; + if (indexPath.row == 0) { + [cell setPlaceholder:@" 用户名" value:self.myRegister.global_key]; + cell.textValueChangedBlock = ^(NSString *valueStr){ + weakSelf.myRegister.global_key = [valueStr trimWhitespace]; + }; + }else if (indexPath.row == 1){ + cell.textField.keyboardType = UIKeyboardTypeNumberPad; + [cell setPlaceholder:@" 手机号码" value:self.myRegister.phone]; + cell.countryCodeL.text = [NSString stringWithFormat:@"+%@", _countryCodeDict[@"country_code"]]; + cell.countryCodeBtnClickedBlock = ^(){ + [weakSelf goToCountryCodeVC]; + }; + cell.textValueChangedBlock = ^(NSString *valueStr){ + weakSelf.myRegister.phone = valueStr; + }; + }else if (indexPath.row == 2){ + cell.textField.keyboardType = UIKeyboardTypeNumberPad; + [cell setPlaceholder:@" 手机验证码" value:self.myRegister.code]; + cell.textValueChangedBlock = ^(NSString *valueStr){ + weakSelf.myRegister.code = valueStr; + }; + cell.phoneCodeBtnClckedBlock = ^(PhoneCodeButton *btn){ + [weakSelf phoneCodeBtnClicked:btn withCaptcha:nil]; + }; + } } } - [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kLoginPaddingLeftWidth]; return cell; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ - return 44.0; + return 65.0; } #pragma mark TTTAttributedLabelDelegate @@ -334,59 +387,151 @@ - (void)attributedLabel:(TTTAttributedLabel *)label didSelectLinkWithTransitInfo [self gotoServiceTermsVC]; } #pragma mark Btn Clicked -- (void)phoneCodeBtnClicked:(PhoneCodeButton *)sender{ +- (void)phoneCodeBtnClicked:(PhoneCodeButton *)sender withCaptcha:(NSString *)captcha{ if (![_myRegister.phone isPhoneNo]) { [NSObject showHudTipStr:@"手机号码格式有误"]; return; } sender.enabled = NO; - NSDictionary *params = @{@"phone": _myRegister.phone, - @"phoneCountryCode": [NSString stringWithFormat:@"+%@", _countryCodeDict[@"country_code"]]}; - [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:@"api/account/register/generate_phone_code" withParams:params withMethodType:Post andBlock:^(id data, NSError *error) { + NSMutableDictionary *params = @{@"phone": _myRegister.phone, + @"phoneCountryCode": [NSString stringWithFormat:@"+%@", _countryCodeDict[@"country_code"]]}.mutableCopy; + if (captcha.length > 0) { + params[@"j_captcha"] = captcha; + } + __weak typeof(self) weakSelf = self; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:@"api/account/register/generate_phone_code" withParams:params withMethodType:Post autoShowError:captcha.length > 0 andBlock:^(id data, NSError *error) { if (data) { [NSObject showHudTipStr:@"验证码发送成功"]; [sender startUpTimer]; }else{ [sender invalidateTimer]; + if (error && error.userInfo[@"msg"] && [[error.userInfo[@"msg"] allKeys] containsObject:@"j_captcha_error"]) { + [weakSelf p_showCaptchaAlert:sender]; + }else if (captcha.length <= 0){ + [NSObject showError:error]; + } + } + }]; +} + +- (void)p_showCaptchaAlert:(PhoneCodeButton *)sender{ + SDCAlertController *alertV = [SDCAlertController alertControllerWithTitle:@"提示" message:@"请输入图片验证码" preferredStyle:SDCAlertControllerStyleAlert]; + UITextField *textF = [UITextField new]; + textF.layer.sublayerTransform = CATransform3DMakeTranslation(5, 0, 0); + textF.backgroundColor = [UIColor whiteColor]; + [textF doBorderWidth:0.5 color:nil cornerRadius:2.0]; + UIImageView *imageV = [YLImageView new]; + imageV.backgroundColor = [UIColor lightGrayColor]; + imageV.contentMode = UIViewContentModeScaleAspectFit; + imageV.clipsToBounds = YES; + imageV.userInteractionEnabled = YES; + [textF doBorderWidth:0.5 color:nil cornerRadius:2.0]; + NSURL *imageURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@api/getCaptcha", [NSObject baseURLStr]]]; + [imageV sd_setImageWithURL:imageURL placeholderImage:nil options:(SDWebImageRetryFailed | SDWebImageRefreshCached | SDWebImageHandleCookies)]; + + [alertV.contentView addSubview:textF]; + [alertV.contentView addSubview:imageV]; + [textF mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(alertV.contentView).offset(15); + make.height.mas_equalTo(25); + make.bottom.equalTo(alertV.contentView).offset(-10); + }]; + [imageV mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.equalTo(alertV.contentView).offset(-15); + make.left.equalTo(textF.mas_right).offset(10); + make.width.mas_equalTo(60); + make.height.mas_equalTo(25); + make.centerY.equalTo(textF); + }]; + //Action + __weak typeof(imageV) weakImageV = imageV; + [imageV bk_whenTapped:^{ + [weakImageV sd_setImageWithURL:imageURL placeholderImage:nil options:(SDWebImageRetryFailed | SDWebImageRefreshCached | SDWebImageHandleCookies)]; + }]; + __weak typeof(self) weakSelf = self; + [alertV addAction:[SDCAlertAction actionWithTitle:@"取消" style:SDCAlertActionStyleCancel handler:nil]]; + [alertV addAction:[SDCAlertAction actionWithTitle:@"确定" style:SDCAlertActionStyleDefault handler:nil]]; + alertV.shouldDismissBlock = ^BOOL (SDCAlertAction *action){ + if (![action.title isEqualToString:@"取消"]) { + [weakSelf phoneCodeBtnClicked:sender withCaptcha:textF.text]; } + return YES; + }; + [alertV presentWithCompletion:^{ + [textF becomeFirstResponder]; }]; } - (void)sendRegister{ + NSString *tipStr = nil; if (![_myRegister.global_key isGK]) { - [NSObject showHudTipStr:@"个性后缀仅支持英文字母、数字、横线(-)以及下划线(_)"]; + tipStr = @"用户名仅支持英文字母、数字、横线(-)以及下划线(_)"; + }else if (_step > 0 && ![_myRegister.confirm_password isEqualToString:_myRegister.password]){ + tipStr = @"密码输入不一致"; + } + if (tipStr) { + [NSObject showHudTipStr:tipStr]; return; } __weak typeof(self) weakSelf = self; - NSMutableDictionary *params = @{@"channel": [Register channel], - @"global_key": _myRegister.global_key, - @"password": [_myRegister.password sha1Str], - @"confirm": [_myRegister.password sha1Str]}.mutableCopy; - if (_medthodType == RegisterMethodEamil) { - params[@"email"] = _myRegister.email; - }else{ - params[@"phone"] = _myRegister.phone; - params[@"code"] = _myRegister.code; - params[@"country"] = _countryCodeDict[@"iso_code"]; - params[@"phoneCountryCode"] = [NSString stringWithFormat:@"+%@", _countryCodeDict[@"country_code"]]; - } - if (_captchaNeeded) { - params[@"j_captcha"] = _myRegister.j_captcha; - } - [self.footerBtn startQueryAnimate]; - [[Coding_NetAPIManager sharedManager] request_Register_V2_WithParams:params andBlock:^(id data, NSError *error) { - [weakSelf.footerBtn stopQueryAnimate]; - if (data) { - [self.view endEditing:YES]; - [Login setPreUserEmail:self.myRegister.global_key];//记住登录账号 - [((AppDelegate *)[UIApplication sharedApplication].delegate) setupTabViewController]; - if (weakSelf.medthodType == RegisterMethodEamil) { - kTipAlert(@"欢迎注册 Coding,请尽快去邮箱查收邮件并激活账号。如若在收件箱中未看到激活邮件,请留意一下垃圾邮件箱(T_T)。"); + if (_medthodType == RegisterMethodPhone && _step <= 0) { + [self.footerBtn startQueryAnimate]; + NSDictionary *gkP = @{@"key": _myRegister.global_key}; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:@"api/user/check" withParams:gkP withMethodType:Get andBlock:^(id data, NSError *error) { + if (!error && [data[@"data"] boolValue]) {//用户名还未被注册 + NSDictionary *phoneCodeP = @{@"phone": _myRegister.phone, + @"verifyCode": _myRegister.code, + @"phoneCountryCode": [NSString stringWithFormat:@"+%@", _countryCodeDict[@"country_code"]], + }; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:@"api/account/register/check-verify-code" withParams:phoneCodeP withMethodType:Post andBlock:^(id data, NSError *error) { + [weakSelf.footerBtn stopQueryAnimate]; + if (!error) { + //手机验证码通过校验 + RegisterViewController *vc = [RegisterViewController new]; + vc.medthodType = RegisterMethodPhone; + vc.myRegister = weakSelf.myRegister; + vc.step = 1; + [weakSelf.navigationController pushViewController:vc animated:YES]; + } + }]; + }else{ + [weakSelf.footerBtn stopQueryAnimate]; + if (!error) { + [NSObject showHudTipStr:@"用户名已存在"]; + } } + }]; + }else{ + NSMutableDictionary *params = @{@"channel": [Register channel], + @"global_key": _myRegister.global_key, + @"password": [_myRegister.password sha1Str], + @"confirm": [_myRegister.password sha1Str]}.mutableCopy; + if (_medthodType == RegisterMethodEamil) { + params[@"email"] = _myRegister.email; }else{ - [weakSelf refreshCaptchaNeeded]; + params[@"phone"] = _myRegister.phone; + params[@"code"] = _myRegister.code; + params[@"country"] = _countryCodeDict[@"iso_code"]; + params[@"phoneCountryCode"] = [NSString stringWithFormat:@"+%@", _countryCodeDict[@"country_code"]]; } - }]; + if (_captchaNeeded) { + params[@"j_captcha"] = _myRegister.j_captcha; + } + [self.footerBtn startQueryAnimate]; + [[Coding_NetAPIManager sharedManager] request_Register_V2_WithParams:params andBlock:^(id data, NSError *error) { + [weakSelf.footerBtn stopQueryAnimate]; + if (data) { + [self.view endEditing:YES]; + [Login setPreUserEmail:self.myRegister.global_key];//记住登录账号 + [((AppDelegate *)[UIApplication sharedApplication].delegate) setupTabViewController]; + if (weakSelf.medthodType == RegisterMethodEamil) { + kTipAlert(@"欢迎注册 Coding,请尽快去邮箱查收邮件并激活账号。如若在收件箱中未看到激活邮件,请留意一下垃圾邮件箱(T_T)。"); + } + }else{ + [weakSelf refreshCaptchaNeeded]; + } + }]; + } } #pragma mark VC diff --git a/Coding_iOS/Controllers/MRDetailViewController.m b/Coding_iOS/Controllers/MRDetailViewController.m index 51cf6171b..75505476c 100644 --- a/Coding_iOS/Controllers/MRDetailViewController.m +++ b/Coding_iOS/Controllers/MRDetailViewController.m @@ -8,7 +8,7 @@ -#define kMRPRDetailViewController_BottomViewHeight 49.0 +#define kMRPRDetailViewController_BottomViewHeight 56.0 #import "MRDetailViewController.h" #import "PRDetailViewController.h" #import "ReviewerListController.h" @@ -110,6 +110,9 @@ - (void)viewDidLoad{ [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; @@ -122,9 +125,9 @@ - (void)viewWillAppear:(BOOL)animated { - (void)configBottomView{ BOOL canCancel = [self.curPreMRPRInfo.mrpr.author.global_key isEqualToString:[Login curLoginUser].global_key]; - BOOL canAction = self.curPreMRPRInfo.can_edit.boolValue ||(canCancel && self.curPreMRPRInfo.mrpr.granted.boolValue);//有权限 || (作者身份 && 被授权) - BOOL canAuthorization = self.curPreMRPRInfo.can_edit.boolValue &&!canCancel &&!self.curPreMRPRInfo.author_can_edit.boolValue && !self.curPreMRPRInfo.mrpr.granted.boolValue; - BOOL canCancelAuthorization = self.curPreMRPRInfo.can_edit.boolValue &&!canCancel &&!self.curPreMRPRInfo.author_can_edit.boolValue && self.curPreMRPRInfo.mrpr.granted.boolValue; + BOOL canAction = (self.curPreMRPRInfo.can_merge.boolValue || self.curPreMRPRInfo.can_edit.boolValue) ||(canCancel && self.curPreMRPRInfo.mrpr.granted.boolValue);//有权限 || (作者身份 && 被授权) + BOOL canAuthorization = NO;//NO 不是说不可以,只是说不要这按钮了 + BOOL canCancelAuthorization = NO;//NO 不是说不可以,只是说不要这按钮了 BOOL hasBottomView = self.curMRPRInfo.mrpr.status <= MRPRStatusCannotMerge && (canAction || canCancel); if(self.curMRPRInfo == nil || self.curPreMRPRInfo == nil) { hasBottomView = NO ; @@ -144,7 +147,7 @@ - (void)configBottomView{ NSArray *buttonArray; if (canAction && canCancel) {//三个按钮 buttonArray = @[ [self buttonWithType:MRPRActionCancel], - [self buttonWithType:MRPRActionRefuse], +// [self buttonWithType:MRPRActionRefuse], [self buttonWithType:MRPRActionAccept]]; } else if (canAction && !canCancel){//两个按钮 if(canAuthorization) { @@ -168,7 +171,7 @@ - (void)configBottomView{ buttonArray = nil; } if (buttonArray.count > 0) { - CGFloat buttonHeight = 29; + CGFloat buttonHeight = 36; CGFloat padding = 15; CGFloat buttonWidth = ((kScreen_Width - 2*kPaddingLeftWidth) - padding* (buttonArray.count -1))/buttonArray.count; CGFloat buttonY = (kMRPRDetailViewController_BottomViewHeight - buttonHeight)/2; @@ -206,11 +209,9 @@ - (void)updateActivityList{ - (void)updateProjectStatus { __weak typeof(self) weakSelf = self; - [[Coding_NetAPIManager sharedManager] request_MRPRPreInfo_WithObj:_curMRPR andBlock:^(MRPRBaseInfo *data, NSError *error) { - [weakSelf.view endLoading]; - [weakSelf.myRefreshControl endRefreshing]; + [[Coding_NetAPIManager sharedManager] request_MRPRPreInfo_WithObj:_curMRPR andBlock:^(MRPRPreInfo *data, NSError *error) { if (data) { - weakSelf.curPreMRPRInfo = (MRPRPreInfo*)data; + weakSelf.curPreMRPRInfo = data; [weakSelf.myTableView reloadData]; [weakSelf configBottomView]; } @@ -258,7 +259,6 @@ - (void)refresh{ }]; //项目成员 [[Coding_NetAPIManager sharedManager] request_ProjectMembers_WithObj:self.curProject andBlock:^(id data, NSError *error) { - [weakSelf.view endLoading]; if (data) { NSMutableArray* projectUsers = data; weakSelf.projectUsers = projectUsers; @@ -266,8 +266,6 @@ - (void)refresh{ }]; //MR 评审者 [[Coding_NetAPIManager sharedManager] request_MRReviewerInfo_WithObj:_curMRPR andBlock:^(ReviewersInfo *data, NSError *error) { - [weakSelf.view endLoading]; - [weakSelf.myRefreshControl endRefreshing]; if (data) { weakSelf.curReviewersInfo = data; } @@ -306,29 +304,28 @@ - (UIButton *)buttonWithType:(MRPRAction)actionType{ curButton.layer.cornerRadius = 2.0; curButton.tag = actionType; [curButton addTarget:self action:@selector(actionMRPR:) forControlEvents:UIControlEventTouchUpInside]; - [curButton.titleLabel setFont:[UIFont systemFontOfSize:13]]; + [curButton.titleLabel setFont:[UIFont systemFontOfSize:15]]; NSString *title, *colorStr; if (actionType == MRPRActionAccept) { title = @"合并"; - colorStr = @"0x4E90BF"; + colorStr = @"0x425063"; if (_curMRPRInfo.mrpr.status == MRPRStatusCannotMerge) { curButton.alpha = 0.5; } } else if (actionType == MRPRActionRefuse){ title = @"拒绝"; - colorStr = @"0xE15957"; + colorStr = @"0xF56061"; } else if (actionType == MRPRActionCancel){ title = @"取消"; - colorStr = @"0xF8F8F8"; - [curButton doBorderWidth:0.5 color:[UIColor colorWithHexString:@"0xB5B5B5"] cornerRadius:2.0]; + colorStr = @"0xD8DDE4"; } else if(actionType == MRPRActionAuthorization) { title = @"授权"; - colorStr = @"0x38BD78"; + colorStr = @"0x4F95E8"; } else if(actionType == MRPRActionCancelAuthorization) { title = @"取消授权"; - colorStr = @"0x38BD78"; + colorStr = @"0x4F95E8"; } - [curButton setTitleColor:[UIColor colorWithHexString:(actionType == MRPRActionCancel? @"0x222222": @"0xffffff")] forState:UIControlStateNormal]; + [curButton setTitleColor:[UIColor colorWithHexString:(actionType == MRPRActionCancel? @"0x323A45": @"0xFFFFFF")] forState:UIControlStateNormal]; [curButton setTitle:title forState:UIControlStateNormal]; [curButton setBackgroundColor:[UIColor colorWithHexString:colorStr]]; return curButton; @@ -339,7 +336,7 @@ - (void)actionMRPR:(UIButton *)sender{ NSString *tipStr; if (sender.tag == MRPRActionAccept) {//合并 if (_curMRPRInfo.mrpr.status == MRPRStatusCannotMerge) {//不能合并 - tipStr = @"Coding 不能帮你在线自动合并这个合并请求。"; + tipStr = @"CODING 不能帮你在线自动合并这个合并请求。"; kTipAlert(@"%@", tipStr); } else { MRPRAcceptViewController *vc = [MRPRAcceptViewController new]; @@ -354,28 +351,28 @@ - (void)actionMRPR:(UIButton *)sender{ } } else if (sender.tag == MRPRActionRefuse){//拒绝 tipStr = [_curMRPRInfo.mrpr isMR]? @"确定要拒绝这个 Merge Request 么?": @"确定要拒绝这个 Pull Request 么?"; - [[UIActionSheet bk_actionSheetCustomWithTitle:tipStr buttonTitles:@[@"确定"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + [[UIAlertController ea_actionSheetCustomWithTitle:tipStr buttonTitles:@[@"确定"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf refuseMRPR]; } }] showInView:self.view]; } else if (sender.tag == MRPRActionCancel){//取消 tipStr = [_curMRPRInfo.mrpr isMR]? @"确定要取消这个 Merge Request 么?": @"确定要取消这个 Pull Request 么?"; - [[UIActionSheet bk_actionSheetCustomWithTitle:tipStr buttonTitles:@[@"确定"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + [[UIAlertController ea_actionSheetCustomWithTitle:tipStr buttonTitles:@[@"确定"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf cancelMRPR]; } }] showInView:self.view]; } else if(sender.tag == MRPRActionAuthorization) { tipStr = [_curMRPRInfo.mrpr isMR]? @"确定要授权这个 Merge Request 么?": @"确定要授权这个 Pull Request 么?"; - [[UIActionSheet bk_actionSheetCustomWithTitle:tipStr buttonTitles:@[@"确定"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + [[UIAlertController ea_actionSheetCustomWithTitle:tipStr buttonTitles:@[@"确定"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf authorizationMRPR]; } }] showInView:self.view]; } else if(sender.tag == MRPRActionCancelAuthorization) { tipStr = [_curMRPRInfo.mrpr isMR]? @"确定要取消授权这个 Merge Request 么?": @"确定要取消授权这个 Pull Request 么?"; - [[UIActionSheet bk_actionSheetCustomWithTitle:tipStr buttonTitles:@[@"确定"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + [[UIAlertController ea_actionSheetCustomWithTitle:tipStr buttonTitles:@[@"确定"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf cancelAuthorizationMRPR]; } @@ -408,10 +405,6 @@ - (void)authorizationMRPR{ [[Coding_NetAPIManager sharedManager] request_MRPRAuthorization:_curMRPRInfo.mrpr andBlock:^(id data, NSError *error) { if (data) { weakSelf.curPreMRPRInfo.mrpr.granted = @1; -// weakSelf.bottomView = nil; - [weakSelf refresh]; - [weakSelf.myTableView reloadData]; - [weakSelf configBottomView]; } }]; } @@ -421,17 +414,13 @@ - (void)cancelAuthorizationMRPR{ [[Coding_NetAPIManager sharedManager] request_MRPRCancelAuthorization:_curMRPRInfo.mrpr andBlock:^(id data, NSError *error) { if (data) { weakSelf.curPreMRPRInfo.mrpr.granted = @0; -// weakSelf.bottomView = nil; - [weakSelf refresh]; - [weakSelf.myTableView reloadData]; - [weakSelf configBottomView]; } }]; } #pragma mark TableM Footer Header - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ - return 20.0; + return 15.0; } - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ return 0.5; @@ -496,9 +485,6 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N [cell setImageStr:@"mrpr_icon_commit" andTitle:@"提交记录"]; }else if(indexPath.row == 1){ [cell setImageStr:@"mrpr_icon_fileChange" andTitle:@"文件改动"]; - if ([[FunctionTipsManager shareManager] needToTip:kFunctionTipStr_LineNote_FileChange]) { - [cell addTipIcon]; - } } else { [cell setImageStr:@"PR_TaskResource" andTitle:@"关联资源"]; if(self.resourceReference.itemList.count > 0) { @@ -528,9 +514,12 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N [cell setImageStr:@"PRReviewer" isowner:NO hasLikeMr:self.isLike]; } - if (self.curMRPRInfo.mrpr.status == MRPRStatusAccepted || self.curMRPRInfo.mrpr.status == MRPRStatusRefused || self.curMRPRInfo.mrpr.status == MRPRStatusRefused) { + if (self.curMRPRInfo.mrpr.status == MRPRStatusAccepted || self.curMRPRInfo.mrpr.status == MRPRStatusRefused) { [cell cantReviewer]; } + cell.rightSideClickedBlock = ^(){ + [weakSelf jiaYi]; + }; [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:50]; return cell; }else { @@ -543,9 +532,9 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N [tmpReviewers addObject:self.curReviewersInfo.volunteer_reviewers[i]]; } [cell initCellWithReviewers:tmpReviewers]; - if ([[FunctionTipsManager shareManager] needToTip:kFunctionTipStr_LineNote_FileChange]) { - [cell addTipHeadIcon:@"PointLikeHead"]; - } + cell.lastItemClickedBlock = ^(){ + [weakSelf goToReviewerList]; + }; [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:50]; return cell; } @@ -573,6 +562,46 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } } +- (void)jiaYi{ + if (self.curMRPRInfo.mrpr.status == MRPRStatusAccepted || self.curMRPRInfo.mrpr.status == MRPRStatusRefused) { + return; + } + if([self CurrentUserIsOwer]) { + NSArray *apparray= [[NSBundle mainBundle]loadNibNamed:@"AddReviewerViewController" owner:nil options:nil]; + AddReviewerViewController *appview=[apparray firstObject]; + appview.currentProject = self.curProject; + appview.curMRPR = self.curMRPR; + [self.navigationController pushViewController:appview animated:YES]; + } else { + __weak typeof(self) weakSelf = self; + if ([self.isLike isEqual:@0]) { + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:self.reviewGoodPath withParams:nil withMethodType:Delete andBlock:^(id data, NSError *error) { + weakSelf.isLike = @1; + [weakSelf refresh]; + if (weakSelf.curPreMRPRInfo.can_grant.boolValue) { + [weakSelf cancelAuthorizationMRPR]; + } + }]; + } else { + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:self.reviewGoodPath withParams:nil withMethodType:Post andBlock:^(id data, NSError *error) { + weakSelf.isLike = @0; + [weakSelf refresh]; + if (weakSelf.curPreMRPRInfo.can_grant.boolValue) { + [weakSelf authorizationMRPR]; + } + }]; + } + } +} + +- (void)goToReviewerList{ + NSArray *apparray= [[NSBundle mainBundle]loadNibNamed:@"ReviewerListController" owner:nil options:nil]; + ReviewerListController *appview=[apparray firstObject]; + appview.currentProject = self.curProject; + appview.curMRPR = self.curMRPR; + appview.isPublisher = [self currentUserCanAddMember]; + [self.navigationController pushViewController:appview animated:YES]; +} - (BOOL)CurrentUserIsOwer{ User *currentUser = [Login curLoginUser]; @@ -591,7 +620,7 @@ - (bool)currentUserCanAddMember { return NO; } } - if (self.curMRPRInfo.mrpr.status == MRPRStatusAccepted || self.curMRPRInfo.mrpr.status == MRPRStatusRefused || self.curMRPRInfo.mrpr.status == MRPRStatusRefused) { + if (self.curMRPRInfo.mrpr.status == MRPRStatusAccepted || self.curMRPRInfo.mrpr.status == MRPRStatusRefused) { return NO; } return YES; @@ -656,12 +685,6 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath vc.curMRPRInfo = _curMRPRInfo; vc.curProject = _curProject; [self.navigationController pushViewController:vc animated:YES]; - if ([[FunctionTipsManager shareManager] needToTip:kFunctionTipStr_LineNote_FileChange]) { - [[FunctionTipsManager shareManager] markTiped:kFunctionTipStr_LineNote_FileChange]; - [[FunctionTipsManager shareManager] markTiped:kFunctionTipStr_LineNote_MRPR]; - NProjectItemCell *cell = (NProjectItemCell *)[tableView cellForRowAtIndexPath:indexPath]; - [cell removeTip]; - } } else { TaskResourceReferenceViewController *vc = [TaskResourceReferenceViewController new]; vc.resourceReference = self.resourceReference; @@ -669,38 +692,6 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath [self.navigationController pushViewController:vc animated:YES]; } } else if (indexPath.section == 2){//Disclosure - if (indexPath.row == 0) { - if (self.curMRPRInfo.mrpr.status == MRPRStatusAccepted || self.curMRPRInfo.mrpr.status == MRPRStatusRefused || self.curMRPRInfo.mrpr.status == MRPRStatusRefused) { - return; - } - if([self CurrentUserIsOwer]) { - NSArray *apparray= [[NSBundle mainBundle]loadNibNamed:@"AddReviewerViewController" owner:nil options:nil]; - AddReviewerViewController *appview=[apparray firstObject]; - appview.currentProject = self.curProject; - appview.curMRPR = self.curMRPR; - [self.navigationController pushViewController:appview animated:YES]; - } else { - __weak typeof(self) weakSelf = self; - if ([self.isLike isEqual:@0]) { - [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:self.reviewGoodPath withParams:nil withMethodType:Delete andBlock:^(id data, NSError *error) { - weakSelf.isLike = @1; - [weakSelf refresh]; - }]; - } else { - [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:self.reviewGoodPath withParams:nil withMethodType:Post andBlock:^(id data, NSError *error) { - weakSelf.isLike = @0; - [weakSelf refresh]; - }]; - } - } - } else { - NSArray *apparray= [[NSBundle mainBundle]loadNibNamed:@"ReviewerListController" owner:nil options:nil]; - ReviewerListController *appview=[apparray firstObject]; - appview.currentProject = self.curProject; - appview.curMRPR = self.curMRPR; - appview.isPublisher = [self currentUserCanAddMember]; - [self.navigationController pushViewController:appview animated:YES]; - } } else if (self.activityList.count > 0 && indexPath.section == 3){//Comment ProjectLineNote *curCommentItem = self.activityList[indexPath.row]; if ([curCommentItem.action isEqual:@"mergeChanges"]) { @@ -815,4 +806,4 @@ - (void)attributedLabel:(TTTAttributedLabel *)label didSelectLinkWithTransitInfo } -@end \ No newline at end of file +@end diff --git a/Coding_iOS/Controllers/MRListViewController.h b/Coding_iOS/Controllers/MRListViewController.h deleted file mode 100644 index 37603df29..000000000 --- a/Coding_iOS/Controllers/MRListViewController.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// MRListViewController.h -// Coding_iOS -// -// Created by Ease on 15/10/23. -// Copyright © 2015年 Coding. All rights reserved. -// - -#import "BaseViewController.h" -#import "Project.h" - -@interface MRListViewController : BaseViewController -@property (strong, nonatomic) Project *curProject; - -@end diff --git a/Coding_iOS/Controllers/MRListViewController.m b/Coding_iOS/Controllers/MRListViewController.m deleted file mode 100644 index c818285d2..000000000 --- a/Coding_iOS/Controllers/MRListViewController.m +++ /dev/null @@ -1,185 +0,0 @@ -// -// MRListViewController.m -// Coding_iOS -// -// Created by Ease on 15/10/23. -// Copyright © 2015年 Coding. All rights reserved. -// - -#define kMRPRListViewController_IsNew NO - -#define kMRPRListViewController_BottomViewHeight 49.0 - -#import "MRListViewController.h" -#import "XTSegmentControl.h" -#import "iCarousel.h" -#import "MRListView.h" -#import "MRDetailViewController.h" - - -@interface MRListViewController () -@property (strong, nonatomic) XTSegmentControl *mySegmentControl; -@property (strong, nonatomic) iCarousel *myCarousel; -@property (strong, nonatomic) NSMutableDictionary *myMRsDict; -@property (nonatomic, assign) NSInteger segmentIndex; - -@property (strong, nonatomic) UIView *bottomView; -@property (strong, nonatomic) UISegmentedControl *mySegmentedControl; -@end - -@implementation MRListViewController -- (void)viewDidLoad -{ - [super viewDidLoad]; - // Do any additional setup after loading the view. - self.view.backgroundColor = kColorTableBG; - self.title = @"Merge Requests"; - _myMRsDict = [[NSMutableDictionary alloc] initWithCapacity:6]; - - //添加myCarousel - _myCarousel = ({ - iCarousel *icarousel = [[iCarousel alloc] init]; - icarousel.dataSource = self; - icarousel.delegate = self; - icarousel.decelerationRate = 1.0; - icarousel.scrollSpeed = 1.0; - icarousel.type = iCarouselTypeLinear; - icarousel.pagingEnabled = YES; - icarousel.clipsToBounds = YES; - icarousel.bounceDistance = 0.2; - icarousel.scrollEnabled = kMRPRListViewController_IsNew; - [self.view addSubview:icarousel]; - [icarousel mas_makeConstraints:^(MASConstraintMaker *make) { - make.edges.equalTo(self.view).insets(UIEdgeInsetsMake(kMRPRListViewController_IsNew? kMySegmentControl_Height: 0, 0, 0, 0)); - }]; - icarousel; - }); - - //添加滑块 - if (kMRPRListViewController_IsNew) { - __weak typeof(_myCarousel) weakCarousel = _myCarousel; - _mySegmentControl = [[XTSegmentControl alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, kMySegmentControl_Height) Items:@[@"我评审的", @"我发布的", @"其他的"] selectedBlock:^(NSInteger index) { - [weakCarousel scrollToItemAtIndex:index animated:NO]; - }]; - [self.view addSubview:_mySegmentControl]; - } - [self configBottomView]; - self.segmentIndex = 0; -} - -- (void)setSegmentIndex:(NSInteger)segmentIndex{ - _segmentIndex = segmentIndex; - if (self.mySegmentedControl.selectedSegmentIndex != _segmentIndex) { - [self.mySegmentedControl setSelectedSegmentIndex:_segmentIndex]; - } - MRListView *curView = (MRListView *)_myCarousel.currentItemView; - curView.curMRPRS = [self curMRPRS]; - [curView refreshToQueryData]; -} - -- (MRPRS *)curMRPRS{ - NSString *curKey = [NSString stringWithFormat:@"%ld_%ld", (long)_myCarousel.currentItemIndex, (long)_segmentIndex]; - MRPRS *curMRPRS = _myMRsDict[curKey]; - if (!curMRPRS) { - curMRPRS = [[MRPRS alloc] initWithType:(kMRPRListViewController_IsNew? MRPRSTypeMRMine: MRPRSTypeMRAll) + _myCarousel.currentItemIndex - statusIsOpen:_segmentIndex == 0 - userGK:_curProject.owner_user_name - projectName:_curProject.name]; - _myMRsDict[curKey] = curMRPRS; - } - return curMRPRS; -} - -#pragma mark Segment -- (void)configBottomView{ - if (!_bottomView) { - _bottomView = [UIView new]; - _bottomView.backgroundColor = self.view.backgroundColor; - [_bottomView addLineUp:YES andDown:NO]; - [self.view addSubview:_bottomView]; - [_bottomView mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.right.bottom.equalTo(self.view); - make.height.mas_equalTo(kMRPRListViewController_BottomViewHeight); - }]; - } - if (!_mySegmentedControl) { - _mySegmentedControl = ({ - UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:@[@"Open", @"Closed"]]; - segmentedControl.tintColor = kColorBrandGreen; - [segmentedControl setTitleTextAttributes:@{ - NSFontAttributeName: [UIFont boldSystemFontOfSize:16], - NSForegroundColorAttributeName: [UIColor whiteColor] - } - forState:UIControlStateSelected]; - [segmentedControl setTitleTextAttributes:@{ - NSFontAttributeName: [UIFont boldSystemFontOfSize:16], - NSForegroundColorAttributeName: kColorBrandGreen - } forState:UIControlStateNormal]; - [segmentedControl addTarget:self action:@selector(segmentedControlSelected:) forControlEvents:UIControlEventValueChanged]; - segmentedControl; - }); - _mySegmentedControl.frame = CGRectMake(kPaddingLeftWidth, (kMRPRListViewController_BottomViewHeight - 30)/2, kScreen_Width - 2*kPaddingLeftWidth, 30); - [_bottomView addSubview:_mySegmentedControl]; - } -} - -- (void)segmentedControlSelected:(id)sender{ - UISegmentedControl *segmentedControl = (UISegmentedControl *)sender; - self.segmentIndex = segmentedControl.selectedSegmentIndex; -} - -#pragma mark iCarousel M -- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel{ - return 3; -} - -- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view{ - - MRListView *listView = (MRListView *)view; - if (!listView) { - listView = [[MRListView alloc] initWithFrame:carousel.bounds]; - __weak typeof(self) weakSelf = self; - listView.clickedMRBlock = ^(MRPR *clickedMR){ - [weakSelf goToMRDetail:clickedMR]; - }; - } - listView.curMRPRS = [self curMRPRS]; - if (index == carousel.currentItemIndex) { - [listView refreshToQueryData]; - } - [listView setSubScrollsToTop:(index == carousel.currentItemIndex)]; - return listView; -} - -- (void)carouselDidScroll:(iCarousel *)carousel{ - [self.view endEditing:YES]; - if (_mySegmentControl) { - float offset = carousel.scrollOffset; - if (offset > 0) { - [_mySegmentControl moveIndexWithProgress:offset]; - } - } -} - -- (void)carouselCurrentItemIndexDidChange:(iCarousel *)carousel -{ - if (_mySegmentControl) { - _mySegmentControl.currentIndex = carousel.currentItemIndex; - } - MRListView *listView = (MRListView *)carousel.currentItemView; - listView.curMRPRS = [self curMRPRS]; - [listView refreshToQueryData]; - [carousel.visibleItemViews enumerateObjectsUsingBlock:^(UIView *obj, NSUInteger idx, BOOL *stop) { - [obj setSubScrollsToTop:(obj == carousel.currentItemView)]; - }]; -} - -#pragma mark goto VC -- (void)goToMRDetail:(MRPR *)curMR{ - NSLog(@"%@", curMR.title); - MRDetailViewController *vc = [MRDetailViewController new]; - vc.curMRPR = curMR; - vc.curProject = _curProject; - [self.navigationController pushViewController:vc animated:YES]; -} -@end diff --git a/Coding_iOS/Controllers/MRPRAcceptViewController.m b/Coding_iOS/Controllers/MRPRAcceptViewController.m index dcc35997a..0740300d1 100644 --- a/Coding_iOS/Controllers/MRPRAcceptViewController.m +++ b/Coding_iOS/Controllers/MRPRAcceptViewController.m @@ -41,6 +41,22 @@ - (void)viewDidLoad{ } self.curMRPR.message = [NSString stringWithFormat:@"Accept Merge Request #%@ : (%@ -> %@)", _curMRPR.iid.stringValue, fromStr, toStr]; + self.curMRPR.message = [NSString stringWithFormat: +@"Accept Merge Request #%@ : %@\n\n\ +From -> To: (%@ -> %@)\n\n\ +Merge Request: %@\n\n\ +Created By: @%@\n\ +Accepted By: @%@\n\ +URL:%@", +_curMRPR.iid.stringValue, +_curMRPR.title, +fromStr, +toStr, +_curMRPR.title, +_curMRPR.author.name, +[Login curLoginUser].name, +[NSURL URLWithString:_curMRPR.path relativeToURL:[NSURL URLWithString:[NSObject baseURLStr]]].absoluteString]; + _myTableView = ({ UITableView *tableView = [[TPKeyboardAvoidingTableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; tableView.backgroundColor = kColorTableSectionBg; @@ -53,6 +69,9 @@ - (void)viewDidLoad{ [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _myTableView.tableFooterView = [self tableFooterView]; @@ -122,9 +141,23 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath - (UIView*)tableFooterView{ UIView *footerV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 90)]; - _mergeBtn = [UIButton buttonWithStyle:StrapInfoStyle andTitle:@"确认合并" andFrame:CGRectMake(10, 0, kScreen_Width-10*2, 44) target:self action:@selector(mergeBtnClicked:)]; - [_mergeBtn setCenter:footerV.center]; + _mergeBtn = ({ + UIButton *curButton = [UIButton new]; + curButton.cornerRadius = 4.0; + [curButton addTarget:self action:@selector(mergeBtnClicked:) forControlEvents:UIControlEventTouchUpInside]; + [curButton.titleLabel setFont:[UIFont systemFontOfSize:17]]; + [curButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [curButton setTitle:@"确认合并" forState:UIControlStateNormal]; + [curButton setBackgroundColor:[UIColor colorWithHexString:@"0x425063"]]; + curButton; + }); [footerV addSubview:_mergeBtn]; + [_mergeBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.offset(kPaddingLeftWidth); + make.right.offset(-kPaddingLeftWidth); + make.centerY.equalTo(footerV); + make.height.mas_equalTo(44); + }]; return footerV; } diff --git a/Coding_iOS/Controllers/MRPRCommitsViewController.m b/Coding_iOS/Controllers/MRPRCommitsViewController.m index dbdbf05aa..39e84f2ad 100644 --- a/Coding_iOS/Controllers/MRPRCommitsViewController.m +++ b/Coding_iOS/Controllers/MRPRCommitsViewController.m @@ -38,6 +38,9 @@ - (void)viewDidLoad{ [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; diff --git a/Coding_iOS/Controllers/MRPRFilesViewController.m b/Coding_iOS/Controllers/MRPRFilesViewController.m index dd2628501..9be303601 100644 --- a/Coding_iOS/Controllers/MRPRFilesViewController.m +++ b/Coding_iOS/Controllers/MRPRFilesViewController.m @@ -44,6 +44,9 @@ - (void)viewDidLoad{ [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; diff --git a/Coding_iOS/Controllers/MRPRListViewController.h b/Coding_iOS/Controllers/MRPRListViewController.h new file mode 100644 index 000000000..52e082e63 --- /dev/null +++ b/Coding_iOS/Controllers/MRPRListViewController.h @@ -0,0 +1,15 @@ +// +// MRPRListViewController.h +// Coding_iOS +// +// Created by Ease on 2017/2/14. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "BaseViewController.h" +#import "Project.h" + +@interface MRPRListViewController : BaseViewController +@property (strong, nonatomic) Project *curProject; +@property (assign, nonatomic) BOOL isMR; +@end diff --git a/Coding_iOS/Controllers/PRListViewController.m b/Coding_iOS/Controllers/MRPRListViewController.m similarity index 60% rename from Coding_iOS/Controllers/PRListViewController.m rename to Coding_iOS/Controllers/MRPRListViewController.m index 08c1f7e66..183657b93 100644 --- a/Coding_iOS/Controllers/PRListViewController.m +++ b/Coding_iOS/Controllers/MRPRListViewController.m @@ -2,13 +2,11 @@ // MRPRListViewController.m // Coding_iOS // -// Created by Ease on 15/5/29. -// Copyright (c) 2015年 Coding. All rights reserved. +// Created by Ease on 2017/2/14. +// Copyright © 2017年 Coding. All rights reserved. // -#define kMRPRListViewController_BottomViewHeight 49.0 - -#import "PRListViewController.h" +#import "MRPRListViewController.h" #import "ODRefreshControl.h" #import "SVPullToRefresh.h" #import "MRPRS.h" @@ -16,22 +14,26 @@ #import "MRPRListCell.h" #import "PRDetailViewController.h" #import "MRDetailViewController.h" +#import "EAFliterMenu.h" -@interface PRListViewController () +@interface MRPRListViewController () @property (strong, nonatomic) NSMutableDictionary *dataDict; @property (strong, nonatomic) UITableView *myTableView; @property (nonatomic, strong) ODRefreshControl *myRefreshControl; + @property (nonatomic, assign) NSInteger selectedIndex; +@property (strong, nonatomic) UIButton *titleBtn; +@property (nonatomic, strong) EAFliterMenu *myFliterMenu; -@property (strong, nonatomic) UIView *bottomView; -@property (strong, nonatomic) UISegmentedControl *mySegmentedControl; @end -@implementation PRListViewController -- (void)viewDidLoad{ +@implementation MRPRListViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. [super viewDidLoad]; self.view.backgroundColor = kColorTableBG; - self.title = @"Pull Requests"; _dataDict = [NSMutableDictionary new]; _myTableView = ({ @@ -45,9 +47,12 @@ - (void)viewDidLoad{ [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; - UIEdgeInsets insets = UIEdgeInsetsMake(0, 0, kMRPRListViewController_BottomViewHeight, 0); + UIEdgeInsets insets = UIEdgeInsetsMake(0, 0, 0, 0); tableView.contentInset = insets; tableView.scrollIndicatorInsets = insets; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; @@ -57,31 +62,42 @@ - (void)viewDidLoad{ [_myTableView addInfiniteScrollingWithActionHandler:^{ [weakSelf refreshMore:YES]; }]; - [self configBottomView]; - self.selectedIndex = 0; + + //初始化过滤目录 + _myFliterMenu = [[EAFliterMenu alloc] initWithFrame:CGRectMake(0, 44 + kSafeArea_Top, kScreen_Width, kScreen_Height - (44 + kSafeArea_Top)) items:[self titleList]]; + _myFliterMenu.clickBlock = ^(NSInteger selectIndex){ + if (weakSelf.selectedIndex != selectIndex) { + weakSelf.selectedIndex = selectIndex; + } + }; + + [self refresh]; } - (void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; - if([self curMRPRS].list.count <= 0) { - [self.view configBlankPage:EaseBlankPageTypeTaskResource hasData:NO hasError:NO reloadButtonBlock:nil]; +} + +- (void)viewWillDisappear:(BOOL)animated{ + [super viewWillDisappear:animated]; + if (_myFliterMenu.isShowing) { + [_myFliterMenu dismissMenu]; } - [self refresh]; } +#pragma mark Fliter + - (void)setSelectedIndex:(NSInteger)selectedIndex{ _selectedIndex = selectedIndex; - if (self.mySegmentedControl.selectedSegmentIndex != _selectedIndex) { - [self.mySegmentedControl setSelectedSegmentIndex:_selectedIndex]; - } + [self setupTitleBtn]; + [self.myTableView reloadData]; __weak typeof(self) weakSelf = self; [self.view configBlankPage:EaseBlankPageTypeView hasData:YES hasError:NO reloadButtonBlock:^(id sender) { [weakSelf refreshMore:NO]; }]; - if ([self curMRPRS].list.count <= 0) { [self refresh]; }else{ @@ -89,10 +105,56 @@ - (void)setSelectedIndex:(NSInteger)selectedIndex{ } } +- (NSArray *)titleList{ + NSArray *titleList = (_isMR? @[@"默认", + @"可合并", + @"不可自动合并", + @"已拒绝", + @"已合并", + ]: + @[@"未处理", + @"已处理", + @"全部", + ]); + return titleList; +} + +- (void)setupTitleBtn{ + if (!_titleBtn) { + _titleBtn = [UIButton new]; + [_titleBtn setTitleColor:kColorNavTitle forState:UIControlStateNormal]; + [_titleBtn.titleLabel setFont:[UIFont systemFontOfSize:kNavTitleFontSize]]; + [_titleBtn addTarget:self action:@selector(fliterClicked) forControlEvents:UIControlEventTouchUpInside]; + self.navigationItem.titleView = _titleBtn; + } + + NSString *titleStr = [self titleList][_selectedIndex]; + CGFloat titleWidth = [titleStr getWidthWithFont:_titleBtn.titleLabel.font constrainedToSize:CGSizeMake(kScreen_Width, 30)]; + CGFloat imageWidth = 12; + CGFloat btnWidth = titleWidth +imageWidth; + _titleBtn.frame = CGRectMake((kScreen_Width-btnWidth)/2, (44-30)/2, btnWidth, 30); + _titleBtn.titleEdgeInsets = UIEdgeInsetsMake(0, -imageWidth, 0, imageWidth); + _titleBtn.imageEdgeInsets = UIEdgeInsetsMake(0, titleWidth, 0, -titleWidth); + [_titleBtn setTitle:titleStr forState:UIControlStateNormal]; + [_titleBtn setImage:[UIImage imageNamed:@"btn_fliter_down"] forState:UIControlStateNormal]; +} + +-(void)fliterClicked{ + if (_myFliterMenu.isShowing) { + [_myFliterMenu dismissMenu]; + }else{ + _myFliterMenu.selectIndex = self.selectedIndex; + [_myFliterMenu showMenuInView:kKeyWindow]; + } +} + +#pragma mark Data + - (MRPRS *)curMRPRS{ MRPRS *curMRPRS = [_dataDict objectForKey:@(_selectedIndex)]; if (!curMRPRS) { - curMRPRS = [[MRPRS alloc] initWithType:MRPRSTypePR statusIsOpen:_selectedIndex == 0 userGK:_curProject.owner_user_name projectName:_curProject.name]; + + curMRPRS = [[MRPRS alloc] initWithType:_isMR? _selectedIndex: _selectedIndex + MRPRSTypePROpen userGK:_curProject.owner_user_name projectName:_curProject.name]; [_dataDict setObject:curMRPRS forKey:@(_selectedIndex)]; } return curMRPRS; @@ -135,43 +197,6 @@ - (void)sendRequest:(MRPRS *)curMRPRS{ }]; } -#pragma mark Segment -- (void)configBottomView{ - if (!_bottomView) { - _bottomView = [UIView new]; - _bottomView.backgroundColor = self.view.backgroundColor; - [_bottomView addLineUp:YES andDown:NO]; - [self.view addSubview:_bottomView]; - [_bottomView mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.right.bottom.equalTo(self.view); - make.height.mas_equalTo(kMRPRListViewController_BottomViewHeight); - }]; - } - if (!_mySegmentedControl) { - _mySegmentedControl = ({ - UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:@[@"Open", @"Closed"]]; - segmentedControl.tintColor = kColorBrandGreen; - [segmentedControl setTitleTextAttributes:@{ - NSFontAttributeName: [UIFont boldSystemFontOfSize:16], - NSForegroundColorAttributeName: [UIColor whiteColor] - } - forState:UIControlStateSelected]; - [segmentedControl setTitleTextAttributes:@{ - NSFontAttributeName: [UIFont boldSystemFontOfSize:16], - NSForegroundColorAttributeName: kColorBrandGreen - } forState:UIControlStateNormal]; - [segmentedControl addTarget:self action:@selector(segmentedControlSelected:) forControlEvents:UIControlEventValueChanged]; - segmentedControl; - }); - _mySegmentedControl.frame = CGRectMake(kPaddingLeftWidth, (kMRPRListViewController_BottomViewHeight - 30)/2, kScreen_Width - 2*kPaddingLeftWidth, 30); - [_bottomView addSubview:_mySegmentedControl]; - } -} - -- (void)segmentedControlSelected:(id)sender{ - UISegmentedControl *segmentedControl = (UISegmentedControl *)sender; - self.selectedIndex = segmentedControl.selectedSegmentIndex; -} #pragma mark TableM - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ @@ -182,12 +207,12 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N MRPR *curMRPR = [[self curMRPRS].list objectAtIndex:indexPath.row]; MRPRListCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_MRPRListCell forIndexPath:indexPath]; cell.curMRPR = curMRPR; - [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:60]; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; return cell; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ - return [MRPRListCell cellHeight]; + return [MRPRListCell cellHeightWithObj:[[self curMRPRS].list objectAtIndex:indexPath.row]]; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ @@ -204,9 +229,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath vc.curProject = _curProject; [self.navigationController pushViewController:vc animated:YES]; } - + } - - @end diff --git a/Coding_iOS/Controllers/MeDisplayViewController.m b/Coding_iOS/Controllers/MeDisplayViewController.m index e2ed406e2..254b90669 100644 --- a/Coding_iOS/Controllers/MeDisplayViewController.m +++ b/Coding_iOS/Controllers/MeDisplayViewController.m @@ -19,10 +19,10 @@ #import "SVPullToRefresh.h" #import "Coding_NetAPIManager.h" #import "SettingMineInfoViewController.h" - +#import "EaseUserInfoCell.h" +#import "UserActiveGraphCell.h" @interface MeDisplayViewController () -@property (strong, nonatomic) UIView *tableHeaderView; @property (strong, nonatomic) EaseUserHeaderView *eaV; @property (strong, nonatomic) UIView *sectionHeaderView; @@ -31,13 +31,13 @@ @interface MeDisplayViewController () @property (strong, nonatomic) NSMutableArray *dataList;//特指「话题列表」的数据 @property (assign, nonatomic) BOOL canLoadMore, willLoadMore, isLoading; @property (nonatomic, assign) NSInteger curPage; - +@property (nonatomic, strong) EaseUserInfoCell *userInfoCell; +@property (nonatomic, strong) ActivenessModel *activenessModel; @end @implementation MeDisplayViewController - (void)viewDidLoad{ - _curUser = [Login curLoginUser]; _dataIndex = 0; _dataList = @[].mutableCopy; _canLoadMore = YES; @@ -47,30 +47,41 @@ - (void)viewDidLoad{ [super viewDidLoad]; self.title = @"个人主页"; [self.myTableView registerClass:[CSTopicCell class] forCellReuseIdentifier:kCellIdentifier_TopicCell]; + [self.myTableView registerClass:[UserActiveGraphCell class] forCellReuseIdentifier:kCellIdentifier_UserActiveGraphCell]; [self setupHeaderV]; } +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + [self.myTableView reloadData]; +} + +- (User *)curUser{ + return [Login curLoginUser]; +} + - (void)setupHeaderV{ __weak typeof(self) weakSelf = self; - if (!_tableHeaderView) { - _eaV = [EaseUserHeaderView userHeaderViewWithUser:_curUser image:[StartImagesManager shareManager].curImage.image]; - _eaV.userIconClicked = ^(){ - [weakSelf userIconClicked]; - }; - _eaV.fansCountBtnClicked = ^(){ - [weakSelf fansCountBtnClicked]; - }; - _eaV.followsCountBtnClicked = ^(){ - [weakSelf followsCountBtnClicked]; - }; - _eaV.nameBtnClicked = ^(){ - [weakSelf goToSettingInfo]; - }; - _eaV.clipsToBounds = YES; - _tableHeaderView = [[UIView alloc] initWithFrame:_eaV.bounds]; - [_tableHeaderView addSubview:_eaV]; - self.myTableView.tableHeaderView = _tableHeaderView; - } + _userInfoCell = [[EaseUserInfoCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellIdentifier_EaseUserInfoCell]; + _userInfoCell.userIconClicked = ^(){ + [weakSelf userIconClicked]; //用户头像点击 + }; + _userInfoCell.fansCountBtnClicked = ^(){ + [weakSelf fansCountBtnClicked]; //粉丝 + }; + _userInfoCell.followsCountBtnClicked = ^(){ + [weakSelf followsCountBtnClicked]; //关注 + }; + _userInfoCell.editButtonClicked = ^(){ + [weakSelf goToSettingInfo]; //编辑 + }; + + [[Coding_NetAPIManager sharedManager] request_Users_activenessWithGlobalKey:self.curUser.global_key andBlock:^(ActivenessModel *data, NSError *error) { + weakSelf.activenessModel = data; + [weakSelf.myTableView reloadData]; + }]; + + if (!_sectionHeaderView) { _sectionHeaderView = [[XTSegmentControl alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 44.0) Items:@[@"冒泡", @"话题"] selectedBlock:^(NSInteger index) { weakSelf.dataIndex = index; @@ -86,6 +97,8 @@ - (void)setDataIndex:(NSInteger)dataIndex{ if ((_dataIndex == 0 && self.curTweets.list.count <= 0) || (_dataIndex == 1 && _dataList.count <= 0)) { [self refresh]; + }else{ + self.view.blankPageView.hidden = YES; } } @@ -93,12 +106,26 @@ - (void)setDataIndex:(NSInteger)dataIndex{ - (void)refresh{ if (_dataIndex == 0) { + self.curUser = [Login curLoginUser]; + [self.myTableView reloadData]; + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_Users_activenessWithGlobalKey:self.curUser.global_key andBlock:^(ActivenessModel *data, NSError *error) { + weakSelf.activenessModel = data; + [weakSelf.myTableView reloadData]; + }]; [super refresh]; }else{ if (!_isLoading) { [self requestTopicsMore:NO]; } } + if (self.myTableView.loadingView) { + CGFloat offsetY = _userInfoCell.frame.size.height + [UserActiveGraphCell cellHeight] + 80; + [self.myTableView.loadingView mas_updateConstraints:^(MASConstraintMaker *make) { + make.centerY.offset(offsetY); + make.height.mas_equalTo(200); + }]; + } } - (void)refreshMore{ @@ -116,13 +143,13 @@ - (void)refreshMore{ - (void)requestTopicsMore:(BOOL)loadMore{ _willLoadMore = loadMore; _curPage = _willLoadMore? _curPage + 1: 0; - if (_dataList.count <= 0) { - [self.view beginLoading]; + if (self.dataList.count <= 0) { + [self.myTableView beginLoading]; } __weak typeof(self) weakSelf = self; - [[Coding_NetAPIManager sharedManager] request_JoinedTopicsWithUserGK:_curUser.global_key page:weakSelf.curPage block:^(id data, BOOL hasMoreData, NSError *error) { + [[Coding_NetAPIManager sharedManager] request_JoinedTopicsWithUserGK:self.curUser.global_key page:weakSelf.curPage block:^(id data, BOOL hasMoreData, NSError *error) { [weakSelf.refreshControl endRefreshing]; - [weakSelf.view endLoading]; + [weakSelf.myTableView endLoading]; [weakSelf.myTableView.infiniteScrollingView stopAnimating]; if (data) { if (weakSelf.willLoadMore) { @@ -133,7 +160,9 @@ - (void)requestTopicsMore:(BOOL)loadMore{ [weakSelf.myTableView reloadData]; weakSelf.myTableView.showsInfiniteScrolling = hasMoreData; } - [weakSelf.view configBlankPage:EaseBlankPageTypeMyJoinedTopic hasData:weakSelf.dataList.count > 0 hasError:error != nil offsetY:[_eaV originalHeight] + 60 reloadButtonBlock:^(id sender) { + + CGFloat offsetY = _userInfoCell.frame.size.height + [UserActiveGraphCell cellHeight] + 80; + [weakSelf.view configBlankPage:EaseBlankPageTypeMyJoinedTopic hasData:weakSelf.dataList.count > 0 hasError:error != nil offsetY:offsetY reloadButtonBlock:^(id sender) { [weakSelf refresh]; }]; @@ -143,19 +172,19 @@ - (void)requestTopicsMore:(BOOL)loadMore{ #pragma mark headerV - (void)fansCountBtnClicked{ UsersViewController *vc = [[UsersViewController alloc] init]; - vc.curUsers = [Users usersWithOwner:_curUser Type:UsersTypeFollowers]; + vc.curUsers = [Users usersWithOwner:self.curUser Type:UsersTypeFollowers]; [self.navigationController pushViewController:vc animated:YES]; } - (void)followsCountBtnClicked{ UsersViewController *vc = [[UsersViewController alloc] init]; - vc.curUsers = [Users usersWithOwner:_curUser Type:UsersTypeFriends_Attentive]; + vc.curUsers = [Users usersWithOwner:self.curUser Type:UsersTypeFriends_Attentive]; [self.navigationController pushViewController:vc animated:YES]; } - (void)userIconClicked{ // 显示大图 MJPhoto *photo = [[MJPhoto alloc] init]; - photo.url = [_curUser.avatar urlWithCodePath]; + photo.url = [self.curUser.avatar urlWithCodePath]; MJPhotoBrowser *browser = [[MJPhotoBrowser alloc] init]; browser.currentPhotoIndex = 0; @@ -173,15 +202,46 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView{ } #pragma mark TableM -- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ - return self.sectionHeaderView; +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ + return 3; } - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ + if (section < 2) { + return 0.0; + } return 44.0; } +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ + if (section < 2) { + return [UIView new]; + } + return self.sectionHeaderView; + +} + +- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ + if (section < 2) { + return 20; + }else{ + if (_dataIndex == 0) { + return 0; + }else{ + return _dataList.count == 0? self.view.height - self.sectionHeaderView.height: 0; + } + } +} + +- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{ + return [UIView new]; +} + + - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + if (section < 2) { + return 1; + } if (_dataIndex == 0) { return [super tableView:tableView numberOfRowsInSection:section]; }else{ @@ -190,9 +250,18 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ - if (_dataIndex == 0) { + if (indexPath.section == 0) { + EaseUserInfoCell *cell = self.userInfoCell; + cell.user = self.curUser; + return cell; + } else if (indexPath.section == 1) { + UserActiveGraphCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_UserActiveGraphCell forIndexPath:indexPath]; + cell.activenessModel = _activenessModel; + return cell; + + } else if (_dataIndex == 0) { return [super tableView:tableView cellForRowAtIndexPath:indexPath]; - }else{ + } else{ NSDictionary *topic = _dataList[indexPath.row]; CSTopicCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_TopicCell forIndexPath:indexPath]; [cell updateDisplayByTopic:topic]; @@ -202,7 +271,12 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ - if (_dataIndex == 0) { + if (indexPath.section == 0) { + return [tableView cellHeightForIndexPath:indexPath model:self.curUser keyPath:@"user" cellClass:[EaseUserInfoCell class] contentViewWidth:kScreen_Width]; + + } else if (indexPath.section == 1) { + return [UserActiveGraphCell cellHeight]; + } else if (_dataIndex == 0) { return [super tableView:tableView heightForRowAtIndexPath:indexPath]; }else{ NSDictionary *topic = _dataList[indexPath.row]; @@ -211,6 +285,9 @@ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPa } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ + if (indexPath.section < 2) { + return; + } if (_dataIndex == 0) { [super tableView:tableView didSelectRowAtIndexPath:indexPath]; }else{ diff --git a/Coding_iOS/Controllers/MeSetting/AboutViewController.m b/Coding_iOS/Controllers/MeSetting/AboutViewController.m index 278017458..01f551af9 100755 --- a/Coding_iOS/Controllers/MeSetting/AboutViewController.m +++ b/Coding_iOS/Controllers/MeSetting/AboutViewController.m @@ -10,6 +10,88 @@ #import "TitleDisclosureCell.h" #import "CodingShareView.h" + +#ifdef Target_Enterprise + +@interface AboutViewController () +@end + +@implementation AboutViewController + +- (void)viewDidLoad{ + [super viewDidLoad]; + // Do any additional setup after loading the view. + self.view.backgroundColor = kColorTableSectionBg; + self.title = @"关于我们"; + + CGFloat logoViewTop, logoLabelTop, versionLabelTop, infoLabelBottom; + NSString *icon_user_monkey; + if (kDevice_Is_iPhone6Plus) { + logoViewTop = 80; + logoLabelTop = 30; + versionLabelTop = 35; + infoLabelBottom = 35; + icon_user_monkey = @"icon_user_monkey"; + }else if (kDevice_Is_iPhone6){ + logoViewTop = 65; + logoLabelTop = 20; + versionLabelTop = 20; + infoLabelBottom = 20; + icon_user_monkey = @"icon_user_monkey"; + }else{ + logoViewTop = 40; + logoLabelTop = 15; + versionLabelTop = 20; + infoLabelBottom = 20; + icon_user_monkey = @"icon_user_monkey"; + } + + UIImageView *logoView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:icon_user_monkey]]; + [self.view addSubview:logoView]; + + UILabel *versionLabel = [[UILabel alloc] init]; + versionLabel.font = [UIFont systemFontOfSize:13]; + versionLabel.textColor = [UIColor colorWithHexString:@"0x323A45"]; + versionLabel.textAlignment = NSTextAlignmentCenter; + versionLabel.numberOfLines = 0; + versionLabel.text = [NSString stringWithFormat:@"CODING Enterprise\n\n版本:V%@", kVersion_Coding]; + versionLabel.userInteractionEnabled = YES; + __weak typeof(versionLabel) weakLabel = versionLabel; + [versionLabel bk_whenTapped:^{ + weakLabel.text = [NSString stringWithFormat:@"CODING Enterprise\n\n版本:V%@", [weakLabel.text hasSuffix:kVersion_Coding]? kVersionBuild_Coding: kVersion_Coding]; + }]; + [self.view addSubview:versionLabel]; + + UILabel *infoLabel = [[UILabel alloc] init]; + infoLabel.numberOfLines = 0; + infoLabel.backgroundColor = [UIColor clearColor]; + infoLabel.font = [UIFont systemFontOfSize:13]; + infoLabel.textColor = [UIColor colorWithHexString:@"0x76808E"]; + infoLabel.textAlignment = NSTextAlignmentCenter; + infoLabel.text = [NSString stringWithFormat:@"官网:https://e.coding.net \n联系电话:400-930-9163 \n客服邮箱:enterprise@coding.net\n客服 QQ:2847276903"]; + [self.view addSubview:infoLabel]; + + [logoView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.view.mas_top).offset(logoViewTop); + make.centerX.equalTo(self.view.mas_centerX); + }]; + + [versionLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(logoView.mas_bottom).offset(logoLabelTop); + make.left.right.equalTo(self.view); + }]; + + [infoLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.bottom.equalTo(self.view.mas_bottom).offset(-infoLabelBottom - kSafeArea_Bottom); + make.left.right.mas_equalTo(self.view); + }]; +} + +@end + +#else + + @interface AboutViewController () @end @@ -50,14 +132,20 @@ - (void)viewDidLoad{ logoLabel.font = [UIFont boldSystemFontOfSize:17]; logoLabel.textColor = kColor222; logoLabel.textAlignment = NSTextAlignmentCenter; - logoLabel.text = @"Coding-让开发更简单"; + logoLabel.text = @"CODING-让开发更简单"; [self.view addSubview:logoLabel]; UILabel *versionLabel = [[UILabel alloc] init]; versionLabel.font = [UIFont systemFontOfSize:12]; versionLabel.textColor = kColor666; versionLabel.textAlignment = NSTextAlignmentCenter; - versionLabel.text = [NSString stringWithFormat:@"版本:V%@", kVersionBuild_Coding]; + versionLabel.text = [NSString stringWithFormat:@"版本:V%@", kVersion_Coding]; + versionLabel.userInteractionEnabled = YES; + __weak typeof(versionLabel) weakLabel = versionLabel; + [versionLabel bk_whenTapped:^{ + weakLabel.text = [NSString stringWithFormat:@"版本:V%@", [weakLabel.text hasSuffix:kVersion_Coding]? kVersionBuild_Coding: kVersion_Coding]; + }]; + [self.view addSubview:versionLabel]; UILabel *infoLabel = [[UILabel alloc] init]; @@ -66,7 +154,7 @@ - (void)viewDidLoad{ infoLabel.font = [UIFont systemFontOfSize:12]; infoLabel.textColor = kColor666; infoLabel.textAlignment = NSTextAlignmentCenter; - infoLabel.text = [NSString stringWithFormat:@"官网:https://coding.net \nE-mail:link@coding.net \n微博:Coding \n微信:扣钉Coding"]; + infoLabel.text = [NSString stringWithFormat:@"官网:https://coding.net \nE-mail:support@coding.net \n微博:Coding \n微信:扣钉Coding\nQQ 群:617404718"]; [self.view addSubview:infoLabel]; [logoView mas_makeConstraints:^(MASConstraintMaker *make) { @@ -89,9 +177,9 @@ - (void)viewDidLoad{ [infoLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.bottom.equalTo(self.view.mas_bottom).offset(-infoLabelBottom); make.left.right.mas_equalTo(self.view); - make.height.mas_equalTo(5*infoLabel.font.pointSize); + make.height.mas_equalTo(6*infoLabel.font.pointSize); }]; - + UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; tableView.scrollEnabled = NO; tableView.backgroundColor = [UIColor clearColor]; @@ -113,7 +201,7 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ TitleDisclosureCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_TitleDisclosure forIndexPath:indexPath]; - [cell setTitleStr:indexPath.row == 0? @"去评分": @"推荐 Coding"]; + [cell setTitleStr:indexPath.row == 0? @"去评分": @"推荐 CODING"]; [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; return cell; } @@ -127,3 +215,6 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath } @end + +#endif + diff --git a/Coding_iOS/Controllers/MeSetting/SettingAccountViewController.m b/Coding_iOS/Controllers/MeSetting/SettingAccountViewController.m index 41e510b11..8721435fc 100755 --- a/Coding_iOS/Controllers/MeSetting/SettingAccountViewController.m +++ b/Coding_iOS/Controllers/MeSetting/SettingAccountViewController.m @@ -17,6 +17,7 @@ #import "Login.h" #import "Close2FAViewController.h" #import "SettingEmailViewController.h" +#import "CannotLoginViewController.h" @interface SettingAccountViewController () @property (strong, nonatomic) User *myUser; @@ -47,6 +48,9 @@ - (void)viewDidLoad [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); } @@ -68,6 +72,99 @@ - (void)refresh2FA{ }]; } + +#ifdef Target_Enterprise + +#pragma mark TableM + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ + return 2; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + NSInteger row = (section == 0? 2: _is2FAOpen? 3: 2); + return row; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + if (indexPath.section == 0) { + TitleValueCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_TitleValue forIndexPath:indexPath]; + if (indexPath.row == 0) { + cell.selectionStyle = UITableViewCellSelectionStyleNone; + [cell setTitleStr:@"用户名" valueStr:self.myUser.global_key]; + }else{ + cell.selectionStyle = self.myUser.email_validation.boolValue? UITableViewCellSelectionStyleNone: UITableViewCellSelectionStyleDefault; + NSString *valueStr = (self.myUser.email.length <= 0? @"未绑定": + self.myUser.email_validation.boolValue? self.myUser.email: + [NSString stringWithFormat:@"%@ 未验证",self.myUser.email]); + [cell setTitleStr:@"邮箱" valueStr:valueStr]; + } + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; + return cell; + }else{ + if (indexPath.row == 0) { + TitleValueMoreCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_TitleValueMore forIndexPath:indexPath]; + [cell setTitleStr:@"手机号码" valueStr:self.myUser.phone.length > 0 ? self.myUser.phone: @"未绑定"]; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; + return cell; + }else{ + TitleDisclosureCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_TitleDisclosure forIndexPath:indexPath]; + [cell setTitleStr:indexPath.row == 1? @"修改密码": @"关闭两步验证"]; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; + return cell; + } + } +} +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ + UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 20)]; + headerView.backgroundColor = kColorTableSectionBg; + return headerView; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ + return 15.0; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ + return 1.0/[UIScreen mainScreen].scale; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + if (indexPath.section == 0) { + if (indexPath.row == 1) { + if (!self.myUser.email_validation.boolValue && self.myUser.email.length > 0) { + [self.view endEditing:YES]; + [[UIAlertController ea_alertViewWithTitle:@"激活邮箱" message:@"该邮箱尚未激活,请尽快去邮箱查收邮件并激活账号。如果在收件箱中没有看到,请留意一下垃圾邮件箱子(T_T)" buttonTitles:@[@"重发激活邮件"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { + [self sendActivateEmail]; + } + }] show]; + } + } + }else{ + if (indexPath.row == 0) { + if ([NSObject isPrivateCloud].boolValue) { + [NSObject showHudTipStr:@"App 暂不支持设置手机号码"]; + }else{ + SettingPhoneViewController *vc = [[SettingPhoneViewController alloc] init]; + [self.navigationController pushViewController:vc animated:YES]; + } + }else if (indexPath.row == 1){ + SettingPasswordViewController *vc = [[SettingPasswordViewController alloc] init]; + vc.myUser = self.myUser; + [self.navigationController pushViewController:vc animated:YES]; + }else{ + Close2FAViewController *vc = [Close2FAViewController vcWithPhone:_myUser.phone sucessBlock:^(UIViewController *vcc) { + [vcc.navigationController popToRootViewControllerAnimated:YES]; + }]; + [self.navigationController pushViewController:vc animated:YES]; + } + } +} + +#else + #pragma mark TableM - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ @@ -75,7 +172,7 @@ - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ - NSInteger row = (section == 1? 2: 1); + NSInteger row = ((section == 1 || section == 2)? 2: 1); return row; } @@ -83,7 +180,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N if (indexPath.section == 0) { TitleValueCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_TitleValue forIndexPath:indexPath]; cell.selectionStyle = UITableViewCellSelectionStyleNone; - [cell setTitleStr:@"个性后缀" valueStr:self.myUser.global_key]; + [cell setTitleStr:@"用户名" valueStr:self.myUser.global_key]; [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; return cell; }else if (indexPath.section == 1){ @@ -105,7 +202,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } }else{ TitleDisclosureCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_TitleDisclosure forIndexPath:indexPath]; - [cell setTitleStr:indexPath.section == 2? @"修改密码": @"关闭两步验证"]; + [cell setTitleStr:indexPath.section == 2? indexPath.row == 0? @"修改密码": @"找回密码": @"关闭两步验证"]; [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; return cell; } @@ -129,15 +226,11 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath if (indexPath.section == 1) { if (indexPath.row == 0) { if (!self.myUser.email_validation.boolValue && self.myUser.email.length > 0) { - UIAlertView *alertView = [UIAlertView bk_alertViewWithTitle:@"激活邮箱" message:@"该邮箱尚未激活,请尽快去邮箱查收邮件并激活账号。如果在收件箱中没有看到,请留意一下垃圾邮件箱子(T_T)"]; - [alertView bk_setCancelButtonWithTitle:@"取消" handler:nil]; - [alertView bk_addButtonWithTitle:@"重发激活邮件" handler:nil]; - [alertView bk_setDidDismissBlock:^(UIAlertView *alert, NSInteger index) { - if (index == 1) { + [[UIAlertController ea_alertViewWithTitle:@"激活邮箱" message:@"该邮箱尚未激活,请尽快去邮箱查收邮件并激活账号。如果在收件箱中没有看到,请留意一下垃圾邮件箱子(T_T)" buttonTitles:@[@"重发激活邮件"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { [self sendActivateEmail]; } - }]; - [alertView show]; + }] show]; }else{ SettingEmailViewController *vc = [SettingEmailViewController new]; [self.navigationController pushViewController:vc animated:YES]; @@ -147,9 +240,18 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath [self.navigationController pushViewController:vc animated:YES]; } }else if (indexPath.section == 2){ - SettingPasswordViewController *vc = [[SettingPasswordViewController alloc] init]; - vc.myUser = self.myUser; - [self.navigationController pushViewController:vc animated:YES]; + if (indexPath.row == 0) { + SettingPasswordViewController *vc = [[SettingPasswordViewController alloc] init]; + vc.myUser = self.myUser; + [self.navigationController pushViewController:vc animated:YES]; + }else{ + if (self.myUser.hasNoEamilAndPhone) { + [NSObject showHudTipStr:@"邮箱和手机账号均未填写的情况下,无法使用找回密码功能"]; + }else{ + CannotLoginViewController *vc = [CannotLoginViewController vcWithMethodType:(self.myUser.phone.length > 0? CannotLoginMethodPhone: CannotLoginMethodEamil) stepIndex:0 userStr:nil]; + [self.navigationController pushViewController:vc animated:YES]; + } + } }else if (indexPath.section == 3){ Close2FAViewController *vc = [Close2FAViewController vcWithPhone:_myUser.phone sucessBlock:^(UIViewController *vcc) { [vcc.navigationController popToRootViewControllerAnimated:YES]; @@ -158,6 +260,10 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath } } +#endif + + + - (void)sendActivateEmail{ [[Coding_NetAPIManager sharedManager] request_SendActivateEmail:self.myUser.email block:^(id data, NSError *error) { if (data) { diff --git a/Coding_iOS/Controllers/MeSetting/SettingEmailViewController.m b/Coding_iOS/Controllers/MeSetting/SettingEmailViewController.m index 81344ccf0..4ba5070e4 100644 --- a/Coding_iOS/Controllers/MeSetting/SettingEmailViewController.m +++ b/Coding_iOS/Controllers/MeSetting/SettingEmailViewController.m @@ -40,6 +40,9 @@ - (void)viewDidLoad{ [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _myTableView.tableFooterView = [self customFooterView]; @@ -71,7 +74,7 @@ - (UIView *)customFooterView{ RACObserve(self, j_captcha), RACObserve(self, two_factor_code)] reduce:^id(NSString *email, NSString *j_captcha, NSString *two_factor_code){ - return @(email.length > 0 && j_captcha.length > 0 && two_factor_code.length > 0); + return @(email.length > 0 && j_captcha.length > 0 && (two_factor_code.length > 0 || [Login curLoginUser].hasNoEamilAndPhone)); }]; [footerV addSubview:_footerBtn]; @@ -110,6 +113,13 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N return cell; } +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ + if (indexPath.row == 1 && [Login curLoginUser].hasNoEamilAndPhone) { + return 0; + } + return 50; +} + - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 20)]; headerView.backgroundColor = kColorTableSectionBg; @@ -133,7 +143,7 @@ - (void)doneBtnClicked:(id)sender{ NSString *tipStr; if (![_email isEmail]) { tipStr = @"邮箱格式有误"; - }else if (_two_factor_code.length <= 0){ + }else if (_two_factor_code.length <= 0 && ![Login curLoginUser].hasNoEamilAndPhone){ tipStr = !_is2FAOpen? @"请填写密码": @"请填写两步验证码"; }else if (_j_captcha.length <= 0){ tipStr = @"请填写验证码"; diff --git a/Coding_iOS/Controllers/MeSetting/SettingMineInfoViewController.m b/Coding_iOS/Controllers/MeSetting/SettingMineInfoViewController.m index 852ab58d9..0ff7a140f 100755 --- a/Coding_iOS/Controllers/MeSetting/SettingMineInfoViewController.m +++ b/Coding_iOS/Controllers/MeSetting/SettingMineInfoViewController.m @@ -21,6 +21,10 @@ #import "Helper.h" #import "UserInfoDetailTagCell.h" #import "JDStatusBarNotification.h" +#import "SettingSkillsViewController.h" +#import "SettingAccountViewController.h" + +#ifdef Target_Enterprise @interface SettingMineInfoViewController () @property (strong, nonatomic) UITableView *myTableView; @@ -117,7 +121,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N case 0:{ switch (indexPath.row) { case 1: - [cell setTitleStr:@"昵称" valueStr:_curUser.name]; + [cell setTitleStr:@"名字" valueStr:_curUser.name]; break; case 2: if (_curUser.sex.intValue == 0) { @@ -194,13 +198,15 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath switch (indexPath.row) { case 0:{//头像 if (![JDStatusBarNotification isVisible]) { - UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"更换头像" delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"拍照", @"从相册选择", nil]; - [actionSheet showInView:self.view]; + __weak typeof(self) weakSelf = self; + [[UIAlertController ea_actionSheetCustomWithTitle:@"更换头像" buttonTitles:@[@"拍照", @"从相册选择"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + [weakSelf actionSheetDidDismissWithButtonIndex:index]; + }] showInView:self.view]; } } break; - case 1:{//昵称 - SettingTextViewController *vc = [SettingTextViewController settingTextVCWithTitle:@"昵称" textValue:_curUser.name doneBlock:^(NSString *textValue) { + case 1:{//名字 + SettingTextViewController *vc = [SettingTextViewController settingTextVCWithTitle:@"名字" textValue:_curUser.name doneBlock:^(NSString *textValue) { NSString *preValue = weakSelf.curUser.name; weakSelf.curUser.name = textValue; [weakSelf.myTableView reloadData]; @@ -333,10 +339,10 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath NSNumber *index = [_curJobManager indexOfJobName:_curUser.job_str]; [ActionSheetStringPicker showPickerWithTitle:nil rows:@[jobNameArray] initialSelection:@[index] doneBlock:^(ActionSheetStringPicker *picker, NSArray *selectedIndex, NSArray *selectedValue) { NSString *preValue = weakSelf.curUser.job_str; - NSString *preValueKey = weakSelf.curUser.job; - + NSNumber *preValueKey = weakSelf.curUser.job; + NSNumber *jobIndex = selectedIndex.firstObject; - NSString *job = [NSString stringWithFormat:@"%d", jobIndex.intValue +1]; + NSNumber *job = @(jobIndex.intValue +1); NSString *job_str = selectedValue.firstObject; _curUser.job = job; _curUser.job_str = job_str; @@ -370,7 +376,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath tags = [selectedTags componentsJoinedByString:@","]; tags_str = [weakSelf.curTagsManager getTags_strWithTags:selectedTags]; } - + weakSelf.curUser.tags = tags; weakSelf.curUser.tags_str = tags_str; [weakSelf.myTableView reloadData]; @@ -391,7 +397,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath } #pragma mark UIActionSheetDelegate M -- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex{ +- (void)actionSheetDidDismissWithButtonIndex:(NSInteger)buttonIndex{ if (buttonIndex == 2) { return; } @@ -400,20 +406,565 @@ - (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSIn picker.allowsEditing = YES;//设置可编辑 if (buttonIndex == 0) { -// 拍照 + // 拍照 if (![Helper checkCameraAuthorizationStatus]) { return; } picker.sourceType = UIImagePickerControllerSourceTypeCamera; }else if (buttonIndex == 1){ -// 相册 + // 相册 if (![Helper checkPhotoLibraryAuthorizationStatus]) { return; } picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum; } [self presentViewController:picker animated:YES completion:nil];//进入照相界面 + +} + +#pragma mark UIImagePickerControllerDelegate +- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{ + [picker dismissViewControllerAnimated:YES completion:^{ + UIImage *editedImage, *originalImage; + editedImage = [info objectForKey:UIImagePickerControllerEditedImage]; + __weak typeof(self) weakSelf = self; + + [[Coding_NetAPIManager sharedManager] request_UpdateUserIconImage:editedImage successBlock:^(id responseObj) { + weakSelf.curUser.avatar = responseObj; + [weakSelf.myTableView reloadData]; + } failureBlock:^(NSError *error) { + [NSObject showError:error]; + } progerssBlock:^(CGFloat progressValue) { + }]; + + // 保存原图片到相册中 + if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) { + originalImage = [info objectForKey:UIImagePickerControllerOriginalImage]; + UIImageWriteToSavedPhotosAlbum(originalImage, self, nil, NULL); + } + }]; +} + +- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{ + [picker dismissViewControllerAnimated:YES completion:nil]; +} + +- (void)dealloc +{ + _myTableView.delegate = nil; + _myTableView.dataSource = nil; +} + +@end + +#else + +@interface SettingMineInfoViewController () +@property (strong, nonatomic) UITableView *myTableView; +@property (strong, nonatomic) User *curUser; +@property (strong, nonatomic) JobManager *curJobManager; +@property (strong, nonatomic) TagsManager *curTagsManager; + +@property (assign, nonatomic) BOOL isHeaderClosed; +@end + +@implementation SettingMineInfoViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + self.title = @"个人信息"; + + // 添加myTableView + _myTableView = ({ + UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped]; + tableView.backgroundColor = kColorTableSectionBg; + tableView.dataSource = self; + tableView.delegate = self; + tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + [tableView registerClass:[TitleValueMoreCell class] forCellReuseIdentifier:kCellIdentifier_TitleValueMore]; + [tableView registerClass:[TitleRImageMoreCell class] forCellReuseIdentifier:kCellIdentifier_TitleRImageMore]; + [tableView registerClass:[UserInfoDetailTagCell class] forCellReuseIdentifier:kCellIdentifier_UserInfoDetailTagCell]; + [self.view addSubview:tableView]; + [tableView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; + tableView; + }); + _curJobManager = [[JobManager alloc] init]; + _curTagsManager = [[TagsManager alloc] init]; + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_UserJobArrayWithBlock:^(id data, NSError *error) { + if (data) { + weakSelf.curJobManager.jobDict = data; + } + }]; + [[Coding_NetAPIManager sharedManager] request_UserTagArrayWithBlock:^(id data, NSError *error) { + if (data) { + weakSelf.curTagsManager.tagArray = data; + } + }]; +} + +- (void)viewWillAppear:(BOOL)animated{ + [super viewWillAppear:animated]; + self.curUser =[Login curLoginUser]; +} + +- (void)setCurUser:(User *)curUser{ + _curUser = curUser; + + [self configHeader]; +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. + self.myTableView = nil; + self.curUser = nil; + self.curJobManager = nil; + self.curTagsManager = nil; + self.view = nil; +} + +- (void)configHeader{ + BOOL isHeaderNeedToShow = !_isHeaderClosed && (!_curUser.is_phone_validated.boolValue || !_curUser.email_validation.boolValue) && _curUser.canUpgradeByCompleteUserInfo; + UIView *headerV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, !isHeaderNeedToShow? 1: 44)]; + headerV.backgroundColor = !isHeaderNeedToShow? [UIColor clearColor]: [UIColor colorWithHexString:@"0xF2DADA"]; + if (isHeaderNeedToShow) { + __weak typeof(self) weakSelf = self; + UIButton *closeBtn = [UIButton new]; + [closeBtn setImage:[UIImage imageNamed:@"button_red_close"] forState:UIControlStateNormal]; + [closeBtn bk_addEventHandler:^(id sender) { + weakSelf.isHeaderClosed = YES; + [weakSelf configHeader]; + } forControlEvents:UIControlEventTouchUpInside]; + [headerV addSubview:closeBtn]; + [closeBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.bottom.right.equalTo(headerV); + make.width.equalTo(closeBtn.mas_height); + }]; + UILabel *tipL = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:[UIColor colorWithHexString:@"0xA64C4B"]]; + tipL.adjustsFontSizeToFitWidth = YES; + tipL.minimumScaleFactor = .5; + tipL.userInteractionEnabled = YES; + NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:@"验证手机或邮箱后完善资料才能升级,去验证"]; + [attrStr addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:[attrStr.string rangeOfString:@"去验证"]]; + tipL.attributedText = attrStr; + [tipL bk_whenTapped:^{ + SettingAccountViewController *vc = [SettingAccountViewController new]; + [weakSelf.navigationController pushViewController:vc animated:YES]; + }]; + [headerV addSubview:tipL]; + [tipL mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(headerV); + make.left.equalTo(headerV).offset(15); + make.right.equalTo(closeBtn.mas_left); + }]; + } + self.myTableView.tableHeaderView = headerV; +} + +#pragma mark TableM + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ + return 4; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + NSInteger row; + switch (section) { + case 0: + row = 6; + break; + case 1: + row = 4; + break; + default: + row = 1; + break; + } + return row; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + if (indexPath.section == 0 && indexPath.row == 0) { + TitleRImageMoreCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_TitleRImageMore forIndexPath:indexPath]; + cell.curUser = _curUser; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; + return cell; + }else if (indexPath.section == 2 || indexPath.section == 3){ + UserInfoDetailTagCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_UserInfoDetailTagCell forIndexPath:indexPath]; + [cell setTitleStr:indexPath.section == 2? @"开发技能": @"个性标签"]; + [cell setTagStr:indexPath.section == 2? _curUser.skills_str: _curUser.tags_str]; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; + return cell; + }else{ + TitleValueMoreCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_TitleValueMore forIndexPath:indexPath]; + switch (indexPath.section) { + case 0:{ + switch (indexPath.row) { + case 1: + [cell setTitleStr:@"昵称" valueStr:_curUser.name]; + break; + case 2: + if (_curUser.sex.intValue == 0) { + // 男 + [cell setTitleStr:@"性别" valueStr:@"男"]; + }else if (_curUser.sex.intValue == 1){ + // 女 + [cell setTitleStr:@"性别" valueStr:@"女"]; + }else{ + // 未知 + [cell setTitleStr:@"性别" valueStr:@"未知"]; + } + break; + case 3: + [cell setTitleStr:@"生日" valueStr:_curUser.birthday]; + break; + case 4: + [cell setTitleStr:@"所在地" valueStr:_curUser.location]; + break; + default: + [cell setTitleStr:@"座右铭" valueStr:_curUser.slogan]; + break; + } + } + break; + case 1:{ + if (indexPath.row == 0) { + [cell setTitleStr:@"学历" valueStr:_curUser.degree_str]; + }else if (indexPath.row == 1){ + [cell setTitleStr:@"学校" valueStr:_curUser.school]; + }else if (indexPath.row == 2){ + [cell setTitleStr:@"公司" valueStr:_curUser.company]; + }else{ + [cell setTitleStr:@"工作" valueStr:_curUser.job_str]; + } + } + break; + default: + break; + } + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; + return cell; + } +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ + CGFloat cellHeight; + if (indexPath.section == 0 && indexPath.row == 0) { + cellHeight = [TitleRImageMoreCell cellHeight]; + }else if (indexPath.section == 2 || indexPath.section == 3){ + cellHeight = [UserInfoDetailTagCell cellHeightWithObj:indexPath.section == 2? _curUser.skills_str: _curUser.tags_str]; + }else{ + cellHeight = [TitleValueMoreCell cellHeight]; + } + return cellHeight; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ + return 20.0; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ + return 0.5; +} + +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ + UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 1)]; + headerView.backgroundColor = kColorTableSectionBg; + [headerView setHeight:20.0]; + return headerView; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + __weak typeof(self) weakSelf = self; + switch (indexPath.section) { + case 0:{ + switch (indexPath.row) { + case 0:{//头像 + if (![JDStatusBarNotification isVisible]) { + __weak typeof(self) weakSelf = self; + [[UIAlertController ea_actionSheetCustomWithTitle:@"更换头像" buttonTitles:@[@"拍照", @"从相册选择"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + [weakSelf actionSheetDidDismissWithButtonIndex:index]; + }] showInView:self.view]; + } + } + break; + case 1:{//昵称 + SettingTextViewController *vc = [SettingTextViewController settingTextVCWithTitle:@"昵称" textValue:_curUser.name doneBlock:^(NSString *textValue) { + NSString *preValue = weakSelf.curUser.name; + weakSelf.curUser.name = textValue; + [weakSelf.myTableView reloadData]; + [[Coding_NetAPIManager sharedManager] request_UpdateUserInfo_WithObj:weakSelf.curUser andBlock:^(id data, NSError *error) { + if (data) { + weakSelf.curUser = data; + }else{ + weakSelf.curUser.name = preValue; + } + [weakSelf.myTableView reloadData]; + }]; + }]; + [self.navigationController pushViewController:vc animated:YES]; + } + break; + case 2:{//性别 + [ActionSheetStringPicker showPickerWithTitle:nil rows:@[@[@"男", @"女", @"未知"]] initialSelection:@[_curUser.sex] doneBlock:^(ActionSheetStringPicker *picker, NSArray * selectedIndex, NSArray *selectedValue) { + NSNumber *preValue = weakSelf.curUser.sex; + weakSelf.curUser.sex = [selectedIndex firstObject]; + [weakSelf.myTableView reloadData]; + [[Coding_NetAPIManager sharedManager] request_UpdateUserInfo_WithObj:weakSelf.curUser andBlock:^(id data, NSError *error) { + if (data) { + weakSelf.curUser = data; + }else{ + weakSelf.curUser.sex = preValue; + } + [weakSelf.myTableView reloadData]; + }]; + } cancelBlock:nil origin:self.view]; + } + break; + case 3:{//生日 + NSDate *curDate = [NSDate dateFromString:_curUser.birthday withFormat:@"yyyy-MM-dd"]; + if (!curDate) { + curDate = [NSDate dateFromString:@"1990-01-01" withFormat:@"yyyy-MM-dd"]; + } + ActionSheetDatePicker *picker = [[ActionSheetDatePicker alloc] initWithTitle:nil datePickerMode:UIDatePickerModeDate selectedDate:curDate doneBlock:^(ActionSheetDatePicker *picker, NSDate *selectedDate, id origin) { + NSString *preValue = weakSelf.curUser.birthday; + weakSelf.curUser.birthday = [selectedDate string_yyyy_MM_dd]; + [weakSelf.myTableView reloadData]; + [[Coding_NetAPIManager sharedManager] request_UpdateUserInfo_WithObj:weakSelf.curUser andBlock:^(id data, NSError *error) { + if (data) { + weakSelf.curUser = data; + }else{ + weakSelf.curUser.birthday = preValue; + } + [weakSelf.myTableView reloadData]; + }]; + } cancelBlock:^(ActionSheetDatePicker *picker) { + DebugLog(@"%@", picker.description); + } origin:self.view]; + picker.minimumDate = [[NSDate date] offsetYear:-120]; + picker.maximumDate = [NSDate date]; + [picker showActionSheetPicker]; + } + break; + case 4:{//所在地 + NSNumber *firstLevel = nil, *secondLevel = nil; + if (_curUser.location && _curUser.location.length > 0) { + NSArray *locationArray = [_curUser.location componentsSeparatedByString:@" "]; + if (locationArray.count == 2) { + firstLevel = [AddressManager indexOfFirst:[locationArray firstObject]]; + secondLevel = [AddressManager indexOfSecond:[locationArray lastObject] inFirst:[locationArray firstObject]]; + } + } + if (!firstLevel) { + firstLevel = [NSNumber numberWithInteger:0]; + } + if (!secondLevel) { + secondLevel = [NSNumber numberWithInteger:0]; + } + + [ActionSheetStringPicker showPickerWithTitle:nil rows:@[[AddressManager firstLevelArray], [AddressManager secondLevelMap]] initialSelection:@[firstLevel, secondLevel] doneBlock:^(ActionSheetStringPicker *picker, NSArray * selectedIndex, NSArray *selectedValue) { + NSString *preValue = weakSelf.curUser.location; + NSString *location = [selectedValue componentsJoinedByString:@" "]; + weakSelf.curUser.location = location; + [weakSelf.myTableView reloadData]; + [[Coding_NetAPIManager sharedManager] request_UpdateUserInfo_WithObj:weakSelf.curUser andBlock:^(id data, NSError *error) { + if (data) { + weakSelf.curUser = data; + }else{ + weakSelf.curUser.location = preValue; + } + [weakSelf.myTableView reloadData]; + }]; + } cancelBlock:nil origin:self.view]; + } + break; + default:{//座右铭 + SettingTextViewController *vc = [SettingTextViewController settingTextVCWithTitle:@"座右铭" textValue:_curUser.slogan doneBlock:^(NSString *textValue) { + NSString *preValue = weakSelf.curUser.slogan; + weakSelf.curUser.slogan = textValue; + [weakSelf.myTableView reloadData]; + [[Coding_NetAPIManager sharedManager] request_UpdateUserInfo_WithObj:weakSelf.curUser andBlock:^(id data, NSError *error) { + if (data) { + weakSelf.curUser = data; + }else{ + weakSelf.curUser.slogan = preValue; + } + [weakSelf.myTableView reloadData]; + }]; + }]; + [self.navigationController pushViewController:vc animated:YES]; + } + break; + } + } + break; + case 1:{ + switch (indexPath.row) { + case 0:{ + //学历 + NSArray *list = [User degreeList]; + NSNumber *index = @(MIN(list.count, MAX(0, _curUser.degree.integerValue - 1))); + [ActionSheetStringPicker showPickerWithTitle:nil rows:@[list] initialSelection:@[index] doneBlock:^(ActionSheetStringPicker *picker, NSArray *selectedIndex, NSArray *selectedValue) { + NSNumber *preValue = weakSelf.curUser.degree; + weakSelf.curUser.degree = @([selectedIndex.firstObject integerValue] + 1); + [weakSelf.myTableView reloadData]; + [[Coding_NetAPIManager sharedManager] request_UpdateUserInfo_WithObj:weakSelf.curUser andBlock:^(id data, NSError *error) { + if (data) { + weakSelf.curUser = data; + }else{ + weakSelf.curUser.degree = preValue; + } + [weakSelf.myTableView reloadData]; + }]; + } cancelBlock:nil origin:self.view]; + } + break; + case 1:{ + //学校 + SettingTextViewController *vc = [SettingTextViewController settingTextVCWithTitle:@"学校" textValue:_curUser.school doneBlock:^(NSString *textValue) { + NSString *preValue = weakSelf.curUser.school; + weakSelf.curUser.school = textValue; + [weakSelf.myTableView reloadData]; + [[Coding_NetAPIManager sharedManager] request_UpdateUserInfo_WithObj:weakSelf.curUser andBlock:^(id data, NSError *error) { + if (data) { + weakSelf.curUser = data; + }else{ + weakSelf.curUser.school = preValue; + } + [weakSelf.myTableView reloadData]; + }]; + }]; + [self.navigationController pushViewController:vc animated:YES]; + } + break; + case 2:{//公司 + SettingTextViewController *vc = [SettingTextViewController settingTextVCWithTitle:@"公司" textValue:_curUser.company doneBlock:^(NSString *textValue) { + NSString *preValue = weakSelf.curUser.company; + weakSelf.curUser.company = textValue; + [weakSelf.myTableView reloadData]; + [[Coding_NetAPIManager sharedManager] request_UpdateUserInfo_WithObj:weakSelf.curUser andBlock:^(id data, NSError *error) { + if (data) { + weakSelf.curUser = data; + }else{ + weakSelf.curUser.company = preValue; + } + [weakSelf.myTableView reloadData]; + }]; + }]; + [self.navigationController pushViewController:vc animated:YES]; + } + break; + default:{//职位 + NSArray *jobNameArray = _curJobManager.jobNameArray; + NSNumber *index = [_curJobManager indexOfJobName:_curUser.job_str]; + [ActionSheetStringPicker showPickerWithTitle:nil rows:@[jobNameArray] initialSelection:@[index] doneBlock:^(ActionSheetStringPicker *picker, NSArray *selectedIndex, NSArray *selectedValue) { + NSString *preValue = weakSelf.curUser.job_str; + NSNumber *preValueKey = weakSelf.curUser.job; + + NSNumber *jobIndex = selectedIndex.firstObject; + NSNumber *job = @(jobIndex.intValue +1); + NSString *job_str = selectedValue.firstObject; + _curUser.job = job; + _curUser.job_str = job_str; + [weakSelf.myTableView reloadData]; + [[Coding_NetAPIManager sharedManager] request_UpdateUserInfo_WithObj:weakSelf.curUser andBlock:^(id data, NSError *error) { + if (data) { + weakSelf.curUser = data; + }else{ + weakSelf.curUser.job_str = preValue; + weakSelf.curUser.job = preValueKey; + } + [weakSelf.myTableView reloadData]; + }]; + } cancelBlock:nil origin:self.view]; + } + break; + } + } + break; + case 2:{//开发技能 + SettingSkillsViewController *vc = [SettingSkillsViewController settingSkillsVCWithDoneBlock:^(NSArray *selectedSkills) { + NSArray *preSkills = weakSelf.curUser.skills; + weakSelf.curUser.skills = selectedSkills; + [weakSelf.myTableView reloadData]; + [[Coding_NetAPIManager sharedManager] request_UpdateUserInfo_WithObj:weakSelf.curUser andBlock:^(id data, NSError *error) { + if (data) { + weakSelf.curUser = data; + }else{ + weakSelf.curUser.skills = preSkills; + } + [weakSelf.myTableView reloadData]; + }]; + }]; + [self.navigationController pushViewController:vc animated:YES]; + } + break; + default:{//个性标签 + NSArray *selectedTags = nil; + if (_curUser.tags && _curUser.tags.length > 0) { + selectedTags = [_curUser.tags componentsSeparatedByString:@","]; + } + SettingTagsViewController *vc = [SettingTagsViewController settingTagsVCWithAllTags:_curTagsManager.tagArray selectedTags:selectedTags doneBlock:^(NSArray *selectedTags) { + NSString *preValue = weakSelf.curUser.tags_str; + NSString *preValueKey = weakSelf.curUser.tags; + + NSString *tags = @"", *tags_str = @""; + if (selectedTags.count > 0) { + tags = [selectedTags componentsJoinedByString:@","]; + tags_str = [weakSelf.curTagsManager getTags_strWithTags:selectedTags]; + } + + weakSelf.curUser.tags = tags; + weakSelf.curUser.tags_str = tags_str; + [weakSelf.myTableView reloadData]; + [[Coding_NetAPIManager sharedManager] request_UpdateUserInfo_WithObj:weakSelf.curUser andBlock:^(id data, NSError *error) { + if (data) { + weakSelf.curUser = data; + }else{ + weakSelf.curUser.tags_str = preValue; + weakSelf.curUser.tags = preValueKey; + } + [weakSelf.myTableView reloadData]; + }]; + }]; + [self.navigationController pushViewController:vc animated:YES]; + } + break; + } +} +#pragma mark UIActionSheetDelegate M +- (void)actionSheetDidDismissWithButtonIndex:(NSInteger)buttonIndex{ + if (buttonIndex == 2) { + return; + } + UIImagePickerController *picker = [[UIImagePickerController alloc] init]; + picker.delegate = self; + picker.allowsEditing = YES;//设置可编辑 + + if (buttonIndex == 0) { + // 拍照 + if (![Helper checkCameraAuthorizationStatus]) { + return; + } + picker.sourceType = UIImagePickerControllerSourceTypeCamera; + }else if (buttonIndex == 1){ + // 相册 + if (![Helper checkPhotoLibraryAuthorizationStatus]) { + return; + } + picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum; + } + [self presentViewController:picker animated:YES completion:nil];//进入照相界面 + } #pragma mark UIImagePickerControllerDelegate @@ -450,3 +1001,7 @@ - (void)dealloc } @end + +#endif + + diff --git a/Coding_iOS/Controllers/MeSetting/SettingPasswordViewController.m b/Coding_iOS/Controllers/MeSetting/SettingPasswordViewController.m index 87ad701c0..150e4e7d1 100755 --- a/Coding_iOS/Controllers/MeSetting/SettingPasswordViewController.m +++ b/Coding_iOS/Controllers/MeSetting/SettingPasswordViewController.m @@ -46,6 +46,9 @@ - (void)viewDidLoad [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"完成" style:UIBarButtonItemStylePlain target:self action:@selector(doneBtnClicked:)]; @@ -102,6 +105,10 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; return cell; } +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ + return 50; +} + - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 20)]; headerView.backgroundColor = kColorTableSectionBg; @@ -133,12 +140,9 @@ - (void)doneBtnClicked:(id)sender{ self.navigationItem.rightBarButtonItem.enabled = YES; if (data) { __weak typeof(self) weakSelf = self; - UIAlertView *alertView = [UIAlertView bk_alertViewWithTitle:@"提示" message:@"修改密码成功,您需要重新登陆哦~"]; - [alertView bk_setCancelButtonWithTitle:@"知道了" handler:nil]; - [alertView bk_setDidDismissBlock:^(UIAlertView *alert, NSInteger index) { + [[UIAlertController ea_alertViewWithTitle:@"提示" message:@"修改密码成功,您需要重新登陆哦~" buttonTitles:nil destructiveTitle:nil cancelTitle:@"知道了" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { [weakSelf loginOutToLoginVC]; - }]; - [alertView show]; + }] show]; } }]; } diff --git a/Coding_iOS/Controllers/MeSetting/SettingPhoneViewController.m b/Coding_iOS/Controllers/MeSetting/SettingPhoneViewController.m index 337031c9a..1fd1ea6c5 100644 --- a/Coding_iOS/Controllers/MeSetting/SettingPhoneViewController.m +++ b/Coding_iOS/Controllers/MeSetting/SettingPhoneViewController.m @@ -13,6 +13,7 @@ #import "Login.h" #import "CountryCodeListViewController.h" #import "Ease_2FA.h" +#import "RewardTipManager.h" @interface SettingPhoneViewController () @property (strong, nonatomic) TPKeyboardAvoidingTableView *myTableView; @@ -46,6 +47,9 @@ - (void)viewDidLoad { [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"完成" style:UIBarButtonItemStylePlain target:self action:@selector(doneBtnClicked:)]; @@ -65,10 +69,6 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger return 3; } -- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ - return 44.0; -} - - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ NSString *identifier = (indexPath.row == 0? kCellIdentifier_Input_OnlyText_Cell_Phone: indexPath.row == 1? self.phoneCodeCellIdentifier: @@ -94,7 +94,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N weakSelf.code = valueStr; }; cell.phoneCodeBtnClckedBlock = ^(PhoneCodeButton *btn){ - [weakSelf phoneCodeBtnClicked:btn]; + [weakSelf phoneCodeBtnClicked:btn withCaptcha:nil]; }; }else{ [cell setPlaceholder:_verifyType == VerifyTypePassword? @" 输入密码": @" 输入两步验证码" value:_verifyStr]; @@ -105,6 +105,14 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; return cell; } + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ + if (indexPath.row == 2 && [Login curLoginUser].hasNoEamilAndPhone) { + return 0; + } + return 50; +} + - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 20)]; headerView.backgroundColor = kColorTableSectionBg; @@ -124,22 +132,74 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath } #pragma mark CodeBtn -- (void)phoneCodeBtnClicked:(PhoneCodeButton *)sender{ +- (void)phoneCodeBtnClicked:(PhoneCodeButton *)sender withCaptcha:(NSString *)captcha{ if (![_phone isPhoneNo]) { [NSObject showHudTipStr:@"手机号码格式有误"]; return; } sender.enabled = NO; - [[Coding_NetAPIManager sharedManager] request_GeneratePhoneCodeToResetPhone:_phone phoneCountryCode:_phone_country_code block:^(id data, NSError *error) { + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_GeneratePhoneCodeToResetPhone:_phone phoneCountryCode:_phone_country_code withCaptcha:captcha block:^(id data, NSError *error) { if (data) { [NSObject showHudTipStr:@"验证码发送成功"]; [sender startUpTimer]; }else{ [sender invalidateTimer]; + if (error && error.userInfo[@"msg"] && [[error.userInfo[@"msg"] allKeys] containsObject:@"j_captcha_error"]) { + [weakSelf p_showCaptchaAlert:sender]; + } } }]; } +- (void)p_showCaptchaAlert:(PhoneCodeButton *)sender{ + SDCAlertController *alertV = [SDCAlertController alertControllerWithTitle:@"提示" message:@"请输入图片验证码" preferredStyle:SDCAlertControllerStyleAlert]; + UITextField *textF = [UITextField new]; + textF.layer.sublayerTransform = CATransform3DMakeTranslation(5, 0, 0); + textF.backgroundColor = [UIColor whiteColor]; + [textF doBorderWidth:0.5 color:nil cornerRadius:2.0]; + UIImageView *imageV = [YLImageView new]; + imageV.backgroundColor = [UIColor lightGrayColor]; + imageV.contentMode = UIViewContentModeScaleAspectFit; + imageV.clipsToBounds = YES; + imageV.userInteractionEnabled = YES; + [textF doBorderWidth:0.5 color:nil cornerRadius:2.0]; + NSURL *imageURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@api/getCaptcha", [NSObject baseURLStr]]]; + [imageV sd_setImageWithURL:imageURL placeholderImage:nil options:(SDWebImageRetryFailed | SDWebImageRefreshCached | SDWebImageHandleCookies)]; + + [alertV.contentView addSubview:textF]; + [alertV.contentView addSubview:imageV]; + [textF mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(alertV.contentView).offset(15); + make.height.mas_equalTo(25); + make.bottom.equalTo(alertV.contentView).offset(-10); + }]; + [imageV mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.equalTo(alertV.contentView).offset(-15); + make.left.equalTo(textF.mas_right).offset(10); + make.width.mas_equalTo(60); + make.height.mas_equalTo(25); + make.centerY.equalTo(textF); + }]; + //Action + __weak typeof(imageV) weakImageV = imageV; + [imageV bk_whenTapped:^{ + [weakImageV sd_setImageWithURL:imageURL placeholderImage:nil options:(SDWebImageRetryFailed | SDWebImageRefreshCached | SDWebImageHandleCookies)]; + }]; + __weak typeof(self) weakSelf = self; + [alertV addAction:[SDCAlertAction actionWithTitle:@"取消" style:SDCAlertActionStyleCancel handler:nil]]; + [alertV addAction:[SDCAlertAction actionWithTitle:@"确定" style:SDCAlertActionStyleDefault handler:nil]]; + alertV.shouldDismissBlock = ^BOOL (SDCAlertAction *action){ + if (![action.title isEqualToString:@"取消"]) { + [weakSelf phoneCodeBtnClicked:sender withCaptcha:textF.text]; + } + return YES; + }; + [alertV presentWithCompletion:^{ + [textF becomeFirstResponder]; + }]; +} + #pragma mark DoneBtn Clicked - (void)doneBtnClicked:(id)sender{ NSString *tipStr; @@ -147,7 +207,7 @@ - (void)doneBtnClicked:(id)sender{ tipStr = @"手机号码格式有误"; }else if (_code.length <= 0){ tipStr = @"请填写手机验证码"; - }else if (_verifyStr.length <= 0){ + }else if (_verifyStr.length <= 0 && ![Login curLoginUser].hasNoEamilAndPhone){ tipStr = _verifyType == VerifyTypePassword? @"请填写密码": @"请填写两步验证码"; } if (tipStr.length > 0) { @@ -161,7 +221,14 @@ - (void)doneBtnClicked:(id)sender{ __weak typeof(self) weakSelf = self; [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:@"api/account/phone/change" withParams:params withMethodType:Post andBlock:^(id data, NSError *error) { if (data) { - [NSObject showHudTipStr:@"手机号码绑定成功"]; + if (![Login curLoginUser].is_phone_validated.boolValue && !kTarget_Enterprise) {//之前没有绑定过手机号的,奖励码币 + [RewardTipManager showTipWithTitle:@"成功完成手机验证 !" rewardPoint:@"0.1 MB"]; + }else{ + [NSObject showHudTipStr:@"手机号码绑定成功"]; + } + [Login curLoginUser].is_phone_validated = @(YES); + [Login curLoginUser].phone = weakSelf.phone; + [Login curLoginUser].phone_country_code = weakSelf.phone_country_code; [weakSelf.navigationController popViewControllerAnimated:YES]; } }]; diff --git a/Coding_iOS/Controllers/MeSetting/SettingSkillsViewController.h b/Coding_iOS/Controllers/MeSetting/SettingSkillsViewController.h new file mode 100644 index 000000000..3b9aea867 --- /dev/null +++ b/Coding_iOS/Controllers/MeSetting/SettingSkillsViewController.h @@ -0,0 +1,19 @@ +// +// SettingSkillsViewController.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2017/12/25. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "BaseViewController.h" + +#import "CodingSkill.h" + +@interface SettingSkillsViewController : BaseViewController + +@property (copy, nonatomic) void(^doneBlock)(NSArray *selectedSkills); + ++ (instancetype)settingSkillsVCWithDoneBlock:(void(^)(NSArray *selectedSkills))block; + +@end diff --git a/Coding_iOS/Controllers/MeSetting/SettingSkillsViewController.m b/Coding_iOS/Controllers/MeSetting/SettingSkillsViewController.m new file mode 100644 index 000000000..30a1abe34 --- /dev/null +++ b/Coding_iOS/Controllers/MeSetting/SettingSkillsViewController.m @@ -0,0 +1,168 @@ +// +// SettingSkillsViewController.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2017/12/25. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "SettingSkillsViewController.h" + +#import "Login.h" +#import "Coding_NetAPIManager.h" + +#import "SkillCCell.h" +#import "ActionSheetStringPicker.h" + + +@interface SettingSkillsViewController () + +@property (strong, nonatomic) UICollectionView *tagsView; + +//CodingSkill +@property (strong, nonatomic) NSDictionary *skillNameDict; +@property (strong, nonatomic) NSMutableArray *skills; +@end + +@implementation SettingSkillsViewController + ++ (instancetype)settingSkillsVCWithDoneBlock:(void(^)(NSArray *selectedSkills))block{ + SettingSkillsViewController *vc = [SettingSkillsViewController new]; + vc.doneBlock = block; + return vc; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + self.title = @"设置开发技能"; + [self refresh]; +} + +- (void)refresh{ + [self.view beginLoading]; + __weak typeof(self) weakSelf = self; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:@"api/options/skills" withParams:nil withMethodType:Get andBlock:^(id data, NSError *error) { + [weakSelf.view endLoading]; + if (data) { + weakSelf.skillNameDict = data[@"data"]; + [weakSelf setupContent]; + } + }]; +} + +- (void)setupContent{ + User *curUser = [Login curLoginUser]; + self.skills = curUser.skills.mutableCopy ?: @[].mutableCopy; + [self.navigationItem setRightBarButtonItem:[UIBarButtonItem itemWithBtnTitle:@"完成" target:self action:@selector(doneBtnClicked:)] animated:YES]; + + __weak typeof(self) weakSelf = self; + UIButton *addBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 15, kScreen_Width, 44)]; + addBtn.backgroundColor = kColorWhite; + [addBtn bk_addEventHandler:^(id sender) { + [weakSelf addBtnClicked]; + } forControlEvents:UIControlEventTouchUpInside]; + [addBtn addLineUp:YES andDown:YES andColor:kColorD8DDE4]; + [self.view addSubview:addBtn]; + UILabel *addLeftL = [UILabel labelWithFont:[UIFont systemFontOfSize:15] textColor:kColor222]; + UILabel *addRightL = [UILabel labelWithFont:[UIFont systemFontOfSize:15] textColor:kColorDark7]; + addLeftL.text = @"开发技能"; + addRightL.text = @"请选择"; + UIImageView *addRightArrow = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cell_arrow_left"]]; + [addBtn addSubview:addLeftL]; + [addBtn addSubview:addRightL]; + [addBtn addSubview:addRightArrow]; + [addLeftL mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(addBtn); + make.left.offset(15); + }]; + [addRightArrow mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(addBtn); + make.right.offset(-10); + }]; + [addRightL mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(addBtn); + make.right.equalTo(addRightArrow.mas_left).offset(-5); + }]; + + UILabel *headerL = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDark7]; + headerL.text = @"已选择的开发技能"; + [self.view addSubview:headerL]; + [headerL mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.view); + make.top.equalTo(addBtn.mas_bottom).offset(20); + }]; + + UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; + self.tagsView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout]; + [self.tagsView setBackgroundColor:[UIColor clearColor]]; + [self.tagsView registerClass:[SkillCCell class] forCellWithReuseIdentifier:kCCellIdentifier_SkillCCell]; + self.tagsView.dataSource = self; + self.tagsView.delegate = self; + [self.view addSubview:self.tagsView]; + [self.tagsView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(headerL.mas_bottom).offset(5); + make.left.right.bottom.equalTo(self.view); + }]; +} + +- (void)addBtnClicked{ + __weak typeof(self) weakSelf = self; + NSMutableArray *skillNameList = _skillNameDict.allValues.mutableCopy; + [skillNameList removeObjectsInArray:[_skills valueForKey:@"skillName"]]; + [ActionSheetStringPicker showPickerWithTitle:nil rows:@[skillNameList, [CodingSkill levelList]] initialSelection:@[@0, @0] doneBlock:^(ActionSheetStringPicker *picker, NSArray *selectedIndex, NSArray *selectedValue) { + CodingSkill *addSkill = [CodingSkill new]; + addSkill.skillName = selectedValue.firstObject; + for (NSString *key in weakSelf.skillNameDict) { + if ([weakSelf.skillNameDict[key] isEqualToString:addSkill.skillName]) { + addSkill.skillId = @(key.integerValue); + break; + } + } + addSkill.level = @([selectedIndex.lastObject integerValue] + 1); + [weakSelf.skills addObject:addSkill]; + [weakSelf.tagsView reloadData]; + } cancelBlock:nil origin:self.view]; +} + +- (void)doneBtnClicked:(id)sender{ + if (_skills.count <= 0) { + [NSObject showHudTipStr:@"开发技能不能为空"]; + }else{ + [self.navigationController popViewControllerAnimated:YES]; + if (self.doneBlock) { + self.doneBlock(_skills); + } + } +} + +#pragma mark Collection M +- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ + return _skills.count; +} + +- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ + SkillCCell *ccell = [collectionView dequeueReusableCellWithReuseIdentifier:kCCellIdentifier_SkillCCell forIndexPath:indexPath]; + ccell.curSkill = _skills[indexPath.row]; + __weak typeof(self) weakSelf = self; + ccell.deleteBlock = ^(CodingSkill *deletedSkill) { + [weakSelf.skills removeObject:deletedSkill]; + [weakSelf.tagsView reloadData]; + }; + return ccell; +} + +- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{ + return [SkillCCell ccellSizeWithObj:_skills[indexPath.row]]; +} +- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{ + return UIEdgeInsetsMake(15, 15, 15, 15); +} +- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section{ + return 10; +} +- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section{ + return 10; +} + +@end diff --git a/Coding_iOS/Controllers/MeSetting/SettingTextViewController.m b/Coding_iOS/Controllers/MeSetting/SettingTextViewController.m index a431d5505..5e458067e 100755 --- a/Coding_iOS/Controllers/MeSetting/SettingTextViewController.m +++ b/Coding_iOS/Controllers/MeSetting/SettingTextViewController.m @@ -66,6 +66,9 @@ - (void)viewDidLoad { [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); if (self.settingType != SettingTypeOnlyText) { @@ -83,12 +86,12 @@ - (void)doneBtnClicked:(id)sender{ if (self.doneBlock) { self.doneBlock(_myTextValue); } - if (self.settingType == SettingTypeOnlyText) { - [self.navigationController popViewControllerAnimated:YES]; - }else{ + if (self.navigationController.viewControllers.count <= 1) { [self.view endEditing:YES]; [self dismissViewControllerAnimated:YES completion:^{ }]; + }else{ + [self.navigationController popViewControllerAnimated:YES]; } } - (void)dismissSelf{ diff --git a/Coding_iOS/Controllers/MeSetting/SettingViewController.m b/Coding_iOS/Controllers/MeSetting/SettingViewController.m index 1b430ce5d..ea12af858 100755 --- a/Coding_iOS/Controllers/MeSetting/SettingViewController.m +++ b/Coding_iOS/Controllers/MeSetting/SettingViewController.m @@ -38,6 +38,9 @@ - (void)viewDidLoad [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _myTableView.tableFooterView = [self tableFooterView]; @@ -65,7 +68,15 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N }else{ cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_TitleValueMore forIndexPath:indexPath]; - [(TitleValueMoreCell *)cell setTitleStr:@"清除缓存" valueStr:[self p_diskCacheSizeStr]]; + [(TitleValueMoreCell *)cell setTitleStr:@"清除缓存" valueStr:@"--"]; + __weak typeof(self) weakSelf = self; + __weak typeof(cell) weakCell = cell; + dispatch_async(dispatch_get_global_queue(0, 0), ^{ + NSString *diskCacheSizeStr = [weakSelf p_diskCacheSizeStr]; + dispatch_async(dispatch_get_main_queue(), ^{ + ((UILabel *)[weakCell valueForKey:@"valueLabel"]).text = diskCacheSizeStr; + }); + }); } [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; return cell; @@ -91,7 +102,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath [self.navigationController pushViewController:vc animated:YES]; }else{ __weak typeof(self) weakSelf = self; - [[UIActionSheet bk_actionSheetCustomWithTitle:@"缓存数据有助于再次浏览或离线查看,你确定要清除缓存吗?" buttonTitles:nil destructiveTitle:@"确定清除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + [[UIAlertController ea_actionSheetCustomWithTitle:@"缓存数据有助于再次浏览或离线查看,你确定要清除缓存吗?" buttonTitles:nil destructiveTitle:@"确定清除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf clearDiskCache]; } @@ -103,7 +114,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath - (void)loginOutBtnClicked:(id)sender{ __weak typeof(self) weakSelf = self; - [[UIActionSheet bk_actionSheetCustomWithTitle:@"确定要退出当前账号吗?" buttonTitles:nil destructiveTitle:@"确定退出" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + [[UIAlertController ea_actionSheetCustomWithTitle:@"确定要退出当前账号吗?" buttonTitles:nil destructiveTitle:@"确定退出" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf loginOutToLoginVC]; } diff --git a/Coding_iOS/Controllers/NFileListViewController.h b/Coding_iOS/Controllers/NFileListViewController.h new file mode 100644 index 000000000..2b81505e9 --- /dev/null +++ b/Coding_iOS/Controllers/NFileListViewController.h @@ -0,0 +1,16 @@ +// +// NFileListViewController.h +// Coding_Enterprise_iOS +// +// Created by Easeeeeeeeee on 2017/5/11. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "BaseViewController.h" +#import "ProjectFile.h" +#import "Project.h" + +@interface NFileListViewController : BaseViewController +@property (nonatomic, strong) Project *curProject; +@property (strong, nonatomic) ProjectFile *curFolder; +@end diff --git a/Coding_iOS/Controllers/NFileListViewController.m b/Coding_iOS/Controllers/NFileListViewController.m new file mode 100644 index 000000000..2ea34d2fd --- /dev/null +++ b/Coding_iOS/Controllers/NFileListViewController.m @@ -0,0 +1,30 @@ +// +// NFileListViewController.m +// Coding_Enterprise_iOS +// +// Created by Easeeeeeeeee on 2017/5/11. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "NFileListViewController.h" +#import "NProjectFileListView.h" + +@interface NFileListViewController () +@property (strong, nonatomic) NProjectFileListView *listView; +@end + +@implementation NFileListViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + self.title = _curFolder.name ?: _curProject.name; + _listView = [[NProjectFileListView alloc] initWithFrame:self.view.bounds project:_curProject folder:_curFolder]; + _listView.containerVC = self; + [self.view addSubview:_listView]; + [_listView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; +} + +@end diff --git a/Coding_iOS/Controllers/NProjectViewController/NProjectViewController.h b/Coding_iOS/Controllers/NProjectViewController/NProjectViewController.h index a247f76a6..917306fe2 100644 --- a/Coding_iOS/Controllers/NProjectViewController/NProjectViewController.h +++ b/Coding_iOS/Controllers/NProjectViewController/NProjectViewController.h @@ -11,4 +11,7 @@ @interface NProjectViewController : BaseViewController @property (nonatomic, strong) Project *myProject; + +- (void)cloneRepo; + @end diff --git a/Coding_iOS/Controllers/NProjectViewController/NProjectViewController.m b/Coding_iOS/Controllers/NProjectViewController/NProjectViewController.m index eacca6b49..d34d23352 100644 --- a/Coding_iOS/Controllers/NProjectViewController/NProjectViewController.m +++ b/Coding_iOS/Controllers/NProjectViewController/NProjectViewController.m @@ -11,27 +11,25 @@ #import "ProjectDescriptionCell.h" #import "NProjectItemCell.h" -//#import "ProjectItemsCell.h" -//#import "ProjectActivityListCell.h" #import "ProjectViewController.h" #import "Coding_NetAPIManager.h" #import "ODRefreshControl.h" #import "WebViewController.h" -//#import "UserInfoViewController.h" -//#import "EditTaskViewController.h" -//#import "TopicDetailViewController.h" -//#import "FileListViewController.h" -//#import "FileViewController.h" #import "UsersViewController.h" #import "ForkTreeViewController.h" #import "CodeViewController.h" -#import "PRListViewController.h" -#import "MRListViewController.h" #import "EaseGitButtonsView.h" #import "UserOrProjectTweetsViewController.h" #import "FunctionTipsManager.h" +#import "MRPRListViewController.h" +#import "WikiViewController.h" +#import "EACodeBranchListViewController.h" +#import "EACodeReleaseListViewController.h" +#import "EALocalCodeListViewController.h" +#import "TaskBoardsViewController.h" + @interface NProjectViewController () @property (nonatomic, strong) UITableView *myTableView; @@ -68,6 +66,9 @@ - (void)viewDidLoad{ [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); @@ -101,7 +102,7 @@ - (void)refresh{ [[Coding_NetAPIManager sharedManager] request_ProjectDetail_WithObj:_myProject andBlock:^(id data, NSError *error) { if (data) { weakSelf.myProject = data; - weakSelf.navigationItem.rightBarButtonItem = weakSelf.myProject.is_public.boolValue? nil: [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"tweetsBtn_Nav"] style:UIBarButtonItemStylePlain target:self action:@selector(tweetsBtnClicked)]; + weakSelf.navigationItem.rightBarButtonItem = weakSelf.myProject.is_public.boolValue? nil: [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"addBtn_Artboard"] style:UIBarButtonItemStylePlain target:self action:@selector(tweetsBtnClicked)]; [self refreshGitButtonsView]; [weakSelf.myTableView reloadData]; } @@ -117,46 +118,76 @@ - (void)tweetsBtnClicked{ #pragma mark Table M - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ - return 3; -} - -//footer -- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{ - if (section < 2) { - UIView *footerView = [UIView new]; - footerView.backgroundColor = kColorTableSectionBg; - return footerView; + if (!_myProject.is_public) { + return 0; + }else if (_myProject.is_public.boolValue) { + return 4; + }else if (_myProject.current_user_role_id.integerValue <= 75){ + return 4; }else{ - return nil; + return 6; } } -- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ - CGFloat footerHeight = section < 2? 20: 0.5; - return footerHeight; -} - +//header - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ - return 0.5; + CGFloat sectionH = 15; + if (section == 0) { + sectionH = kLine_MinHeight; + }else if (!_myProject.is_public.boolValue && (section == 2 || section == 4)){ + sectionH = 50; + } + return sectionH; } - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ - if (section > 0) { - UIView *headerView = [UIView new]; - headerView.backgroundColor = kColorTableSectionBg; - return headerView; - }else{ - return nil; + UIView *headerView = [UIView new]; + headerView.backgroundColor = kColorTableSectionBg; + if (!_myProject.is_public.boolValue && (section == 2 || section == 4)) { + UILabel *leftL = [UILabel labelWithFont:[UIFont systemFontOfSize:15] textColor:kColorDark3]; + leftL.text = section == 2? @"任务": @"代码"; + [headerView addSubview:leftL]; + [leftL mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.offset(20); + make.left.offset(kPaddingLeftWidth); + }]; + if (section == 4) { + UILabel *rightL = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorLightBlue]; + rightL.text = @"查看 README"; + __weak typeof(self) weakSelf = self; + rightL.userInteractionEnabled = YES; + [rightL bk_whenTapped:^{ + [weakSelf goToReadme]; + }]; + [headerView addSubview:rightL]; + [rightL mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(leftL); + make.right.offset(-kPaddingLeftWidth); + }]; + } } + return headerView; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ + return section == ([self numberOfSectionsInTableView:_myTableView] - 1)? 44: kLine_MinHeight; } //data - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ NSInteger row = 0; - if (section == 0 || section == 2) { - row = 2; - }else if (section == 1){ - row = _myProject.is_public.boolValue? _myProject.current_user_role_id.integerValue <= 70? 3: 4: 6; + if (_myProject.is_public.boolValue) { + row = (section == 0? 2: + section == 1? 4: + section == 2? 2: + 1); + }else{ + row = (section == 0? 2: + section == 1? 1: + section == 2? 2: + section == 3? 2: + section == 4? 4: + 1); } return row; } @@ -178,58 +209,52 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } }else{ NProjectItemCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_NProjectItemCell forIndexPath:indexPath]; - if (indexPath.section == 1){ - switch (indexPath.row) { - case 0: - [cell setImageStr:@"project_item_activity" andTitle:@"动态"]; - if (_myProject.un_read_activities_count.integerValue > 0) { - [cell addTip:_myProject.un_read_activities_count.stringValue]; - } - break; - case 1: - if (_myProject.is_public.boolValue) { - [cell setImageStr:@"project_item_topic" andTitle:@"讨论"]; - }else{ - [cell setImageStr:@"project_item_task" andTitle:@"任务"]; - } - break; - case 2: - if (_myProject.is_public.boolValue) { - [cell setImageStr:@"project_item_code" andTitle:@"代码"]; - }else{ - [cell setImageStr:@"project_item_topic" andTitle:@"讨论"]; - } - break; - case 3: - if (_myProject.is_public.boolValue) { - [cell setImageStr:@"project_item_member" andTitle:@"成员"]; - }else{ - [cell setImageStr:@"project_item_file" andTitle:@"文件"]; - } - break; - case 4: - [cell setImageStr:@"project_item_code" andTitle:@"代码"]; - break; - default: - [cell setImageStr:@"project_item_member" andTitle:@"成员"]; - break; + if (indexPath.section == 1 && indexPath.row == 0) { + [cell setImageStr:@"project_item_activity" andTitle:@"动态"]; + if (_myProject.un_read_activities_count.integerValue > 0) { + [cell addTip:_myProject.un_read_activities_count.stringValue]; } - }else if (indexPath.section == 2){ - switch (indexPath.row) { - case 0: - [cell setImageStr:@"project_item_readme" andTitle:@"README"]; - break; - default: - [cell setImageStr:@"project_item_mr_pr" andTitle:_myProject.is_public.boolValue? @"Pull Request": @"Merge Request"]; - break; - } - } - FunctionTipsManager *ftm = [FunctionTipsManager shareManager]; - NSString *tipStr = [self p_TipStrForIndexPath:indexPath]; - if (tipStr && [ftm needToTip:tipStr]) { - [cell addTipIcon]; + }else if (_myProject.is_public.boolValue) { + [cell setImageStr:(indexPath.section == 1? (indexPath.row == 1? @"project_item_topic": + indexPath.row == 2? @"project_item_code": + @"project_item_member"): + indexPath.section == 2? (indexPath.row == 0? @"project_item_readme": + @"project_item_mr_pr"): + @"project_item_reading") + andTitle:(indexPath.section == 1? (indexPath.row == 1? @"讨论": + indexPath.row == 2? @"代码": + @"成员"): + indexPath.section == 2? (indexPath.row == 0? @"README": + @"Pull Request"): + @"本地阅读")]; + }else{ + [cell setImageStr:(indexPath.section == 2? (indexPath.row == 0? @"project_item_task": + @"project_item_taskboard"): +// indexPath.section == 3? (indexPath.row == 0? @"project_item_topic": + indexPath.section == 3? (indexPath.row == 0? @"project_item_wiki": + @"project_item_file"): + indexPath.section == 4? (indexPath.row == 0? @"project_item_code": + indexPath.row == 1? @"project_item_branch": + indexPath.row == 2? @"project_item_tag": + @"project_item_mr_pr"): + @"project_item_reading") + andTitle:(indexPath.section == 2? (indexPath.row == 0? @"任务列表": + @"任务看板"): +// indexPath.section == 3? (indexPath.row == 0? @"讨论": + indexPath.section == 3? (indexPath.row == 0? @"Wiki": + @"文件"): + indexPath.section == 4? (indexPath.row == 0? @"代码浏览": + indexPath.row == 1? @"分支管理": + indexPath.row == 2? @"发布管理": + @"合并请求"): + @"本地阅读")]; } - [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:50]; +// FunctionTipsManager *ftm = [FunctionTipsManager shareManager]; +// NSString *tipStr = [self p_TipStrForIndexPath:indexPath]; +// if (tipStr && [ftm needToTip:tipStr]) { +// [cell addTipIcon]; +// } + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:52]; return cell; } } @@ -239,14 +264,8 @@ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPa CGFloat cellHeight = 0; if (indexPath.section == 0) { cellHeight = indexPath.row == 0? [ProjectInfoCell cellHeight]: [ProjectDescriptionCell cellHeightWithObj:_myProject]; - }else if (indexPath.section == 1){ - if (!_myProject.is_public.boolValue && _myProject.current_user_role_id.integerValue <= 75 && indexPath.row == 4) {//私有项目的受限成员,不能查看代码 - cellHeight = 0; - }else{ - cellHeight = [NProjectItemCell cellHeight]; - } }else{ - cellHeight = (!_myProject.is_public.boolValue && _myProject.current_user_role_id.integerValue <= 75)? 0: [NProjectItemCell cellHeight];//私有项目的受限成员,不能查看代码 + cellHeight = [NProjectItemCell cellHeight]; } return cellHeight; } @@ -254,63 +273,116 @@ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPa //selected - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ [tableView deselectRowAtIndexPath:indexPath animated:YES]; - - if (indexPath.section == 0 && indexPath.row == 0) { - // 如果是自己的项目才能进入设置 - if ([self.myProject.owner_id isEqual:[Login curLoginUser].id]) { + if (indexPath.section == 0) { + if (indexPath.row == 0) { UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"ProjectSetting" bundle:nil]; - UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"ProjectSettingVC"]; + UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"Entrance"]; [vc setValue:self.myProject forKey:@"project"]; [self.navigationController pushViewController:vc animated:YES]; } - }else if (indexPath.section == 1){ - [self goToIndex:indexPath.row]; - }else if (indexPath.section == 2){ - if (indexPath.row == 0) { - [self goToReadme]; - }else if (indexPath.row == 1){ - [self goTo_MR_PR]; + }else if (_myProject.is_public.boolValue){ + if (indexPath.section == 1) { + if (indexPath.row == 0) { + [self goToProjectType:ProjectViewTypeActivities]; + }else if (indexPath.row == 1){ + [self goToProjectType:ProjectViewTypeTopics]; + }else if (indexPath.row == 2){ + [self goToProjectType:ProjectViewTypeCodes]; + }else{ + [self goToProjectType:ProjectViewTypeMembers]; + } + }else if (indexPath.section == 2){ + if (indexPath.row == 0) { + [self goToReadme]; + }else{ + [self goTo_MR_PR]; + } + }else{ + [self goToLocalRepo]; + } + }else{ + if (indexPath.section == 1) { + [self goToProjectType:ProjectViewTypeActivities]; + }else if (indexPath.section == 2){ + if (indexPath.row == 0) { + [self goToProjectType:ProjectViewTypeTasks]; + }else{ + [self goToTaskBoards]; + } + }else if (indexPath.section == 3){ + if (indexPath.row == 0) { +// [self goToProjectType:ProjectViewTypeTopics]; + [self goToWiki]; + }else{ + [self goToProjectType:ProjectViewTypeFiles]; + } + }else if (indexPath.section == 4){ + if (indexPath.row == 0) { + [self goToProjectType:ProjectViewTypeCodes]; + }else if (indexPath.row == 1){ + [self goToBranchList]; + }else if (indexPath.row == 2){ + [self goToReleaseList]; + }else{ + [self goTo_MR_PR]; + } + }else{ + [self goToLocalRepo]; } } - - FunctionTipsManager *ftm = [FunctionTipsManager shareManager]; - NSString *tipStr = [self p_TipStrForIndexPath:indexPath]; - if (tipStr && [ftm needToTip:tipStr]) { - [ftm markTiped:tipStr]; - NProjectItemCell *cell = (NProjectItemCell *)[tableView cellForRowAtIndexPath:indexPath]; - [cell removeTip]; - } +// FunctionTipsManager *ftm = [FunctionTipsManager shareManager]; +// NSString *tipStr = [self p_TipStrForIndexPath:indexPath]; +// if (tipStr && [ftm needToTip:tipStr]) { +// [ftm markTiped:tipStr]; +// NProjectItemCell *cell = (NProjectItemCell *)[tableView cellForRowAtIndexPath:indexPath]; +// [cell removeTip]; +// } } - (NSString *)p_TipStrForIndexPath:(NSIndexPath *)indexPath{ NSString *tipStr = nil; - if (indexPath.section == 1) { - if (!_myProject.is_public.boolValue && indexPath.row == 3) { - tipStr = kFunctionTipStr_File_2V; - } - }else if (indexPath.section == 2){ - if (indexPath.row == 1) { - tipStr = kFunctionTipStr_LineNote_MRPR; - } - } return tipStr; } #pragma mark goTo VC -- (void)goToIndex:(NSInteger)index{ - if (index == 0) { - __weak typeof(self) weakSelf = self; - [[Coding_NetAPIManager sharedManager] request_Project_UpdateVisit_WithObj:_myProject andBlock:^(id data, NSError *error) { - if (data) { - weakSelf.myProject.un_read_activities_count = [NSNumber numberWithInteger:0]; - } - }]; - } + +- (void)goToTaskBoards{ + TaskBoardsViewController *vc = [TaskBoardsViewController new]; + vc.myProject = self.myProject; + [self.navigationController pushViewController:vc animated:YES]; +} + +- (void)goToProjectType:(ProjectViewType)type{ + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_Project_UpdateVisit_WithObj:_myProject andBlock:^(id data, NSError *error) { + if (data) { + weakSelf.myProject.un_read_activities_count = [NSNumber numberWithInteger:0]; + } + }]; ProjectViewController *vc = [[ProjectViewController alloc] init]; vc.myProject = self.myProject; - vc.curIndex = index; + vc.curType = type; + [self.navigationController pushViewController:vc animated:YES]; +} + +- (void)goToWiki{ + WikiViewController *vc = [WikiViewController new]; + vc.myProject = self.myProject; + [self.navigationController pushViewController:vc animated:YES]; +} + +- (void)goToBranchList{ + EACodeBranchListViewController *vc = [EACodeBranchListViewController new]; + vc.myProject = self.myProject; + [self.navigationController pushViewController:vc animated:YES]; +} + +- (void)goToReleaseList{ + EACodeReleaseListViewController *vc = [EACodeReleaseListViewController new]; + vc.myProject = self.myProject; [self.navigationController pushViewController:vc animated:YES]; } + - (void)gotoPro:(Project *)project{ NProjectViewController *vc = [[NProjectViewController alloc] init]; vc.myProject = project; @@ -324,17 +396,44 @@ - (void)goToReadme{ } - (void)goTo_MR_PR{ - if (_myProject.is_public.boolValue) { - PRListViewController *vc = [[PRListViewController alloc] init]; - vc.curProject = self.myProject; + MRPRListViewController *vc = [[MRPRListViewController alloc] init]; + vc.curProject = self.myProject; + vc.isMR = !_myProject.is_public.boolValue; + [self.navigationController pushViewController:vc animated:YES]; +} + +- (void)goToLocalRepo{ + if (_myProject.isLocalRepoExist) { + EALocalCodeListViewController *vc = [EALocalCodeListViewController new]; + vc.curPro = _myProject; + vc.curRepo = _myProject.localRepo; + vc.curURL = _myProject.localURL; [self.navigationController pushViewController:vc animated:YES]; }else{ - MRListViewController *vc = [[MRListViewController alloc] init]; - vc.curProject = self.myProject; - [self.navigationController pushViewController:vc animated:YES]; + __weak typeof(self) weakSelf = self; + [[UIAlertController ea_actionSheetCustomWithTitle:@"本地阅读需要先 clone 代码,过程可能比较耗时,且不可中断,是否确认要 clone 代码?" buttonTitles:@[@"Clone"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { + [weakSelf cloneRepo]; + } + }] showInView:self.view]; } } +- (void)cloneRepo{ + __weak typeof(self) weakSelf = self; + MBProgressHUD *hud = [NSObject showHUDQueryStr:@"正在 clone..."]; + [_myProject gitCloneBlock:^(GTRepository *repo, NSError *error) { + [NSObject hideHUDQuery]; + if (error) { + [NSObject showError:error]; + }else{ + [weakSelf goToLocalRepo]; + } + } progressBlock:^(const git_transfer_progress *progress, BOOL *stop) { + hud.detailsLabelText = [NSString stringWithFormat:@"%d / %d", progress->received_objects, progress->total_objects]; + }]; +} + #pragma mark Git_Btn - (void)actionWithGitBtnIndex:(NSInteger)index{ __weak typeof(self) weakSelf = self; @@ -359,7 +458,7 @@ - (void)actionWithGitBtnIndex:(NSInteger)index{ break; default://Fork { - [[UIActionSheet bk_actionSheetCustomWithTitle:@"fork将会将此项目复制到您的个人空间,确定要fork吗?" buttonTitles:@[@"确定"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + [[UIAlertController ea_actionSheetCustomWithTitle:@"fork将会将此项目复制到您的个人空间,确定要fork吗?" buttonTitles:@[@"确定"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [[Coding_NetAPIManager sharedManager] request_ForkProject:_myProject andBlock:^(id data, NSError *error) { [weakSelf refreshGitButtonsView]; diff --git a/Coding_iOS/Controllers/NewProject/NewProject.storyboard b/Coding_iOS/Controllers/NewProject/NewProject.storyboard index c6e1d4016..36f97bf90 100644 --- a/Coding_iOS/Controllers/NewProject/NewProject.storyboard +++ b/Coding_iOS/Controllers/NewProject/NewProject.storyboard @@ -1,96 +1,87 @@ - - + + + + + - - + + - - + + - + - + - + - - + + + + + + - + - + - - - - - - - - - - + + + + - + - + - - - - - - - - - - + + + - - - @@ -100,94 +91,64 @@ - - + + - + - - - - - - - - + - + - + - - - + - - @@ -200,40 +161,35 @@ - - - - - - + - + - + - + - + - + @@ -242,11 +198,13 @@ - - + + + + diff --git a/Coding_iOS/Controllers/NewProject/NewProjectTypeViewController.m b/Coding_iOS/Controllers/NewProject/NewProjectTypeViewController.m index 8ff8a11e7..cffe3ea0f 100644 --- a/Coding_iOS/Controllers/NewProject/NewProjectTypeViewController.m +++ b/Coding_iOS/Controllers/NewProject/NewProjectTypeViewController.m @@ -22,13 +22,9 @@ - (void)viewDidLoad { self.tableView.tableFooterView = [UIView new]; [self.tableView setSeparatorColor:[UIColor colorWithRGBHex:0xe5e5e5]]; - + self.tableView.backgroundColor = kColorTableSectionBg; + // 添加右上角按钮 -// UIButton *submitButton = [UIButton buttonWithType:UIButtonTypeInfoLight]; -// [submitButton addTarget:self action:@selector(showHelpView) forControlEvents:UIControlEventTouchUpInside]; -// UIBarButtonItem *submitButtonItem = [[UIBarButtonItem alloc] initWithCustomView:submitButton]; -// self.navigationItem.rightBarButtonItem = submitButtonItem; - [self.navigationItem setRightBarButtonItem:[[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"info_Nav"] style:UIBarButtonItemStylePlain target:self action:@selector(showHelpView)] animated:NO]; } @@ -163,7 +159,7 @@ -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath * #pragma mark - Orientations - (BOOL)shouldAutorotate{ - return UIInterfaceOrientationIsLandscape(self.interfaceOrientation); + return UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication.statusBarOrientation); } - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { diff --git a/Coding_iOS/Controllers/NewProject/NewProjectViewController.m b/Coding_iOS/Controllers/NewProject/NewProjectViewController.m index 9faffd271..5d63c8b8c 100644 --- a/Coding_iOS/Controllers/NewProject/NewProjectViewController.m +++ b/Coding_iOS/Controllers/NewProject/NewProjectViewController.m @@ -40,7 +40,7 @@ - (void)viewDidLoad { // self.tableView.tableFooterView = [UIView new]; [self.tableView setSeparatorColor:[UIColor colorWithRGBHex:0xe5e5e5]]; - + self.tableView.backgroundColor = kColorTableSectionBg; // self.descTextView.placeholder = @"填写项目描述..."; @@ -68,7 +68,7 @@ - (void)viewDidLoad { } -(void)selectProjectImage{ - [[UIActionSheet bk_actionSheetCustomWithTitle:@"选择照片" buttonTitles:@[@"拍照",@"从相册选择"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + [[UIAlertController ea_actionSheetCustomWithTitle:@"选择照片" buttonTitles:@[@"拍照",@"从相册选择"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index > 1) { return ; @@ -123,19 +123,34 @@ -(void)submit{ [[Coding_NetAPIManager sharedManager] request_NewProject_WithObj:project image:self.projectIconImage andBlock:^(NSString *data, NSError *error) { weakSelf.submitButtonItem.enabled = YES; if (data.length > 0) { - - NSString *projectRegexStr = @"/u/([^/]+)/p/([^/]+)"; - NSArray *matchedCaptures = [data captureComponentsMatchedByRegex:projectRegexStr]; - if (matchedCaptures.count >= 3) { - NSString *user_global_key = matchedCaptures[1]; - NSString *project_name = matchedCaptures[2]; - Project *curPro = [[Project alloc] init]; - curPro.owner_user_name = user_global_key; - curPro.name = project_name; - //标记已读 - [[Coding_NetAPIManager sharedManager] request_Project_UpdateVisit_WithObj:curPro andBlock:^(id dataTemp, NSError *errorTemp) { - }]; - [weakSelf gotoPro:curPro]; + if (kTarget_Enterprise) { + NSString *projectRegexStr = @"/p/([^/]+)"; + NSArray *matchedCaptures = [data captureComponentsMatchedByRegex:projectRegexStr]; + if (matchedCaptures.count >= 2) { + NSString *user_global_key = [NSObject baseCompany]; + NSString *project_name = matchedCaptures[1]; + Project *curPro = [[Project alloc] init]; + curPro.owner_user_name = user_global_key; + curPro.name = project_name; + //标记已读 + [[Coding_NetAPIManager sharedManager] request_Project_UpdateVisit_WithObj:curPro andBlock:^(id dataTemp, NSError *errorTemp) { + }]; + [weakSelf gotoPro:curPro]; + } + }else{ + NSString *projectRegexStr = @"/u/([^/]+)/p/([^/]+)"; + NSArray *matchedCaptures = [data captureComponentsMatchedByRegex:projectRegexStr]; + if (matchedCaptures.count >= 3) { + NSString *user_global_key = matchedCaptures[1]; + NSString *project_name = matchedCaptures[2]; + Project *curPro = [[Project alloc] init]; + curPro.owner_user_name = user_global_key; + curPro.name = project_name; + //标记已读 + [[Coding_NetAPIManager sharedManager] request_Project_UpdateVisit_WithObj:curPro andBlock:^(id dataTemp, NSError *errorTemp) { + }]; + [weakSelf gotoPro:curPro]; + } } } }]; @@ -201,32 +216,41 @@ -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath * -(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { - // - if (indexPath.section == 0 && indexPath.row == 0) { - return; - } - if (indexPath.section == 1 && indexPath.row == 0) { - cell.separatorInset = UIEdgeInsetsMake(0.f, cell.bounds.size.width, 0.f, 0.f); - return; - } - - // Remove seperator inset - if ([cell respondsToSelector:@selector(setSeparatorInset:)]) { - [cell setSeparatorInset:UIEdgeInsetsZero]; - } - - // Prevent the cell from inheriting the Table View's margin settings - if ([cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) { - [cell setPreservesSuperviewLayoutMargins:NO]; - } - - // Explictly set your cell's layout margins - if ([cell respondsToSelector:@selector(setLayoutMargins:)]) { - [cell setLayoutMargins:UIEdgeInsetsZero]; - } - +// // +// if (indexPath.section == 0 && indexPath.row == 0) { +// return; +// } +// if (indexPath.section == 1 && indexPath.row == 0) { +// cell.separatorInset = UIEdgeInsetsMake(0.f, cell.bounds.size.width, 0.f, 0.f); +// return; +// } +// +// // Remove seperator inset +// if ([cell respondsToSelector:@selector(setSeparatorInset:)]) { +// [cell setSeparatorInset:UIEdgeInsetsZero]; +// } +// +// // Prevent the cell from inheriting the Table View's margin settings +// if ([cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) { +// [cell setPreservesSuperviewLayoutMargins:NO]; +// } +// +// // Explictly set your cell's layout margins +// if ([cell respondsToSelector:@selector(setLayoutMargins:)]) { +// [cell setLayoutMargins:UIEdgeInsetsZero]; +// } + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; } +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ + CGFloat rowH = 44; + if (indexPath.section == 0) { + rowH = (indexPath.row == 0? 120: 80); + }else if (indexPath.section == 1 && indexPath.row == 0){//个人版、企业版 都不让创建公有项目了 + rowH = 0; + } + return rowH; +} #pragma mark NewProjectTypeViewController Delegate -(void)newProjectType:(NewProjectTypeViewController *)newProjectVC didSelectType:(NewProjectType)type{ @@ -244,7 +268,7 @@ -(void)newProjectType:(NewProjectTypeViewController *)newProjectVC didSelectType #pragma mark - Orientations - (BOOL)shouldAutorotate{ - return UIInterfaceOrientationIsLandscape(self.interfaceOrientation); + return UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication.statusBarOrientation); } - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { diff --git a/Coding_iOS/Controllers/PRDetailViewController.m b/Coding_iOS/Controllers/PRDetailViewController.m index 4a4f4c719..318565cd3 100644 --- a/Coding_iOS/Controllers/PRDetailViewController.m +++ b/Coding_iOS/Controllers/PRDetailViewController.m @@ -5,7 +5,7 @@ // Created by Ease on 15/6/1. // Copyright (c) 2015年 Coding. All rights reserved. // -#define kMRPRDetailViewController_BottomViewHeight 49.0 +#define kMRPRDetailViewController_BottomViewHeight 56.0 #import "PRDetailViewController.h" #import "Coding_NetAPIManager.h" #import "FunctionTipsManager.h" @@ -69,6 +69,9 @@ - (void)viewDidLoad{ [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; @@ -96,7 +99,7 @@ - (void)configBottomView{ NSArray *buttonArray; if (canAction && canCancel) {//三个按钮 buttonArray = @[[self buttonWithType:MRPRActionAccept], - [self buttonWithType:MRPRActionRefuse], +// [self buttonWithType:MRPRActionRefuse], [self buttonWithType:MRPRActionCancel]]; }else if (canAction && !canCancel){//两个按钮 buttonArray = @[[self buttonWithType:MRPRActionAccept], @@ -107,7 +110,7 @@ - (void)configBottomView{ buttonArray = nil; } if (buttonArray.count > 0) { - CGFloat buttonHeight = 29; + CGFloat buttonHeight = 36; CGFloat padding = 15; CGFloat buttonWidth = ((kScreen_Width - 2*kPaddingLeftWidth) - padding* (buttonArray.count -1))/buttonArray.count; CGFloat buttonY = (kMRPRDetailViewController_BottomViewHeight - buttonHeight)/2; @@ -167,24 +170,22 @@ - (UIButton *)buttonWithType:(MRPRAction)actionType{ curButton.layer.cornerRadius = 2.0; curButton.tag = actionType; [curButton addTarget:self action:@selector(actionMRPR:) forControlEvents:UIControlEventTouchUpInside]; - [curButton.titleLabel setFont:[UIFont systemFontOfSize:13]]; - + [curButton.titleLabel setFont:[UIFont systemFontOfSize:15]]; NSString *title, *colorStr; if (actionType == MRPRActionAccept) { title = @"合并"; - colorStr = @"0x4E90BF"; + colorStr = @"0x425063"; if (_curMRPRInfo.mrpr.status == MRPRStatusCannotMerge) { curButton.alpha = 0.5; } - }else if (actionType == MRPRActionRefuse){ + } else if (actionType == MRPRActionRefuse){ title = @"拒绝"; - colorStr = @"0xE15957"; - }else if (actionType == MRPRActionCancel){ + colorStr = @"0xF56061"; + } else if (actionType == MRPRActionCancel){ title = @"取消"; - colorStr = @"0xF8F8F8"; - [curButton doBorderWidth:0.5 color:[UIColor colorWithHexString:@"0xB5B5B5"] cornerRadius:2.0]; + colorStr = @"0xD8DDE4"; } - [curButton setTitleColor:[UIColor colorWithHexString:(actionType == MRPRActionCancel? @"0x222222": @"0xffffff")] forState:UIControlStateNormal]; + [curButton setTitleColor:[UIColor colorWithHexString:(actionType == MRPRActionCancel? @"0x323A45": @"0xFFFFFF")] forState:UIControlStateNormal]; [curButton setTitle:title forState:UIControlStateNormal]; [curButton setBackgroundColor:[UIColor colorWithHexString:colorStr]]; return curButton; @@ -194,7 +195,7 @@ - (void)actionMRPR:(UIButton *)sender{ NSString *tipStr; if (sender.tag == MRPRActionAccept) {//合并 if (_curMRPRInfo.mrpr.status == MRPRStatusCannotMerge) {//不能合并 - tipStr = @"Coding 不能帮你在线自动合并这个合并请求。"; + tipStr = @"CODING 不能帮你在线自动合并这个合并请求。"; kTipAlert(@"%@", tipStr); }else{ MRPRAcceptViewController *vc = [MRPRAcceptViewController new]; @@ -209,14 +210,14 @@ - (void)actionMRPR:(UIButton *)sender{ } }else if (sender.tag == MRPRActionRefuse){//拒绝 tipStr = [_curMRPRInfo.mrpr isMR]? @"确定要拒绝这个 Merge Request 么?": @"确定要拒绝这个 Pull Request 么?"; - [[UIActionSheet bk_actionSheetCustomWithTitle:tipStr buttonTitles:@[@"确定"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + [[UIAlertController ea_actionSheetCustomWithTitle:tipStr buttonTitles:@[@"确定"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf refuseMRPR]; } }] showInView:self.view]; }else if (sender.tag == MRPRActionCancel){//取消 tipStr = [_curMRPRInfo.mrpr isMR]? @"确定要取消这个 Merge Request 么?": @"确定要取消这个 Pull Request 么?"; - [[UIActionSheet bk_actionSheetCustomWithTitle:tipStr buttonTitles:@[@"确定"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + [[UIAlertController ea_actionSheetCustomWithTitle:tipStr buttonTitles:@[@"确定"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf cancelMRPR]; } @@ -245,7 +246,7 @@ - (void)cancelMRPR{ } #pragma mark TableM Footer Header - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ - return 20.0; + return 15.0; } - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ return 0.5; @@ -295,9 +296,6 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N [cell setImageStr:@"mrpr_icon_commit" andTitle:@"提交记录"]; }else{ [cell setImageStr:@"mrpr_icon_fileChange" andTitle:@"文件改动"]; - if ([[FunctionTipsManager shareManager] needToTip:kFunctionTipStr_LineNote_FileChange]) { - [cell addTipIcon]; - } } [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:50]; return cell; @@ -347,12 +345,6 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath vc.curMRPRInfo = _curMRPRInfo; vc.curProject = _curProject; [self.navigationController pushViewController:vc animated:YES]; - if ([[FunctionTipsManager shareManager] needToTip:kFunctionTipStr_LineNote_FileChange]) { - [[FunctionTipsManager shareManager] markTiped:kFunctionTipStr_LineNote_FileChange]; - [[FunctionTipsManager shareManager] markTiped:kFunctionTipStr_LineNote_MRPR]; - NProjectItemCell *cell = (NProjectItemCell *)[tableView cellForRowAtIndexPath:indexPath]; - [cell removeTip]; - } } }else if (_curMRPRInfo.discussions.count > 0 && indexPath.section == 2){//Comment ProjectLineNote *curCommentItem = [[_curMRPRInfo.discussions objectAtIndex:indexPath.row] firstObject]; @@ -449,4 +441,4 @@ - (void)attributedLabel:(TTTAttributedLabel *)label didSelectLinkWithTransitInfo HtmlMediaItem *clickedItem = [components objectForKey:@"value"]; [self analyseLinkStr:clickedItem.href]; } -@end \ No newline at end of file +@end diff --git a/Coding_iOS/Controllers/PRListViewController.h b/Coding_iOS/Controllers/PRListViewController.h deleted file mode 100644 index e4b9b7a34..000000000 --- a/Coding_iOS/Controllers/PRListViewController.h +++ /dev/null @@ -1,14 +0,0 @@ -// -// MRPRListViewController.h -// Coding_iOS -// -// Created by Ease on 15/5/29. -// Copyright (c) 2015年 Coding. All rights reserved. -// - -#import "BaseViewController.h" -#import "Project.h" - -@interface PRListViewController : BaseViewController -@property (strong, nonatomic) Project *curProject; -@end diff --git a/Coding_iOS/Controllers/PointRecordsViewController.m b/Coding_iOS/Controllers/PointRecordsViewController.m index eb6343b1d..2f58c3426 100644 --- a/Coding_iOS/Controllers/PointRecordsViewController.m +++ b/Coding_iOS/Controllers/PointRecordsViewController.m @@ -18,6 +18,8 @@ #import "PointShopCell.h" #import "PointRecordCell.h" +#import "AboutPointViewController.h" + @interface PointRecordsViewController () @property (strong, nonatomic) PointRecords *curRecords; @@ -50,6 +52,9 @@ - (void)viewDidLoad [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _refreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; @@ -82,7 +87,7 @@ - (void)refreshMore{ } - (void)sendRequest{ - if (_curRecords.list.count <= 0) { + if (_curRecords.list.count <= 0 && !_curRecords.points_left) { [self.view beginLoading]; } __weak typeof(self) weakSelf = self; @@ -95,7 +100,7 @@ - (void)sendRequest{ [weakSelf.myTableView reloadData]; weakSelf.myTableView.showsInfiniteScrolling = weakSelf.curRecords.canLoadMore; } - [weakSelf.view configBlankPage:EaseBlankPageTypeView hasData:(weakSelf.curRecords.list.count > 0) hasError:(error != nil) reloadButtonBlock:^(id sender) { + [weakSelf.view configBlankPage:EaseBlankPageTypeView hasData:(weakSelf.curRecords.list.count > 0 || weakSelf.curRecords.points_left) hasError:(error != nil) reloadButtonBlock:^(id sender) { [weakSelf refresh]; }]; }]; @@ -103,7 +108,7 @@ - (void)sendRequest{ #pragma mark Table M - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ - return _curRecords.list.count <= 0? 0:2; + return _curRecords.list.count <= 0? 1:2; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return section == 0? 2: self.curRecords.list.count; @@ -112,9 +117,8 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N if (indexPath.section == 0) { if (indexPath.row == 0) { - PointRecord *record = [_curRecords.list firstObject]; PointTopCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_PointTopCell forIndexPath:indexPath]; - cell.pointLeftStr = [NSString stringWithFormat:@"%.2f", record.points_left.floatValue]; + cell.pointLeftStr = _curRecords.points_left? [NSString stringWithFormat:@"%.2f", _curRecords.points_left.floatValue]: @"--"; [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:0 hasSectionLine:NO]; return cell; }else{ @@ -159,69 +163,17 @@ - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ [tableView deselectRowAtIndexPath:indexPath animated:YES]; - if (indexPath.section == 0 && indexPath.row == 1) { - //商城入口 - ShopViewController *shopvc = [[ShopViewController alloc] init]; - [self.navigationController pushViewController:shopvc animated:YES]; - } +// if (indexPath.section == 0 && indexPath.row == 1) { +// //商城入口 +// ShopViewController *shopvc = [[ShopViewController alloc] init]; +// [self.navigationController pushViewController:shopvc animated:YES]; +// } } #pragma mark rightNavBtn - (void)rightNavBtnClicked{ - CGRect originFrame = CGRectMake(kScreen_Width - 15, 0, 0, 0); - if (_isShowingTip) { - [UIView animateWithDuration:0.3 animations:^{ - self.tipContainerV.backgroundColor = [UIColor colorWithWhite:0 alpha:0]; - self.tipBGV.frame = originFrame; - } completion:^(BOOL finished) { - [self.tipContainerV removeFromSuperview]; - self.isShowingTip = NO; - }]; - }else{ - NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; - paragraphStyle.lineSpacing = kDevice_Is_iPhone4? 0: 5; - if (!_tipContainerV) { - _tipContainerV = [[UIView alloc] initWithFrame:self.view.bounds]; - } - if (!_tipBGV) { - _tipBGV = [[UIImageView alloc] initWithImage:[[UIImage imageNamed:@"tip_bg"] resizableImageWithCapInsets:UIEdgeInsetsMake(20, 15, 20, 30) resizingMode:UIImageResizingModeStretch]]; - _tipBGV.frame = originFrame; - _tipBGV.clipsToBounds = YES; - [_tipContainerV addSubview:_tipBGV]; - } - if (!_tipL) { - _tipL = [UILabel new]; - _tipL.textColor = kColor222; - _tipL.font = [UIFont systemFontOfSize:14]; - _tipL.numberOfLines = 0; - NSString *tipStr = -@"1. 使用人民币 兑换 (请通过点击账户码币页面的”购买码币”,以充值的形式购买码币。码币与人民币的兑换标准是 1 码币= 50 元人民币(0.1 码币起购买),支持支付宝及微信付款)\n\ -2. 冒泡 被管理员推荐上广场 奖励 0.01\n\ -3. 邀请好友 注册 Coding 并绑定手机号 奖励 0.02mb\n\ -4. 过生日赠送 0.1mb\n\ -5. 完善 个人信息 奖励 0.1mb\n\ -6. 完成 手机验证 奖励 0.1mb\n\ -7. 开启 两步验证 奖励 0.1mb\n\ -8. App 首次登录 奖励 0.1mb\n\ -9. 我们不定期发布的其他形式的码币悬赏活动(请关注 Coding冒泡,Coding微博 及 Coding微信公众号),数量不等\n\ -10. 转发 Coding微博,每周抽 1 名转发用户赠送 0.5mb\n\ -11. 给 Coding 博客 投稿 奖励 1-2mb"; - NSMutableAttributedString *tipAttrStr = [[NSMutableAttributedString alloc] initWithString:tipStr]; - [tipAttrStr addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, tipStr.length)]; - _tipL.attributedText = tipAttrStr; - _tipL.frame = CGRectMake(15, 40, kScreen_Width - 15 * 4, 0); - [_tipBGV addSubview:_tipL]; - } - CGFloat textHeight = [_tipL.text boundingRectWithSize:CGSizeMake(kScreen_Width - 15 * 4, CGFLOAT_MAX) options:(NSStringDrawingUsesFontLeading | NSStringDrawingUsesLineFragmentOrigin) attributes:@{NSParagraphStyleAttributeName: paragraphStyle, NSFontAttributeName: _tipL.font} context:nil].size.height; - _tipL.height = textHeight; - [self.view addSubview:self.tipContainerV]; - [UIView animateWithDuration:0.3 animations:^{ - self.tipContainerV.backgroundColor = [UIColor colorWithWhite:0 alpha:0.3]; - self.tipBGV.frame = CGRectMake(15, 0, kScreen_Width - 15 * 2, textHeight + 40 + 30); - } completion:^(BOOL finished) { - self.isShowingTip = YES; - }]; - } + AboutPointViewController *vc = [AboutPointViewController new]; + [self.navigationController pushViewController:vc animated:YES]; } @end diff --git a/Coding_iOS/Controllers/ProjectCommitsViewController.m b/Coding_iOS/Controllers/ProjectCommitsViewController.m index 986198450..7caa0e5eb 100644 --- a/Coding_iOS/Controllers/ProjectCommitsViewController.m +++ b/Coding_iOS/Controllers/ProjectCommitsViewController.m @@ -43,6 +43,9 @@ - (void)viewDidLoad{ [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; diff --git a/Coding_iOS/Controllers/ProjectListViewController.h b/Coding_iOS/Controllers/ProjectListViewController.h index be18813ae..f3984913a 100644 --- a/Coding_iOS/Controllers/ProjectListViewController.h +++ b/Coding_iOS/Controllers/ProjectListViewController.h @@ -11,5 +11,5 @@ @interface ProjectListViewController : Project_RootViewController @property (strong, nonatomic) User *curUser; -@property (assign, nonatomic) BOOL isFromMeRoot; +@property (assign, nonatomic) BOOL isFromMeRoot, isForPrivateProjects; @end diff --git a/Coding_iOS/Controllers/ProjectListViewController.m b/Coding_iOS/Controllers/ProjectListViewController.m index 9811e839d..a00ebf89e 100644 --- a/Coding_iOS/Controllers/ProjectListViewController.m +++ b/Coding_iOS/Controllers/ProjectListViewController.m @@ -46,7 +46,7 @@ - (void)configSegmentItems{ } - (Projects *)projectsWithIndex:(NSUInteger)index{ - return [Projects projectsWithType:_isFromMeRoot? ProjectsTypeCreated:(index + ProjectsTypeTaProject) andUser:self.curUser]; + return [Projects projectsWithType:_isFromMeRoot? _isForPrivateProjects? ProjectsTypeCreatedPrivate: ProjectsTypeCreatedPublic:(index + ProjectsTypeTaProject) andUser:self.curUser]; } @end diff --git a/Coding_iOS/Controllers/ProjectMemberActivityListViewController.m b/Coding_iOS/Controllers/ProjectMemberActivityListViewController.m index 544a75722..d8b6f2e7a 100755 --- a/Coding_iOS/Controllers/ProjectMemberActivityListViewController.m +++ b/Coding_iOS/Controllers/ProjectMemberActivityListViewController.m @@ -10,7 +10,7 @@ #import "UserInfoViewController.h" #import "EditTaskViewController.h" #import "TopicDetailViewController.h" -#import "FileListViewController.h" +#import "NFileListViewController.h" #import "FileViewController.h" #import "MRDetailViewController.h" @@ -64,125 +64,103 @@ - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { #pragma mark toVC - (void)goToUserInfo:(User *)user{ - UserInfoViewController *vc = [[UserInfoViewController alloc] init]; - vc.curUser = user; - [self.navigationController pushViewController:vc animated:YES]; + if (kTarget_Enterprise) { + UserInfoDetailViewController *vc = [UserInfoDetailViewController new]; + vc.curUser = user; + [self.navigationController pushViewController:vc animated:YES]; + }else{ + UserInfoViewController *vc = [[UserInfoViewController alloc] init]; + vc.curUser = user; + [self.navigationController pushViewController:vc animated:YES]; + } } - (void)goToVCWithItem:(HtmlMediaItem *)clickedItem activity:(ProjectActivity *)proAct isContent:(BOOL)isContent inProject:(Project *)project{ if (isContent) {//cell上面第二个Label NSString *target_type = proAct.target_type; + NSString *linkPath = nil, *tipStr = nil; + if ([target_type isEqualToString:@"Task"]) { - Task *task = proAct.task; - NSArray *pathArray = [task.path componentsSeparatedByString:@"/"]; - if (pathArray.count >= 7) { - EditTaskViewController *vc = [[EditTaskViewController alloc] init]; - vc.myTask = [Task taskWithBackend_project_path:[NSString stringWithFormat:@"/user/%@/project/%@", pathArray[2], pathArray[4]] andId:pathArray[6]]; - [self.navigationController pushViewController:vc animated:YES]; - }else{ - [NSObject showHudTipStr:@"任务不存在"]; - } + linkPath = proAct.task.path; + tipStr = @"任务不存在"; }else if ([target_type isEqualToString:@"TaskComment"]){ - Task *task = proAct.task; NSArray *pathArray = [proAct.project.full_name componentsSeparatedByString:@"/"]; - if (pathArray.count >= 2) { - EditTaskViewController *vc = [[EditTaskViewController alloc] init]; - vc.myTask = [Task taskWithBackend_project_path:[NSString stringWithFormat:@"/user/%@/project/%@", pathArray[0], pathArray[1]] andId:task.id.stringValue]; - [self.navigationController pushViewController:vc animated:YES]; - }else{ - [NSObject showHudTipStr:@"任务不存在"]; - } - }else if ([target_type isEqualToString:@"ProjectTopic"]){ - - ProjectTopicActivity *topic = proAct.project_topic; - NSArray *pathArray; - if ([proAct.action isEqualToString:@"comment"]) { - pathArray = [topic.parent.path componentsSeparatedByString:@"/"]; - }else{ - pathArray = [topic.path componentsSeparatedByString:@"/"]; - } - if (pathArray.count >= 7) { - TopicDetailViewController *vc = [[TopicDetailViewController alloc] init]; - vc.curTopic = [ProjectTopic topicWithId:[NSNumber numberWithInteger:[pathArray[6] integerValue]]]; - [self.navigationController pushViewController:vc animated:YES]; - }else{ - [NSObject showHudTipStr:@"讨论不存在"]; - } + linkPath = pathArray.count >= 2? [NSString stringWithFormat:@"/u/%@/p/%@/task/%@", pathArray[0], pathArray[1], proAct.task.id]: nil; }else if ([target_type isEqualToString:@"ProjectFile"]){ - File *file = proAct.file; - NSArray *pathArray = [file.path componentsSeparatedByString:@"/"]; +// BOOL isFile = [proAct.type isEqualToString:@"file"]; +// NSArray *pathArray = [proAct.file.path componentsSeparatedByString:@"/"]; +// if (!isFile && pathArray.count >= 7){ +// //文件夹 +// ProjectFolder *folder; +// NSString *folderIdStr = pathArray[6]; +// if (![folderIdStr isEqualToString:@"default"] && [folderIdStr isPureInt]) { +// NSNumber *folderId = [NSNumber numberWithInteger:folderIdStr.integerValue]; +// folder = [ProjectFolder folderWithId:folderId]; +// folder.name = proAct.file.name; +// }else{ +// folder = [ProjectFolder defaultFolder]; +// } +// FileListViewController *vc = [[FileListViewController alloc] init]; +// vc.curProject = project; +// vc.curFolder = folder; +// vc.rootFolders = nil; +// [self.navigationController pushViewController:vc animated:YES]; +// }else{ +// if (isFile) { +// linkPath = proAct.file.path; +// } +// tipStr = isFile? @"文件不存在" :@"文件夹不存在"; +// } BOOL isFile = [proAct.type isEqualToString:@"file"]; - - if (isFile && pathArray.count >= 9) { - //文件 - NSString *fileIdStr = pathArray[8]; - ProjectFile *curFile = [ProjectFile fileWithFileId:@(fileIdStr.integerValue) andProjectId:@(project.id.integerValue)]; - curFile.name = file.name; - FileViewController *vc = [FileViewController vcWithFile:curFile andVersion:nil]; - [self.navigationController pushViewController:vc animated:YES]; - }else if (!isFile && pathArray.count >= 7){ + NSArray *pathArray = [proAct.file.path componentsSeparatedByString:@"/"]; + if (!isFile && pathArray.count >= (kTarget_Enterprise? 5: 7)){ //文件夹 - ProjectFolder *folder; - NSString *folderIdStr = pathArray[6]; + ProjectFile *folder = nil; + NSString *folderIdStr = pathArray.lastObject; if (![folderIdStr isEqualToString:@"default"] && [folderIdStr isPureInt]) { NSNumber *folderId = [NSNumber numberWithInteger:folderIdStr.integerValue]; - folder = [ProjectFolder folderWithId:folderId]; - folder.name = file.name; - }else{ - folder = [ProjectFolder defaultFolder]; + folder = [[ProjectFile alloc] initWithFileId:folderId inProject:project.name ofUser:project.owner_user_name]; + folder.name = proAct.file.name; } - FileListViewController *vc = [[FileListViewController alloc] init]; + NFileListViewController *vc = [[NFileListViewController alloc] init]; vc.curProject = project; vc.curFolder = folder; - vc.rootFolders = nil; [self.navigationController pushViewController:vc animated:YES]; }else{ - [NSObject showHudTipStr:(isFile? @"文件不存在" :@"文件夹不存在")]; + if (isFile) { + linkPath = proAct.file.path; + } + tipStr = isFile? @"文件不存在" :@"文件夹不存在"; } }else if ([target_type isEqualToString:@"ProjectMember"]) { if ([proAct.action isEqualToString:@"quit"]) { //退出项目 - }else{ //添加了某成员 - User *user = proAct.target_user; - UserInfoViewController *vc = [[UserInfoViewController alloc] init]; - vc.curUser = [User userWithGlobalKey:user.global_key]; - [self.navigationController pushViewController:vc animated:YES]; + linkPath = [NSString stringWithFormat:@"/u/%@", proAct.target_user.global_key]; } - - }else if ([target_type isEqualToString:@"Depot"]) { if ([proAct.action_msg isEqualToString:@"删除了"]) { - [NSObject showHudTipStr:@"删除了,不能看了~"]; + tipStr = @"删除了,不能看了~"; }else if ([proAct.action isEqualToString:@"fork"]) { NSArray *nameComponents = [proAct.depot.name componentsSeparatedByString:@"/"]; - if (nameComponents.count == 2) { - NProjectViewController *vc = [NProjectViewController new]; - vc.myProject = [Project new]; - vc.myProject.owner_user_name = nameComponents[0]; - vc.myProject.name = nameComponents[1]; - [self.navigationController pushViewController:vc animated:YES]; - }else{ - [NSObject showHudTipStr:@"没找到 Fork 到哪里去了~"]; - } + linkPath = nameComponents.count == 2? [NSString stringWithFormat:@"/u/%@/p/%@", nameComponents[0], nameComponents[1]]: nil; + tipStr = @"没找到 Fork 到哪里去了~"; }else if ([proAct.action isEqualToString:@"push"]){ // current_user_role_id = 75 是受限成员,不可访问代码 if (!project.is_public.boolValue && project.current_user_role_id.integerValue <= 75) { - [NSObject showHudTipStr:@"无权访问项目代码相关功能"]; - return; - } - if (proAct.commits.count == 1) { - Commit *firstCommit = [proAct.commits firstObject]; - NSString *request_path = [NSString stringWithFormat:@"%@/commit/%@", proAct.depot.path, firstCommit.sha]; - CommitFilesViewController *vc = [CommitFilesViewController vcWithPath:request_path]; - [self.navigationController pushViewController:vc animated:YES]; + tipStr = @"无权访问项目代码相关功能"; }else{ - NSString *ref = proAct.ref? proAct.ref : @"master"; - ProjectCommitsViewController *vc = [ProjectCommitsViewController new]; - vc.curProject = project; - vc.curCommits = [Commits commitsWithRef:ref Path:@""]; - [self.navigationController pushViewController:vc animated:YES]; + if (proAct.commits.count == 1) { + Commit *firstCommit = [proAct.commits firstObject]; + linkPath = [NSString stringWithFormat:@"%@/commit/%@", proAct.depot.path, firstCommit.sha]; + }else{ + NSString *ref = proAct.ref? proAct.ref : @"master"; + ProjectCommitsViewController *vc = [ProjectCommitsViewController new]; + vc.curProject = project; + vc.curCommits = [Commits commitsWithRef:ref Path:@""]; + [self.navigationController pushViewController:vc animated:YES]; + } } }else{ ProjectViewController *vc = [ProjectViewController codeVCWithCodeRef:proAct.ref andProject:project]; @@ -193,46 +171,62 @@ - (void)goToVCWithItem:(HtmlMediaItem *)clickedItem activity:(ProjectActivity *) [target_type isEqualToString:@"CommitLineNote"]){ // current_user_role_id = 75 是受限成员,不可访问代码 if (!project.is_public.boolValue && project.current_user_role_id.integerValue <= 75) { - [NSObject showHudTipStr:@"无权访问项目代码相关功能"]; - return; + tipStr = @"无权访问项目代码相关功能"; + }else{ + if ([target_type isEqualToString:@"PullRequestBean"]){ + linkPath = proAct.pull_request_path; + }else if ([target_type isEqualToString:@"MergeRequestBean"]){ + linkPath = proAct.merge_request_path; + }else if ([target_type isEqualToString:@"CommitLineNote"]){ + linkPath = proAct.line_note.noteable_url; + } + tipStr = @"不知道这是个什么东西o(╯□╰)o~"; } - NSString *request_path; - if ([target_type isEqualToString:@"PullRequestBean"]){ - request_path = proAct.pull_request_path; - }else if ([target_type isEqualToString:@"MergeRequestBean"]){ - request_path = proAct.merge_request_path; - }else if ([target_type isEqualToString:@"CommitLineNote"]){ - request_path = proAct.line_note.noteable_url; + }else if ([target_type isEqualToString:@"ProjectTweet"]) { + if ([proAct.action isEqualToString:@"delete"]) { + tipStr = @"删除了,不能看了~"; + }else{ + linkPath = [NSString stringWithFormat:@"/p/%@/setting/notice", proAct.project.name]; } - - UIViewController *vc; - if ([proAct.line_note.noteable_type isEqualToString:@"Commit"]) { - vc = [CommitFilesViewController vcWithPath:request_path]; + }else if ([target_type isEqualToString:@"Wiki"]) { + if ([proAct.action isEqualToString:@"delete"]) { + tipStr = @"删除了,不能看了~"; }else{ - if([request_path rangeOfString:@"merge"].location == NSNotFound) { - vc = [PRDetailViewController vcWithPath:request_path]; - } else { - vc = [MRDetailViewController vcWithPath:request_path]; - - } - + linkPath = proAct.wiki_path; } - if (vc) { + }else if ([target_type isEqualToString:@"BranchMember"]){ + if ([@[@"add", @"remove"] containsObject:proAct.action]) { + linkPath = [NSString stringWithFormat:@"/u/%@", proAct.target_user.global_key]; + }else{//deny_push/allow_push + ProjectViewController *vc = [ProjectViewController codeVCWithCodeRef:proAct.ref_name andProject:project]; [self.navigationController pushViewController:vc animated:YES]; + } + }else if ([target_type isEqualToString:@"ProtectedBranch"]){ + ProjectViewController *vc = [ProjectViewController codeVCWithCodeRef:proAct.ref_name andProject:project]; + [self.navigationController pushViewController:vc animated:YES]; + }else if ([target_type isEqualToString:@"Release"]) { + if ([proAct.action isEqualToString:@"delete"]) { + tipStr = @"版本已删除"; }else{ - [NSObject showHudTipStr:@"不知道这是个什么东西o(╯□╰)o~"]; + linkPath = proAct.release_path; } }else{ - if ([target_type isEqualToString:@"Project"]){//这是什么鬼。。遗留的 type 吧 - [NSObject showHudTipStr:@"还不能查看详细信息呢~"]; - // }else if ([target_type isEqualToString:@"MergeRequestComment"]){//过期类型,已用CommitLineNote替代 - // }else if ([target_type isEqualToString:@"PullRequestComment"]){//过期类型,已用CommitLineNote替代 - // }else if ([target_type isEqualToString:@"ProjectStar"]){//不用解析 - // }else if ([target_type isEqualToString:@"ProjectWatcher"]){//不用解析 - }else if ([target_type isEqualToString:@"QcTask"]){//还不能解析 - [NSObject showHudTipStr:@"还不能查看详细信息呢~"]; + if ([target_type isEqualToString:@"Project"]){//转让项目之类的 +// }else if ([target_type isEqualToString:@"MergeRequestComment"]){//过期类型,已用CommitLineNote替代 +// }else if ([target_type isEqualToString:@"PullRequestComment"]){//过期类型,已用CommitLineNote替代 +// }else if ([target_type isEqualToString:@"ProjectStar"]){//不用解析 +// }else if ([target_type isEqualToString:@"ProjectWatcher"]){//不用解析 +// }else if ([target_type isEqualToString:@"QcTask"]){//还不能解析 + }else{ + tipStr = @"还不能查看详细信息呢~"; } } + UIViewController *vc = [BaseViewController analyseVCFromLinkStr:linkPath]; + if (vc) { + [self.navigationController pushViewController:vc animated:YES]; + }else{ + [NSObject showHudTipStr:tipStr]; + } }else{//cell上面第一个Label [self goToUserInfo:[User userWithGlobalKey:[clickedItem.href substringFromIndex:3]]]; } diff --git a/Coding_iOS/Controllers/ProjectMemberListViewController.m b/Coding_iOS/Controllers/ProjectMemberListViewController.m index 12327b9f6..00b7f297b 100755 --- a/Coding_iOS/Controllers/ProjectMemberListViewController.m +++ b/Coding_iOS/Controllers/ProjectMemberListViewController.m @@ -35,15 +35,30 @@ @interface ProjectMemberListViewController () @implementation ProjectMemberListViewController - (void)setMyMemberArray:(NSMutableArray *)myMemberArray{ + [myMemberArray sortUsingComparator:^NSComparisonResult(ProjectMember *obj1, ProjectMember *obj2) { + return [[self p_sortWeightOfMember:obj2] compare:[self p_sortWeightOfMember:obj1]]; + }]; _myMemberArray = myMemberArray; - ProjectMember *mem = [_myMemberArray firstObject]; - if ([mem.user_id isEqualToNumber:[Login curLoginUser].id]) { - _selfRoleType = mem.type; - }else{ - _selfRoleType = @80;//普通成员 + + for (ProjectMember *mem in _myMemberArray) { + if ([mem.user_id isEqualToNumber:[Login curLoginUser].id]) { + _selfRoleType = mem.type; + break; + } } } +- (NSNumber *)p_sortWeightOfMember:(ProjectMember *)mem{ + CGFloat maxMemCount = 9999; + NSNumber *weight = nil; + BOOL isLoginUser = [mem.user_id isEqualToNumber:[Login curLoginUser].id]; + BOOL isAddedToWatcher = (_type == ProMemTypeTaskWatchers? [self.curTask hasWatcher:mem.user]: + _type == ProMemTypeTopicWatchers? [self.curTopic hasWatcher:mem.user]: + NO); + weight = @(mem.type.integerValue + (isLoginUser? maxMemCount: 0) + (isAddedToWatcher? maxMemCount * 2: 0)); + return weight; +} + - (void)willHiden{ [self.mySearchBar resignFirstResponder]; } @@ -64,13 +79,16 @@ - (void)loadView{ [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _mySearchBar = ({ UISearchBar *searchBar = [[UISearchBar alloc] init]; searchBar.delegate = self; [searchBar sizeToFit]; - [searchBar setPlaceholder:@"昵称/个性后缀"]; + [searchBar setPlaceholder:@"昵称/用户名"]; searchBar; }); _myTableView.tableHeaderView = _mySearchBar; @@ -99,16 +117,6 @@ - (void)loadView{ if (resultData) { NSMutableArray *resultA = [NSObject arrayFromJSON:resultData ofObjects:@"ProjectMember"]; - __block NSUInteger mineIndex = 0; - [resultA enumerateObjectsUsingBlock:^(ProjectMember *obj, NSUInteger idx, BOOL *stop) { - if (obj.user_id.integerValue == [Login curLoginUser].id.integerValue) { - mineIndex = idx; - *stop = YES; - } - }]; - if (mineIndex > 0) { - [resultA exchangeObjectAtIndex:mineIndex withObjectAtIndex:0]; - } weakSelf.myMemberArray = resultA; [weakSelf.myTableView reloadData]; }else{ @@ -214,8 +222,8 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N curMember = [_myMemberArray objectAtIndex:indexPath.row]; } __weak typeof(self) weakSelf = self; - cell.curMember = curMember; cell.type = _type; + cell.curMember = curMember; if (_type == ProMemTypeProject) { [cell setRightUtilityButtons:[self rightButtonsWithObj:curMember] WithButtonWidth:[MemberCell cellHeight]];//编辑按钮 cell.delegate = self; @@ -231,7 +239,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N if (weakSelf.type == ProMemTypeProject) { if (curMember.user_id.intValue == [Login curLoginUser].id.intValue) { // 自己,退出项目 - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"确定退出项目?" buttonTitles:nil destructiveTitle:@"确认退出" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + UIAlertController *actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"确定退出项目?" buttonTitles:nil destructiveTitle:@"确认退出" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf quitSelf_ProjectMember:curMember]; } @@ -353,7 +361,7 @@ - (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerRightUtilityBut }else if (index == 1){//修改权限 [self editTypeOfMember:mem]; }else if (index == 2){//移除成员 - [[UIActionSheet bk_actionSheetCustomWithTitle:@"移除该成员后,他将不再显示在项目中" buttonTitles:nil destructiveTitle:@"确认移除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + [[UIAlertController ea_actionSheetCustomWithTitle:@"移除该成员后,他将不再显示在项目中" buttonTitles:nil destructiveTitle:@"确认移除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [self removeMember:mem]; } diff --git a/Coding_iOS/Controllers/ProjectSetting/ProjectAdvancedSettingViewController.m b/Coding_iOS/Controllers/ProjectSetting/ProjectAdvancedSettingViewController.m index b5cb17a68..7dd61b48c 100644 --- a/Coding_iOS/Controllers/ProjectSetting/ProjectAdvancedSettingViewController.m +++ b/Coding_iOS/Controllers/ProjectSetting/ProjectAdvancedSettingViewController.m @@ -32,6 +32,8 @@ - (void)viewDidLoad { self.tableView.tableFooterView = [UIView new]; [self.tableView setSeparatorColor:[UIColor colorWithRGBHex:0xe5e5e5]]; + self.tableView.backgroundColor = kColorTableSectionBg; + } - (void)didReceiveMemoryWarning { @@ -163,7 +165,7 @@ -(BOOL)textFieldShouldReturn:(UITextField *)textField{ #pragma mark - Orientations - (BOOL)shouldAutorotate{ - return UIInterfaceOrientationIsLandscape(self.interfaceOrientation); + return UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication.statusBarOrientation); } - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { diff --git a/Coding_iOS/Controllers/ProjectSetting/ProjectArchiveViewController.h b/Coding_iOS/Controllers/ProjectSetting/ProjectArchiveViewController.h new file mode 100644 index 000000000..cd6dfa285 --- /dev/null +++ b/Coding_iOS/Controllers/ProjectSetting/ProjectArchiveViewController.h @@ -0,0 +1,17 @@ +// +// ProjectArchiveViewController.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/4/26. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import +#import "Project.h" + +@interface ProjectArchiveViewController : UITableViewController + +@property (nonatomic, strong) Project *project; +@property (strong, nonatomic) IBOutletCollection(NSLayoutConstraint) NSArray *lines; + +@end diff --git a/Coding_iOS/Controllers/ProjectSetting/ProjectArchiveViewController.m b/Coding_iOS/Controllers/ProjectSetting/ProjectArchiveViewController.m new file mode 100644 index 000000000..053630f7f --- /dev/null +++ b/Coding_iOS/Controllers/ProjectSetting/ProjectArchiveViewController.m @@ -0,0 +1,153 @@ +// +// ProjectArchiveViewController.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/4/26. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "ProjectArchiveViewController.h" +#import "Coding_NetAPIManager.h" + +#import +#import +#import +#import "ProjectDeleteAlertControllerVisualStyle.h" + +#import "Ease_2FA.h" + +@interface ProjectArchiveViewController () +@property (strong, nonatomic) SDCAlertController *alert; + +@end + +@implementation ProjectArchiveViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + self.title = @"归档项目"; + + for (NSLayoutConstraint *cons in self.lines) { + cons.constant = 0.5; + } + + self.tableView.tableFooterView = [UIView new]; + [self.tableView setSeparatorColor:[UIColor colorWithRGBHex:0xe5e5e5]]; + self.tableView.backgroundColor = kColorTableSectionBg; +} + + +-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ + return [UIView new]; +} + +-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath +{ + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; +} + +-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + if (indexPath.section != 1) { + return; + } + [[Coding_NetAPIManager sharedManager] request_VerifyTypeWithBlock:^(VerifyType type, NSError *error) { + if (!error) { + [self showArchiveAlertWithType:type]; + } + }]; +} + +- (void)showArchiveAlertWithType:(VerifyType)type{ + + if (self.alert) {//正在显示 + return; + } + + NSString *title, *message, *placeHolder; + if (type == VerifyTypePassword) { + title = @"需要验证密码"; + message = @"这是一个危险的操作,请提供登录密码确认!"; + placeHolder = @"请输入密码"; + }else if (type == VerifyTypeTotp){ + title = @"需要动态验证码"; + message = @"这是一个危险操作,需要进行身份验证!"; + placeHolder = @"请输入动态验证码"; + }else{//不知道啥类型,不处理 + return; + } + + _alert = [SDCAlertController alertControllerWithTitle:title message:message preferredStyle:SDCAlertControllerStyleAlert]; + + UITextField *passwordTextField = [[UITextField alloc] initWithFrame:CGRectMake(15, 0, 240.0, 30.0)]; + passwordTextField.leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 30)]; + passwordTextField.leftViewMode = UITextFieldViewModeAlways; + passwordTextField.layer.borderColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.6].CGColor; + passwordTextField.layer.borderWidth = 1; + passwordTextField.secureTextEntry = (type == VerifyTypePassword); + passwordTextField.backgroundColor = [UIColor whiteColor]; + passwordTextField.placeholder = placeHolder; + if (type == VerifyTypeTotp) { + passwordTextField.text = [OTPListViewController otpCodeWithGK:[Login curLoginUser].global_key]; + } + passwordTextField.delegate = self; + + [_alert.contentView addSubview:passwordTextField]; + + NSDictionary* passwordViews = NSDictionaryOfVariableBindings(passwordTextField); + + [_alert.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[passwordTextField]-(>=14)-|" options:0 metrics:nil views:passwordViews]]; + + // Style + _alert.visualStyle = [ProjectDeleteAlertControllerVisualStyle new]; + + // 添加密码框 + // [alert addTextFieldWithConfigurationHandler:^(UITextField *textField) { + // textField.secureTextEntry = YES; + // }]; + + // 添加按钮 + @weakify(self); + _alert.actionLayout = SDCAlertControllerActionLayoutHorizontal; + [_alert addAction:[SDCAlertAction actionWithTitle:@"取消" style:SDCAlertActionStyleDefault handler:^(SDCAlertAction *action) { + @strongify(self); + self.alert = nil; + }]]; + [_alert addAction:[SDCAlertAction actionWithTitle:@"确定" style:SDCAlertActionStyleDefault handler:^(SDCAlertAction *action) { + @strongify(self); + self.alert = nil; + NSString *passCode = passwordTextField.text; + if ([passCode length] > 0) { + // 归档项目 + [[Coding_NetAPIManager sharedManager] request_ArchiveProject_WithObj:self.project passCode:passCode type:type andBlock:^(Project *data, NSError *error) { + if (!error) { + [self.navigationController popToRootViewControllerAnimated:YES]; + } + }]; + } + }]]; + + [_alert presentWithCompletion:^{ + [passwordTextField becomeFirstResponder]; + }]; +} + + +-(BOOL)textFieldShouldReturn:(UITextField *)textField{ + [textField resignFirstResponder]; + return YES; +} + +#pragma mark - Orientations +- (BOOL)shouldAutorotate{ + return UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication.statusBarOrientation); +} + +- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { + return UIInterfaceOrientationPortrait; +} + +- (UIInterfaceOrientationMask)supportedInterfaceOrientations { + return UIInterfaceOrientationMaskPortrait; +} +@end diff --git a/Coding_iOS/Controllers/ProjectSetting/ProjectSetting.storyboard b/Coding_iOS/Controllers/ProjectSetting/ProjectSetting.storyboard index 5d42b9926..bb0f03179 100644 --- a/Coding_iOS/Controllers/ProjectSetting/ProjectSetting.storyboard +++ b/Coding_iOS/Controllers/ProjectSetting/ProjectSetting.storyboard @@ -1,244 +1,145 @@ - - + + + + + - - + + - - + + - - - + + + - + + + + + + + + + + + - + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - + + - - + + - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - + + - - + + - - - - - - + + - - + - - + + - - - - - - - - - - - - - + - + - + - + - + - + - @@ -250,38 +151,38 @@ - + - + - + - @@ -316,22 +216,22 @@ - + - + - + - + - + @@ -352,17 +252,17 @@ - + - + @@ -373,57 +273,57 @@ - + - + - + - - + + @@ -453,7 +353,6 @@ - @@ -464,11 +363,390 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + diff --git a/Coding_iOS/Controllers/ProjectSetting/ProjectSettingEntranceController.h b/Coding_iOS/Controllers/ProjectSetting/ProjectSettingEntranceController.h new file mode 100644 index 000000000..1576df9f9 --- /dev/null +++ b/Coding_iOS/Controllers/ProjectSetting/ProjectSettingEntranceController.h @@ -0,0 +1,16 @@ +// +// ProjectSettingEntranceController.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/4/25. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import +#import "Project.h" + +@interface ProjectSettingEntranceController : UITableViewController + +@property (nonatomic, strong) Project *project; + +@end diff --git a/Coding_iOS/Controllers/ProjectSetting/ProjectSettingEntranceController.m b/Coding_iOS/Controllers/ProjectSetting/ProjectSettingEntranceController.m new file mode 100644 index 000000000..2eedb15b9 --- /dev/null +++ b/Coding_iOS/Controllers/ProjectSetting/ProjectSettingEntranceController.m @@ -0,0 +1,46 @@ +// +// ProjectSettingEntranceController.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/4/25. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "ProjectSettingEntranceController.h" +#import "UserOrProjectTweetsViewController.h" +#import "ProjectViewController.h" + +@interface ProjectSettingEntranceController () + +@end + +@implementation ProjectSettingEntranceController + +- (void)viewDidLoad { + [super viewDidLoad]; +} + +-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{ + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + if (indexPath.row == 0) { + UserOrProjectTweetsViewController *vc = [UserOrProjectTweetsViewController new]; + vc.curTweets = [Tweets tweetsWithProject:self.project]; + [self.navigationController pushViewController:vc animated:YES]; + }else if (indexPath.row == 1){ + ProjectViewController *vc = [[ProjectViewController alloc] init]; + vc.myProject = self.project; + vc.curType = ProjectViewTypeMembers; + [self.navigationController pushViewController:vc animated:YES]; + } +} + +-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ + UIViewController *vc = segue.destinationViewController; + [vc setValue:self.project forKey:@"project"]; +} + +@end diff --git a/Coding_iOS/Controllers/ProjectSetting/ProjectSettingViewController.h b/Coding_iOS/Controllers/ProjectSetting/ProjectSettingViewController.h index fe611dcf0..5f1da443f 100644 --- a/Coding_iOS/Controllers/ProjectSetting/ProjectSettingViewController.h +++ b/Coding_iOS/Controllers/ProjectSetting/ProjectSettingViewController.h @@ -15,13 +15,12 @@ @property (nonatomic, strong) Project *project; -@property (strong, nonatomic) IBOutlet UILabel *projectNameLabel; +@property (weak, nonatomic) IBOutlet UITextField *projectNameF; @property (strong, nonatomic) IBOutlet UIImageView *projectImageView; @property (strong, nonatomic) IBOutlet UIPlaceHolderTextView *descTextView; @property (strong, nonatomic) IBOutletCollection(NSLayoutConstraint) NSArray *lines; @property (strong, nonatomic) IBOutlet UIImageView *privateImageView; -@property (strong, nonatomic) IBOutlet NSLayoutConstraint *privateIconLeftConstraint; @end diff --git a/Coding_iOS/Controllers/ProjectSetting/ProjectSettingViewController.m b/Coding_iOS/Controllers/ProjectSetting/ProjectSettingViewController.m index 307ace847..c6e37f807 100644 --- a/Coding_iOS/Controllers/ProjectSetting/ProjectSettingViewController.m +++ b/Coding_iOS/Controllers/ProjectSetting/ProjectSettingViewController.m @@ -12,13 +12,15 @@ #import "Coding_NetAPIManager.h" #import "MBProgressHUD+Add.h" #import "JDStatusBarNotification.h" +#import "Coding_NetAPIManager.h" -@interface ProjectSettingViewController () +@interface ProjectSettingViewController () -@property (nonatomic, strong) UIBarButtonItem *submitButtonItem; @property (nonatomic, strong) UIImage *projectIconImage; @property (nonatomic, strong) MBProgressHUD *uploadHUD; +@property (weak, nonatomic) IBOutlet UIView *tableHeaderV; + @end @implementation ProjectSettingViewController @@ -26,27 +28,27 @@ @implementation ProjectSettingViewController - (void)viewDidLoad { [super viewDidLoad]; + self.title = @"项目设置"; // Private Icon if ([self.project.is_public isEqual:@YES]) { self.privateImageView.hidden = YES; - self.privateIconLeftConstraint.constant = -5; } // sep for (NSLayoutConstraint *cons in self.lines) { - cons.constant = 0.5; + cons.constant = kLine_MinHeight; } //tabview self.tableView.tableFooterView = [UIView new]; [self.tableView setSeparatorColor:[UIColor colorWithRGBHex:0xe5e5e5]]; - - self.projectNameLabel.text = self.project.name; - + self.tableView.backgroundColor = kColorTableSectionBg; + + self.projectNameF.text = self.project.name; + // self.descTextView.placeholder = @"填写项目描述..."; self.descTextView.text = self.project.description_mine; - self.descTextView.delegate = self; // self.projectImageView.layer.cornerRadius = 2; @@ -55,33 +57,44 @@ - (void)viewDidLoad { [self.projectImageView addGestureRecognizer:tapProjectImageViewGR]; // 添加 “完成” 按钮 - self.submitButtonItem = [UIBarButtonItem itemWithBtnTitle:@"完成" target:self action:@selector(submit)]; - self.submitButtonItem.enabled = NO; - self.navigationItem.rightBarButtonItem = self.submitButtonItem; + if ([self p_canEditPro]) { + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"done_un_Nav"] style:UIBarButtonItemStylePlain target:self action:@selector(submit)]; + + RAC(self, navigationItem.rightBarButtonItem.enabled) = [RACSignal combineLatest:@[self.projectNameF.rac_textSignal, self.descTextView.rac_textSignal] reduce:^id (NSString *name, NSString *desc){ + BOOL hasChange = ![name isEqualToString:self.project.name] || ![desc isEqualToString:self.project.description_mine]; + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:hasChange? @"done_Nav": @"done_un_Nav"] style:UIBarButtonItemStylePlain target:self action:@selector(submit)]; + return @(hasChange); + }]; + } //HUD self.uploadHUD = [[MBProgressHUD alloc] initWithView:self.view]; self.uploadHUD.mode = MBProgressHUDModeDeterminate; [self.view addSubview:self.uploadHUD]; + + if ([self p_isOwner]) { + self.tableHeaderV.height = 0; + } } -(void)submit{ + self.project.name = [self.projectNameF.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; self.project.description_mine = [self.descTextView.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; - self.submitButtonItem.enabled = NO; + self.navigationItem.rightBarButtonItem.enabled = NO; // 更新项目 [[Coding_NetAPIManager sharedManager] request_UpdateProject_WithObj:self.project andBlock:^(Project *data, NSError *error) { if (!error) { [self.navigationController popViewControllerAnimated:YES]; } - self.submitButtonItem.enabled = YES; + self.navigationItem.rightBarButtonItem.enabled = YES; }]; } -(void)selectProjectImage{ - [[UIActionSheet bk_actionSheetCustomWithTitle:@"选择照片" buttonTitles:@[@"拍照",@"从相册选择"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + [[UIAlertController ea_actionSheetCustomWithTitle:@"选择照片" buttonTitles:@[@"拍照",@"从相册选择"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index > 1) { return ; @@ -136,19 +149,6 @@ -(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{ [picker dismissViewControllerAnimated:YES completion:nil]; } - --(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{ - NSString *string = [textView.text stringByReplacingCharactersInRange:range withString:text]; - - if ([string isEqualToString:self.project.description_mine]) { - self.submitButtonItem.enabled = NO; - }else{ - self.submitButtonItem.enabled = YES; - } - - return YES; -} - - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. @@ -156,13 +156,49 @@ - (void)didReceiveMemoryWarning { #pragma mark UITableView +- (BOOL)p_canEditPro{ + return _project.current_user_role_id.integerValue >= 90 || [self p_isOwner]; +} + +- (BOOL)p_isOwner{ + if (kTarget_Enterprise) { + return NO;//企业里面没有所有者 +// return [Login curLoginUser].isAdministrator.boolValue;//企业版里,企业管理员比项目所有者的权限更大。项目所有者无权 + }else{ + return [self.project.owner_id isEqual:[Login curLoginUser].id]; + } +} + -(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ return [UIView new]; } --(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath -{ - [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:13]; +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ + if (section == 0) { + return [self p_isOwner]? 15: 0; + }else if (section == 1){ + return [self p_isOwner]? 15: 0; + }else{ + return [self p_isOwner]? 0: 15; + } +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + if (section == 0) { + return [self p_canEditPro]? 2: 0; + }else if (section == 1){ + return [self p_isOwner]? 3: 0; + }else{ + return [self p_isOwner]? 0: 1; + } +} + +-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{ + if (indexPath.section == 0 && indexPath.row == 0) { + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:15 hasSectionLine:NO]; + }else{ + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:15]; + } } -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ @@ -170,9 +206,30 @@ -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ [vc setValue:self.project forKey:@"project"]; } +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + if (indexPath.section == 2) { + __weak typeof(self) weakSelf = self; + [[UIAlertController ea_actionSheetCustomWithTitle:@"确定退出项目?" buttonTitles:nil destructiveTitle:@"确认退出" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { + [weakSelf quitPro]; + } + }] showInView:self.view]; + } +} + +- (void)quitPro{ + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_ProjectQuit:_project.id andBlock:^(id data, NSError *error) { + if (data) { + [weakSelf.navigationController popToRootViewControllerAnimated:YES]; + } + }]; +} + #pragma mark - Orientations - (BOOL)shouldAutorotate{ - return UIInterfaceOrientationIsLandscape(self.interfaceOrientation); + return UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication.statusBarOrientation); } - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { diff --git a/Coding_iOS/Controllers/ProjectSetting/ProjectTransferSettingViewController.m b/Coding_iOS/Controllers/ProjectSetting/ProjectTransferSettingViewController.m index 66acae64c..81e9e9f3e 100644 --- a/Coding_iOS/Controllers/ProjectSetting/ProjectTransferSettingViewController.m +++ b/Coding_iOS/Controllers/ProjectSetting/ProjectTransferSettingViewController.m @@ -35,6 +35,8 @@ - (void)viewDidLoad { } [self.tableView setSeparatorColor:[UIColor colorWithRGBHex:0xe5e5e5]]; + self.tableView.backgroundColor = kColorTableSectionBg; + [_userIconView doCircleFrame]; [_transferBtn successStyle]; _transferBtn.enabled = NO; @@ -185,7 +187,7 @@ -(BOOL)textFieldShouldReturn:(UITextField *)textField{ #pragma mark - Orientations - (BOOL)shouldAutorotate{ - return UIInterfaceOrientationIsLandscape(self.interfaceOrientation); + return UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication.statusBarOrientation); } - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { diff --git a/Coding_iOS/Controllers/ProjectToChooseListViewController.m b/Coding_iOS/Controllers/ProjectToChooseListViewController.m index e09734ed9..8bf84b5f6 100644 --- a/Coding_iOS/Controllers/ProjectToChooseListViewController.m +++ b/Coding_iOS/Controllers/ProjectToChooseListViewController.m @@ -8,6 +8,7 @@ #import "ProjectToChooseListViewController.h" #import "ProjectListView.h" +#import "EditTaskViewController.h" @interface ProjectToChooseListViewController () @property (strong, nonatomic) Projects *curPros; @@ -20,11 +21,12 @@ - (void)viewDidLoad { // Do any additional setup after loading the view. self.title = @"所属项目"; self.curPros = [Projects projectsWithType:ProjectsTypeToChoose andUser:nil]; - __weak typeof(self) weakSelf = self; ProjectListView *listView = [[ProjectListView alloc] initWithFrame:self.view.bounds projects:self.curPros block:^(Project *project) { if (weakSelf.projectChoosedBlock) { weakSelf.projectChoosedBlock(self, project); + }else{ + [weakSelf goToNewTaskWithPro:project]; } } tabBarHeight:0]; [self.view addSubview:listView]; @@ -33,9 +35,16 @@ - (void)viewDidLoad { }]; } -- (void)didReceiveMemoryWarning { - [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. +- (void)goToNewTaskWithPro:(Project *)project{ + EditTaskViewController *taskVC = [EditTaskViewController new]; + taskVC.myTask = [Task taskWithProject:project andUser:[Login curLoginUser]]; + taskVC.myTask.handleType = TaskHandleTypeAddWithoutProject; + NSUInteger index = MIN(0, [self.navigationController.viewControllers indexOfObject:self] - 1); + UIViewController *doneVC = self.navigationController.viewControllers[index]; + __weak UIViewController *weakDoneVC = doneVC; + taskVC.doneBlock = ^(EditTaskViewController *vc){ + [vc.navigationController popToViewController:weakDoneVC animated:YES]; + }; + [self.navigationController pushViewController:taskVC animated:YES]; } - @end diff --git a/Coding_iOS/Controllers/ProjectTweetSendViewController.h b/Coding_iOS/Controllers/ProjectTweetSendViewController.h index 2b510b5d8..63cba7879 100644 --- a/Coding_iOS/Controllers/ProjectTweetSendViewController.h +++ b/Coding_iOS/Controllers/ProjectTweetSendViewController.h @@ -12,6 +12,7 @@ @interface ProjectTweetSendViewController : BaseViewController @property (strong, nonatomic) Project *curPro; +@property (strong, nonatomic) Tweet *curTweet;//有的话,就是编辑。。没有的话,就是添加 @property (copy, nonatomic) void(^sentBlock)(Tweet *tweet); @end diff --git a/Coding_iOS/Controllers/ProjectTweetSendViewController.m b/Coding_iOS/Controllers/ProjectTweetSendViewController.m index 22be01b77..c5527b3c7 100644 --- a/Coding_iOS/Controllers/ProjectTweetSendViewController.m +++ b/Coding_iOS/Controllers/ProjectTweetSendViewController.m @@ -11,6 +11,7 @@ #import "WebContentManager.h" #import "EaseMarkdownTextView.h" #import "WebViewController.h" +#import "UIViewController+BackButtonHandler.h" @interface ProjectTweetSendViewController () @@ -72,6 +73,21 @@ - (void)viewDidAppear:(BOOL)animated{ } } +- (BOOL)navigationShouldPopOnBackButton{ + BOOL hasChanged = ![self.curTweet.raw ?: @"" isEqualToString:_editView.text]; + if (hasChanged) { + __weak typeof(self) weakSelf = self; + [[UIAlertController ea_alertViewWithTitle:@"提示" message:@"如果不保存,更改将丢失,是否确认返回?" buttonTitles:@[@"确认返回"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { + [weakSelf.navigationController popViewControllerAnimated:YES]; + } + }] show]; + return NO; + }else{ + return YES; + } +} + #pragma mark UISegmentedControl - (void)segmentedControlSelected:(id)sender{ UISegmentedControl *segmentedControl = (UISegmentedControl *)sender; @@ -107,9 +123,9 @@ - (void)loadEditView{ _editView.textColor = kColor666; _editView.font = [UIFont systemFontOfSize:16]; _editView.textContainerInset = UIEdgeInsetsMake(15, kPaddingLeftWidth - 5, 8, kPaddingLeftWidth - 5); - _editView.placeholder = @"任务描述"; + _editView.placeholder = @"公告内容"; - _editView.text = nil; + _editView.text = _curTweet.raw; [self.view addSubview:_editView]; [_editView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); @@ -170,19 +186,35 @@ - (void)previewLoadMDData{ #pragma mark nav_btn - (void)sendBtnClicked{ - [NSObject showHUDQueryStr:@"正在发布..."]; - @weakify(self); - [[Coding_NetAPIManager sharedManager] request_Tweet_DoProjectTweet_WithPro:self.curPro.id content:self.editView.text andBlock:^(id data, NSError *error) { - [NSObject hideHUDQuery]; - if (data) { - [NSObject showHudTipStr:@"发布成功"]; - @strongify(self); - if (self.sentBlock) { - self.sentBlock(data); + if (_curTweet && _curTweet.isProjectTweet) { + [NSObject showHUDQueryStr:@"正在修改..."]; + @weakify(self); + [[Coding_NetAPIManager sharedManager] request_Tweet_EditProjectTweet:self.curTweet content:self.editView.text andBlock:^(id data, NSError *error) { + [NSObject hideHUDQuery]; + if (data) { + [NSObject showHudTipStr:@"修改成功"]; + @strongify(self); + if (self.sentBlock) { + self.sentBlock(data); + } + [self.navigationController popViewControllerAnimated:YES]; } - [self.navigationController popViewControllerAnimated:YES]; - } - }]; + }]; + }else{ + [NSObject showHUDQueryStr:@"正在发布..."]; + @weakify(self); + [[Coding_NetAPIManager sharedManager] request_Tweet_DoProjectTweet_WithPro:self.curPro.id content:self.editView.text andBlock:^(id data, NSError *error) { + [NSObject hideHUDQuery]; + if (data) { + [NSObject showHudTipStr:@"发布成功"]; + @strongify(self); + if (self.sentBlock) { + self.sentBlock(data); + } + [self.navigationController popViewControllerAnimated:YES]; + } + }]; + } } #pragma mark UIWebViewDelegate diff --git a/Coding_iOS/Controllers/ProjectTypeExplanationViewController.h b/Coding_iOS/Controllers/ProjectTypeExplanationViewController.h new file mode 100644 index 000000000..729a275ce --- /dev/null +++ b/Coding_iOS/Controllers/ProjectTypeExplanationViewController.h @@ -0,0 +1,13 @@ +// +// ProjectTypeExplanationViewController.h +// Coding_Enterprise_iOS +// +// Created by Easeeeeeeeee on 2017/6/6. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "BaseViewController.h" + +@interface ProjectTypeExplanationViewController : BaseViewController + +@end diff --git a/Coding_iOS/Controllers/ProjectTypeExplanationViewController.m b/Coding_iOS/Controllers/ProjectTypeExplanationViewController.m new file mode 100644 index 000000000..cb7e17db3 --- /dev/null +++ b/Coding_iOS/Controllers/ProjectTypeExplanationViewController.m @@ -0,0 +1,38 @@ +// +// ProjectTypeExplanationViewController.m +// Coding_Enterprise_iOS +// +// Created by Easeeeeeeeee on 2017/6/6. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "ProjectTypeExplanationViewController.h" + +@interface ProjectTypeExplanationViewController () + +@end + +@implementation ProjectTypeExplanationViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view from its nib. + self.title = @"成员权限说明"; +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +/* +#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ + +@end diff --git a/Coding_iOS/Controllers/ProjectTypeExplanationViewController.xib b/Coding_iOS/Controllers/ProjectTypeExplanationViewController.xib new file mode 100644 index 000000000..2ce19640d --- /dev/null +++ b/Coding_iOS/Controllers/ProjectTypeExplanationViewController.xib @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Coding_iOS/Controllers/ProjectViewController.h b/Coding_iOS/Controllers/ProjectViewController.h index 845e2ebf9..9c0b77719 100755 --- a/Coding_iOS/Controllers/ProjectViewController.h +++ b/Coding_iOS/Controllers/ProjectViewController.h @@ -13,18 +13,17 @@ typedef NS_ENUM(NSInteger, ProjectViewType) { ProjectViewTypeActivities = 0, ProjectViewTypeTasks, - ProjectViewTypeTopics, ProjectViewTypeFiles, + ProjectViewTypeTopics, ProjectViewTypeCodes, ProjectViewTypeMembers }; @interface ProjectViewController : BaseViewController @property (nonatomic, strong) Project *myProject; -@property (nonatomic, assign) NSInteger curIndex; -@property (nonatomic, assign, readonly) ProjectViewType curType; -@property (strong, nonatomic) NSString *codeRef; +@property (nonatomic, assign) ProjectViewType curType; +@property (assign, nonatomic) BOOL hideBranchTagButton; + (ProjectViewController *)codeVCWithCodeRef:(NSString *)codeRef andProject:(Project *)project; @end diff --git a/Coding_iOS/Controllers/ProjectViewController.m b/Coding_iOS/Controllers/ProjectViewController.m index 692389565..d1cc36eca 100644 --- a/Coding_iOS/Controllers/ProjectViewController.m +++ b/Coding_iOS/Controllers/ProjectViewController.m @@ -19,12 +19,12 @@ #import "Coding_NetAPIManager.h" #import "UserInfoViewController.h" #import "AddUserViewController.h" -#import "ProjectFolderListView.h" +#import "NProjectFileListView.h" #import "ProjectCodeListView.h" #import "CodeListViewController.h" #import "CodeViewController.h" #import "ProjectMemberActivityListViewController.h" -#import "FileListViewController.h" +#import "NFileListViewController.h" #import "SettingTextViewController.h" #import "FolderToMoveViewController.h" #import "FileViewController.h" @@ -37,6 +37,9 @@ #import "CommitFilesViewController.h" #import "FunctionTipsManager.h" +#import "TaskSelectionView.h" +#import "ScreenView.h" + @interface ProjectViewController () @@ -44,6 +47,21 @@ @interface ProjectViewController () //项目成员 @property (strong, nonatomic) ProjectMemberListViewController *proMemberVC; +@property (strong, nonatomic) UIButton *titleBtn; + +@property (nonatomic, strong) TaskSelectionView *myFliterMenu; +@property (nonatomic, strong) ScreenView *screenView; + + +@property (nonatomic, strong) NSString *keyword; +@property (nonatomic, strong) NSString *status; //任务状态,进行中的为1,已完成的为2 +@property (nonatomic, strong) NSString *label; //任务标签 +@property (nonatomic, strong) NSString *userId; +@property (nonatomic, assign) TaskRoleType role; + +@property (nonatomic, strong) UIBarButtonItem *screenBar; + +@property (strong, nonatomic) CodeTree *myCodeTree; @end @@ -51,29 +69,35 @@ @implementation ProjectViewController + (ProjectViewController *)codeVCWithCodeRef:(NSString *)codeRef andProject:(Project *)project{ ProjectViewController *vc = [self new]; - vc.codeRef = codeRef; + vc.myCodeTree = [CodeTree codeTreeWithRef:codeRef andPath:@""]; vc.myProject = project; - if (vc.myProject.is_public.boolValue) { - vc.curIndex = 2; - }else{ - vc.curIndex = 4; - } + vc.curType = ProjectViewTypeCodes; return vc; } + +- (CodeTree *)myCodeTree{ + if (!_myCodeTree) { + _myCodeTree = [CodeTree codeTreeWithRef:@"master" andPath:@""]; + } + return _myCodeTree; +} + - (instancetype)init { self = [super init]; if (self) { - _curIndex = 0; + _curType = ProjectViewTypeActivities; } return self; } + - (UIView *)getCurContentView{ - return [_projectContentDict objectForKey:[NSNumber numberWithInteger:_curIndex]]; + return [_projectContentDict objectForKey:[NSNumber numberWithInteger:_curType]]; } + - (void)saveCurContentView:(UIView *)curContentView{ if (curContentView) { - [_projectContentDict setObject:curContentView forKey:[NSNumber numberWithInteger:_curIndex]]; + [_projectContentDict setObject:curContentView forKey:[NSNumber numberWithInteger:_curType]]; } } @@ -88,9 +112,69 @@ - (void)viewDidLoad [self requestForMyProject]; }else{ [self configNavBtnWithMyProject]; - [self refreshWithNewIndex:_curIndex]; + [self refreshWithNewIndex:_curType]; } } + UIView *curView = [self getCurContentView]; + if ([curView isKindOfClass:[ProjectTasksView class]]) { + [self setupTitleBtn]; + + ProjectTasksView *tasksView = (ProjectTasksView *)curView; + [self assignmentWithlistView:tasksView]; + [tasksView refresh]; + + _role = TaskRoleTypeAll; + //初始化过滤目录 + _myFliterMenu = [[TaskSelectionView alloc] initWithFrame:CGRectMake(0, 44 + kSafeArea_Top, kScreen_Width, kScreen_Height - (44 + kSafeArea_Top)) items:@[@"所有任务(0)", @"我关注的(0)", @"我创建的(0)"]]; + __weak typeof(self) weakSelf = self; + _myFliterMenu.clickBlock = ^(NSInteger pageIndex){ + _role = pageIndex; + if (pageIndex == 0) { + _role = TaskRoleTypeAll; + } + + NSString *title = weakSelf.myFliterMenu.items[pageIndex]; + [weakSelf.titleBtn setTitle:[title substringToIndex:4] forState:UIControlStateNormal]; + + UIView *curView = [weakSelf getCurContentView]; + if (![curView isKindOfClass:[ProjectTasksView class]]) { + return; + } + ProjectTasksView *tasksView = (ProjectTasksView *)curView; + [weakSelf assignmentWithlistView:tasksView]; + [tasksView refresh]; + [weakSelf resetTaskCount]; + [weakSelf loadTasksLabels]; + + }; + _myFliterMenu.closeBlock=^(){ + [weakSelf.myFliterMenu dismissMenu]; + }; + + _screenView = [ScreenView creat]; + weakSelf.screenView.tastArray = @[[NSString stringWithFormat:@"进行中的(0)"], + [NSString stringWithFormat:@"已完成的(0)"] + ]; + + _screenView.selectBlock = ^(NSString *keyword, NSString *status, NSString *label) { + weakSelf.keyword = keyword; + weakSelf.status = status; + weakSelf.label = label; + if (keyword == nil && status == nil && label == nil) { + weakSelf.screenBar.image = [[UIImage imageNamed:@"task_filter_nav_unchecked"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + }else{ + weakSelf.screenBar.image = [[UIImage imageNamed:@"task_filter_nav_checked"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; + } + UIView *curView = [weakSelf getCurContentView]; + if (![curView isKindOfClass:[ProjectTasksView class]]) { + return; + } + ProjectTasksView *tasksView = (ProjectTasksView *)curView; + [weakSelf assignmentWithlistView:tasksView]; + [tasksView refresh]; + + }; + } } - (void)didReceiveMemoryWarning { @@ -100,22 +184,25 @@ - (void)didReceiveMemoryWarning - (void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; [self refreshToQueryData]; + [self resetTaskCount]; + [self loadTasksLabels]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + [_myFliterMenu dismissMenu]; } - (void)refreshToQueryData{ UIView *curView = [self getCurContentView]; - if (curView && [curView respondsToSelector:@selector(refreshToQueryData)]) { - [curView performSelector:@selector(refreshToQueryData)]; + if (!curView) { + return; } - - if ([curView isKindOfClass:[ProjectTasksView class]]) { - ProjectTasksView *tasksView = (ProjectTasksView *)curView; - [tasksView refreshToQueryData]; - }else{ - if (curView && [curView respondsToSelector:@selector(reloadData)]) { - [curView performSelector:@selector(reloadData)]; - } + if ([curView respondsToSelector:@selector(refreshToQueryData)]) { + [curView performSelector:@selector(refreshToQueryData)]; + }else if ([curView respondsToSelector:@selector(reloadData)]){ + [curView performSelector:@selector(reloadData)]; } } @@ -128,13 +215,15 @@ - (void)requestForMyProject{ if (data) { weakSelf.myProject = data; [weakSelf configNavBtnWithMyProject]; - [weakSelf refreshWithNewIndex:_curIndex]; + [weakSelf refreshWithNewIndex:_curType]; } }]; } - (void)configNavBtnWithMyProject{ - self.title = _myProject.name; + if (self.curType != ProjectViewTypeTasks) { + self.title = (self.curType == ProjectViewTypeCodes && _hideBranchTagButton)? _myCodeTree.ref: (self.curType == ProjectViewTypeMembers)? @"成员管理": _myProject.name; + } } - (void)configRightBarButtonItemWithViewType:(ProjectViewType)viewType{ @@ -142,59 +231,33 @@ - (void)configRightBarButtonItemWithViewType:(ProjectViewType)viewType{ if ((viewType == ProjectViewTypeMembers && _myProject.current_user_role_id.integerValue >= 90) || viewType == ProjectViewTypeTasks || viewType == ProjectViewTypeTopics - || viewType == ProjectViewTypeFiles) { + || viewType == ProjectViewTypeCodes) { navRightBtn = [[UIBarButtonItem alloc] initWithImage:[UIImage - imageNamed:(viewType == ProjectViewTypeCodes ? @"timeBtn_Nav" : @"addBtn_Nav")] + imageNamed:(viewType == ProjectViewTypeCodes ? @"moreBtn_Nav" : @"addBtn_Nav")] style:UIBarButtonItemStylePlain target:self action:@selector(navRightBtnClicked)]; - }else if (viewType == ProjectViewTypeCodes){ - UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 20, 20)]; - [button setImage:[UIImage imageNamed:@"timeBtn_Nav"] forState:UIControlStateNormal]; - [button addTarget:self action:@selector(navRightBtnClicked) forControlEvents:UIControlEventTouchUpInside]; - if ([[FunctionTipsManager shareManager] needToTip:kFunctionTipStr_CommitList]) { - [button addBadgeTip:kBadgeTipStr withCenterPosition:CGPointMake(20, 0)]; - } - navRightBtn = [[UIBarButtonItem alloc] initWithCustomView:button]; + } + if (ProjectViewTypeTasks == viewType) { + UIBarButtonItem *screenBar = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"task_filter_nav_unchecked"] style:UIBarButtonItemStylePlain target:self action:@selector(screenItemClicked:)]; + self.navigationItem.rightBarButtonItems = @[navRightBtn, screenBar]; + _screenBar = screenBar; + } else { + [self.navigationItem setRightBarButtonItem:navRightBtn animated:YES]; } - [self.navigationItem setRightBarButtonItem:navRightBtn animated:YES]; } - (ProjectViewType)viewTypeFromIndex:(NSInteger)index{ - ProjectViewType type = 0; - if (_myProject.is_public) { - if (_myProject.is_public.boolValue) { - switch (index) { - case 0: - type = ProjectViewTypeActivities; - break; - case 1: - type = ProjectViewTypeTopics; - break; - case 2: - type = ProjectViewTypeCodes; - break; - case 3: - type = ProjectViewTypeMembers; - break; - default: - type = ProjectViewTypeActivities; - break; - } - }else{ - type = index; - } - } - return type; + return index; } - (ProjectViewType)curType{ - return [self viewTypeFromIndex:_curIndex]; + return [self viewTypeFromIndex:_curType]; } - (void)refreshWithNewIndex:(NSInteger)newIndex{ - ProjectViewType curViewType = [self viewTypeFromIndex:_curIndex]; + ProjectViewType curViewType = [self viewTypeFromIndex:_curType]; ProjectViewType newViewType = [self viewTypeFromIndex:newIndex]; // 配置navBtn @@ -206,7 +269,7 @@ - (void)refreshWithNewIndex:(NSInteger)newIndex{ curView.hidden = YES; } // 配置将要显示的视图 - _curIndex = newIndex; + _curType = newIndex; curView = [self getCurContentView]; __weak typeof(self) weakSelf = self; if (curView == nil) { @@ -237,6 +300,11 @@ - (void)refreshWithNewIndex:(NSInteger)newIndex{ [weakSelf.navigationController pushViewController:vc animated:YES]; } defaultIndex:0]; }); + ((ProjectTasksView *)curView).selctUserBlock = ^(NSString *owner) { + weakSelf.userId = owner; + [weakSelf resetTaskCount]; + [weakSelf loadTasksLabels]; + }; } break; case ProjectViewTypeTopics:{ @@ -249,26 +317,22 @@ - (void)refreshWithNewIndex:(NSInteger)newIndex{ break; case ProjectViewTypeFiles:{ curView = ({ - ProjectFolderListView *folderListView = [[ProjectFolderListView alloc] initWithFrame:self.view.bounds project:_myProject]; + NProjectFileListView *folderListView = [[NProjectFileListView alloc] initWithFrame:self.view.bounds project:_myProject folder:nil]; folderListView.containerVC = self; - folderListView.folderInProjectBlock = ^(ProjectFolders *rootFolders, ProjectFolder *clickedFolder, Project *inProject){ - DebugLog(@"folderInProjectBlock-----: %@- %@", clickedFolder.name, inProject.name); - [weakSelf goToVCWithRootFolder:rootFolders folder:clickedFolder inProject:inProject]; - }; folderListView; }); } break; case ProjectViewTypeCodes:{ curView = ({ - ProjectCodeListView *codeListView = [[ProjectCodeListView alloc] initWithFrame:self.view.bounds project:_myProject andCodeTree:[CodeTree codeTreeWithRef:_codeRef andPath:@""]]; + ProjectCodeListView *codeListView = [[ProjectCodeListView alloc] initWithFrame:self.view.bounds project:_myProject andCodeTree:_myCodeTree]; codeListView.codeTreeFileOfRefBlock = ^(CodeTree_File *curCodeTreeFile, NSString *ref){ [weakSelf goToVCWith:curCodeTreeFile andRef:ref]; }; - codeListView.refChangedBlock = ^(NSString *ref){ - weakSelf.codeRef = ref; + codeListView.codeTreeChangedBlock = ^(CodeTree *tree){ + weakSelf.myCodeTree = tree; }; - [codeListView addBranchTagButton]; + codeListView.hideBranchTagButton = self.hideBranchTagButton; codeListView; }); } @@ -307,9 +371,15 @@ - (void)refreshWithNewIndex:(NSInteger)newIndex{ #pragma mark toVC - (void)goToUserInfo:(User *)user{ - UserInfoViewController *vc = [[UserInfoViewController alloc] init]; - vc.curUser = user; - [self.navigationController pushViewController:vc animated:YES]; + if (kTarget_Enterprise) { + UserInfoDetailViewController *vc = [UserInfoDetailViewController new]; + vc.curUser = user; + [self.navigationController pushViewController:vc animated:YES]; + }else{ + UserInfoViewController *vc = [[UserInfoViewController alloc] init]; + vc.curUser = user; + [self.navigationController pushViewController:vc animated:YES]; + } } - (void)goToActivityListOfUser:(User *)user{ @@ -326,137 +396,117 @@ - (void)goToVCWith:(CodeTree_File *)codeTreeFile andRef:(NSString *)ref{ CodeListViewController *vc = [[CodeListViewController alloc] init]; vc.myProject = _myProject; vc.myCodeTree = nextCodeTree; + vc.hideBranchTagButton = self.hideBranchTagButton; [self.navigationController pushViewController:vc animated:YES]; }else if ([@[@"file", @"image", @"sym_link", @"executable"] containsObject:codeTreeFile.mode]){//文件 CodeFile *nextCodeFile = [CodeFile codeFileWithRef:ref andPath:codeTreeFile.path]; CodeViewController *vc = [CodeViewController codeVCWithProject:_myProject andCodeFile:nextCodeFile]; [self.navigationController pushViewController:vc animated:YES]; + }else if ([codeTreeFile.mode isEqualToString:@"git_link"]){ + UIViewController *vc = [BaseViewController analyseVCFromLinkStr:codeTreeFile.info.submoduleLink]; + if (vc) { + [self.navigationController pushViewController:vc animated:YES]; + }else{ + [NSObject showHudTipStr:@"有些文件还不支持查看呢_(:з」∠)_"]; + } }else{ [NSObject showHudTipStr:@"有些文件还不支持查看呢_(:з」∠)_"]; } } -- (void)goToVCWithRootFolder:(ProjectFolders *)rootFolders folder:(ProjectFolder *)folder inProject:(Project *)project{ - FileListViewController *vc = [[FileListViewController alloc] init]; - vc.rootFolders = rootFolders; - vc.curFolder = folder; - vc.curProject = project; - [self.navigationController pushViewController:vc animated:YES]; -} +//- (void)goToVCWithRootFolder:(ProjectFolders *)rootFolders folder:(ProjectFolder *)folder inProject:(Project *)project{ +// FileListViewController *vc = [[FileListViewController alloc] init]; +// vc.rootFolders = rootFolders; +// vc.curFolder = folder; +// vc.curProject = project; +// [self.navigationController pushViewController:vc animated:YES]; +//} - (void)goToVCWithItem:(HtmlMediaItem *)clickedItem activity:(ProjectActivity *)proAct isContent:(BOOL)isContent inProject:(Project *)project{ if (isContent) {//cell上面第二个Label NSString *target_type = proAct.target_type; + NSString *linkPath = nil, *tipStr = nil; + if ([target_type isEqualToString:@"Task"]) { - Task *task = proAct.task; - NSArray *pathArray = [task.path componentsSeparatedByString:@"/"]; - if (pathArray.count >= 7) { - EditTaskViewController *vc = [[EditTaskViewController alloc] init]; - vc.myTask = [Task taskWithBackend_project_path:[NSString stringWithFormat:@"/user/%@/project/%@", pathArray[2], pathArray[4]] andId:pathArray[6]]; - [self.navigationController pushViewController:vc animated:YES]; - }else{ - [NSObject showHudTipStr:@"任务不存在"]; - } + linkPath = proAct.task.path; + tipStr = @"任务不存在"; }else if ([target_type isEqualToString:@"TaskComment"]){ - Task *task = proAct.task; NSArray *pathArray = [proAct.project.full_name componentsSeparatedByString:@"/"]; - if (pathArray.count >= 2) { - EditTaskViewController *vc = [[EditTaskViewController alloc] init]; - vc.myTask = [Task taskWithBackend_project_path:[NSString stringWithFormat:@"/user/%@/project/%@", pathArray[0], pathArray[1]] andId:task.id.stringValue]; - [self.navigationController pushViewController:vc animated:YES]; - }else{ - [NSObject showHudTipStr:@"任务不存在"]; - } - }else if ([target_type isEqualToString:@"ProjectTopic"]){ - - ProjectTopicActivity *topic = proAct.project_topic; - NSArray *pathArray; - if ([proAct.action isEqualToString:@"comment"]) { - pathArray = [topic.parent.path componentsSeparatedByString:@"/"]; - }else{ - pathArray = [topic.path componentsSeparatedByString:@"/"]; - } - if (pathArray.count >= 7) { - TopicDetailViewController *vc = [[TopicDetailViewController alloc] init]; - vc.curTopic = [ProjectTopic topicWithId:[NSNumber numberWithInteger:[pathArray[6] integerValue]]]; - [self.navigationController pushViewController:vc animated:YES]; - }else{ - [NSObject showHudTipStr:@"讨论不存在"]; - } + linkPath = pathArray.count >= 2? [NSString stringWithFormat:@"/u/%@/p/%@/task/%@", pathArray[0], pathArray[1], proAct.task.id]: nil; }else if ([target_type isEqualToString:@"ProjectFile"]){ - File *file = proAct.file; - NSArray *pathArray = [file.path componentsSeparatedByString:@"/"]; +// BOOL isFile = [proAct.type isEqualToString:@"file"]; +// NSArray *pathArray = [proAct.file.path componentsSeparatedByString:@"/"]; +// if (!isFile && pathArray.count >= 7){ +// //文件夹 +// ProjectFolder *folder; +// NSString *folderIdStr = pathArray[6]; +// if (![folderIdStr isEqualToString:@"default"] && [folderIdStr isPureInt]) { +// NSNumber *folderId = [NSNumber numberWithInteger:folderIdStr.integerValue]; +// folder = [ProjectFolder folderWithId:folderId]; +// folder.name = proAct.file.name; +// }else{ +// folder = [ProjectFolder defaultFolder]; +// } +// FileListViewController *vc = [[FileListViewController alloc] init]; +// vc.curProject = project; +// vc.curFolder = folder; +// vc.rootFolders = nil; +// [self.navigationController pushViewController:vc animated:YES]; +// }else{ +// if (isFile) { +// linkPath = proAct.file.path; +// } +// tipStr = isFile? @"文件不存在" :@"文件夹不存在"; +// } BOOL isFile = [proAct.type isEqualToString:@"file"]; - - if (isFile && pathArray.count >= 9) { - //文件 - NSString *fileIdStr = pathArray[8]; - ProjectFile *curFile = [ProjectFile fileWithFileId:@(fileIdStr.integerValue) andProjectId:@(project.id.integerValue)]; - curFile.name = file.name; - FileViewController *vc = [FileViewController vcWithFile:curFile andVersion:nil]; - [self.navigationController pushViewController:vc animated:YES]; - }else if (!isFile && pathArray.count >= 7){ + NSArray *pathArray = [proAct.file.path componentsSeparatedByString:@"/"]; + if (!isFile && pathArray.count >= (kTarget_Enterprise? 5: 7)){ //文件夹 - ProjectFolder *folder; - NSString *folderIdStr = pathArray[6]; + ProjectFile *folder = nil; + NSString *folderIdStr = pathArray.lastObject; if (![folderIdStr isEqualToString:@"default"] && [folderIdStr isPureInt]) { NSNumber *folderId = [NSNumber numberWithInteger:folderIdStr.integerValue]; - folder = [ProjectFolder folderWithId:folderId]; - folder.name = file.name; - }else{ - folder = [ProjectFolder defaultFolder]; + folder = [[ProjectFile alloc] initWithFileId:folderId inProject:project.name ofUser:project.owner_user_name]; + folder.name = proAct.file.name; } - FileListViewController *vc = [[FileListViewController alloc] init]; + NFileListViewController *vc = [[NFileListViewController alloc] init]; vc.curProject = project; vc.curFolder = folder; - vc.rootFolders = nil; [self.navigationController pushViewController:vc animated:YES]; }else{ - [NSObject showHudTipStr:(isFile? @"文件不存在" :@"文件夹不存在")]; + if (isFile) { + linkPath = proAct.file.path; + } + tipStr = isFile? @"文件不存在" :@"文件夹不存在"; } }else if ([target_type isEqualToString:@"ProjectMember"]) { if ([proAct.action isEqualToString:@"quit"]) { //退出项目 - }else{ //添加了某成员 - User *user = proAct.target_user; - UserInfoViewController *vc = [[UserInfoViewController alloc] init]; - vc.curUser = [User userWithGlobalKey:user.global_key]; - [self.navigationController pushViewController:vc animated:YES]; + linkPath = [NSString stringWithFormat:@"/u/%@", proAct.target_user.global_key]; } - - }else if ([target_type isEqualToString:@"Depot"]) { if ([proAct.action_msg isEqualToString:@"删除了"]) { - [NSObject showHudTipStr:@"删除了,不能看了~"]; + tipStr = @"删除了,不能看了~"; }else if ([proAct.action isEqualToString:@"fork"]) { NSArray *nameComponents = [proAct.depot.name componentsSeparatedByString:@"/"]; - if (nameComponents.count == 2) { - NProjectViewController *vc = [NProjectViewController new]; - vc.myProject = [Project new]; - vc.myProject.owner_user_name = nameComponents[0]; - vc.myProject.name = nameComponents[1]; - [self.navigationController pushViewController:vc animated:YES]; - }else{ - [NSObject showHudTipStr:@"没找到 Fork 到哪里去了~"]; - } + linkPath = nameComponents.count == 2? [NSString stringWithFormat:@"/u/%@/p/%@", nameComponents[0], nameComponents[1]]: nil; + tipStr = @"没找到 Fork 到哪里去了~"; }else if ([proAct.action isEqualToString:@"push"]){ // current_user_role_id = 75 是受限成员,不可访问代码 if (!project.is_public.boolValue && project.current_user_role_id.integerValue <= 75) { - [NSObject showHudTipStr:@"无权访问项目代码相关功能"]; - return; - } - if (proAct.commits.count == 1) { - Commit *firstCommit = [proAct.commits firstObject]; - NSString *request_path = [NSString stringWithFormat:@"%@/commit/%@", proAct.depot.path, firstCommit.sha]; - CommitFilesViewController *vc = [CommitFilesViewController vcWithPath:request_path]; - [self.navigationController pushViewController:vc animated:YES]; + tipStr = @"无权访问项目代码相关功能"; }else{ - NSString *ref = proAct.ref? proAct.ref : @"master"; - ProjectCommitsViewController *vc = [ProjectCommitsViewController new]; - vc.curProject = project; - vc.curCommits = [Commits commitsWithRef:ref Path:@""]; - [self.navigationController pushViewController:vc animated:YES]; + if (proAct.commits.count == 1) { + Commit *firstCommit = [proAct.commits firstObject]; + linkPath = [NSString stringWithFormat:@"%@/commit/%@", proAct.depot.path, firstCommit.sha]; + }else{ + NSString *ref = proAct.ref? proAct.ref : @"master"; + ProjectCommitsViewController *vc = [ProjectCommitsViewController new]; + vc.curProject = project; + vc.curCommits = [Commits commitsWithRef:ref Path:@""]; + [self.navigationController pushViewController:vc animated:YES]; + } } }else{ ProjectViewController *vc = [ProjectViewController codeVCWithCodeRef:proAct.ref andProject:project]; @@ -467,45 +517,62 @@ - (void)goToVCWithItem:(HtmlMediaItem *)clickedItem activity:(ProjectActivity *) [target_type isEqualToString:@"CommitLineNote"]){ // current_user_role_id = 75 是受限成员,不可访问代码 if (!project.is_public.boolValue && project.current_user_role_id.integerValue <= 75) { - [NSObject showHudTipStr:@"无权访问项目代码相关功能"]; - return; + tipStr = @"无权访问项目代码相关功能"; + }else{ + if ([target_type isEqualToString:@"PullRequestBean"]){ + linkPath = proAct.pull_request_path; + }else if ([target_type isEqualToString:@"MergeRequestBean"]){ + linkPath = proAct.merge_request_path; + }else if ([target_type isEqualToString:@"CommitLineNote"]){ + linkPath = proAct.line_note.noteable_url; + } + tipStr = @"不知道这是个什么东西o(╯□╰)o~"; } - NSString *request_path; - if ([target_type isEqualToString:@"PullRequestBean"]){ - request_path = proAct.pull_request_path; - }else if ([target_type isEqualToString:@"MergeRequestBean"]){ - request_path = proAct.merge_request_path; - }else if ([target_type isEqualToString:@"CommitLineNote"]){ - request_path = proAct.line_note.noteable_url; + }else if ([target_type isEqualToString:@"ProjectTweet"]) { + if ([proAct.action isEqualToString:@"delete"]) { + tipStr = @"删除了,不能看了~"; + }else{ + linkPath = [NSString stringWithFormat:@"/p/%@/setting/notice", proAct.project.name]; } - - UIViewController *vc; - if ([proAct.line_note.noteable_type isEqualToString:@"Commit"]) { - vc = [CommitFilesViewController vcWithPath:request_path]; + }else if ([target_type isEqualToString:@"Wiki"]) { + if ([proAct.action isEqualToString:@"delete"]) { + tipStr = @"删除了,不能看了~"; }else{ - if([request_path rangeOfString:@"merge"].location == NSNotFound) { - vc = [PRDetailViewController vcWithPath:request_path]; - } else { - vc = [MRDetailViewController vcWithPath:request_path]; - } - + linkPath = proAct.wiki_path; } - if (vc) { + }else if ([target_type isEqualToString:@"BranchMember"]){ + if ([@[@"add", @"remove"] containsObject:proAct.action]) { + linkPath = [NSString stringWithFormat:@"/u/%@", proAct.target_user.global_key]; + }else{//deny_push/allow_push + ProjectViewController *vc = [ProjectViewController codeVCWithCodeRef:proAct.ref_name andProject:project]; [self.navigationController pushViewController:vc animated:YES]; + } + }else if ([target_type isEqualToString:@"ProtectedBranch"]){ + ProjectViewController *vc = [ProjectViewController codeVCWithCodeRef:proAct.ref_name andProject:project]; + [self.navigationController pushViewController:vc animated:YES]; + }else if ([target_type isEqualToString:@"Release"]) { + if ([proAct.action isEqualToString:@"delete"]) { + tipStr = @"版本已删除"; }else{ - [NSObject showHudTipStr:@"不知道这是个什么东西o(╯□╰)o~"]; + linkPath = proAct.release_path; } }else{ - if ([target_type isEqualToString:@"Project"]){//这是什么鬼。。遗留的 type 吧 - [NSObject showHudTipStr:@"还不能查看详细信息呢~"]; -// }else if ([target_type isEqualToString:@"MergeRequestComment"]){//过期类型,已用CommitLineNote替代 -// }else if ([target_type isEqualToString:@"PullRequestComment"]){//过期类型,已用CommitLineNote替代 -// }else if ([target_type isEqualToString:@"ProjectStar"]){//不用解析 -// }else if ([target_type isEqualToString:@"ProjectWatcher"]){//不用解析 - }else if ([target_type isEqualToString:@"QcTask"]){//还不能解析 - [NSObject showHudTipStr:@"还不能查看详细信息呢~"]; + if ([target_type isEqualToString:@"Project"]){//转让项目之类的 + // }else if ([target_type isEqualToString:@"MergeRequestComment"]){//过期类型,已用CommitLineNote替代 + // }else if ([target_type isEqualToString:@"PullRequestComment"]){//过期类型,已用CommitLineNote替代 + // }else if ([target_type isEqualToString:@"ProjectStar"]){//不用解析 + // }else if ([target_type isEqualToString:@"ProjectWatcher"]){//不用解析 + // }else if ([target_type isEqualToString:@"QcTask"]){//还不能解析 + }else{ + tipStr = @"还不能查看详细信息呢~"; } } + UIViewController *vc = [BaseViewController analyseVCFromLinkStr:linkPath]; + if (vc) { + [self.navigationController pushViewController:vc animated:YES]; + }else{ + [NSObject showHudTipStr:tipStr]; + } }else{//cell上面第一个Label [self goToUserInfo:[User userWithGlobalKey:[clickedItem.href substringFromIndex:3]]]; } @@ -513,7 +580,9 @@ - (void)goToVCWithItem:(HtmlMediaItem *)clickedItem activity:(ProjectActivity *) #pragma mark Mine M - (void)navRightBtnClicked{ - ProjectViewType curViewType = [self viewTypeFromIndex:_curIndex]; + [_myFliterMenu dismissMenu]; + + ProjectViewType curViewType = [self viewTypeFromIndex:_curType]; switch (curViewType) { case ProjectViewTypeTasks: { @@ -542,7 +611,7 @@ - (void)navRightBtnClicked{ __weak typeof(self) weakSelf = self; AddUserViewController *vc = [[AddUserViewController alloc] init]; vc.curProject = self.myProject; - vc.type = AddUserTypeProjectRoot; + vc.type = kTarget_Enterprise? AddUserTypeProjectCompany: AddUserTypeProjectRoot; if (_proMemberVC && _proMemberVC.myMemberArray) { [vc configAddedArrayWithMembers:_proMemberVC.myMemberArray]; } @@ -554,36 +623,44 @@ - (void)navRightBtnClicked{ [self.navigationController pushViewController:vc animated:YES]; } break; - case ProjectViewTypeFiles: - { - //新建文件夹 - __weak typeof(self) weakSelf = self; - [SettingTextViewController showSettingFolderNameVCFromVC:self withTitle:@"新建文件夹" textValue:nil type:SettingTypeNewFolderName doneBlock:^(NSString *textValue) { - DebugLog(@"%@", textValue); - [[Coding_NetAPIManager sharedManager] request_CreatFolder:textValue inFolder:nil inProject:weakSelf.myProject andBlock:^(id data, NSError *error) { - if (data) { - [NSObject showHudTipStr:@"创建文件夹成功"]; - ProjectFolderListView *folderListView = (ProjectFolderListView *)[weakSelf getCurContentView]; - if (folderListView && [folderListView isKindOfClass:[ProjectFolderListView class]]) { - [folderListView refreshToQueryData]; - } - } - }]; - }]; - - } - break; +// case ProjectViewTypeFiles: +// { +// //新建文件夹 +// __weak typeof(self) weakSelf = self; +// [SettingTextViewController showSettingFolderNameVCFromVC:self withTitle:@"新建文件夹" textValue:nil type:SettingTypeNewFolderName doneBlock:^(NSString *textValue) { +// DebugLog(@"%@", textValue); +// [[Coding_NetAPIManager sharedManager] request_CreatFolder:textValue inFolder:nil inProject:weakSelf.myProject andBlock:^(id data, NSError *error) { +// if (data) { +// [NSObject showHudTipStr:@"创建文件夹成功"]; +// ProjectFolderListView *folderListView = (ProjectFolderListView *)[weakSelf getCurContentView]; +// if (folderListView && [folderListView isKindOfClass:[ProjectFolderListView class]]) { +// [folderListView refreshToQueryData]; +// } +// } +// }]; +// }]; +// +// } +// break; case ProjectViewTypeCodes: { - if ([[FunctionTipsManager shareManager] needToTip:kFunctionTipStr_CommitList]) { - [[FunctionTipsManager shareManager] markTiped:kFunctionTipStr_CommitList]; - [self configRightBarButtonItemWithViewType:ProjectViewTypeCodes]; + NSMutableArray *actionTitles = @[@"上传图片", @"创建文本文件", @"查看提交记录"].mutableCopy; + if (!self.myCodeTree.can_edit) { + [actionTitles removeObjectsInRange:NSMakeRange(0, 2)]; } - //代码提交记录 - ProjectCommitsViewController *vc = [ProjectCommitsViewController new]; - vc.curProject = self.myProject; - vc.curCommits = [Commits commitsWithRef:self.codeRef? self.codeRef: @"master" Path:@""]; - [self.navigationController pushViewController:vc animated:YES]; + __weak typeof(self) weakSelf = self; + [[UIAlertController ea_actionSheetCustomWithTitle:nil buttonTitles:actionTitles destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (!weakSelf.myCodeTree.can_edit) { + index += 2; + } + if (index == 0) { + [(ProjectCodeListView *)[weakSelf getCurContentView] uploadImageClicked]; + }else if (index == 1){ + [(ProjectCodeListView *)[weakSelf getCurContentView] createFileClicked]; + }else if (index == 2){ + [weakSelf goToCommitsVC]; + } + }] showInView:self.view]; } break; default: @@ -591,5 +668,147 @@ - (void)navRightBtnClicked{ } } +- (void)goToCommitsVC{ + //代码提交记录 + ProjectCommitsViewController *vc = [ProjectCommitsViewController new]; + vc.curProject = self.myProject; + vc.curCommits = [Commits commitsWithRef:self.myCodeTree.ref Path:@""]; + [self.navigationController pushViewController:vc animated:YES]; +} + +- (void)screenItemClicked:(UIBarButtonItem *)sender { + [_myFliterMenu dismissMenu]; + [_screenView showOrHide]; +} + +- (void)setupTitleBtn{ + if (!_titleBtn) { + _titleBtn = [UIButton new]; + [_titleBtn setTitleColor:kColorNavTitle forState:UIControlStateNormal]; + [_titleBtn.titleLabel setFont:[UIFont systemFontOfSize:kNavTitleFontSize]]; + [_titleBtn addTarget:self action:@selector(fliterClicked:) forControlEvents:UIControlEventTouchUpInside]; + self.navigationItem.titleView = _titleBtn; + [self setTitleBtnStr:@"所有任务"]; + } +} + +- (void)setTitleBtnStr:(NSString *)titleStr{ + if (_titleBtn) { + CGFloat titleWidth = [titleStr getWidthWithFont:_titleBtn.titleLabel.font constrainedToSize:CGSizeMake(kScreen_Width, 30)]; + CGFloat imageWidth = 12; + CGFloat btnWidth = titleWidth +imageWidth; + _titleBtn.frame = CGRectMake((kScreen_Width-btnWidth)/2, (44-30)/2, btnWidth, 30); + _titleBtn.titleEdgeInsets = UIEdgeInsetsMake(0, -imageWidth, 0, imageWidth); + _titleBtn.imageEdgeInsets = UIEdgeInsetsMake(0, titleWidth, 0, -titleWidth); + [_titleBtn setTitle:titleStr forState:UIControlStateNormal]; + [_titleBtn setImage:[UIImage imageNamed:@"btn_fliter_down"] forState:UIControlStateNormal]; + } +} + +-(void)fliterClicked:(id)sender{ + if (_myFliterMenu.showStatus) { + [_myFliterMenu dismissMenu]; + }else { + [_myFliterMenu showMenuAtView:kKeyWindow]; + } + +} + +- (void)assignmentWithlistView:(ProjectTasksView *)listView { + listView.keyword = self.keyword; + listView.status = self.status; + listView.label = self.label; + listView.userId = self.userId; + listView.role = self.role; + listView.project_id = self.myProject.id.stringValue; +} + +- (void)resetTaskCount { + if (self.curType != ProjectViewTypeTasks) { + return; + } + __weak typeof(self) weakSelf = self; + if (_userId != nil) { + [[Coding_NetAPIManager sharedManager] request_tasks_searchWithUserId:_userId role:TaskRoleTypeAll project_id:_myProject.id.stringValue andBlock:^(id data, NSError *error) { + NSInteger ownerDone = [data[@"data"][@"memberDone"] integerValue]; + NSInteger ownerProcessing = [data[@"data"][@"memberProcessing"] integerValue]; + NSInteger watcherDone = [data[@"data"][@"watcherDone"] integerValue]; + NSInteger watcherProcessing = [data[@"data"][@"watcherProcessing"] integerValue]; + NSInteger creatorDone = [data[@"data"][@"creatorDone"] integerValue]; + NSInteger creatorProcessing = [data[@"data"][@"creatorProcessing"] integerValue]; + weakSelf.myFliterMenu.items = @[[NSString stringWithFormat:@"所有任务(%ld)", ownerDone + ownerProcessing], + [NSString stringWithFormat:@"我关注的(%ld)", watcherDone + watcherProcessing], + [NSString stringWithFormat:@"我创建的(%ld)", creatorDone + creatorProcessing] + ]; + if (_role == TaskRoleTypeAll) { + weakSelf.screenView.tastArray = @[[NSString stringWithFormat:@"进行中的(%ld)", ownerProcessing], + [NSString stringWithFormat:@"已完成的(%ld)", ownerDone] + ]; + } + if (_role == TaskRoleTypeWatcher) { + weakSelf.screenView.tastArray = @[[NSString stringWithFormat:@"进行中的(%ld)", watcherProcessing], + [NSString stringWithFormat:@"已完成的(%ld)", watcherDone] + ]; + } + if (_role == TaskRoleTypeCreator) { + weakSelf.screenView.tastArray = @[[NSString stringWithFormat:@"进行中的(%ld)", creatorProcessing], + [NSString stringWithFormat:@"已完成的(%ld)", creatorDone] + ]; + } + }]; + + } else { + [[Coding_NetAPIManager sharedManager] request_tasks_searchWithUserId:nil role:TaskRoleTypeAll project_id:_myProject.id.stringValue andBlock:^(id data, NSError *error) { + NSInteger ownerDone, ownerProcessing; + + + ownerDone = [data[@"data"][@"done"] integerValue]; + ownerProcessing = [data[@"data"][@"processing"] integerValue]; + + weakSelf.myFliterMenu.items = @[[NSString stringWithFormat:@"所有任务(%ld)", ownerDone + ownerProcessing], + weakSelf.myFliterMenu.items[1], + weakSelf.myFliterMenu.items[2] + ]; + if (_role == TaskRoleTypeAll) { + weakSelf.screenView.tastArray = @[[NSString stringWithFormat:@"进行中的(%ld)", ownerProcessing], + [NSString stringWithFormat:@"已完成的(%ld)", ownerDone] + ]; + } + }]; + [[Coding_NetAPIManager sharedManager] request_tasks_searchWithUserId:nil role:TaskRoleTypeWatcher project_id:_myProject.id.stringValue andBlock:^(id data, NSError *error) { + NSInteger watcherDone = [data[@"data"][@"watcherDone"] integerValue]; + NSInteger watcherProcessing = [data[@"data"][@"watcherProcessing"] integerValue]; + NSInteger creatorDone = [data[@"data"][@"creatorDone"] integerValue]; + NSInteger creatorProcessing = [data[@"data"][@"creatorProcessing"] integerValue]; + weakSelf.myFliterMenu.items = @[weakSelf.myFliterMenu.items[0], + [NSString stringWithFormat:@"我关注的(%ld)", watcherDone + watcherProcessing], + [NSString stringWithFormat:@"我创建的(%ld)", creatorDone + creatorProcessing] + ]; + if (_role == TaskRoleTypeWatcher) { + weakSelf.screenView.tastArray = @[[NSString stringWithFormat:@"进行中的(%ld)", watcherProcessing], + [NSString stringWithFormat:@"已完成的(%ld)", watcherDone] + ]; + } + if (_role == TaskRoleTypeCreator) { + weakSelf.screenView.tastArray = @[[NSString stringWithFormat:@"进行中的(%ld)", creatorProcessing], + [NSString stringWithFormat:@"已完成的(%ld)", creatorDone] + ]; + } + }]; + } +} + +- (void)loadTasksLabels { + if (self.curType != ProjectViewTypeTasks) { + return; + } + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_projects_tasks_labelsWithRole:_role projectId:_myProject.id.stringValue projectName:_myProject.name memberId:_userId owner_user_name:_myProject.owner_user_name andBlock:^(id data, NSError *error) { + if (data != nil) { + weakSelf.screenView.labels = data; + } + }]; +} + @end diff --git a/Coding_iOS/Controllers/RATaskBoardListListViewController.h b/Coding_iOS/Controllers/RATaskBoardListListViewController.h new file mode 100644 index 000000000..db4fca332 --- /dev/null +++ b/Coding_iOS/Controllers/RATaskBoardListListViewController.h @@ -0,0 +1,18 @@ +// +// RATaskBoardListListViewController.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/4/28. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "BaseViewController.h" +#import "ProjectViewController.h" +#import "EABoardTaskList.h" + +@interface RATaskBoardListListViewController : BaseViewController +@property (strong, nonatomic) Project *curPro; +@property (strong, nonatomic) EABoardTaskList *selectedBoardTL; +@property (assign, nonatomic) BOOL needToShowDoneBoardTL; +@property (copy, nonatomic) void(^selectedBlock)(EABoardTaskList *selectedBoardTL); +@end diff --git a/Coding_iOS/Controllers/RATaskBoardListListViewController.m b/Coding_iOS/Controllers/RATaskBoardListListViewController.m new file mode 100644 index 000000000..64d2407ae --- /dev/null +++ b/Coding_iOS/Controllers/RATaskBoardListListViewController.m @@ -0,0 +1,108 @@ +// +// RATaskBoardListListViewController.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/4/28. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "RATaskBoardListListViewController.h" +#import "ValueListCell.h" +#import "Coding_NetAPIManager.h" +#import "ODRefreshControl.h" + +@interface RATaskBoardListListViewController () +@property (strong, nonatomic) UITableView *myTableView; +@property (strong, nonatomic) ODRefreshControl *myRefreshControl; + +@property (strong, nonatomic) NSArray *myBoardTLs; +@end + +@implementation RATaskBoardListListViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + self.title = @"看板列表"; + // 添加myTableView + _myTableView = ({ + UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped]; + tableView.dataSource = self; + tableView.delegate = self; + tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + [tableView registerClass:[ValueListCell class] forCellReuseIdentifier:kCellIdentifier_ValueList]; + tableView.backgroundColor = kColorTableSectionBg; + [self.view addSubview:tableView]; + [tableView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; + tableView; + }); + _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; + [_myRefreshControl addTarget:self action:@selector(refresh) forControlEvents:UIControlEventValueChanged]; + [self refresh]; +} + +- (void)refresh{ + if (_myBoardTLs.count <= 0) { + [self.view beginLoading]; + } + __weak typeof(self) weakSelf = self;; + [[Coding_NetAPIManager sharedManager] request_BoardTaskListsInPro:_curPro andBlock:^(NSArray *data, NSError *error) { + [weakSelf.view endLoading]; + [weakSelf.myRefreshControl endRefreshing]; + if (data) { + weakSelf.myBoardTLs = data; + [weakSelf.myTableView reloadData]; + } + [weakSelf.view configBlankPage:EaseBlankPageTypeView hasData:weakSelf.myBoardTLs.count > 0 hasError:(error != nil) reloadButtonBlock:^(id sender) { + [weakSelf refresh]; + }]; + }]; +} + +#pragma mark TableM + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + return [self.myBoardTLs count]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + ValueListCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_ValueList forIndexPath:indexPath]; + [cell setTitleStr:_myBoardTLs[indexPath.row].title imageStr:nil isSelected:[_selectedBoardTL.id isEqualToNumber:_myBoardTLs[indexPath.row].id]]; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:10]; + return cell; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ + return (!_needToShowDoneBoardTL && _myBoardTLs[indexPath.row].type == EABoardTaskListDone)? 0: 44; +} + +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ + UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 30)]; + headerView.backgroundColor = kColorTableSectionBg; + return headerView; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ + return 30; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ + return 0.5; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + _selectedBoardTL = _myBoardTLs[indexPath.row]; + [self.myTableView reloadData]; + if (self.selectedBlock) { + self.selectedBlock(_selectedBoardTL); + } + [self.navigationController popViewControllerAnimated:YES]; +} + +@end diff --git a/Coding_iOS/Controllers/ReportIllegalViewController.m b/Coding_iOS/Controllers/ReportIllegalViewController.m index ce85ab86a..c120faf43 100644 --- a/Coding_iOS/Controllers/ReportIllegalViewController.m +++ b/Coding_iOS/Controllers/ReportIllegalViewController.m @@ -50,6 +50,9 @@ - (void)viewDidLoad{ [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); diff --git a/Coding_iOS/Controllers/ResetLabelViewController.m b/Coding_iOS/Controllers/ResetLabelViewController.m index c402775de..7179b2bd0 100644 --- a/Coding_iOS/Controllers/ResetLabelViewController.m +++ b/Coding_iOS/Controllers/ResetLabelViewController.m @@ -46,6 +46,9 @@ - (void)viewDidLoad { [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _tempStr = _ptLabel.name; diff --git a/Coding_iOS/Controllers/ReviewCell.m b/Coding_iOS/Controllers/ReviewCell.m index 7df4fc552..720e4aa67 100644 --- a/Coding_iOS/Controllers/ReviewCell.m +++ b/Coding_iOS/Controllers/ReviewCell.m @@ -12,7 +12,7 @@ @implementation ReviewCell - (void)awakeFromNib{ [super awakeFromNib]; - self.userIcon.frame = CGRectMake(12, 5, 33, 33); +// self.userIcon.frame = CGRectMake(12, 5, 33, 33); } - (void)initCellWithReviewer:(User*)reviewer @@ -25,11 +25,11 @@ - (void)initCellWithReviewer:(User*)reviewer self.userState.text = @"+1"; [self.reviewIcon setHidden:NO]; self.reviewIcon.image = [UIImage imageNamed:@"PointLikeHead"]; - self.userState.textColor = kColorBrandGreen; + self.userState.textColor = kColorBrandBlue; } else { [self.reviewIcon setHidden:YES]; self.userState.text = @"未评审"; - self.userState.textColor = kColor999; + self.userState.textColor = kColorDark7; } } @@ -43,7 +43,7 @@ - (void)initCellWithVolunteerReviewers:(User*)reviewer self.userName.text = reviewer.name; if([likeValue isEqual:@100]) { self.userState.text = @"+1"; - self.userState.textColor = kColorBrandGreen; + self.userState.textColor = kColorBrandBlue; } } @@ -58,7 +58,7 @@ - (void)initCellWithUsers:(User*)user{ } + (CGFloat)cellHeight{ - return 44.0; + return 60.0; } @end diff --git a/Coding_iOS/Controllers/ReviewCell.xib b/Coding_iOS/Controllers/ReviewCell.xib index 29aa5036f..7dc864b49 100644 --- a/Coding_iOS/Controllers/ReviewCell.xib +++ b/Coding_iOS/Controllers/ReviewCell.xib @@ -1,25 +1,28 @@ - + + + + - - + - - + + - + - + + - - + + @@ -29,6 +32,7 @@ + @@ -36,22 +40,24 @@ - + - + @@ -63,7 +69,7 @@ - + diff --git a/Coding_iOS/Controllers/ReviewerListController.m b/Coding_iOS/Controllers/ReviewerListController.m index 16c271d2c..43f573d94 100644 --- a/Coding_iOS/Controllers/ReviewerListController.m +++ b/Coding_iOS/Controllers/ReviewerListController.m @@ -43,13 +43,7 @@ -(void)viewDidLoad { -(void)viewWillAppear:(BOOL)animated { if(self.isPublisher) { - UIImage* backImage = [UIImage imageNamed:@"addBtn_Nav"]; - CGRect backframe = CGRectMake(0,0,19,19); - UIButton* addReviewerButton= [[UIButton alloc] initWithFrame:backframe]; - [addReviewerButton setBackgroundImage:backImage forState:UIControlStateNormal]; - [addReviewerButton addTarget:self action:@selector(selectRightAction:) forControlEvents:UIControlEventTouchUpInside]; - UIBarButtonItem* leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:addReviewerButton]; - self.navigationItem.rightBarButtonItem = leftBarButtonItem; + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"addBtn_Nav"] style:UIBarButtonItemStylePlain target:self action:@selector(selectRightAction:)]; } self.delReviewerPath = [NSString stringWithFormat:@"/api/user/%@/project/%@/git/merge/%@/del_reviewer",_curMRPR.des_owner_name, _curMRPR.des_project_name,self.curMRPR.iid]; [self updateData]; @@ -97,18 +91,6 @@ -(void)selectRightAction:(id)sender { } #pragma mark Table M -- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { - return 20; -} - -- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { - return nil; -} - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - return 1; -} - - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.reviewers count]; } @@ -121,7 +103,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } else { [cell initCellWithVolunteerReviewers:cellReviewer.reviewer likeValue:cellReviewer.value]; } - [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:60]; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:70]; return cell; } @@ -130,10 +112,17 @@ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPa } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + //用 cell 去拿数据,特么很迷啊。。 ReviewCell *currentCell = [tableView cellForRowAtIndexPath:indexPath]; - UserInfoViewController *vc = [[UserInfoViewController alloc] init]; - vc.curUser = currentCell.user; - [self.navigationController pushViewController:vc animated:YES]; + if (kTarget_Enterprise) { + UserInfoDetailViewController *vc = [UserInfoDetailViewController new]; + vc.curUser = currentCell.user; + [self.navigationController pushViewController:vc animated:YES]; + }else{ + UserInfoViewController *vc = [[UserInfoViewController alloc] init]; + vc.curUser = currentCell.user; + [self.navigationController pushViewController:vc animated:YES]; + } } #pragma mark SWTableViewCellDelegate diff --git a/Coding_iOS/Controllers/ReviewerListController.xib b/Coding_iOS/Controllers/ReviewerListController.xib index 69a7ffdcb..9a7ea3bd4 100644 --- a/Coding_iOS/Controllers/ReviewerListController.xib +++ b/Coding_iOS/Controllers/ReviewerListController.xib @@ -1,8 +1,11 @@ - + + + + - + @@ -18,6 +21,7 @@ + diff --git a/Coding_iOS/Controllers/RootControllers/BaseNavigationController.h b/Coding_iOS/Controllers/RootControllers/BaseNavigationController.h index 271cff685..7c39e7a3e 100644 --- a/Coding_iOS/Controllers/RootControllers/BaseNavigationController.h +++ b/Coding_iOS/Controllers/RootControllers/BaseNavigationController.h @@ -9,5 +9,6 @@ #import @interface BaseNavigationController : UINavigationController - +- (void)hideNavBottomLine; +- (void)showNavBottomLine; @end diff --git a/Coding_iOS/Controllers/RootControllers/BaseNavigationController.m b/Coding_iOS/Controllers/RootControllers/BaseNavigationController.m index c10f7b607..52cf4684a 100644 --- a/Coding_iOS/Controllers/RootControllers/BaseNavigationController.m +++ b/Coding_iOS/Controllers/RootControllers/BaseNavigationController.m @@ -24,15 +24,24 @@ - (void)viewWillAppear:(BOOL)animated{ [self hideBorderInView:self.navigationBar]; //添新 if (!_navLineV) { - _navLineV = [[UIView alloc]initWithFrame:CGRectMake(0, 44, kScreen_Width, 1.0/ [UIScreen mainScreen].scale)]; - _navLineV.backgroundColor = kColorCCC; + _navLineV = [[UIView alloc]initWithFrame:CGRectMake(0, 44, kScreen_Width, kLine_MinHeight)]; + _navLineV.backgroundColor = kColorD8DDE4; [self.navigationBar addSubview:_navLineV]; } } -- (void)hideBorderInView:(UIView *)view{ +- (void)hideNavBottomLine{ + [self hideBorderInView:self.navigationBar]; + if (_navLineV) { + _navLineV.hidden = YES; + } +} - +- (void)showNavBottomLine{ + _navLineV.hidden = NO; +} + +- (void)hideBorderInView:(UIView *)view{ if ([view isKindOfClass:[UIImageView class]] && view.frame.size.height <= 1) { view.hidden = YES; diff --git a/Coding_iOS/Controllers/RootControllers/BaseViewController.m b/Coding_iOS/Controllers/RootControllers/BaseViewController.m index 0a8fb332c..571fe3d4e 100755 --- a/Coding_iOS/Controllers/RootControllers/BaseViewController.m +++ b/Coding_iOS/Controllers/RootControllers/BaseViewController.m @@ -24,6 +24,7 @@ #import "WebViewController.h" #import "RootTabViewController.h" #import "Message_RootViewController.h" +#import "WikiViewController.h" #import "ProjectCommitsViewController.h" #import "PRDetailViewController.h" @@ -31,8 +32,23 @@ #import "FileViewController.h" #import "CSTopicDetailVC.h" #import "CodeViewController.h" +#import "EACodeReleaseViewController.h" #import "Ease_2FA.h" +#import "Project_RootViewController.h" +#import "MyTask_RootViewController.h" +#import "Tweet_RootViewController.h" +#import "Message_RootViewController.h" +#import "Me_RootViewController.h" +#import "ProjectViewController.h" +#import "EACodeReleaseListViewController.h" +#import "EACodeBranchListViewController.h" +#import "MRPRListViewController.h" +#import "ProjectSettingViewController.h" +#import "CodeListViewController.h" +#import "NFileListViewController.h" +#import "TeamViewController.h" + #import "UnReadManager.h" typedef NS_ENUM(NSInteger, AnalyseMethodType) { @@ -54,6 +70,7 @@ - (void)dismissModalVC{ #pragma mark - BaseViewController @interface BaseViewController () +@property (nonatomic ,strong) NSUserActivity *userActivity; @end @@ -66,7 +83,7 @@ - (void)viewWillAppear:(BOOL)animated [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES]; - if (self.interfaceOrientation != UIInterfaceOrientationPortrait + if (UIApplication.sharedApplication.statusBarOrientation != UIInterfaceOrientationPortrait && !([self supportedInterfaceOrientations] & UIInterfaceOrientationMaskLandscapeLeft)) { [self forceChangeToOrientation:UIInterfaceOrientationPortrait]; } @@ -76,6 +93,7 @@ - (void)viewWillDisappear:(BOOL)animated [super viewWillDisappear:animated]; [MobClick endLogPageView:[NSString stringWithUTF8String:object_getClassName(self)]]; + [_userActivity resignCurrent]; } - (void)viewDidLoad{ @@ -83,19 +101,25 @@ - (void)viewDidLoad{ // self.view.backgroundColor = kColorTableBG; self.view.backgroundColor = kColorTableSectionBg; - if (self.interfaceOrientation != UIInterfaceOrientationPortrait + if (UIApplication.sharedApplication.statusBarOrientation != UIInterfaceOrientationPortrait && !([self supportedInterfaceOrientations] & UIInterfaceOrientationMaskLandscapeLeft)) { [self forceChangeToOrientation:UIInterfaceOrientationPortrait]; } } +- (void)viewDidAppear:(BOOL)animated{ + [super viewDidAppear:animated]; + //Handoff + [self p_setupUserActivity]; +} + - (void)tabBarItemClicked{ DebugLog(@"\ntabBarItemClicked : %@", NSStringFromClass([self class])); } #pragma mark - Orientations - (BOOL)shouldAutorotate{ - return UIInterfaceOrientationIsLandscape(self.interfaceOrientation); + return UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication.statusBarOrientation); } - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { @@ -142,6 +166,637 @@ + (UIViewController *)analyseVCFromLinkStr:(NSString *)linkStr{ return [self analyseVCFromLinkStr:linkStr analyseMethod:AnalyseMethodTypeForceCreate isNewVC:nil]; } ++ (void)presentLinkStr:(NSString *)linkStr{ + if (!linkStr || linkStr.length == 0) { + return; + } + BOOL isNewVC = YES; + UIViewController *vc = [self analyseVCFromLinkStr:linkStr analyseMethod:AnalyseMethodTypeLazyCreate isNewVC:&isNewVC]; + if (vc && isNewVC) { + [self presentVC:vc]; + }else if (!vc){ + if (![linkStr hasPrefix:kCodingAppScheme]) { + //网页 + WebViewController *webVc = [WebViewController webVCWithUrlStr:linkStr]; + [self presentVC:webVc]; + } + } +} + ++ (UIViewController *)presentingVC{ + UIWindow * window = [[UIApplication sharedApplication] keyWindow]; + if (window.windowLevel != UIWindowLevelNormal) + { + NSArray *windows = [[UIApplication sharedApplication] windows]; + for(UIWindow * tmpWin in windows) + { + if (tmpWin.windowLevel == UIWindowLevelNormal) + { + window = tmpWin; + break; + } + } + } + UIViewController *result = window.rootViewController; + while (result.presentedViewController) { + result = result.presentedViewController; + } + if ([result isKindOfClass:[RootTabViewController class]]) { + result = [(RootTabViewController *)result selectedViewController]; + } + if ([result isKindOfClass:[UINavigationController class]]) { + result = [(UINavigationController *)result topViewController]; + } + return result; +} + ++ (void)presentVC:(UIViewController *)viewController{ + if (!viewController) { + return; + } + UINavigationController *nav = [[BaseNavigationController alloc] initWithRootViewController:viewController]; + if (!viewController.navigationItem.leftBarButtonItem) { + viewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"关闭" style:UIBarButtonItemStylePlain target:viewController action:@selector(dismissModalVC)]; + } + [[self presentingVC] presentViewController:nav animated:YES completion:nil]; +} ++ (void)goToVC:(UIViewController *)viewController{ + if (!viewController) { + return; + } + UINavigationController *nav = [self presentingVC].navigationController; + if (nav) { + [nav pushViewController:viewController animated:YES]; + } +} + +#pragma mark Login +- (void)loginOutToLoginVC{ + [Login doLogout]; + [((AppDelegate *)[UIApplication sharedApplication].delegate) setupLoginViewController]; +} + + +#pragma mark (URL - ViewController) 特么,放在这里放瞎了 + +#ifdef Target_Enterprise + +- (void)p_setupUserActivity{ + NSString *webStr = nil; + + // 主 Tab + if ([self isKindOfClass:Project_RootViewController.class]) {//Project + webStr = @"/user/projects"; + }else if ([self isKindOfClass:MyTask_RootViewController.class]){//Task + webStr = [NSString stringWithFormat:@"/user/tasks?owner=%@&status=1", [Login curLoginUser].id]; + }else if ([self isKindOfClass:Message_RootViewController.class]){//Message + webStr = @"/user/messages/basic"; + }else if ([self isKindOfClass:Me_RootViewController.class]){//User + webStr = @"/user/account/setting/basic"; + + // Project + }else if ([self isKindOfClass:NProjectViewController.class]){ + Project *curPro = ((NProjectViewController *)self).myProject; + webStr = [NSString stringWithFormat:@"/p/%@", curPro.name]; + }else if ([self isKindOfClass:ProjectViewController.class]){ + Project *curPro = ((ProjectViewController *)self).myProject; + ProjectViewType type = ((ProjectViewController *)self).curType; + NSString *sufStr = (type == ProjectViewTypeTasks? @"/tasks": + type == ProjectViewTypeFiles? @"/attachment": + type == ProjectViewTypeCodes? @"/git": + type == ProjectViewTypeMembers? @"/setting/member": + type == ProjectViewTypeActivities? @"":@""); + webStr = [NSString stringWithFormat:@"/p/%@%@", curPro.name, sufStr]; + }else if ([self isKindOfClass:EACodeBranchListViewController.class]){ + Project *curPro = ((EACodeBranchListViewController *)self).myProject; + webStr = [NSString stringWithFormat:@"/p/%@/git/branches", curPro.name]; + }else if ([self isKindOfClass:EACodeReleaseListViewController.class]){ + Project *curPro = ((EACodeReleaseListViewController *)self).myProject; + webStr = [NSString stringWithFormat:@"/p/%@/git/releases", curPro.name]; + }else if ([self isKindOfClass:MRPRListViewController.class]){ + Project *curPro = ((MRPRListViewController *)self).curProject; + BOOL isMR = ((MRPRListViewController *)self).isMR; + webStr = [NSString stringWithFormat:@"/p/%@/git/%@", curPro.name, isMR? @"merges": @"pulls/open"]; + }else if ([self isKindOfClass:UserOrProjectTweetsViewController.class]){ + Tweets *curTweets = ((UserOrProjectTweetsViewController *)self).curTweets; + if (curTweets.tweetType == TweetTypeProject) { + webStr = [NSString stringWithFormat:@"/p/%@/setting/notice", curTweets.curPro.name]; + }else if (curTweets.tweetType == TweetTypeUserSingle){ + webStr = [NSString stringWithFormat:@"/u/%@/bubble", curTweets.curUser.global_key]; + } + }else if ([self isKindOfClass:ProjectSettingViewController.class]){ + Project *curPro = ((ProjectSettingViewController *)self).project; + webStr = [NSString stringWithFormat:@"/p/%@/setting", curPro.name]; + + // Task + }else if ([self isKindOfClass:EditTaskViewController.class]){ + Task *curTask = ((EditTaskViewController *)self).myTask; + NSString *project_name = [curTask.backend_project_path componentsSeparatedByString:@"/"].lastObject; + webStr = [NSString stringWithFormat:@"/p/%@/task/%@", project_name, curTask.id]; + + // Tweet + }else if ([self isKindOfClass:TweetDetailViewController.class]){ + Tweet *curTweet = ((TweetDetailViewController *)self).curTweet; + if (curTweet.isProjectTweet) { + webStr = [NSString stringWithFormat:@"/p/%@/setting/notice/%@", curTweet.project.name, curTweet.id]; + }else{ + webStr = [NSString stringWithFormat:@"/u/%@/pp/%@", curTweet.user_global_key ?: curTweet.owner.global_key, curTweet.id]; + } + + // Message + }else if ([self isKindOfClass:ConversationViewController.class]){ + PrivateMessages *curPriMs = ((ConversationViewController *)self).myPriMsgs; + webStr = [NSString stringWithFormat:@"/user/messages/history/%@", curPriMs.curFriend.global_key]; + + // User + }else if ([self isKindOfClass:UserInfoViewController.class]){ + User *curU = ((UserInfoViewController *)self).curUser; + webStr = [NSString stringWithFormat:@"/u/%@", curU.global_key]; + + // Topic/File/MR/Code/Wiki/Release + }else if ([self isKindOfClass:FileViewController.class]){ + ProjectFile *curFile = ((FileViewController *)self).curFile; + if (curFile.project_owner_name && curFile.project_name) { + webStr = curFile.owner_preview; + }else if (curFile.owner_preview){ + webStr = [NSString stringWithFormat:@"/p/%@/attachment/default/preview/%@", curFile.project_name, curFile.file_id]; + } + }else if ([self isKindOfClass:MRDetailViewController.class] || [self isKindOfClass:PRDetailViewController.class]){ + MRPR *curMRPR = [self valueForKey:@"curMRPR"]; + NSString *path = curMRPR.path; + NSRange range = [path rangeOfString:@"/p/"]; + webStr = range.location == NSNotFound? path: [path substringFromIndex:range.location]; + }else if ([self isKindOfClass:CodeViewController.class]){ + Project *curPro = ((CodeViewController *) self).myProject; + CodeFile *curCF = ((CodeViewController *) self).myCodeFile; + webStr = [NSString stringWithFormat:@"/p/%@/git/blob/%@/%@", curPro.name, curCF.ref, curCF.path]; + }else if ([self isKindOfClass:WikiViewController.class]){ + WikiViewController *vc = (WikiViewController *)self; + webStr = [NSString stringWithFormat:@"/p/%@/wiki", vc.myProject.name]; + if (vc.iid) { + webStr = [webStr stringByAppendingFormat:@"/%@", vc.iid]; + if (vc.version.integerValue > 0) { + webStr = [webStr stringByAppendingFormat:@"?version=%@", vc.version]; + } + } + }else if ([self isKindOfClass:EACodeReleaseViewController.class]){ + EACodeRelease *curR = ((EACodeReleaseViewController *)self).curRelease; + webStr = [NSString stringWithFormat:@"/p/%@/git/releases/%@", curR.project.name, curR.tag_name]; + + // CodeList/FileList/Webview + }else if ([self isKindOfClass:CodeListViewController.class]){ + Project *curPro = ((CodeListViewController *) self).myProject; + CodeTree *curCT = ((CodeListViewController *) self).myCodeTree; + webStr = [NSString stringWithFormat:@"/p/%@/git/tree/%@/%@", curPro.name, curCT.ref, curCT.path]; + }else if ([self isKindOfClass:NFileListViewController.class]){ + Project *curPro = ((NFileListViewController *) self).curProject; + ProjectFile *curPF = ((NFileListViewController *) self).curFolder; + webStr = [NSString stringWithFormat:@"/p/%@/attachment/%@", curPro.name, curPF.file_id]; + }else if ([self isKindOfClass:WebViewController.class]){ + webStr = ((WebViewController *)self).request.URL.absoluteString; + } + + if (webStr) { + NSURL *webURL = nil; + if (![webStr hasPrefix:@"http"]) { + webURL = [NSURL URLWithString:webStr relativeToURL:[NSURL URLWithString:[NSObject baseURLStr]]]; + }else{ + webURL = [NSURL URLWithString:webStr]; + } + if (!_userActivity) { + _userActivity = [[NSUserActivity alloc]initWithActivityType:@"com.alex.handoffdemo"]; + _userActivity.title = @"CODING_ENTERPRISE"; + } + [_userActivity setWebpageURL:webURL]; + [_userActivity becomeCurrent]; + } +} + ++ (UIViewController *)analyseVCFromLinkStr:(NSString *)linkStr analyseMethod:(AnalyseMethodType)methodType isNewVC:(BOOL *)isNewVC{ + DebugLog(@"\n analyseVCFromLinkStr : %@", linkStr); + + NSString *lowerLinkStr = linkStr.lowercaseString; + if (!linkStr || linkStr.length <= 0) { + return nil; + }else if (!([linkStr hasPrefix:@"/"] || + [lowerLinkStr hasPrefix:kCodingAppScheme] || + [lowerLinkStr hasPrefix:kBaseUrlStr_Phone] || + [lowerLinkStr hasPrefix:[NSObject baseURLStr].lowercaseString] || + [lowerLinkStr hasPrefix:@"https://coding.net"])){//兼容一下先 + return nil; + } + NSRange pRange = [linkStr rangeOfString:@"/p/"]; + if (pRange.location != NSNotFound && + [linkStr rangeOfString:@"/u/"].location == NSNotFound && + [linkStr rangeOfString:@"/t/"].location == NSNotFound) {//强填 u + NSString *defaultTeamStr = [NSString stringWithFormat:@"/u/%@", [Login curLoginCompany].global_key ?: [NSObject baseCompany]]; + linkStr = [linkStr stringByReplacingCharactersInRange:NSMakeRange(pRange.location, 0) withString:defaultTeamStr]; + } + UIViewController *analyseVC = nil; + UIViewController *presentingVC = nil; + BOOL analyseVCIsNew = YES; + if (methodType != AnalyseMethodTypeForceCreate) { + presentingVC = [BaseViewController presentingVC]; + } + + NSString *teamRegexStr = @"/t/([^/]+)$";//AT某人 + NSString *userRegexStr = @"/u/([^/]+)$";//AT某人 + // NSString *userTweetRegexStr = @"/u/([^/]+)/bubble$";//某人的冒泡 + // NSString *ppRegexStr = @"/u/([^/]+)/pp/([0-9]+)";//冒泡 + NSString *pp_projectRegexStr = @"/[ut]/([^/]+)/p/([^\?]+)[\?]pp=([0-9]+)$";//项目内冒泡(含团队项目) + NSString *topicRegexStr = @"/[ut]/([^/]+)/p/([^/]+)/topic/(\\d+)";//讨论(含团队项目) + NSString *taskRegexStr = @"/[ut]/([^/]+)/p/([^/]+)/task/(\\d+)";//任务(含团队项目) + NSString *fileRegexStr = @"/[ut]/([^/]+)/p/([^/]+)/attachment/([^/]+)/preview/(\\d+)";//文件(含团队项目) + NSString *gitMRPRCommitRegexStr = @"/[ut]/([^/]+)/p/([^/]+)/git/(merge|pull|commit)/([^/#]+)";//MR(含团队项目) + NSString *conversionRegexStr = @"/user/messages/history/([^/]+)$";//私信 + // NSString *pp_topicRegexStr = @"/pp/topic/([0-9]+)$";//话题 + NSString *codeRegexStr = @"/[ut]/([^/]+)/p/([^/]+)/git/blob/([^/]+)[/]?([^?]*)";//代码(含团队项目) + NSString *twoFARegexStr = @"/app_intercept/show_2fa";//两步验证 + NSString *projectRegexStr = @"/[ut]/([^/]+)/p/([^/]+)";//项目(含团队项目) + NSString *noticeRegexStr = @"/[ut]/([^/]+)/p/([^/]+)/setting/notice/(\\d+)";//项目公告 + NSString *wikiRegexStr = @"/[ut]/([^/]+)/p/([^/]+)/wiki/(\\d+)";//Wiki + NSString *releaseRegexStr = @"/[ut]/([^/]+)/p/([^/]+)/git/releases/([^/]+)[/]?([^?]*)";//Release + NSArray *matchedCaptures = nil; + + if ((matchedCaptures = [linkStr captureComponentsMatchedByRegex:teamRegexStr]).count > 0) { + //团队 + TeamViewController *vc = [TeamViewController new]; + NSString *team_global_key = matchedCaptures[1]; + vc.curTeam = [Team teamWithGK:team_global_key]; + analyseVC = vc; + }else if ([linkStr hasSuffix:@"/admin"]){ + //企业 + TeamViewController *vc = [TeamViewController new]; + NSString *team_global_key = [NSObject baseCompany]; + vc.curTeam = [Team teamWithGK:team_global_key]; + analyseVC = vc; + }else if ((matchedCaptures = [linkStr captureComponentsMatchedByRegex:noticeRegexStr]).count > 0){ + //项目公告 + NSString *owner_user_global_key = matchedCaptures[1]; + NSString *project_name = matchedCaptures[2]; + NSString *pp_id = matchedCaptures[3]; + Project *curPro = [Project new]; + curPro.owner_user_name = owner_user_global_key; + curPro.name = project_name; + TweetDetailViewController *vc = [[TweetDetailViewController alloc] init]; + vc.curTweet = [Tweet tweetInProject:curPro andPPID:pp_id]; + analyseVC = vc; + }else if ((matchedCaptures = [linkStr captureComponentsMatchedByRegex:wikiRegexStr]).count > 0){ + WikiViewController *vc = [WikiViewController new]; + Project *curPro = [Project new]; + curPro.owner_user_name = matchedCaptures[1]; + curPro.name = matchedCaptures[2]; + NSString *iid = matchedCaptures[3]; + vc.myProject = curPro; + [vc setWikiIid:@(iid.integerValue) version:nil]; + analyseVC = vc; + }else if ((matchedCaptures = [linkStr captureComponentsMatchedByRegex:releaseRegexStr]).count > 0){ + EACodeReleaseViewController *vc = [EACodeReleaseViewController new]; + Project *curPro = [Project new]; + curPro.owner_user_name = matchedCaptures[1]; + curPro.name = matchedCaptures[2]; + EACodeRelease *curR = [EACodeRelease new]; + curR.project = curPro; + curR.tag_name = matchedCaptures[3]; + vc.curRelease = curR; + analyseVC = vc; + // }else if ((matchedCaptures = [linkStr captureComponentsMatchedByRegex:ppRegexStr]).count > 0){ + // //冒泡 + // NSString *user_global_key = matchedCaptures[1]; + // NSString *pp_id = matchedCaptures[2]; + // if ([presentingVC isKindOfClass:[TweetDetailViewController class]]) { + // TweetDetailViewController *vc = (TweetDetailViewController *)presentingVC; + // if ([vc.curTweet.id.stringValue isEqualToString:pp_id] + // && [vc.curTweet.owner.global_key isEqualToString:user_global_key]) { + // [vc refreshTweet]; + // analyseVCIsNew = NO; + // analyseVC = vc; + // } + // } + // if (!analyseVC) { + // TweetDetailViewController *vc = [[TweetDetailViewController alloc] init]; + // vc.curTweet = [Tweet tweetWithGlobalKey:user_global_key andPPID:pp_id]; + // analyseVC = vc; + // } + }else if ((matchedCaptures = [linkStr captureComponentsMatchedByRegex:pp_projectRegexStr]).count > 0){ + //项目内冒泡 + NSString *owner_user_global_key = matchedCaptures[1]; + NSString *project_name = matchedCaptures[2]; + NSString *pp_id = matchedCaptures[3]; + Project *curPro = [Project new]; + curPro.owner_user_name = owner_user_global_key; + curPro.name = project_name; + TweetDetailViewController *vc = [[TweetDetailViewController alloc] init]; + vc.curTweet = [Tweet tweetInProject:curPro andPPID:pp_id]; + analyseVC = vc; + }else if ((matchedCaptures = [linkStr captureComponentsMatchedByRegex:gitMRPRCommitRegexStr]).count > 0){ + //MR + NSString *path = [matchedCaptures[0] stringByReplacingOccurrencesOfString:@"https://coding.net" withString:@""]; + +// NSString *defaultTeamStr = [NSString stringWithFormat:@"/u/%@", [Login curLoginCompany].global_key ?: [NSObject baseCompany]]; +// linkStr = [linkStr stringByReplacingCharactersInRange:NSMakeRange(pRange.location, 0) withString:defaultTeamStr]; + + + if ([matchedCaptures[3] isEqualToString:@"commit"]) { + if ([presentingVC isKindOfClass:[CommitFilesViewController class]]) { + CommitFilesViewController *vc = (CommitFilesViewController *)presentingVC; + if ([vc.commitId isEqualToString:matchedCaptures[3]] && + [vc.projectName isEqualToString:matchedCaptures[2]] && + [vc.ownerGK isEqualToString:matchedCaptures[1]]) { + [vc refresh]; + analyseVCIsNew = NO; + analyseVC = vc; + } + } + if (!analyseVC) { + analyseVC = [CommitFilesViewController vcWithPath:path]; + } + }else{ + if ([presentingVC isKindOfClass:[PRDetailViewController class]]) { + PRDetailViewController *vc = (PRDetailViewController *)presentingVC; + if ([vc.curMRPR.path isEqualToString:path]) { + [vc refresh]; + analyseVCIsNew = NO; + analyseVC = vc; + } + } + if (!analyseVC) { + if([path rangeOfString:@"merge"].location == NSNotFound) { + analyseVC = [PRDetailViewController vcWithPath:path]; + } else { + analyseVC = [MRDetailViewController vcWithPath:path]; + } + } + } + }else if ((matchedCaptures = [linkStr captureComponentsMatchedByRegex:topicRegexStr]).count > 0){ + //讨论 + NSString *topic_id = matchedCaptures[3]; + if ([presentingVC isKindOfClass:[TopicDetailViewController class]]) { + TopicDetailViewController *vc = (TopicDetailViewController *)presentingVC; + if ([vc.curTopic.id.stringValue isEqualToString:topic_id]) { + [vc refreshTopic]; + analyseVCIsNew = NO; + analyseVC = vc; + } + } + if (!analyseVC) { + TopicDetailViewController *vc = [[TopicDetailViewController alloc] init]; + vc.curTopic = [ProjectTopic topicWithId:[NSNumber numberWithInteger:topic_id.integerValue]]; + analyseVC = vc; + } + }else if ((matchedCaptures = [linkStr captureComponentsMatchedByRegex:taskRegexStr]).count > 0){ + //任务 + NSString *user_global_key = matchedCaptures[1]; + NSString *project_name = matchedCaptures[2]; + NSString *taskId = matchedCaptures[3]; + NSString *backend_project_path = [NSString stringWithFormat:@"/user/%@/project/%@", user_global_key, project_name]; + if ([presentingVC isKindOfClass:[EditTaskViewController class]]) { + EditTaskViewController *vc = (EditTaskViewController *)presentingVC; + if ([vc.myTask.backend_project_path isEqualToString:backend_project_path] + && [vc.myTask.id.stringValue isEqualToString:taskId]) { + [vc queryToRefreshTaskDetail]; + analyseVCIsNew = NO; + analyseVC = vc; + } + } + if (!analyseVC) { + EditTaskViewController *vc = [[EditTaskViewController alloc] init]; + vc.myTask = [Task taskWithBackend_project_path:[NSString stringWithFormat:@"/user/%@/project/%@", user_global_key, project_name] andId:taskId]; + @weakify(vc); + vc.taskChangedBlock = ^(){ + @strongify(vc); + [vc dismissViewControllerAnimated:YES completion:nil]; + }; + analyseVC = vc; + } + }else if ((matchedCaptures = [linkStr captureComponentsMatchedByRegex:fileRegexStr]).count > 0){ + //文件 + NSString *user_global_key = matchedCaptures[1]; + NSString *project_name = matchedCaptures[2]; + NSString *fileId = matchedCaptures[4]; + if ([presentingVC isKindOfClass:[FileViewController class]]) { + FileViewController *vc = (FileViewController *)presentingVC; + if (vc.curFile.file_id.integerValue == fileId.integerValue) { + [vc requestFileData]; + analyseVCIsNew = NO; + analyseVC = vc; + } + } + if (!analyseVC) { + ProjectFile *curFile = [[ProjectFile alloc] initWithFileId:@(fileId.integerValue) inProject:project_name ofUser:user_global_key]; + FileViewController *vc = [FileViewController vcWithFile:curFile andVersion:nil]; + analyseVC = vc; + } + }else if ((matchedCaptures = [linkStr captureComponentsMatchedByRegex:conversionRegexStr]).count > 0) { + //私信 + NSString *user_global_key = matchedCaptures[1]; + if ([presentingVC isKindOfClass:[ConversationViewController class]]) { + ConversationViewController *vc = (ConversationViewController *)presentingVC; + if ([vc.myPriMsgs.curFriend.global_key isEqualToString:user_global_key]) { + [vc doPoll]; + analyseVCIsNew = NO; + analyseVC = vc; + } + } + if (!analyseVC) { + ConversationViewController *vc = [[ConversationViewController alloc] init]; + vc.myPriMsgs = [PrivateMessages priMsgsWithUser:[User userWithGlobalKey:user_global_key]]; + analyseVC = vc; + } + }else if (methodType != AnalyseMethodTypeJustRefresh){ + if ((matchedCaptures = [linkStr captureComponentsMatchedByRegex:userRegexStr]).count > 0) { + //AT某人 + NSString *user_global_key = matchedCaptures[1]; + UserInfoDetailViewController *vc = [UserInfoDetailViewController new]; + vc.curUser = [User userWithGlobalKey:user_global_key]; + analyseVC = vc; + // }else if ((matchedCaptures = [linkStr captureComponentsMatchedByRegex:userTweetRegexStr]).count > 0){ + // //某人的冒泡 + // UserOrProjectTweetsViewController *vc = [[UserOrProjectTweetsViewController alloc] init]; + // NSString *user_global_key = matchedCaptures[1]; + // vc.curTweets = [Tweets tweetsWithUser:[User userWithGlobalKey:user_global_key]]; + // analyseVC = vc; + // }else if ((matchedCaptures = [linkStr captureComponentsMatchedByRegex:pp_topicRegexStr]).count > 0){ + // //话题 + // NSString *pp_topic_id = matchedCaptures[1]; + // CSTopicDetailVC *vc = [CSTopicDetailVC new]; + // vc.topicID = pp_topic_id.integerValue; + // analyseVC = vc; + }else if ((matchedCaptures = [linkStr captureComponentsMatchedByRegex:codeRegexStr]).count > 0){ + //代码 + NSString *user_global_key = matchedCaptures[1]; + NSString *project_name = matchedCaptures[2]; + NSString *ref = matchedCaptures[3]; + NSString *path = matchedCaptures.count >= 5? matchedCaptures[4]: @""; + + Project *curPro = [[Project alloc] init]; + curPro.owner_user_name = user_global_key; + curPro.name = project_name; + CodeFile *codeFile = [CodeFile codeFileWithRef:ref andPath:path]; + CodeViewController *vc = [CodeViewController codeVCWithProject:curPro andCodeFile:codeFile]; + analyseVC = vc; + }else if ((matchedCaptures = [linkStr captureComponentsMatchedByRegex:twoFARegexStr]).count > 0){ + //两步验证 + analyseVC = [OTPListViewController new]; + }else if ((matchedCaptures = [linkStr captureComponentsMatchedByRegex:projectRegexStr]).count > 0){ + //项目 + NSString *user_global_key = matchedCaptures[1]; + NSString *project_name = matchedCaptures[2]; + Project *curPro = [[Project alloc] init]; + curPro.owner_user_name = user_global_key; + curPro.name = project_name; + NProjectViewController *vc = [[NProjectViewController alloc] init]; + vc.myProject = curPro; + analyseVC = vc; + } + } + if (isNewVC) { + *isNewVC = analyseVCIsNew; + } + return analyseVC; +} + +#else + +- (void)p_setupUserActivity{ + NSString *webStr = nil; + + // 主 Tab + if ([self isKindOfClass:Project_RootViewController.class]) {//Project + webStr = @"/user/projects"; + }else if ([self isKindOfClass:MyTask_RootViewController.class]){//Task + webStr = [NSString stringWithFormat:@"/user/tasks?owner=%@&status=1", [Login curLoginUser].id]; + }else if ([self isKindOfClass:Tweet_RootViewController.class]){//Tweet + Tweet_RootViewControllerType type = ((Tweet_RootViewController *)self).type; + webStr = [NSString stringWithFormat:@"/pp%@", (type == Tweet_RootViewControllerTypeHot? @"/hot": + type == Tweet_RootViewControllerTypeFriend? @"/friends": + @"")]; + }else if ([self isKindOfClass:Message_RootViewController.class]){//Message + webStr = @"/user/messages/basic"; + }else if ([self isKindOfClass:Me_RootViewController.class]){//User + webStr = @"/user/account"; + + // Project + }else if ([self isKindOfClass:NProjectViewController.class]){ + Project *curPro = ((NProjectViewController *)self).myProject; + webStr = [NSString stringWithFormat:@"/u/%@/p/%@", curPro.owner_user_name, curPro.name]; + }else if ([self isKindOfClass:ProjectViewController.class]){ + Project *curPro = ((ProjectViewController *)self).myProject; + ProjectViewType type = ((ProjectViewController *)self).curType; + NSString *sufStr = (type == ProjectViewTypeTasks? @"/tasks": + type == ProjectViewTypeFiles? @"/attachment": + type == ProjectViewTypeTopics? @"/topics": + type == ProjectViewTypeCodes? @"/git": + type == ProjectViewTypeMembers? @"/setting/member": + type == ProjectViewTypeActivities? @"":@""); + webStr = [NSString stringWithFormat:@"/u/%@/p/%@%@", curPro.owner_user_name, curPro.name, sufStr]; + }else if ([self isKindOfClass:EACodeBranchListViewController.class]){ + Project *curPro = ((EACodeBranchListViewController *)self).myProject; + webStr = [NSString stringWithFormat:@"/u/%@/p/%@/git/branches", curPro.owner_user_name, curPro.name]; + }else if ([self isKindOfClass:EACodeReleaseListViewController.class]){ + Project *curPro = ((EACodeReleaseListViewController *)self).myProject; + webStr = [NSString stringWithFormat:@"/u/%@/p/%@/git/releases", curPro.owner_user_name, curPro.name]; + }else if ([self isKindOfClass:MRPRListViewController.class]){ + Project *curPro = ((MRPRListViewController *)self).curProject; + BOOL isMR = ((MRPRListViewController *)self).isMR; + webStr = [NSString stringWithFormat:@"/u/%@/p/%@/git/%@", curPro.owner_user_name, curPro.name, isMR? @"merges": @"pulls/open"]; + }else if ([self isKindOfClass:UserOrProjectTweetsViewController.class]){ + Tweets *curTweets = ((UserOrProjectTweetsViewController *)self).curTweets; + if (curTweets.tweetType == TweetTypeProject) { + webStr = [NSString stringWithFormat:@"/u/%@/p/%@/setting/notice", curTweets.curPro.owner_user_name, curTweets.curPro.name]; + }else if (curTweets.tweetType == TweetTypeUserSingle){ + webStr = [NSString stringWithFormat:@"/u/%@/bubble", curTweets.curUser.global_key]; + } + }else if ([self isKindOfClass:ProjectSettingViewController.class]){ + Project *curPro = ((ProjectSettingViewController *)self).project; + webStr = [NSString stringWithFormat:@"/u/%@/p/%@/setting", curPro.owner_user_name, curPro.name]; + + // Task + }else if ([self isKindOfClass:EditTaskViewController.class]){ + Task *curTask = ((EditTaskViewController *)self).myTask; + NSString *project_path = curTask.backend_project_path.copy; + project_path = [[project_path stringByReplacingOccurrencesOfString:@"/user/" withString:@"/u/"] stringByReplacingOccurrencesOfString:@"/project/" withString:@"/p/"]; + webStr = [NSString stringWithFormat:@"%@/task/%@", project_path, curTask.id]; + + // Tweet + }else if ([self isKindOfClass:TweetDetailViewController.class]){ + Tweet *curTweet = ((TweetDetailViewController *)self).curTweet; + if (curTweet.isProjectTweet) { + webStr = [NSString stringWithFormat:@"/u/%@/p/%@/setting/notice/%@", curTweet.project.owner_user_name, curTweet.project.name, curTweet.id]; + }else{ + webStr = [NSString stringWithFormat:@"/u/%@/pp/%@", curTweet.user_global_key ?: curTweet.owner.global_key, curTweet.id]; + } + + // Message + }else if ([self isKindOfClass:ConversationViewController.class]){ + PrivateMessages *curPriMs = ((ConversationViewController *)self).myPriMsgs; + webStr = [NSString stringWithFormat:@"/user/messages/history/%@", curPriMs.curFriend.global_key]; + + // User + }else if ([self isKindOfClass:UserInfoViewController.class]){ + User *curU = ((UserInfoViewController *)self).curUser; + webStr = [NSString stringWithFormat:@"/u/%@", curU.global_key]; + + // Topic/File/MR/Code/Wiki/Release + }else if ([self isKindOfClass:TopicDetailViewController.class]){ + ProjectTopic *curTopic = ((TopicDetailViewController *)self).curTopic; + webStr = [NSString stringWithFormat:@"/u/%@/p/%@/topic/%@", curTopic.project.owner_user_name, curTopic.project.name, curTopic.id]; + }else if ([self isKindOfClass:FileViewController.class]){ + ProjectFile *curFile = ((FileViewController *)self).curFile; + if (curFile.project_owner_name && curFile.project_name) { + webStr = curFile.owner_preview; + }else if (curFile.owner_preview){ + webStr = [NSString stringWithFormat:@"/u/%@/p/%@/attachment/default/preview/%@", curFile.project_owner_name, curFile.project_name, curFile.file_id]; + } + }else if ([self isKindOfClass:MRDetailViewController.class] || [self isKindOfClass:PRDetailViewController.class]){ + MRPR *curMRPR = [self valueForKey:@"curMRPR"]; + webStr = curMRPR.path; + }else if ([self isKindOfClass:CodeViewController.class]){ + Project *curPro = ((CodeViewController *) self).myProject; + CodeFile *curCF = ((CodeViewController *) self).myCodeFile; + webStr = [NSString stringWithFormat:@"/u/%@/p/%@/git/blob/%@/%@", curPro.owner_user_name, curPro.name, curCF.ref, curCF.path]; + }else if ([self isKindOfClass:WikiViewController.class]){ + WikiViewController *vc = (WikiViewController *)self; + webStr = [NSString stringWithFormat:@"/u/%@/p/%@/wiki", vc.myProject.owner_user_name, vc.myProject.name]; + if (vc.iid) { + webStr = [webStr stringByAppendingFormat:@"/%@", vc.iid]; + if (vc.version.integerValue > 0) { + webStr = [webStr stringByAppendingFormat:@"?version=%@", vc.version]; + } + } + }else if ([self isKindOfClass:EACodeReleaseViewController.class]){ + EACodeRelease *curR = ((EACodeReleaseViewController *)self).curRelease; + webStr = [NSString stringWithFormat:@"/u/%@/p/%@/git/releases/%@", curR.project.owner_user_name, curR.project.name, curR.tag_name]; + + // CodeList/FileList/Webview + }else if ([self isKindOfClass:CodeListViewController.class]){ + Project *curPro = ((CodeListViewController *) self).myProject; + CodeTree *curCT = ((CodeListViewController *) self).myCodeTree; + webStr = [NSString stringWithFormat:@"/u/%@/p/%@/git/tree/%@/%@", curPro.owner_user_name, curPro.name, curCT.ref, curCT.path]; + }else if ([self isKindOfClass:NFileListViewController.class]){ + Project *curPro = ((NFileListViewController *) self).curProject; + ProjectFile *curPF = ((NFileListViewController *) self).curFolder; + webStr = [NSString stringWithFormat:@"/u/%@/p/%@/attachment/%@", curPro.owner_user_name, curPro.name, curPF.file_id]; + }else if ([self isKindOfClass:WebViewController.class]){ + webStr = ((WebViewController *)self).request.URL.absoluteString; + } + + if (webStr) { + NSURL *webURL = nil; + if (![webStr hasPrefix:@"http"]) { + webURL = [NSURL URLWithString:webStr relativeToURL:[NSURL URLWithString:[NSObject baseURLStr]]]; + }else{ + webURL = [NSURL URLWithString:webStr]; + } + if (!_userActivity) { + _userActivity = [[NSUserActivity alloc]initWithActivityType:@"com.alex.handoffdemo"]; + _userActivity.title = @"CODING"; + } + [_userActivity setWebpageURL:webURL]; + [_userActivity becomeCurrent]; + } +} + + (UIViewController *)analyseVCFromLinkStr:(NSString *)linkStr analyseMethod:(AnalyseMethodType)methodType isNewVC:(BOOL *)isNewVC{ DebugLog(@"\n analyseVCFromLinkStr : %@", linkStr); @@ -174,6 +829,9 @@ + (UIViewController *)analyseVCFromLinkStr:(NSString *)linkStr analyseMethod:(An NSString *codeRegexStr = @"/[ut]/([^/]+)/p/([^/]+)/git/blob/([^/]+)[/]?([^?]*)";//代码(含团队项目) NSString *twoFARegexStr = @"/app_intercept/show_2fa";//两步验证 NSString *projectRegexStr = @"/[ut]/([^/]+)/p/([^/]+)";//项目(含团队项目) + NSString *noticeRegexStr = @"/[ut]/([^/]+)/p/([^/]+)/setting/notice/(\\d+)";//项目公告 + NSString *wikiRegexStr = @"/[ut]/([^/]+)/p/([^/]+)/wiki/(\\d+)";//Wiki + NSString *releaseRegexStr = @"/[ut]/([^/]+)/p/([^/]+)/git/releases/([^/]+)[/]?([^?]*)";//Release NSArray *matchedCaptures = nil; if ((matchedCaptures = [linkStr captureComponentsMatchedByRegex:ppRegexStr]).count > 0){ //冒泡 @@ -193,6 +851,36 @@ + (UIViewController *)analyseVCFromLinkStr:(NSString *)linkStr analyseMethod:(An vc.curTweet = [Tweet tweetWithGlobalKey:user_global_key andPPID:pp_id]; analyseVC = vc; } + }else if ((matchedCaptures = [linkStr captureComponentsMatchedByRegex:noticeRegexStr]).count > 0){ + //项目公告 + NSString *owner_user_global_key = matchedCaptures[1]; + NSString *project_name = matchedCaptures[2]; + NSString *pp_id = matchedCaptures[3]; + Project *curPro = [Project new]; + curPro.owner_user_name = owner_user_global_key; + curPro.name = project_name; + TweetDetailViewController *vc = [[TweetDetailViewController alloc] init]; + vc.curTweet = [Tweet tweetInProject:curPro andPPID:pp_id]; + analyseVC = vc; + }else if ((matchedCaptures = [linkStr captureComponentsMatchedByRegex:wikiRegexStr]).count > 0){ + WikiViewController *vc = [WikiViewController new]; + Project *curPro = [Project new]; + curPro.owner_user_name = matchedCaptures[1]; + curPro.name = matchedCaptures[2]; + NSString *iid = matchedCaptures[3]; + vc.myProject = curPro; + [vc setWikiIid:@(iid.integerValue) version:nil]; + analyseVC = vc; + }else if ((matchedCaptures = [linkStr captureComponentsMatchedByRegex:releaseRegexStr]).count > 0){ + EACodeReleaseViewController *vc = [EACodeReleaseViewController new]; + Project *curPro = [Project new]; + curPro.owner_user_name = matchedCaptures[1]; + curPro.name = matchedCaptures[2]; + EACodeRelease *curR = [EACodeRelease new]; + curR.project = curPro; + curR.tag_name = matchedCaptures[3]; + vc.curRelease = curR; + analyseVC = vc; }else if ((matchedCaptures = [linkStr captureComponentsMatchedByRegex:pp_projectRegexStr]).count > 0){ //项目内冒泡 NSString *owner_user_global_key = matchedCaptures[1]; @@ -233,7 +921,7 @@ + (UIViewController *)analyseVCFromLinkStr:(NSString *)linkStr analyseMethod:(An } if (!analyseVC) { if([path rangeOfString:@"merge"].location == NSNotFound) { - analyseVC = [PRDetailViewController vcWithPath:path]; + analyseVC = [PRDetailViewController vcWithPath:path]; } else { analyseVC = [MRDetailViewController vcWithPath:path]; } @@ -252,7 +940,12 @@ + (UIViewController *)analyseVCFromLinkStr:(NSString *)linkStr analyseMethod:(An } if (!analyseVC) { TopicDetailViewController *vc = [[TopicDetailViewController alloc] init]; - vc.curTopic = [ProjectTopic topicWithId:[NSNumber numberWithInteger:topic_id.integerValue]]; + ProjectTopic *curTopic = [ProjectTopic topicWithId:[NSNumber numberWithInteger:topic_id.integerValue]]; + Project *curPro = [[Project alloc] init]; + curPro.owner_user_name = matchedCaptures[1]; + curPro.name = matchedCaptures[2]; + curTopic.project = curPro; + vc.curTopic = curTopic; analyseVC = vc; } }else if ((matchedCaptures = [linkStr captureComponentsMatchedByRegex:taskRegexStr]).count > 0){ @@ -367,74 +1060,6 @@ + (UIViewController *)analyseVCFromLinkStr:(NSString *)linkStr analyseMethod:(An return analyseVC; } -+ (void)presentLinkStr:(NSString *)linkStr{ - if (!linkStr || linkStr.length == 0) { - return; - } - BOOL isNewVC = YES; - UIViewController *vc = [self analyseVCFromLinkStr:linkStr analyseMethod:AnalyseMethodTypeLazyCreate isNewVC:&isNewVC]; - if (vc && isNewVC) { - [self presentVC:vc]; - }else if (!vc){ - if (![linkStr hasPrefix:kCodingAppScheme]) { - //网页 - WebViewController *webVc = [WebViewController webVCWithUrlStr:linkStr]; - [self presentVC:webVc]; - } - } -} - -+ (UIViewController *)presentingVC{ - UIWindow * window = [[UIApplication sharedApplication] keyWindow]; - if (window.windowLevel != UIWindowLevelNormal) - { - NSArray *windows = [[UIApplication sharedApplication] windows]; - for(UIWindow * tmpWin in windows) - { - if (tmpWin.windowLevel == UIWindowLevelNormal) - { - window = tmpWin; - break; - } - } - } - UIViewController *result = window.rootViewController; - while (result.presentedViewController) { - result = result.presentedViewController; - } - if ([result isKindOfClass:[RootTabViewController class]]) { - result = [(RootTabViewController *)result selectedViewController]; - } - if ([result isKindOfClass:[UINavigationController class]]) { - result = [(UINavigationController *)result topViewController]; - } - return result; -} - -+ (void)presentVC:(UIViewController *)viewController{ - if (!viewController) { - return; - } - UINavigationController *nav = [[BaseNavigationController alloc] initWithRootViewController:viewController]; - if (!viewController.navigationItem.leftBarButtonItem) { - viewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"关闭" style:UIBarButtonItemStylePlain target:viewController action:@selector(dismissModalVC)]; - } - [[self presentingVC] presentViewController:nav animated:YES completion:nil]; -} -+ (void)goToVC:(UIViewController *)viewController{ - if (!viewController) { - return; - } - UINavigationController *nav = [self presentingVC].navigationController; - if (nav) { - [nav pushViewController:viewController animated:YES]; - } -} - -#pragma mark Login -- (void)loginOutToLoginVC{ - [Login doLogout]; - [((AppDelegate *)[UIApplication sharedApplication].delegate) setupLoginViewController]; -} +#endif @end diff --git a/Coding_iOS/Controllers/RootControllers/Me_RootViewController.m b/Coding_iOS/Controllers/RootControllers/Me_RootViewController.m index 68b77cf42..cbd1a31f1 100755 --- a/Coding_iOS/Controllers/RootControllers/Me_RootViewController.m +++ b/Coding_iOS/Controllers/RootControllers/Me_RootViewController.m @@ -18,6 +18,7 @@ #import "PointRecordsViewController.h" #import "AboutViewController.h" #import "HelpViewController.h" +#import "EditTopicViewController.h" #import "RDVTabBarController.h" #import "RDVTabBarItem.h" @@ -31,21 +32,259 @@ #import "TeamListViewController.h" #import "MeDisplayViewController.h" +#import "FunctionTipsManager.h" +#import "ShopViewController.h" + +#import "MeRootCompanyCell.h" +#import "TeamViewController.h" + + + +#ifdef Target_Enterprise + +@interface Me_RootViewController () +@property (strong, nonatomic) UITableView *myTableView; +@property (nonatomic, strong) ODRefreshControl *refreshControl; + +@property (strong, nonatomic) User *curUser; +@property (strong, nonatomic) Team *curTeam; +@end + +@implementation Me_RootViewController + +- (void)tabBarItemClicked{ + [super tabBarItemClicked]; + if (_myTableView.contentOffset.y > 0) { + [_myTableView setContentOffset:CGPointZero animated:YES]; + }else if (!self.refreshControl.isAnimating){ + [self.refreshControl beginRefreshing]; + [self.myTableView setContentOffset:CGPointMake(0, -44)]; + [self refresh]; + } +} + +- (void)viewDidLoad{ + [super viewDidLoad]; + // Do any additional setup after loading the view. + self.title = @"我"; + _curUser = [Login curLoginUser] ?: [User userWithGlobalKey:@""]; + _curTeam = [Login curLoginCompany] ?: [Team teamWithGK:[NSObject baseCompany]]; + // [self.navigationItem setRightBarButtonItem:[[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"addUserBtn_Nav"] style:UIBarButtonItemStylePlain target:self action:@selector(goToAddUser)] animated:NO]; + + // 添加myTableView + _myTableView = ({ + UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped]; + tableView.backgroundColor = kColorTableSectionBg; + tableView.dataSource = self; + tableView.delegate = self; + tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + [tableView registerClass:[UserInfoIconCell class] forCellReuseIdentifier:kCellIdentifier_UserInfoIconCell]; + [tableView registerClass:[MeRootUserCell class] forCellReuseIdentifier:kCellIdentifier_MeRootUserCell]; + [tableView registerClass:[MeRootCompanyCell class] forCellReuseIdentifier:kCellIdentifier_MeRootCompanyCell]; + [self.view addSubview:tableView]; + [tableView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; + UIEdgeInsets insets = UIEdgeInsetsMake(0, 0, CGRectGetHeight(self.rdv_tabBarController.tabBar.frame), 0); + tableView.contentInset = insets; + tableView.scrollIndicatorInsets = insets; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; + tableView; + }); + + _refreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; + [_refreshControl addTarget:self action:@selector(refresh) forControlEvents:UIControlEventValueChanged]; +} + +- (void)viewWillAppear:(BOOL)animated{ + [super viewWillAppear:animated]; + [self refresh]; +} + +- (void)refresh{ + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_UserInfo_WithObj:_curUser andBlock:^(id data, NSError *error) { + if (data) { + weakSelf.curUser = data; + [[Coding_NetAPIManager sharedManager] request_UpdateIsAdministratorBlock:^(id dataI, NSError *errorI) { + if (dataI) { + weakSelf.curUser.isAdministrator = dataI; + [[Coding_NetAPIManager sharedManager] request_UpdateCompanyInfoBlock:^(id dataC, NSError *errorC) { + if (dataC) { + weakSelf.curTeam = dataC; + } + [weakSelf.myTableView reloadData]; + [weakSelf.refreshControl endRefreshing]; + }]; + }else{ + [weakSelf.myTableView reloadData]; + [weakSelf.refreshControl endRefreshing]; + } + }]; + }else{ + [weakSelf.refreshControl endRefreshing]; + } + }]; +} + +#pragma mark Table M +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ + return 4; +} +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + NSInteger row = (section ==0? 1: + section == 1? _curUser.isAdministrator.boolValue? 1: 0: + section == 2? 1: + 3); + return row; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + if (indexPath.section == 0) { + MeRootUserCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_MeRootUserCell forIndexPath:indexPath]; + cell.curUser = _curUser; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:0]; + return cell; + }else if (indexPath.section == 1){ + MeRootCompanyCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_MeRootCompanyCell forIndexPath:indexPath]; + cell.curCompany = _curTeam; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:0]; + return cell; + }else{ + UserInfoIconCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_UserInfoIconCell forIndexPath:indexPath]; + (indexPath.section == 2? [cell setTitle:@"本地文件" icon:@"user_info_file"]: + indexPath.row == 0? [cell setTitle:@"帮助中心" icon:@"user_info_help"]: + indexPath.row == 1? [cell setTitle:@"设置" icon:@"user_info_setup"]: + [cell setTitle:@"关于我们" icon:@"user_info_about"]); + cell.clipsToBounds = YES; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; + return cell; + } +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ + CGFloat cellHeight = 0; + if (indexPath.section == 0) { + cellHeight = [MeRootUserCell cellHeight]; + }else if (indexPath.section == 1){ + cellHeight = [MeRootCompanyCell cellHeight]; + }else{ + cellHeight = [UserInfoIconCell cellHeight]; + // cellHeight = (indexPath.section == 3 && indexPath.row == 0)? 0: [UserInfoIconCell cellHeight]; + } + return cellHeight; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ + return kLine_MinHeight; +} + +- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{ + return [UIView new]; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ + return section == 0 || (section == 1 && !_curUser.isAdministrator.boolValue)? 1.0/[UIScreen mainScreen].scale: 15; +} + +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ + UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 15)]; + headerView.backgroundColor = kColorTableSectionBg; + return headerView; +} +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + if (indexPath.section == 0) { + [self goToMeDisplay]; + }else if (indexPath.section == 1){ + if (_curUser.isAdministrator.boolValue) { + TeamViewController *vc = [TeamViewController new]; + vc.curTeam = _curTeam; + [self.navigationController pushViewController:vc animated:YES]; + } + }else if (indexPath.section == 2){ + [self goToLocalFolders]; + }else{ + if (indexPath.row == 0) { + [self goToHelp]; + }else if (indexPath.row == 1){ + [self goToSetting]; + }else{ + [self goToAbout]; + } + } +} + +#pragma mark GoTo +- (void)goToAddUser{ + AddUserViewController *vc = [[AddUserViewController alloc] init]; + vc.type = AddUserTypeFollow; + [self.navigationController pushViewController:vc animated:YES]; +} + +- (void)goToLocalFolders{ + LocalFoldersViewController *vc = [LocalFoldersViewController new]; + [self.navigationController pushViewController:vc animated:YES]; +} + +- (void)goToPoint{ + PointRecordsViewController *vc = [PointRecordsViewController new]; + [self.navigationController pushViewController:vc animated:YES]; +} + +- (void)goToSetting{ + SettingViewController *vc = [[SettingViewController alloc] init]; + vc.myUser = self.curUser; + [self.navigationController pushViewController:vc animated:YES]; +} + +- (void)goToHelp{ + [self.navigationController pushViewController:[HelpViewController vcWithHelpStr] animated:YES]; +} + +- (void)goToAbout{ + [self.navigationController pushViewController:[AboutViewController new] animated:YES]; +} + +- (void)goToProjects{ + ProjectListViewController *vc = [[ProjectListViewController alloc] init]; + vc.curUser = _curUser; + vc.isFromMeRoot = YES; + [self.navigationController pushViewController:vc animated:YES]; +} + +- (void)goToTeams{ + [self.navigationController pushViewController:[TeamListViewController new] animated:YES]; +} + +- (void)goToMeDisplay{ + SettingMineInfoViewController *vc = [[SettingMineInfoViewController alloc] init]; + [self.navigationController pushViewController:vc animated:YES]; +} + +@end + +#else + @interface Me_RootViewController () @property (strong, nonatomic) UITableView *myTableView; @property (nonatomic, strong) ODRefreshControl *refreshControl; @property (strong, nonatomic) User *curUser; @property (strong, nonatomic) UserServiceInfo *curServiceInfo; + +@property (assign, nonatomic) BOOL isHeaderClosed; @end @implementation Me_RootViewController - (void)viewDidLoad{ [super viewDidLoad]; // Do any additional setup after loading the view. - self.title = @"我"; - _curUser = [Login curLoginUser]? [Login curLoginUser]: [User userWithGlobalKey:@""]; - [self.navigationItem setRightBarButtonItem:[[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"addUserBtn_Nav"] style:UIBarButtonItemStylePlain target:self action:@selector(goToAddUser)] animated:NO]; + self.title = @"我"; + _curUser = [Login curLoginUser]? [Login curLoginUser]: [User userWithGlobalKey:@""]; + [self.navigationItem setRightBarButtonItem:[[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"addUserBtn_Nav"] style:UIBarButtonItemStylePlain target:self action:@selector(goToAddUser)] animated:NO]; // 添加myTableView _myTableView = ({ @@ -64,11 +303,15 @@ - (void)viewDidLoad{ UIEdgeInsets insets = UIEdgeInsetsMake(0, 0, CGRectGetHeight(self.rdv_tabBarController.tabBar.frame), 0); tableView.contentInset = insets; tableView.scrollIndicatorInsets = insets; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _refreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; [_refreshControl addTarget:self action:@selector(refresh) forControlEvents:UIControlEventValueChanged]; + [self configHeader]; } - (void)viewWillAppear:(BOOL)animated{ @@ -85,6 +328,7 @@ - (void)refresh{ if (dataS) { weakSelf.curServiceInfo = dataS; } + [weakSelf configHeader]; [weakSelf.myTableView reloadData]; [weakSelf.refreshControl endRefreshing]; }]; @@ -94,13 +338,66 @@ - (void)refresh{ }]; } +- (BOOL)p_isHeaderNeedToShow{ + + return (!_isHeaderClosed && (_curUser.canUpgradeByCompleteUserInfo || _curUser.willExpired)); +} +- (void)configHeader{ + BOOL isHeaderNeedToShow = [self p_isHeaderNeedToShow]; + UIView *headerV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, !isHeaderNeedToShow? 1: 40)]; + headerV.backgroundColor = !isHeaderNeedToShow? [UIColor clearColor]: [UIColor colorWithHexString:@"0xECF9FF"]; + if (isHeaderNeedToShow) { + __weak typeof(self) weakSelf = self; + UIButton *closeBtn = [UIButton new]; + [closeBtn setImage:[UIImage imageNamed:@"button_tip_close"] forState:UIControlStateNormal]; + [closeBtn bk_addEventHandler:^(id sender) { + weakSelf.isHeaderClosed = YES; + [weakSelf configHeader]; + } forControlEvents:UIControlEventTouchUpInside]; + [headerV addSubview:closeBtn]; + [closeBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.bottom.right.equalTo(headerV); + make.width.equalTo(closeBtn.mas_height); + }]; + UIImageView *noticeV = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"button_tip_notice"]]; + noticeV.contentMode = UIViewContentModeCenter; + [headerV addSubview:noticeV]; + [noticeV mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.bottom.left.equalTo(headerV); + make.width.equalTo(noticeV.mas_height); + }]; + UILabel *tipL = [UILabel labelWithFont:[UIFont systemFontOfSize:15] textColor:[UIColor colorWithHexString:@"0x136BFB"]]; + tipL.adjustsFontSizeToFitWidth = YES; + tipL.minimumScaleFactor = .5; + tipL.userInteractionEnabled = YES; + // tipL.text = _curUser.canUpgradeByCompleteUserInfo? @"完善个人信息,即可升级银牌会员": [NSString stringWithFormat:@"会员过期将自动降级到%@", _curUser.isUserInfoCompleted? @"银牌会员": @"普通会员"]; + tipL.text = _curUser.canUpgradeByCompleteUserInfo? @"完善个人信息,即可升级银牌会员": @"会员过期后将会自动降级"; + [tipL bk_whenTapped:^{ + if (weakSelf.curUser.canUpgradeByCompleteUserInfo) { + SettingMineInfoViewController *vc = [SettingMineInfoViewController new]; + [weakSelf.navigationController pushViewController:vc animated:YES]; + }else{ + kTipAlert(@"请前往 Coding 网页版进行升级操作"); + } + }]; + [headerV addSubview:tipL]; + [tipL mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(headerV); + make.left.equalTo(noticeV.mas_right); + make.right.equalTo(closeBtn.mas_left); + }]; + } + self.myTableView.tableHeaderView = headerV; + [self.myTableView reloadData]; +} + #pragma mark Table M - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 3; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ NSInteger row = (section ==0? 2: - section == 1? 1: + section == 1? 2: 4); return row; } @@ -118,21 +415,45 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N cell.curServiceInfo = _curServiceInfo; ESWeak(self, weakSelf); cell.leftBlock = ^(){ - [weakSelf goToProjects]; + [weakSelf goToProjectsForPrivate:YES]; }; cell.rightBlock = ^(){ - [weakSelf goToTeams]; + [weakSelf goToProjectsForPrivate:NO]; }; [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:0]; return cell; } }else{ UserInfoIconCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_UserInfoIconCell forIndexPath:indexPath]; - (indexPath.section == 1? [cell setTitle:@"我的码币" icon:@"user_info_point"]: + (indexPath.section == 1? (indexPath.row == 0? [cell setTitle:@"我的码币" icon:@"user_info_point"]: + [cell setTitle:@"商城" icon:@"user_info_shop"]): indexPath.row == 0? [cell setTitle:@"本地文件" icon:@"user_info_file"]: - indexPath.row == 1? [cell setTitle:@"帮助与反馈" icon:@"user_info_help"]: +// indexPath.row == 1? [cell setTitle:@"帮助与反馈" icon:@"user_info_help"]: + indexPath.row == 1? [cell setTitle:@"意见反馈" icon:@"user_info_help"]: indexPath.row == 2? [cell setTitle:@"设置" icon:@"user_info_setup"]: [cell setTitle:@"关于我们" icon:@"user_info_about"]); + + NSInteger pointTag = 101; + [cell.contentView removeViewWithTag:pointTag]; + if (indexPath.section == 1 && indexPath.row == 0) { + UILabel *pointL = [UILabel labelWithFont:[UIFont systemFontOfSize:13] textColor:kColorLightBlue]; + pointL.text = _curServiceInfo.point_left? [NSString stringWithFormat:@"%.2f 码币", _curServiceInfo.point_left.floatValue]: @"-- 码币"; + pointL.tag = pointTag; + [cell.contentView addSubview:pointL]; + [pointL mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(cell.contentView); + make.right.offset(-kPaddingLeftWidth); + }]; + } + // if (indexPath.section == 1 && indexPath.row == 1 && [[FunctionTipsManager shareManager] needToTip:kFunctionTipStr_Me_Shop]) { + //// cell.accessoryType = UITableViewCellAccessoryNone; + // CGFloat pointX = kScreen_Width - 40; + // CGFloat pointY = [UserInfoIconCell cellHeight]/2; + // [cell.contentView addBadgeTip:kBadgeTipStr withCenterPosition:CGPointMake(pointX, pointY)]; + // }else{ + //// cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + // [cell.contentView removeBadgeTips]; + // } [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; return cell; } @@ -143,16 +464,20 @@ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPa if (indexPath.section == 0) { cellHeight = indexPath.row == 0? [MeRootUserCell cellHeight]: [MeRootServiceCell cellHeight]; }else{ - cellHeight = [UserInfoIconCell cellHeight]; + if (indexPath.section == 2 && indexPath.row == 1) { + cellHeight = 0; + }else{ + cellHeight = [UserInfoIconCell cellHeight]; + } } return cellHeight; } - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ - return 1.0/[UIScreen mainScreen].scale; + return kLine_MinHeight; } - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ - return 20; + return (section == 0 && [self p_isHeaderNeedToShow])? kLine_MinHeight: 15; } - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ @@ -168,12 +493,17 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath [self goToMeDisplay]; } }else if (indexPath.section == 1){//我的码币 - [self goToPoint]; + if (indexPath.row == 0) { + [self goToPoint]; + }else{ + [self goToShop]; + } }else{ if (indexPath.row == 0) {//本地文件 [self goToLocalFolders]; }else if (indexPath.row == 1){//帮助与反馈 - [self goToHelp]; +// [self goToHelp]; + [self goToFeedBack]; }else if (indexPath.row == 2){//设置 [self goToSetting]; }else{//关于我们 @@ -199,6 +529,15 @@ - (void)goToPoint{ [self.navigationController pushViewController:vc animated:YES]; } +- (void)goToShop{ + if ([[FunctionTipsManager shareManager] needToTip:kFunctionTipStr_Me_Shop]) { + [[FunctionTipsManager shareManager] markTiped:kFunctionTipStr_Me_Shop]; + [self.myTableView reloadData]; + } + ShopViewController *shopvc = [ShopViewController new]; + [self.navigationController pushViewController:shopvc animated:YES]; +} + - (void)goToSetting{ SettingViewController *vc = [[SettingViewController alloc] init]; vc.myUser = self.curUser; @@ -209,20 +548,36 @@ - (void)goToHelp{ [self.navigationController pushViewController:[HelpViewController vcWithHelpStr] animated:YES]; } +- (void)goToFeedBack{ + EditTopicViewController *vc = [[EditTopicViewController alloc] init]; + vc.curProTopic = [ProjectTopic feedbackTopic]; + vc.type = TopicEditTypeFeedBack; + vc.topicChangedBlock = nil; + [self.navigationController pushViewController:vc animated:YES]; +} + - (void)goToAbout{ [self.navigationController pushViewController:[AboutViewController new] animated:YES]; } -- (void)goToProjects{ +- (void)goToProjectsForPrivate:(BOOL)isForPrivateProjects{ ProjectListViewController *vc = [[ProjectListViewController alloc] init]; vc.curUser = _curUser; vc.isFromMeRoot = YES; + vc.isForPrivateProjects = isForPrivateProjects; [self.navigationController pushViewController:vc animated:YES]; } -- (void)goToTeams{ - [self.navigationController pushViewController:[TeamListViewController new] animated:YES]; -} +//- (void)goToProjects{ +// ProjectListViewController *vc = [[ProjectListViewController alloc] init]; +// vc.curUser = _curUser; +// vc.isFromMeRoot = YES; +// [self.navigationController pushViewController:vc animated:YES]; +//} +// +//- (void)goToTeams{ +// [self.navigationController pushViewController:[TeamListViewController new] animated:YES]; +//} - (void)goToMeDisplay{ MeDisplayViewController *vc = [MeDisplayViewController new]; @@ -231,3 +586,7 @@ - (void)goToMeDisplay{ } @end + +#endif + + diff --git a/Coding_iOS/Controllers/RootControllers/Message_RootViewController.m b/Coding_iOS/Controllers/RootControllers/Message_RootViewController.m index e3374149e..0315fd2a4 100755 --- a/Coding_iOS/Controllers/RootControllers/Message_RootViewController.m +++ b/Coding_iOS/Controllers/RootControllers/Message_RootViewController.m @@ -6,6 +6,8 @@ // Copyright (c) 2014年 Coding. All rights reserved. // +#define kTopItemNum 1 + #import "Message_RootViewController.h" #import "ODRefreshControl.h" #import "Coding_NetAPIManager.h" @@ -24,7 +26,7 @@ @interface Message_RootViewController () @property (nonatomic, strong) UITableView *myTableView; @property (nonatomic, strong) ODRefreshControl *refreshControl; @property (strong, nonatomic) PrivateMessages *myPriMsgs; -@property (strong, nonatomic) NSMutableDictionary *notificationDict; +//@property (strong, nonatomic) NSMutableDictionary *notificationDict; @end @implementation Message_RootViewController @@ -76,6 +78,9 @@ - (void)viewDidLoad tableView.contentInset = insets; tableView.scrollIndicatorInsets = insets; } + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _refreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; @@ -112,18 +117,21 @@ - (void)dealloc{ - (void)sendMsgBtnClicked:(id)sender{ UsersViewController *vc = [[UsersViewController alloc] init]; - vc.curUsers = [Users usersWithOwner:[Login curLoginUser] Type:UsersTypeFriends_Message]; + vc.curUsers = [Users usersWithOwner:[Login curLoginUser] Type:kTarget_Enterprise? UsersType_CompanyMember: UsersTypeFriends_Message]; [self.navigationController pushViewController:vc animated:YES]; } - (void)refresh{ - __weak typeof(self) weakSelf = self; - [[Coding_NetAPIManager sharedManager] request_UnReadNotificationsWithBlock:^(id data, NSError *error) { - if (data) { - weakSelf.notificationDict = [NSMutableDictionary dictionaryWithDictionary:data]; - [weakSelf.myTableView reloadData]; - } - }]; +// __weak typeof(self) weakSelf = self; +// [[Coding_NetAPIManager sharedManager] request_UnReadNotificationsWithBlock:^(id data, NSError *error) { +// if (data) { +// weakSelf.notificationDict = [NSMutableDictionary dictionaryWithDictionary:data]; +// [weakSelf.myTableView reloadData]; +// [weakSelf.myTableView configBlankPage:EaseBlankPageTypeMessageList hasData:(weakSelf.myPriMsgs.list.count > 0) hasError:(error != nil) offsetY:(kTopItemNum * [ToMessageCell cellHeight]) reloadButtonBlock:^(id sender) { +// [weakSelf refresh]; +// }]; +// } +// }]; [[UnReadManager shareManager] updateUnRead]; if (_myPriMsgs.isLoading) { @@ -150,13 +158,16 @@ - (void)sendRequest_PrivateMessages{ [weakSelf.myPriMsgs configWithObj:data]; [weakSelf.myTableView reloadData]; weakSelf.myTableView.showsInfiniteScrolling = weakSelf.myPriMsgs.canLoadMore; + [weakSelf.myTableView configBlankPage:EaseBlankPageTypeMessageList hasData:(weakSelf.myPriMsgs.list.count > 0) hasError:(error != nil) offsetY:(kTopItemNum * [ToMessageCell cellHeight]) reloadButtonBlock:^(id sender) { + [weakSelf refresh]; + }]; } }]; } #pragma mark Table M - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ - NSInteger row = 3; + NSInteger row = kTopItemNum; if (_myPriMsgs.list) { row += [_myPriMsgs.list count]; } @@ -164,27 +175,29 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ - if (indexPath.row < 3) { + if (indexPath.row < kTopItemNum) { ToMessageCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_ToMessage forIndexPath:indexPath]; - switch (indexPath.row) { - case 0: - cell.type = ToMessageTypeAT; - cell.unreadCount = [_notificationDict objectForKey:kUnReadKey_notification_AT]; - break; - case 1: - cell.type = ToMessageTypeComment; - cell.unreadCount = [_notificationDict objectForKey:kUnReadKey_notification_Comment]; - break; - default: - cell.type = ToMessageTypeSystemNotification; - cell.unreadCount = [_notificationDict objectForKey:kUnReadKey_notification_System]; - break; - } + cell.type = ToMessageTypeAllNotification; + cell.unreadCount = [UnReadManager shareManager].notifications; +// switch (indexPath.row) { +// case 0: +// cell.type = ToMessageTypeAT; +// cell.unreadCount = [_notificationDict objectForKey:kUnReadKey_notification_AT]; +// break; +// case 1: +// cell.type = ToMessageTypeComment; +// cell.unreadCount = [_notificationDict objectForKey:kUnReadKey_notification_Comment]; +// break; +// default: +// cell.type = ToMessageTypeSystemNotification; +// cell.unreadCount = [_notificationDict objectForKey:kUnReadKey_notification_System]; +// break; +// } [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:75 hasSectionLine:NO]; return cell; }else{ ConversationCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_Conversation forIndexPath:indexPath]; - PrivateMessage *msg = [_myPriMsgs.list objectAtIndex:indexPath.row-3]; + PrivateMessage *msg = [_myPriMsgs.list objectAtIndex:indexPath.row-kTopItemNum]; cell.curPriMsg = msg; [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:75 hasSectionLine:NO]; return cell; @@ -193,7 +206,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ CGFloat cellHeight; - if (indexPath.row < 3) { + if (indexPath.row < kTopItemNum) { cellHeight = [ToMessageCell cellHeight]; }else{ cellHeight = [ConversationCell cellHeight]; @@ -203,12 +216,13 @@ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPa - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ [tableView deselectRowAtIndexPath:indexPath animated:YES]; - if (indexPath.row < 3) { + if (indexPath.row < kTopItemNum) { TipsViewController *vc = [[TipsViewController alloc] init]; - vc.myCodingTips = [CodingTips codingTipsWithType:indexPath.row]; +// vc.myCodingTips = [CodingTips codingTipsWithType:indexPath.row]; + vc.myCodingTips = [CodingTips codingTipsWithType:ToMessageTypeAllNotification]; [self.navigationController pushViewController:vc animated:YES]; }else{ - PrivateMessage *curMsg = [_myPriMsgs.list objectAtIndex:indexPath.row-3]; + PrivateMessage *curMsg = [_myPriMsgs.list objectAtIndex:indexPath.row-kTopItemNum]; ConversationViewController *vc = [[ConversationViewController alloc] init]; User *curFriend = curMsg.friend; @@ -222,14 +236,14 @@ - (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButto return @"删除会话"; } - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{ - return (indexPath.row >= 3); + return (indexPath.row >= kTopItemNum); } - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{ [tableView setEditing:NO animated:YES]; - PrivateMessage *msg = [_myPriMsgs.list objectAtIndex:indexPath.row-3]; + PrivateMessage *msg = [_myPriMsgs.list objectAtIndex:indexPath.row-kTopItemNum]; __weak typeof(self) weakSelf = self; - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:[NSString stringWithFormat:@"这将删除你和 %@ 的所有私信", msg.friend.name] buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + UIAlertController *actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:[NSString stringWithFormat:@"这将删除你和 %@ 的所有私信", msg.friend.name] buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf removeConversation:msg inTableView:tableView]; } @@ -244,6 +258,9 @@ - (void)removeConversation:(PrivateMessage *)curMsg inTableView:(UITableView *)t if (data) { [weakSelf.myPriMsgs.list removeObject:data]; [weakSelf.myTableView reloadData]; + [weakSelf.myTableView configBlankPage:EaseBlankPageTypeMessageList hasData:(weakSelf.myPriMsgs.list.count > 0) hasError:(error != nil) offsetY:(kTopItemNum * [ToMessageCell cellHeight]) reloadButtonBlock:^(id sender) { + [weakSelf refresh]; + }]; } }]; } diff --git a/Coding_iOS/Controllers/RootControllers/MyTask_RootViewController.m b/Coding_iOS/Controllers/RootControllers/MyTask_RootViewController.m index 510b7c5c9..8442c5382 100755 --- a/Coding_iOS/Controllers/RootControllers/MyTask_RootViewController.m +++ b/Coding_iOS/Controllers/RootControllers/MyTask_RootViewController.m @@ -11,6 +11,8 @@ #import "Coding_NetAPIManager.h" #import "EditTaskViewController.h" #import "RDVTabBarController.h" +#import "TaskSelectionView.h" +#import "ScreenView.h" @interface MyTask_RootViewController () @@ -20,6 +22,16 @@ @interface MyTask_RootViewController () @property (strong, nonatomic) XTSegmentControl *mySegmentControl; @property (strong, nonatomic) iCarousel *myCarousel; + +@property (strong, nonatomic) UIButton *titleBtn; +@property (nonatomic, strong) TaskSelectionView *myFliterMenu; +@property (nonatomic, strong) ScreenView *screenView; + +@property (nonatomic, strong) NSString *keyword; +@property (nonatomic, strong) NSString *status; //任务状态,进行中的为1,已完成的为2 +@property (nonatomic, strong) NSString *label; //任务标签 +@property (nonatomic, strong) NSString *project_id; +@property (nonatomic, assign) TaskRoleType role; @end @implementation MyTask_RootViewController @@ -46,7 +58,7 @@ - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. - self.title = @"我的任务"; + [self setupTitleBtn]; _myProjects = [Projects projectsWithType:ProjectsTypeAll andUser:nil]; _myProTksDict = [[NSMutableDictionary alloc] initWithCapacity:1]; @@ -68,10 +80,54 @@ - (void)viewDidLoad }]; icarousel; }); - self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"addBtn_Nav"] style:UIBarButtonItemStylePlain target:self action:@selector(addItemClicked:)]; + + UIBarButtonItem *addBar = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"addBtn_Nav"] style:UIBarButtonItemStylePlain target:self action:@selector(addItemClicked:)]; + UIBarButtonItem *screenBar = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"task_filter_nav_unchecked"] style:UIBarButtonItemStylePlain target:self action:@selector(screenItemClicked:)]; + self.navigationItem.rightBarButtonItems = @[addBar, screenBar]; + + //初始化过滤目录 + _myFliterMenu = [[TaskSelectionView alloc] initWithFrame:CGRectMake(0, 44 + kSafeArea_Top, kScreen_Width, kScreen_Height - (44 + kSafeArea_Top)) items:@[@"我的任务(0)", @"我关注的(0)", @"我创建的(0)"]]; + __weak typeof(self) weakSelf = self; + _myFliterMenu.clickBlock = ^(NSInteger pageIndex){ + _role = pageIndex; + NSString *title = weakSelf.myFliterMenu.items[pageIndex]; + [weakSelf.titleBtn setTitle:[title substringToIndex:4] forState:UIControlStateNormal]; + ProjectTaskListView *listView = (ProjectTaskListView *)weakSelf.myCarousel.currentItemView; + [weakSelf assignmentWithlistView:listView]; + [listView refresh]; + [weakSelf resetTaskCount]; + [weakSelf loadTasksLabels]; + + }; + _myFliterMenu.closeBlock=^(){ + [weakSelf.myFliterMenu dismissMenu]; + }; + + _screenView = [ScreenView creat]; + weakSelf.screenView.tastArray = @[[NSString stringWithFormat:@"进行中的(0)"], + [NSString stringWithFormat:@"已完成的(0)"] + ]; + _screenView.selectBlock = ^(NSString *keyword, NSString *status, NSString *label) { + weakSelf.keyword = keyword; + weakSelf.status = status; + weakSelf.label = label; + if (keyword == nil && status == nil && label == nil) { + screenBar.image = [[UIImage imageNamed:@"task_filter_nav_unchecked"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + }else{ + screenBar.image = [[UIImage imageNamed:@"task_filter_nav_checked"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; + } + ProjectTaskListView *listView = (ProjectTaskListView *)weakSelf.myCarousel.currentItemView; + [weakSelf assignmentWithlistView:listView]; + [listView refresh]; + + }; } + + - (void)addItemClicked:(id)sender{ + [_myFliterMenu dismissMenu]; + EditTaskViewController *vc = [EditTaskViewController new]; NSInteger curIndex = _myCarousel.currentItemIndex; @@ -82,6 +138,11 @@ - (void)addItemClicked:(id)sender{ [self.navigationController pushViewController:vc animated:YES]; } +- (void)screenItemClicked:(UIBarButtonItem *)sender { + [_myFliterMenu dismissMenu]; + [_screenView showOrHide]; +} + - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; @@ -91,10 +152,21 @@ - (void)didReceiveMemoryWarning - (void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; [self resetCurView]; + [self resetTaskCount]; + [self loadTasksLabels]; + +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + [_myFliterMenu dismissMenu]; } - (void)resetCurView{ + if (!_mySegmentControl) { + [self configSegmentControlWithData:nil]; + } if (!_myProjects.isLoading) { __weak typeof(self) weakSelf = self; [[Coding_NetAPIManager sharedManager] request_ProjectsHaveTasks_WithObj:_myProjects andBlock:^(id data, NSError *error) { @@ -105,23 +177,73 @@ - (void)resetCurView{ } } -- (void)configSegmentControlWithData:(Projects *)freshProjects { - BOOL dataHasChanged = NO; - for (Project *freshPro in freshProjects.list) { - BOOL hasFreshPro = NO; - for (Project *oldPro in self.myProjectList) { - if (freshPro.id.integerValue == oldPro.id.integerValue) { - hasFreshPro = YES; - break; - } +- (void)resetTaskCount { + + __block NSInteger processing, done, watchAll, watchAllProcessing, create, createProcessing; + + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_project_tasks_countWithProjectId:_project_id andBlock:^(id data, NSError *error) { + if (_project_id == nil) { + processing = [data[@"data"][@"processing"] integerValue]; + done = [data[@"data"][@"done"] integerValue]; + + watchAll = [data[@"data"][@"watchAll"] integerValue]; + watchAllProcessing = [data[@"data"][@"watchAllProcessing"] integerValue]; + + create = [data[@"data"][@"create"] integerValue]; + createProcessing = [data[@"data"][@"createProcessing"] integerValue]; + } else { + done = [data[@"data"][@"ownerDone"] integerValue]; + processing = [data[@"data"][@"ownerProcessing"] integerValue]; + + NSInteger watcherDone = [data[@"data"][@"watcherDone"] integerValue]; + watchAllProcessing = [data[@"data"][@"watcherProcessing"] integerValue]; + + NSInteger creatorDone = [data[@"data"][@"creatorDone"] integerValue]; + createProcessing = [data[@"data"][@"creatorProcessing"] integerValue]; + + watchAll = watcherDone + watchAllProcessing; + create = creatorDone + createProcessing; + + } + + weakSelf.myFliterMenu.items = @[[NSString stringWithFormat:@"我的任务(%ld)", processing + done], + [NSString stringWithFormat:@"我关注的(%ld)", watchAll], + [NSString stringWithFormat:@"我创建的(%ld)", create] + ]; + if (weakSelf.role == TaskRoleTypeWatcher) { + processing = watchAllProcessing; + done = watchAll - processing; } - if (!hasFreshPro) { - dataHasChanged = YES; - break; + + if (weakSelf.role == TaskRoleTypeCreator) { + processing = createProcessing; + done = create - processing; } - } + + weakSelf.screenView.tastArray = @[[NSString stringWithFormat:@"进行中的(%ld)", processing], + [NSString stringWithFormat:@"已完成的(%ld)", done] + ]; + + }]; +} + +- (void)loadTasksLabels { + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_projects_tasks_labelsWithRole:_role projectId:_project_id andBlock:^(id data, NSError *error) { + if (data != nil) { + weakSelf.screenView.labels = data; + } + }]; +} + +- (void)configSegmentControlWithData:(Projects *)freshProjects { + NSMutableSet *oldProSet = [[NSSet alloc] initWithArray:[self.myProjectList valueForKey:@"id"]].mutableCopy; + NSMutableSet *freshProSet = [[NSSet alloc] initWithArray:[freshProjects.list valueForKey:@"id"]].mutableCopy; + [oldProSet removeObject:@(-1)];//代表「全部项目」的 id 号 + BOOL dataHasChanged = ![oldProSet isEqualToSet:freshProSet]; - if (dataHasChanged) { + if (dataHasChanged || !_mySegmentControl) { self.myProjectList = [[NSMutableArray alloc] initWithObjects:[Project project_All], nil]; [self.myProjectList addObjectsFromArray:freshProjects.list]; @@ -156,13 +278,14 @@ - (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index curTasks = [Tasks tasksWithPro:curPro queryType:TaskQueryTypeAll]; [_myProTksDict setObject:curTasks forKey:curPro.id]; } - + ProjectTaskListView *listView = (ProjectTaskListView *)view; if (listView) { + [self assignmentWithlistView:listView]; [listView setTasks:curTasks]; }else{ __weak typeof(self) weakSelf = self; - listView = [[ProjectTaskListView alloc] initWithFrame:carousel.bounds tasks:curTasks block:^(ProjectTaskListView *taskListView, Task *task) { + listView = [[ProjectTaskListView alloc] initWithFrame:carousel.bounds tasks:curTasks project_id:curTasks.project.id.stringValue keyword:_keyword status:_status label:_label userId:nil role:_role block:^(ProjectTaskListView *taskListView, Task *task) { EditTaskViewController *vc = [[EditTaskViewController alloc] init]; vc.myTask = task; vc.taskChangedBlock = ^(){ @@ -188,10 +311,61 @@ - (void)carouselCurrentItemIndexDidChange:(iCarousel *)carousel{ _mySegmentControl.currentIndex = carousel.currentItemIndex; } ProjectTaskListView *curView = (ProjectTaskListView *)carousel.currentItemView; + NSInteger index = carousel.currentItemIndex; + if (index == 0) { + _project_id = nil; + } else { + _project_id = ((Project *)_myProjectList[index]).id.stringValue; + } + [self assignmentWithlistView:curView]; + [self resetTaskCount]; + [self loadTasksLabels]; + [curView refreshToQueryData]; [carousel.visibleItemViews enumerateObjectsUsingBlock:^(UIView *obj, NSUInteger idx, BOOL *stop) { [obj setSubScrollsToTop:(obj == carousel.currentItemView)]; }]; } +- (void)setupTitleBtn{ + if (!_titleBtn) { + _titleBtn = [UIButton new]; + [_titleBtn setTitleColor:kColorNavTitle forState:UIControlStateNormal]; + [_titleBtn.titleLabel setFont:[UIFont systemFontOfSize:kNavTitleFontSize]]; + [_titleBtn addTarget:self action:@selector(fliterClicked:) forControlEvents:UIControlEventTouchUpInside]; + self.navigationItem.titleView = _titleBtn; + [self setTitleBtnStr:@"我的任务"]; + } +} + +- (void)setTitleBtnStr:(NSString *)titleStr{ + if (_titleBtn) { + CGFloat titleWidth = [titleStr getWidthWithFont:_titleBtn.titleLabel.font constrainedToSize:CGSizeMake(kScreen_Width, 30)]; + CGFloat imageWidth = 12; + CGFloat btnWidth = titleWidth +imageWidth; + _titleBtn.frame = CGRectMake((kScreen_Width-btnWidth)/2, (44-30)/2, btnWidth, 30); + _titleBtn.titleEdgeInsets = UIEdgeInsetsMake(0, -imageWidth, 0, imageWidth); + _titleBtn.imageEdgeInsets = UIEdgeInsetsMake(0, titleWidth, 0, -titleWidth); + [_titleBtn setTitle:titleStr forState:UIControlStateNormal]; + [_titleBtn setImage:[UIImage imageNamed:@"btn_fliter_down"] forState:UIControlStateNormal]; + } +} + +-(void)fliterClicked:(id)sender{ + if (_myFliterMenu.showStatus) { + [_myFliterMenu dismissMenu]; + }else { + [_myFliterMenu showMenuAtView:kKeyWindow]; + } +} + +- (void)assignmentWithlistView:(ProjectTaskListView *)listView { + listView.keyword = self.keyword; + listView.status = self.status; + listView.label = self.label; + listView.project_id = self.project_id; + listView.role = self.role; +} + + @end diff --git a/Coding_iOS/Controllers/RootControllers/Project_RootViewController.m b/Coding_iOS/Controllers/RootControllers/Project_RootViewController.m index 59331e1f1..48ae8110f 100644 --- a/Coding_iOS/Controllers/RootControllers/Project_RootViewController.m +++ b/Coding_iOS/Controllers/RootControllers/Project_RootViewController.m @@ -31,6 +31,434 @@ #import "OTPListViewController.h" #import "WebViewController.h" #import "ProjectToChooseListViewController.h" +#import "EATerminalViewController.h" +#import "KxMenu.h" + +#ifdef Target_Enterprise + +@interface Project_RootViewController () +@property (strong, nonatomic) NSMutableDictionary *myProjectsDict; +//@property (nonatomic, strong) PopMenu *myPopMenu; +//@property (nonatomic, strong) PopFliterMenu *myFliterMenu; +@property (strong, nonatomic) UIButton *titleBtn; +@property (nonatomic,assign) NSInteger selectNum; //筛选状态 +@end +@implementation Project_RootViewController +#pragma mark TabBar +- (void)tabBarItemClicked{ + [super tabBarItemClicked]; + if (_myCarousel.currentItemView && [_myCarousel.currentItemView isKindOfClass:[ProjectListView class]]) { + ProjectListView *listView = (ProjectListView *)_myCarousel.currentItemView; + [listView tabBarItemClicked]; + } +} + +- (BOOL)isRoot{ + return [self isMemberOfClass:[Project_RootViewController class]]; +} + +- (void)viewDidLoad{ + [super viewDidLoad]; + // Do any additional setup after loading the view. + self.title = @"项目"; + [self configSegmentItems]; + _useNewStyle = TRUE; + _oldSelectedIndex = 0; + _selectNum = 0; + _myProjectsDict = [[NSMutableDictionary alloc] initWithCapacity:_segmentItems.count]; + //添加myCarousel + _myCarousel = ({ + iCarousel *icarousel = [[iCarousel alloc] init]; + icarousel.dataSource = self; + icarousel.delegate = self; + icarousel.decelerationRate = 1.0; + icarousel.scrollSpeed = 1.0; + icarousel.type = iCarouselTypeLinear; + icarousel.pagingEnabled = YES; + icarousel.clipsToBounds = YES; + icarousel.bounceDistance = 0.2; + [self.view addSubview:icarousel]; + [icarousel mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; + icarousel; + }); + // __weak typeof(_myCarousel) weakCarousel = _myCarousel; + // //初始化过滤目录 + // _myFliterMenu = [[PopFliterMenu alloc] initWithFrame:CGRectMake(0, 64, kScreen_Width, kScreen_Height - 64) items:nil]; + // __weak typeof(self) weakSelf = self; + // _myFliterMenu.clickBlock = ^(NSInteger pageIndex){ + // [weakSelf mobClickFliterMenuIndex:pageIndex]; + // if (pageIndex==1000) { + // [weakSelf goToProjectSquareVC]; + // }else{ + // [weakCarousel scrollToItemAtIndex:pageIndex animated:NO]; + // weakSelf.selectNum = pageIndex; + // } + // }; + // _myFliterMenu.closeBlock=^(){ + // [weakSelf closeFliter]; + // }; + //初始化弹出菜单 + // NSArray *menuItems = @[ + // [MenuItem itemWithTitle:@"项目" iconName:@"pop_Project" index:0], + // [MenuItem itemWithTitle:@"任务" iconName:@"pop_Task" index:1], + // [MenuItem itemWithTitle:@"私信" iconName:@"pop_Message" index:4], + //// [MenuItem itemWithTitle:@"两步验证" iconName:@"pop_2FA" index:5], + // ]; + // if (!_myPopMenu) { + // _myPopMenu = [[PopMenu alloc] initWithFrame:CGRectMake(0, 64, kScreen_Width, kScreen_Height-64) items:menuItems]; + // _myPopMenu.perRowItemCount = 3; + // _myPopMenu.menuAnimationType = kPopMenuAnimationTypeSina; + // } + // @weakify(self); + // _myPopMenu.didSelectedItemCompletion = ^(MenuItem *selectedItem){ + // @strongify(self); + // if (!selectedItem) return; + // [MobClick event:kUmeng_Event_Request_ActionOfLocal label:[NSString stringWithFormat:@"首页_添加_%@", selectedItem.title]]; + // switch (selectedItem.index) { + // case 0: + // [self goToNewProjectVC]; + // break; + // case 1: + // [self goToNewTaskVC]; + // break; + // case 2: + // [self goToMessageVC]; + // break; + // case 3: + // [self goTo2FA]; + // break; + // default: + // NSLog(@"%@",selectedItem.title); + // break; + // } + // }; + // if ([self isRoot]) { + // [self setupTitleBtn]; + // } + [self setupNavBtn]; + self.icarouselScrollEnabled = NO; + [[StartImagesManager shareManager] handleStartLink];//如果 start_image 有对应的 link 的话,需要进入到相应的 web 页面 + + [self checkToShowLockedTip]; +} + +- (void)checkToShowLockedTip{ + if ([Login curLoginCompany].locked.boolValue) { + [[UIAlertController ea_alertViewWithTitle:@"服务已暂停" message:@"您订购的服务已过期,项目、任务等功能操作与高级权限将会失效。如需正常使用,请前往企业版网站订购。" buttonTitles:nil destructiveTitle:nil cancelTitle:@"知道了" andDidDismissBlock:nil] show]; + } +} + +- (void)viewWillAppear:(BOOL)animated{ + [super viewWillAppear:animated]; + if (_myCarousel) { + ProjectListView *listView = (ProjectListView *)_myCarousel.currentItemView; + if (listView) { + [listView refreshToQueryData]; + } + } + // [_myFliterMenu refreshMenuDate]; +} + +-(void)viewWillDisappear:(BOOL)animated{ + [super viewWillDisappear:animated]; + // [self closeMenu]; + // if (_myFliterMenu.showStatus) { + // [_myFliterMenu dismissMenu]; + // } +} +- (void)viewDidAppear:(BOOL)animated{ + [super viewDidAppear:animated]; + [[UnReadManager shareManager] updateUnRead]; +} + +- (void)mobClickFliterMenuIndex:(NSInteger)index{ + static NSArray *menuList; + if (!menuList) { + menuList = @[@"全部项目", + @"我创建的", + @"我参与的", + @"我关注的", + @"我收藏的", + @"项目广场"]; + } + [MobClick event:kUmeng_Event_Request_ActionOfLocal label:[NSString stringWithFormat:@"首页_筛选_%@", menuList.count > index? menuList[index]: menuList.lastObject]]; +} + +#pragma mark - sub class method +- (void)setIcarouselScrollEnabled:(BOOL)icarouselScrollEnabled{ + _myCarousel.scrollEnabled = icarouselScrollEnabled; +} +- (void)configSegmentItems{ + _segmentItems = @[@"全部项目",@"我创建的", @"我参与的",@"我关注的",@"我收藏的"]; +} +#pragma mark - nav item +- (void)setupNavBtn{ + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"addBtn_Nav"] style:UIBarButtonItemStylePlain target:self action:@selector(addItemClicked:)]; +} + +//- (void)setupTitleBtn{ +// if (!_titleBtn) { +// _titleBtn = [UIButton new]; +// [_titleBtn setTitleColor:kColorNavTitle forState:UIControlStateNormal]; +// [_titleBtn.titleLabel setFont:[UIFont systemFontOfSize:kNavTitleFontSize]]; +// [_titleBtn addTarget:self action:@selector(fliterClicked:) forControlEvents:UIControlEventTouchUpInside]; +// self.navigationItem.titleView = _titleBtn; +// [self setTitleBtnStr:@"全部项目"]; +// } +//} + +- (void)setTitleBtnStr:(NSString *)titleStr{ + if (_titleBtn) { + CGFloat titleWidth = [titleStr getWidthWithFont:_titleBtn.titleLabel.font constrainedToSize:CGSizeMake(kScreen_Width, 30)]; + CGFloat imageWidth = 12; + CGFloat btnWidth = titleWidth +imageWidth; + _titleBtn.frame = CGRectMake((kScreen_Width-btnWidth)/2, (44-30)/2, btnWidth, 30); + _titleBtn.titleEdgeInsets = UIEdgeInsetsMake(0, -imageWidth, 0, imageWidth); + _titleBtn.imageEdgeInsets = UIEdgeInsetsMake(0, titleWidth, 0, -titleWidth); + [_titleBtn setTitle:titleStr forState:UIControlStateNormal]; + [_titleBtn setImage:[UIImage imageNamed:@"btn_fliter_down"] forState:UIControlStateNormal]; + } +} + +- (void)setSelectNum:(NSInteger)selectNum{ + _selectNum = selectNum; + [self setTitleBtnStr:_segmentItems[_selectNum]]; +} + +-(void)addItemClicked:(id)sender{ + if ([KxMenu isShowingInView:kKeyWindow]) { + [KxMenu dismissMenu:YES]; + }else{ + [KxMenu setTitleFont:[UIFont systemFontOfSize:14]]; + [KxMenu setTintColor:[UIColor whiteColor]]; + [KxMenu setLineColor:kColorDDD]; + [KxMenu setYOffset:CGRectGetMaxY(self.navigationController.navigationBar.frame)]; + + NSMutableArray *menuItems = [@[ + [KxMenuItem menuItem:@"新项目" image:[UIImage imageNamed:@"quick_menu_icon_project"] target:self action:@selector(goToNewProjectVC)], + [KxMenuItem menuItem:@"新任务" image:[UIImage imageNamed:@"quick_menu_icon_task"] target:self action:@selector(goToNewTaskVC)], + [KxMenuItem menuItem:@"新私信" image:[UIImage imageNamed:@"quick_menu_icon_message"] target:self action:@selector(goToMessageVC)], + [KxMenuItem menuItem:@"两步验证" image:[UIImage imageNamed:@"quick_menu_icon_2fa"] target:self action:@selector(goTo2FA)], + ] mutableCopy]; + [menuItems setValue:kColor222 forKey:@"foreColor"]; + CGRect senderFrame = CGRectMake(kScreen_Width - (kDevice_Is_iPhone6Plus? 30: 26), 5, 0, 0); + [KxMenu showMenuInView:kKeyWindow + fromRect:senderFrame + menuItems:menuItems]; + } + + // [self closeFliter]; + // if (!_myPopMenu.isShowed) { + // [_myPopMenu showMenuAtView:kKeyWindow startPoint:CGPointMake(0, -100) endPoint:CGPointMake(0, -100)]; + // } else{ + // [self closeMenu]; + // } +} + +//-(void)fliterClicked:(id)sender{ +// [self closeMenu]; +// if (_myFliterMenu.showStatus == YES) { +// [_myFliterMenu dismissMenu]; +// }else { +// _myFliterMenu.selectNum = _selectNum >= 3? _selectNum + 1: _selectNum; +// [_myFliterMenu showMenuAtView:kKeyWindow]; +// } +//} +//-(void)closeFliter{ +// if ([_myFliterMenu showStatus]) { +// [_myFliterMenu dismissMenu]; +// } +//} +//-(void)closeMenu{ +// if ([_myPopMenu isShowed]) { +// [_myPopMenu dismissMenu]; +// } +//} + +#pragma mark iCarousel M +- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel{ + return _segmentItems.count; +} +- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view{ + Projects *curPros = [_myProjectsDict objectForKey:[NSNumber numberWithUnsignedInteger:index]]; + if (!curPros) { + curPros = [self projectsWithIndex:index]; + [_myProjectsDict setObject:curPros forKey:[NSNumber numberWithUnsignedInteger:index]]; + } + ProjectListView *listView = (ProjectListView *)view; + if (listView) { + [listView setProjects:curPros]; + }else{ + __weak Project_RootViewController *weakSelf = self; + listView = [[ProjectListView alloc] initWithFrame:carousel.bounds projects:curPros block:^(Project *project) { + [weakSelf goToProject:project]; + DebugLog(@"\n=====%@", project.name); + } tabBarHeight:CGRectGetHeight(self.rdv_tabBarController.tabBar.frame)]; + + listView.clickButtonBlock=^(EaseBlankPageType curType) { + switch (curType) { + case EaseBlankPageTypeProject_ALL: + case EaseBlankPageTypeProject_CREATE: + case EaseBlankPageTypeProject_JOIN: + [weakSelf goToNewProjectVC]; + break; + case EaseBlankPageTypeProject_WATCHED: + case EaseBlankPageTypeProject_STARED: + [weakSelf goToProjectSquareVC]; + break; + default: + break; + } + }; + //使用新系列Cell样式 + listView.useNewStyle = _useNewStyle; + // if ([self isRoot]) {//根视图设置,子类不设置 + // [listView setSearchBlock:^{ + // [weakSelf goToSearchVC]; + // } andScanBlock:^{ + // [weakSelf scanBtnClicked]; + // }]; + // } + } + [listView setSubScrollsToTop:(index == carousel.currentItemIndex)]; + return listView; +} + +- (Projects *)projectsWithIndex:(NSUInteger)index{ + return [Projects projectsWithType:index andUser:nil]; +} + +- (void)carouselDidScroll:(iCarousel *)carousel{ + [self.view endEditing:YES]; + if (_mySegmentControl) { + float offset = carousel.scrollOffset; + if (offset > 0) { + [_mySegmentControl moveIndexWithProgress:offset]; + } + } +} + +- (void)carouselCurrentItemIndexDidChange:(iCarousel *)carousel{ + if (_mySegmentControl) { + _mySegmentControl.currentIndex = carousel.currentItemIndex; + } + if (_oldSelectedIndex != carousel.currentItemIndex) { + _oldSelectedIndex = carousel.currentItemIndex; + ProjectListView *curView = (ProjectListView *)carousel.currentItemView; + [curView refreshToQueryData]; + } + [carousel.visibleItemViews enumerateObjectsUsingBlock:^(UIView *obj, NSUInteger idx, BOOL *stop) { + [obj setSubScrollsToTop:(obj == carousel.currentItemView)]; + }]; +} +#pragma mark VC +- (void)goToNewProjectVC{ + UIStoryboard *newProjectStoryboard = [UIStoryboard storyboardWithName:@"NewProject" bundle:nil]; + UIViewController *newProjectVC = [newProjectStoryboard instantiateViewControllerWithIdentifier:@"NewProjectVC"]; + [self.navigationController pushViewController:newProjectVC animated:YES]; +} +- (void)goToNewTaskVC{ + ProjectToChooseListViewController *chooseVC = [[ProjectToChooseListViewController alloc] init]; + [self.navigationController pushViewController:chooseVC animated:YES]; +} + +- (void)goToNewTweetVC{ + TweetSendViewController *vc = [[TweetSendViewController alloc] init]; + vc.sendNextTweet = ^(Tweet *nextTweet){ + [[Coding_NetAPIManager sharedManager] request_Tweet_DoTweet_WithObj:nextTweet andBlock:^(id data, NSError *error) { + if (data) { + [Tweet deleteSendData];//发送成功后删除草稿 + }else{ + [nextTweet saveSendData];//发送失败,保存草稿 + } + }]; + }; + UINavigationController *nav = [[BaseNavigationController alloc] initWithRootViewController:vc]; + [self.parentViewController presentViewController:nav animated:YES completion:nil]; +} +- (void)goTo2FA{ + OTPListViewController *vc = [OTPListViewController new]; + [self.navigationController pushViewController:vc animated:YES]; +} +- (void)goToProject:(Project *)project{ + NProjectViewController *vc = [[NProjectViewController alloc] init]; + vc.myProject = project; + [self.navigationController pushViewController:vc animated:YES]; +} +- (void)goToAddUserVC{ + AddUserViewController *vc = [[AddUserViewController alloc] init]; + vc.type = AddUserTypeFollow; + [self.navigationController pushViewController:vc animated:YES]; +} +- (void)goToMessageVC{ + UsersViewController *vc = [[UsersViewController alloc] init]; + vc.curUsers = [Users usersWithOwner:[Login curLoginUser] Type:UsersType_CompanyMember]; + [self.navigationController pushViewController:vc animated:YES]; +} +- (void)goToProjectSquareVC{ + ProjectSquareViewController *vc=[ProjectSquareViewController new]; + [self.navigationController pushViewController:vc animated:YES]; +} +-(void)goToSearchVC{ + // [self closeFliter]; + // [self closeMenu]; + SearchViewController *vc=[SearchViewController new]; + BaseNavigationController *searchNav=[[BaseNavigationController alloc]initWithRootViewController:vc]; + [self.navigationController presentViewController:searchNav animated:NO completion:nil]; +} +#pragma mark scan QR-Code +- (void)scanBtnClicked{ + [MobClick event:kUmeng_Event_Request_ActionOfLocal label:@"首页_扫描二维码"]; + ZXScanCodeViewController *vc = [ZXScanCodeViewController new]; + __weak typeof(self) weakSelf = self; + vc.scanResultBlock = ^(ZXScanCodeViewController *vc, NSString *resultStr){ + [weakSelf dealWithScanResult:resultStr ofVC:vc]; + }; + [self.navigationController pushViewController:vc animated:YES]; +} +- (void)dealWithScanResult:(NSString *)resultStr ofVC:(ZXScanCodeViewController *)vc{ + if ([OTPListViewController handleScanResult:resultStr ofVC:vc]) { + return; + } + UIViewController *nextVC = [BaseViewController analyseVCFromLinkStr:resultStr]; + NSURL *URL = [NSURL URLWithString:resultStr]; + if (nextVC) { + [self.navigationController pushViewController:nextVC animated:YES]; + }else if ([[URL host] hasSuffix:@"coding.net"]){ + //网页 + WebViewController *webVc = [WebViewController webVCWithUrlStr:resultStr]; + [self.navigationController pushViewController:webVc animated:YES]; + }else if ([[UIApplication sharedApplication] canOpenURL:URL]){ + [[UIAlertController ea_alertViewWithTitle:@"提示" message:[NSString stringWithFormat:@"可能存在风险,是否打开此链接?\n「%@」", resultStr] buttonTitles:@[@"打开链接"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { + [[UIApplication sharedApplication] openURL:URL]; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [self.navigationController popViewControllerAnimated:YES]; + }); + }else{ + [self.navigationController popViewControllerAnimated:YES]; + } + }] show]; + }else if (resultStr.length > 0){ + [[UIAlertController ea_alertViewWithTitle:@"提示" message:[NSString stringWithFormat:@"已识别此二维码内容为:\n「%@」", resultStr] buttonTitles:@[@"复制链接"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { + [[UIPasteboard generalPasteboard] setString:resultStr]; + } + [self.navigationController popViewControllerAnimated:YES]; + }] show]; + }else{ + [[UIAlertController ea_alertViewWithTitle:@"无效条码" message:@"未检测到条码信息" buttonTitles:@[@"重试"] destructiveTitle:nil cancelTitle:nil andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (![vc isScaning]) { + [vc startScan]; + } + }] show]; + } +} +@end + +#else @interface Project_RootViewController () @property (strong, nonatomic) NSMutableDictionary *myProjectsDict; @@ -80,7 +508,7 @@ - (void)viewDidLoad{ }); __weak typeof(_myCarousel) weakCarousel = _myCarousel; //初始化过滤目录 - _myFliterMenu = [[PopFliterMenu alloc] initWithFrame:CGRectMake(0, 64, kScreen_Width, kScreen_Height - 64) items:nil]; + _myFliterMenu = [[PopFliterMenu alloc] initWithFrame:CGRectMake(0, 44 + kSafeArea_Top, kScreen_Width, kScreen_Height - (44 + kSafeArea_Top)) items:nil]; __weak typeof(self) weakSelf = self; _myFliterMenu.clickBlock = ^(NSInteger pageIndex){ [weakSelf mobClickFliterMenuIndex:pageIndex]; @@ -104,7 +532,7 @@ - (void)viewDidLoad{ [MenuItem itemWithTitle:@"两步验证" iconName:@"pop_2FA" index:5], ]; if (!_myPopMenu) { - _myPopMenu = [[PopMenu alloc] initWithFrame:CGRectMake(0, 64, kScreen_Width, kScreen_Height-64) items:menuItems]; + _myPopMenu = [[PopMenu alloc] initWithFrame:CGRectMake(0, 44 + kSafeArea_Top, kScreen_Width, kScreen_Height-(44 + kSafeArea_Top)) items:menuItems]; _myPopMenu.perRowItemCount = 3; _myPopMenu.menuAnimationType = kPopMenuAnimationTypeSina; } @@ -142,7 +570,27 @@ - (void)viewDidLoad{ } [self setupNavBtn]; self.icarouselScrollEnabled = NO; - [[StartImagesManager shareManager] handleStartLink];//如果 start_image 有对应的 link 的话,需要进入到相应的 web 页面 + // [[StartImagesManager shareManager] handleStartLink];//如果 start_image 有对应的 link 的话,需要进入到相应的 web 页面 + // [self setupTerminalButton]; +} + +- (void)setupTerminalButton{ + UIButton *terminalB = [UIButton new]; + terminalB.backgroundColor = [UIColor clearColor]; + [terminalB setImage:[UIImage imageNamed:@"button_terminal"] forState:UIControlStateNormal]; + + __weak typeof(self) weakSelf = self; + [terminalB bk_addEventHandler:^(id sender) { + EATerminalViewController *vc = [EATerminalViewController terminalVC]; + [weakSelf.navigationController pushViewController:vc animated:YES]; + } forControlEvents:UIControlEventTouchUpInside]; + + [self.view addSubview:terminalB]; + [terminalB mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.offset(0); + make.bottom.offset(-weakSelf.rdv_tabBarController.tabBar.height); + make.size.mas_equalTo(CGSizeMake(80, 80)); + }]; } - (void)viewWillAppear:(BOOL)animated{ @@ -205,21 +653,23 @@ - (void)setupTitleBtn{ } - (void)setTitleBtnStr:(NSString *)titleStr{ - if (_titleBtn) { + if (_titleBtn.titleLabel.text.length != titleStr.length) { CGFloat titleWidth = [titleStr getWidthWithFont:_titleBtn.titleLabel.font constrainedToSize:CGSizeMake(kScreen_Width, 30)]; CGFloat imageWidth = 12; CGFloat btnWidth = titleWidth +imageWidth; - _titleBtn.frame = CGRectMake((kScreen_Width-btnWidth)/2, (44-30)/2, btnWidth, 30); + _titleBtn.frame = CGRectMake(0, 0, btnWidth, 30); _titleBtn.titleEdgeInsets = UIEdgeInsetsMake(0, -imageWidth, 0, imageWidth); _titleBtn.imageEdgeInsets = UIEdgeInsetsMake(0, titleWidth, 0, -titleWidth); [_titleBtn setTitle:titleStr forState:UIControlStateNormal]; [_titleBtn setImage:[UIImage imageNamed:@"btn_fliter_down"] forState:UIControlStateNormal]; + }else{ + [_titleBtn setTitle:titleStr forState:UIControlStateNormal]; } } - (void)setSelectNum:(NSInteger)selectNum{ _selectNum = selectNum; - [self setTitleBtnStr:_segmentItems[_selectNum]]; + [self setTitleBtnStr:_segmentItems[MIN(_selectNum, _segmentItems.count - 1)]]; } -(void)addItemClicked:(id)sender{ @@ -230,9 +680,10 @@ -(void)addItemClicked:(id)sender{ [self closeMenu]; } } + -(void)fliterClicked:(id)sender{ [self closeMenu]; - if (_myFliterMenu.showStatus) { + if (_myFliterMenu.showStatus == YES) { [_myFliterMenu dismissMenu]; }else { _myFliterMenu.selectNum = _selectNum >= 3? _selectNum + 1: _selectNum; @@ -300,7 +751,13 @@ - (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index } - (Projects *)projectsWithIndex:(NSUInteger)index{ - return [Projects projectsWithType:index andUser:nil]; + ProjectsType type = (index == 0? ProjectsTypeAll: + index == 1? ProjectsTypeCreated: + index == 2? ProjectsTypeJoined: + index == 3? ProjectsTypeWatched: + index == 4? ProjectsTypeStared: + ProjectsTypeAll); + return [Projects projectsWithType:type andUser:nil]; } - (void)carouselDidScroll:(iCarousel *)carousel{ @@ -333,32 +790,18 @@ - (void)goToNewProjectVC{ [self.navigationController pushViewController:newProjectVC animated:YES]; } - (void)goToNewTaskVC{ - __weak typeof(self) weakSelf = self; ProjectToChooseListViewController *chooseVC = [[ProjectToChooseListViewController alloc] init]; - chooseVC.projectChoosedBlock = ^(ProjectToChooseListViewController *blockChooseVC, Project *project){ - [weakSelf goToNewTaskFromVC:blockChooseVC withPro:project]; - }; [self.navigationController pushViewController:chooseVC animated:YES]; } -- (void)goToNewTaskFromVC:(ProjectToChooseListViewController *)proListVC withPro:(Project *)project{ - EditTaskViewController *taskVC = [EditTaskViewController new]; - taskVC.myTask = [Task taskWithProject:project andUser:[Login curLoginUser]]; - taskVC.myTask.handleType = TaskHandleTypeAddWithoutProject; - __weak typeof(self) weakSelf = self; - taskVC.doneBlock = ^(EditTaskViewController *vc){ - [vc.navigationController popToViewController:weakSelf animated:YES]; - }; - [proListVC.navigationController pushViewController:taskVC animated:YES]; -} - - (void)goToNewTweetVC{ TweetSendViewController *vc = [[TweetSendViewController alloc] init]; vc.sendNextTweet = ^(Tweet *nextTweet){ - [nextTweet saveSendData];//发送前保存草稿 [[Coding_NetAPIManager sharedManager] request_Tweet_DoTweet_WithObj:nextTweet andBlock:^(id data, NSError *error) { if (data) { [Tweet deleteSendData];//发送成功后删除草稿 + }else{ + [nextTweet saveSendData];//发送失败,保存草稿 } }]; }; @@ -418,11 +861,8 @@ - (void)dealWithScanResult:(NSString *)resultStr ofVC:(ZXScanCodeViewController WebViewController *webVc = [WebViewController webVCWithUrlStr:resultStr]; [self.navigationController pushViewController:webVc animated:YES]; }else if ([[UIApplication sharedApplication] canOpenURL:URL]){ - UIAlertView *alertV = [UIAlertView bk_alertViewWithTitle:@"提示" message:[NSString stringWithFormat:@"可能存在风险,是否打开此链接?\n「%@」", resultStr]]; - [alertV bk_setCancelButtonWithTitle:@"取消" handler:nil]; - [alertV bk_addButtonWithTitle:@"打开链接" handler:nil]; - [alertV bk_setWillDismissBlock:^(UIAlertView *al, NSInteger index) { - if (index == 1) { + [[UIAlertController ea_alertViewWithTitle:@"提示" message:[NSString stringWithFormat:@"可能存在风险,是否打开此链接?\n「%@」", resultStr] buttonTitles:@[@"打开链接"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { [[UIApplication sharedApplication] openURL:URL]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self.navigationController popViewControllerAnimated:YES]; @@ -430,27 +870,24 @@ - (void)dealWithScanResult:(NSString *)resultStr ofVC:(ZXScanCodeViewController }else{ [self.navigationController popViewControllerAnimated:YES]; } - }]; - [alertV show]; + }] show]; }else if (resultStr.length > 0){ - UIAlertView *alertV = [UIAlertView bk_alertViewWithTitle:@"提示" message:[NSString stringWithFormat:@"已识别此二维码内容为:\n「%@」", resultStr]]; - [alertV bk_setCancelButtonWithTitle:@"取消" handler:nil]; - [alertV bk_addButtonWithTitle:@"复制链接" handler:nil]; - [alertV bk_setWillDismissBlock:^(UIAlertView *al, NSInteger index) { - if (index == 1) { + [[UIAlertController ea_alertViewWithTitle:@"提示" message:[NSString stringWithFormat:@"已识别此二维码内容为:\n「%@」", resultStr] buttonTitles:@[@"复制链接"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { [[UIPasteboard generalPasteboard] setString:resultStr]; } [self.navigationController popViewControllerAnimated:YES]; - }]; - [alertV show]; + }] show]; }else{ - UIAlertView *alertV = [UIAlertView bk_alertViewWithTitle:@"无效条码" message:@"未检测到条码信息"]; - [alertV bk_addButtonWithTitle:@"重试" handler:^{ + [[UIAlertController ea_alertViewWithTitle:@"无效条码" message:@"未检测到条码信息" buttonTitles:@[@"重试"] destructiveTitle:nil cancelTitle:nil andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (![vc isScaning]) { [vc startScan]; } - }]; - [alertV show]; + }] show]; } } @end + +#endif + + diff --git a/Coding_iOS/Controllers/RootControllers/RootTabViewController.m b/Coding_iOS/Controllers/RootControllers/RootTabViewController.m index f36412698..f009159d0 100644 --- a/Coding_iOS/Controllers/RootControllers/RootTabViewController.m +++ b/Coding_iOS/Controllers/RootControllers/RootTabViewController.m @@ -68,12 +68,6 @@ - (void)setupViewControllers { MyTask_RootViewController *mytask = [[MyTask_RootViewController alloc] init]; UINavigationController *nav_mytask = [[BaseNavigationController alloc] initWithRootViewController:mytask]; - RKSwipeBetweenViewControllers *nav_tweet = [RKSwipeBetweenViewControllers newSwipeBetweenViewControllers]; - [nav_tweet.viewControllerArray addObjectsFromArray:@[[Tweet_RootViewController newTweetVCWithType:Tweet_RootViewControllerTypeAll], - [Tweet_RootViewController newTweetVCWithType:Tweet_RootViewControllerTypeFriend], - [Tweet_RootViewController newTweetVCWithType:Tweet_RootViewControllerTypeHot]]]; - nav_tweet.buttonText = @[@"冒泡广场", @"朋友圈", @"热门冒泡"]; - Message_RootViewController *message = [[Message_RootViewController alloc] init]; RAC(message, rdv_tabBarItem.badgeValue) = [RACSignal combineLatest:@[RACObserve([UnReadManager shareManager], messages), RACObserve([UnReadManager shareManager], notifications)] @@ -94,28 +88,47 @@ - (void)setupViewControllers { Me_RootViewController *me = [[Me_RootViewController alloc] init]; UINavigationController *nav_me = [[BaseNavigationController alloc] initWithRootViewController:me]; - [self setViewControllers:@[nav_project, nav_mytask, nav_tweet, nav_message, nav_me]]; + if (kTarget_Enterprise) { + [self setViewControllers:@[nav_project, nav_mytask, nav_message, nav_me]]; + }else{ + RKSwipeBetweenViewControllers *nav_tweet = [RKSwipeBetweenViewControllers newSwipeBetweenViewControllers]; + [nav_tweet.viewControllerArray addObjectsFromArray:@[[Tweet_RootViewController newTweetVCWithType:Tweet_RootViewControllerTypeAll], + [Tweet_RootViewController newTweetVCWithType:Tweet_RootViewControllerTypeFriend], + [Tweet_RootViewController newTweetVCWithType:Tweet_RootViewControllerTypeHot]]]; + nav_tweet.buttonText = @[@"冒泡广场", @"朋友圈", @"热门冒泡"]; + + [self setViewControllers:@[nav_project, nav_mytask, nav_tweet, nav_message, nav_me]]; + } [self customizeTabBarForController]; self.delegate = self; } - (void)customizeTabBarForController { - UIImage *backgroundImage = [UIImage imageWithColor:kColorNavBG]; - NSArray *tabBarItemImages = @[@"project", @"task", @"tweet", @"privatemessage", @"me"]; - NSArray *tabBarItemTitles = @[@"项目", @"任务", @"冒泡", @"消息", @"我"]; + NSArray *tabBarItemImages; + NSArray *tabBarItemTitles; + if (kTarget_Enterprise) { + tabBarItemImages = @[@"project", @"task", @"privatemessage", @"me"]; + tabBarItemTitles = @[@"项目", @"任务", @"消息", @"我的"]; + }else{ + tabBarItemImages = @[@"project", @"task", @"tweet", @"privatemessage", @"me"]; + tabBarItemTitles = @[@"项目", @"任务", @"冒泡", @"消息", @"我"]; + } NSInteger index = 0; for (RDVTabBarItem *item in [[self tabBar] items]) { item.titlePositionAdjustment = UIOffsetMake(0, 3); - [item setBackgroundSelectedImage:backgroundImage withUnselectedImage:backgroundImage]; UIImage *selectedimage = [UIImage imageNamed:[NSString stringWithFormat:@"%@_selected", [tabBarItemImages objectAtIndex:index]]]; UIImage *unselectedimage = [UIImage imageNamed:[NSString stringWithFormat:@"%@_normal", [tabBarItemImages objectAtIndex:index]]]; [item setFinishedSelectedImage:selectedimage withFinishedUnselectedImage:unselectedimage]; [item setTitle:[tabBarItemTitles objectAtIndex:index]]; + item.badgePositionAdjustment = UIOffsetMake(0, kSafeArea_Bottom / 2); index++; } + [self.tabBar setHeight:49 + kSafeArea_Bottom]; + [self.tabBar setContentEdgeInsets:UIEdgeInsetsMake(kSafeArea_Bottom / 2, 0, 0, 0)]; + self.tabBar.backgroundView.backgroundColor = kColorNavBG; [self.tabBar addLineUp:YES andDown:NO andColor:kColorCCC]; } diff --git a/Coding_iOS/Controllers/RootControllers/Tweet_RootViewController.h b/Coding_iOS/Controllers/RootControllers/Tweet_RootViewController.h index 3ed2e8eaf..43c483deb 100755 --- a/Coding_iOS/Controllers/RootControllers/Tweet_RootViewController.h +++ b/Coding_iOS/Controllers/RootControllers/Tweet_RootViewController.h @@ -20,5 +20,10 @@ typedef NS_ENUM(NSUInteger, Tweet_RootViewControllerType){ @interface Tweet_RootViewController : BaseViewController + +@property (assign, nonatomic, readonly) Tweet_RootViewControllerType type; + + (instancetype)newTweetVCWithType:(Tweet_RootViewControllerType)type; + +- (void)refresh; @end diff --git a/Coding_iOS/Controllers/RootControllers/Tweet_RootViewController.m b/Coding_iOS/Controllers/RootControllers/Tweet_RootViewController.m index 5276efbbb..ecdaea5bf 100755 --- a/Coding_iOS/Controllers/RootControllers/Tweet_RootViewController.m +++ b/Coding_iOS/Controllers/RootControllers/Tweet_RootViewController.m @@ -59,6 +59,10 @@ + (instancetype)newTweetVCWithType:(Tweet_RootViewControllerType)type{ return vc; } +- (Tweet_RootViewControllerType)type{ + return _curIndex; +} + - (instancetype)init { self = [super init]; @@ -99,9 +103,9 @@ - (void)viewDidLoad // [self refreshFirst]; // }]; - UIBarButtonItem *leftBarItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"hot_topic_Nav"] style:UIBarButtonItemStylePlain target:self action:@selector(hotTopicBtnClicked:)]; - - [self.parentViewController.navigationItem setLeftBarButtonItem:leftBarItem animated:NO]; +// UIBarButtonItem *leftBarItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"hot_topic_Nav"] style:UIBarButtonItemStylePlain target:self action:@selector(hotTopicBtnClicked:)]; +// +// [self.parentViewController.navigationItem setLeftBarButtonItem:leftBarItem animated:NO]; _tweetsDict = [[NSMutableDictionary alloc] initWithCapacity:4]; @@ -128,6 +132,9 @@ - (void)viewDidLoad UIEdgeInsets insets = UIEdgeInsetsMake(0, 0, CGRectGetHeight(self.rdv_tabBarController.tabBar.frame), 0); tableView.contentInset = insets; } + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _refreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; @@ -148,14 +155,7 @@ - (void)viewWillDisappear:(BOOL)animated{ - (void)viewDidAppear:(BOOL)animated{ [super viewDidAppear:animated]; - - UIButton *leftItemView = (UIButton *)self.parentViewController.navigationItem.leftBarButtonItem.customView; - if ([[FunctionTipsManager shareManager] needToTip:kFunctionTipStr_Search]) { - [leftItemView addBadgePoint:4 withPointPosition:CGPointMake(25, 0)]; - } - [self refreshFirst]; - // 键盘 if (_myMsgInputView) { [_myMsgInputView prepareToShow]; @@ -205,7 +205,7 @@ - (void)messageInputView:(UIMessageInputView *)inputView sendText:(NSString *)te - (void)messageInputView:(UIMessageInputView *)inputView heightToBottomChenged:(CGFloat)heightToBottom{ [UIView animateWithDuration:0.25 delay:0.0f options:UIViewAnimationOptionTransitionFlipFromBottom animations:^{ UIEdgeInsets contentInsets= UIEdgeInsetsMake(0.0, 0.0, heightToBottom, 0.0);; - CGFloat msgInputY = kScreen_Height - heightToBottom - 64; + CGFloat msgInputY = kScreen_Height - heightToBottom - (44 + kSafeArea_Top); self.myTableView.contentInset = contentInsets; @@ -231,7 +231,6 @@ - (void)sendTweet{ __weak typeof(self) weakSelf = self; TweetSendViewController *vc = [[TweetSendViewController alloc] init]; vc.sendNextTweet = ^(Tweet *nextTweet){ - [nextTweet saveSendData];//发送前保存草稿 [[Coding_NetAPIManager sharedManager] request_Tweet_DoTweet_WithObj:nextTweet andBlock:^(id data, NSError *error) { if (data) { [Tweet deleteSendData];//发送成功后删除草稿 @@ -246,11 +245,16 @@ - (void)sendTweet{ } [self.myTableView reloadData]; } - [weakSelf.view configBlankPage:EaseBlankPageTypeTweet hasData:(curTweets.list.count > 0) hasError:(error != nil) reloadButtonBlock:^(id sender) { + [weakSelf.view configBlankPage:EaseBlankPageTypeTweetAction hasData:(curTweets.list.count > 0) hasError:(error != nil) reloadButtonBlock:^(id sender) { [weakSelf sendRequest]; }]; + //空白页按钮事件 + weakSelf.view.blankPageView.clickButtonBlock=^(EaseBlankPageType curType) { + [weakSelf sendTweet]; + }; + }else{ + [nextTweet saveSendData];//发送失败,保存草稿 } - }]; }; @@ -267,9 +271,13 @@ - (void)deleteTweet:(Tweet *)curTweet outTweetsIndex:(NSInteger)outTweetsIndex{ if (outTweetsIndex == weakSelf.curIndex) { [weakSelf.myTableView reloadData]; } - [weakSelf.view configBlankPage:EaseBlankPageTypeTweet hasData:(curTweets.list.count > 0) hasError:(error != nil) reloadButtonBlock:^(id sender) { + [weakSelf.view configBlankPage:EaseBlankPageTypeTweetAction hasData:(curTweets.list.count > 0) hasError:(error != nil) reloadButtonBlock:^(id sender) { [weakSelf sendRequest]; }]; + //空白页按钮事件 + weakSelf.view.blankPageView.clickButtonBlock=^(EaseBlankPageType curType) { + [weakSelf sendTweet]; + }; } }]; } @@ -312,9 +320,14 @@ - (void)refreshFirst{ [self refresh]; } if (!curTweets.isLoading) { - [self.view configBlankPage:EaseBlankPageTypeTweet hasData:(curTweets.list.count > 0) hasError:NO reloadButtonBlock:^(id sender) { - [self sendRequest]; + __weak typeof(self) weakSelf = self; + [self.view configBlankPage:EaseBlankPageTypeTweetAction hasData:(curTweets.list.count > 0) hasError:NO reloadButtonBlock:^(id sender) { + [weakSelf sendRequest]; }]; + //空白页按钮事件 + self.view.blankPageView.clickButtonBlock=^(EaseBlankPageType curType) { + [weakSelf sendTweet]; + }; } } @@ -352,9 +365,13 @@ - (void)sendRequest{ [weakSelf.myTableView reloadData]; weakSelf.myTableView.showsInfiniteScrolling = curTweets.canLoadMore; } - [weakSelf.view configBlankPage:EaseBlankPageTypeTweet hasData:(curTweets.list.count > 0) hasError:(error != nil) reloadButtonBlock:^(id sender) { + [weakSelf.view configBlankPage:EaseBlankPageTypeTweetAction hasData:(curTweets.list.count > 0) hasError:(error != nil) reloadButtonBlock:^(id sender) { [weakSelf sendRequest]; }]; + //空白页按钮事件 + weakSelf.view.blankPageView.clickButtonBlock=^(EaseBlankPageType curType) { + [weakSelf sendTweet]; + }; }]; } @@ -391,7 +408,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N if ([Login isLoginUserGlobalKey:weakSelf.commentToUser.global_key]) { ESWeakSelf - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"删除此评论" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + UIAlertController *actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"删除此评论" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { ESStrongSelf if (index == 0 && _self.commentIndex >= 0) { Comment *comment = [_self.commentTweet.comment_list objectAtIndex:_self.commentIndex]; @@ -428,7 +445,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N ESWeakSelf - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"删除此冒泡" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + UIAlertController *actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"删除此冒泡" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { ESStrongSelf if (index == 0) { [_self deleteTweet:_self.deleteTweet outTweetsIndex:_self.deleteTweetsIndex]; @@ -469,9 +486,13 @@ - (void)goToDetailWithTweet:(Tweet *)curTweet{ Tweets *curTweets = [weakSelf.tweetsDict objectForKey:[NSNumber numberWithInteger:weakSelf.curIndex]]; [curTweets.list removeObject:toDeleteTweet]; [weakSelf.myTableView reloadData]; - [weakSelf.view configBlankPage:EaseBlankPageTypeTweet hasData:(curTweets.list.count > 0) hasError:NO reloadButtonBlock:^(id sender) { + [weakSelf.view configBlankPage:EaseBlankPageTypeTweetAction hasData:(curTweets.list.count > 0) hasError:NO reloadButtonBlock:^(id sender) { [weakSelf sendRequest]; }]; + //空白页按钮事件 + weakSelf.view.blankPageView.clickButtonBlock=^(EaseBlankPageType curType) { + [weakSelf sendTweet]; + }; }; [self.navigationController pushViewController:vc animated:YES]; } diff --git a/Coding_iOS/Controllers/Search/CSSearchDisplayVC.m b/Coding_iOS/Controllers/Search/CSSearchDisplayVC.m index fdef24e75..8f9d2d33b 100644 --- a/Coding_iOS/Controllers/Search/CSSearchDisplayVC.m +++ b/Coding_iOS/Controllers/Search/CSSearchDisplayVC.m @@ -99,8 +99,8 @@ - (void)setActive:(BOOL)visible animated:(BOOL)animated { _contentView = ({ UIView *view = [[UIView alloc] init]; - view.frame = CGRectMake(0.0f, 60.0f, kScreen_Width, kScreen_Height - 60.0f); - view.backgroundColor = [UIColor clearColor]; + view.frame = CGRectMake(0.0f, 44 + kSafeArea_Top, kScreen_Width, kScreen_Height - (44 + kSafeArea_Top)); + view.backgroundColor = kColorNavBG; view.userInteractionEnabled = YES; UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didClickedContentView:)]; @@ -219,6 +219,9 @@ - (void)initSearchResultsTableView { }); tableView.tableHeaderView = headview; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); } diff --git a/Coding_iOS/Controllers/Search/mock_hotTopiclist.geojson b/Coding_iOS/Controllers/Search/mock_hotTopiclist.geojson index 6799c1bde..06702768f 100644 --- a/Coding_iOS/Controllers/Search/mock_hotTopiclist.geojson +++ b/Coding_iOS/Controllers/Search/mock_hotTopiclist.geojson @@ -1 +1 @@ -{"code":0,"data":[{"watched":false,"user_count":52,"hot_tweet":{"id":59630,"owner_id":446,"owner":{"sex":0,"birthday":"7007-01-01","location":"广东 广州","company":"广州大麦","slogan":"学我者生,似我者死","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/826adb47-69d1-4b80-a05e-5303125d2df6.JPG?imageMogr2/auto-orient/format/jpeg/crop/!559x559a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/826adb47-69d1-4b80-a05e-5303125d2df6.JPG?imageMogr2/auto-orient/format/jpeg/crop/!559x559a0a0","created_at":1405501095000,"last_logined_at":1436405182000,"global_key":"james_cai","name":"james_cai","name_pinyin":"","updated_at":1405501095000,"path":"/u/james_cai","status":1,"is_member":0,"id":446,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437026214000,"likes":0,"comments":0,"comment_list":[],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/218\" rel\u003d\"nofollow\"\u003e#码币#\u003c/a\u003e \u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/smiling_imp.png\" title\u003d\"smiling_imp\"\u003e\u003c/p\u003e","path":"/u/james_cai/pp/59630","activity_id":0,"liked":false,"like_users":[]},"name":"码币","created_at":1433145105000,"id":218,"user_list":[{"sex":0,"birthday":"1983-01-24","location":"四川 成都","company":"成都心动云科技有限公司","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/b8834e515dcb433c20951961967b8d8d.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/b8834e515dcb433c20951961967b8d8d.jpg","created_at":1405563080000,"last_logined_at":1436932265000,"global_key":"itimothy","name":"itimothy","name_pinyin":"","updated_at":1405563080000,"path":"/u/itimothy","status":1,"is_member":0,"id":916,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1993-05-26","location":"广东 广州","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/0735b8c9-e4f6-49e4-b947-0dfee78e842e.jpg?imageMogr2/auto-orient/format/jpeg/crop/!534x534a0a50","gravatar":"https://dn-coding-net-avatar.qbox.me/fbb695ba-7023-47c6-b84b-dd813a0219c3.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/0735b8c9-e4f6-49e4-b947-0dfee78e842e.jpg?imageMogr2/auto-orient/format/jpeg/crop/!534x534a0a50","created_at":1433598571000,"last_logined_at":1436266893000,"global_key":"poorguy","name":"poorguy","name_pinyin":"","updated_at":1433598571000,"path":"/u/poorguy","status":1,"is_member":0,"id":106315,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1970-01-01","location":"江西 南昌","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/45e59eef-7421-4f00-93bb-45c4fd3119f5.png?imageMogr2/auto-orient/format/png/crop/!280x280a0a31","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/45e59eef-7421-4f00-93bb-45c4fd3119f5.png?imageMogr2/auto-orient/format/png/crop/!280x280a0a31","created_at":1405577422000,"last_logined_at":1436511843000,"global_key":"hvsy","name":"苏梦华","name_pinyin":"|smh|sumenghua","updated_at":1405577422000,"path":"/u/hvsy","status":1,"is_member":0,"id":1231,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-07-27","location":"北京 朝阳区","company":"cnepay","slogan":"世界那么大, 我想去看看","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/dedb067ecae8155b87428ac7920dd0ae.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/dedb067ecae8155b87428ac7920dd0ae.jpg","created_at":1405659032000,"last_logined_at":1434873266000,"global_key":"yinheli","name":"yinheli","name_pinyin":"","updated_at":1405659032000,"path":"/u/yinheli","status":1,"is_member":0,"id":1890,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1990-10-31","location":"江苏 苏州","company":"pinklian","slogan":"Making Love Out of Nothing at All","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/d1002613-b448-4a91-8a5f-16fac8ebdf49.jpg?imageMogr2/auto-orient/format/jpeg/crop/!412x412a16a388","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/d1002613-b448-4a91-8a5f-16fac8ebdf49.jpg?imageMogr2/auto-orient/format/jpeg/crop/!412x412a16a388","created_at":1413989470000,"last_logined_at":1436850094000,"global_key":"desmond","name":"desmond","name_pinyin":"","updated_at":1413989470000,"path":"/u/desmond","status":1,"is_member":0,"id":36755,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1991-06-21","location":"江苏 南京","company":"viva tech","slogan":"KEEP SIMPLE","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9081b035-427f-40cb-89f4-8cff6664da6f.jpg?imageMogr2/auto-orient/format/jpeg/crop/!400x400a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9081b035-427f-40cb-89f4-8cff6664da6f.jpg?imageMogr2/auto-orient/format/jpeg/crop/!400x400a0a0","created_at":1406882231000,"last_logined_at":1436504747000,"global_key":"dr2009","name":"dr2009","name_pinyin":"","updated_at":1406882231000,"path":"/u/dr2009","status":1,"is_member":0,"id":5814,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1992-11-08","location":"广东 广州","company":"sponia","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/7cc9d1d9-5ba4-478c-96ae-5ca39e715bfd.jpg?imageMogr2/auto-orient/format/jpeg/crop/!506x506a0a3","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/7cc9d1d9-5ba4-478c-96ae-5ca39e715bfd.jpg?imageMogr2/auto-orient/format/jpeg/crop/!506x506a0a3","created_at":1414399181000,"last_logined_at":1436755097000,"global_key":"whisky","name":"whisky","name_pinyin":"","updated_at":1414399181000,"path":"/u/whisky","status":1,"is_member":0,"id":37581,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1992-04-09","location":"江苏 无锡","company":"南京帆软软件有限公司","slogan":"然而这并没有什么卵用","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/802c48fc-a9c7-43d0-9b08-930767f56b2a.png?imageMogr2/auto-orient/format/png/crop/!512x512a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/e11eca9e-6c35-4ca8-98ef-c433416b3f38.png","lavatar":"https://dn-coding-net-production-static.qbox.me/802c48fc-a9c7-43d0-9b08-930767f56b2a.png?imageMogr2/auto-orient/format/png/crop/!512x512a0a0","created_at":1429069193000,"last_logined_at":1434631207000,"global_key":"huhamhire","name":"huhamhire","name_pinyin":"","updated_at":1429069193000,"path":"/u/huhamhire","status":1,"is_member":0,"id":95452,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":1,"birthday":"1992-01-01","location":"上海 ","company":"携程","slogan":"To be better me","introduction":"","avatar":"/static/fruit_avatar/Fruit-7.png","gravatar":"https://dn-coding-net-avatar.qbox.me/a44a2da5-c3fb-4240-80eb-835b3cedffe2.jpg","lavatar":"/static/fruit_avatar/Fruit-7.png","created_at":1432042116000,"last_logined_at":1436925662000,"global_key":"michel","name":"michel","name_pinyin":"","updated_at":1432042116000,"path":"/u/michel","status":1,"is_member":0,"id":102255,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":2,"birthday":"2014-07-22","location":"江苏 苏州","company":"","slogan":"冗码一生(13:28)","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/711ead7c-bda5-4097-ad56-3bc4e535d75e.jpg?imageMogr2/auto-orient/format/jpeg/crop/!600x600a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/a2fbe81e-5f9e-4e55-b09b-87c875c18cd7.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/711ead7c-bda5-4097-ad56-3bc4e535d75e.jpg?imageMogr2/auto-orient/format/jpeg/crop/!600x600a0a0","created_at":1406006889000,"last_logined_at":1437033413000,"global_key":"liuxey","name":"Liuxey","name_pinyin":"","updated_at":1406006889000,"path":"/u/liuxey","status":1,"is_member":0,"id":2530,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":28,"hot_tweet":{"id":59561,"owner_id":35907,"owner":{"sex":0,"birthday":"1111-11-11","location":"北京 西城区","company":"","slogan":"职位:CDO+CZO","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/ec3f4a9d-e6b9-41db-80ec-0ae449a43e10.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/ec3f4a9d-e6b9-41db-80ec-0ae449a43e10.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","created_at":1413647368000,"last_logined_at":1437045443759,"global_key":"itsing","name":"一台一台一台台","name_pinyin":"|ytytytt|yitaiyitaiyitaitai","updated_at":1413647368000,"path":"/u/itsing","status":1,"is_member":0,"id":35907,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437012241000,"likes":3,"comments":6,"comment_list":[{"id":133573,"tweet_id":59561,"owner_id":2279,"owner":{"sex":0,"birthday":"1970-01-01","location":"上海 浦东新区","company":"","slogan":"即使再渺小,也要不顾一切地成长! http://raoyc.com","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/8dc8714c-5f6f-4e4b-8564-83afda50c712.jpg?imageMogr2/auto-orient/format/jpeg/crop/!363x363a32a15","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/8dc8714c-5f6f-4e4b-8564-83afda50c712.jpg?imageMogr2/auto-orient/format/jpeg/crop/!363x363a32a15","created_at":1405924724000,"last_logined_at":1437028982000,"global_key":"rao","name":"飞扬","name_pinyin":"|fy|feiyang","updated_at":1405924724000,"path":"/u/rao","status":1,"is_member":0,"id":2279,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437029897000,"content":"P的一手好图啊"},{"id":133482,"tweet_id":59561,"owner_id":51190,"owner":{"sex":2,"birthday":"1998-03-04","location":"河北 保定","company":"QiLinYunS","slogan":"名字是潘潘起的,头像是拿ziying的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","created_at":1417764325000,"last_logined_at":1437023057000,"global_key":"TXisfine","name":"小谈谈","name_pinyin":"|xtt|xiaotantan","updated_at":1417764325000,"path":"/u/TXisfine","status":1,"is_member":0,"id":51190,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437022090000,"content":"0.02\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/persevere.png\" title\u003d\"persevere\"\u003e"},{"id":133407,"tweet_id":59561,"owner_id":41106,"owner":{"sex":0,"birthday":"1975-01-01","location":"河北 石家庄","company":"( ͡° ͜ʖ ͡°) ⌒* ( `灬` )*y。o0○","slogan":"勤","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","gravatar":"https://dn-coding-net-avatar.qbox.me/778054a6-374c-48cc-ae89-524a28af00ff.png","lavatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","created_at":1415687370000,"last_logined_at":1436982735000,"global_key":"fwolf","name":"Fwolf","name_pinyin":"","updated_at":1415687370000,"path":"/u/fwolf","status":1,"is_member":0,"id":41106,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437015144000,"content":"你這讓我們還怎麼抱猴子啊…"},{"id":133389,"tweet_id":59561,"owner_id":113646,"owner":{"sex":1,"birthday":"1995-01-01","location":"","company":"","slogan":"把猴子抱回家","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/b09accfe-2dd3-4320-aec3-5a335738ebc5.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/8a8f4840-a7f6-48d2-9a17-6c46e66eb212.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/b09accfe-2dd3-4320-aec3-5a335738ebc5.jpg","created_at":1436779066000,"last_logined_at":1437016596000,"global_key":"mian","name":"豆芽芽","name_pinyin":"|dyy|douyaya","updated_at":1436779066000,"path":"/u/mian","status":1,"is_member":0,"id":113646,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437012523000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/songyiwei\" rel\u003d\"nofollow\"\u003e@这个人出现在\u003c/a\u003e 黑我洋葱猴\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/joy.png\" title\u003d\"joy\"\u003e"},{"id":133385,"tweet_id":59561,"owner_id":51246,"owner":{"sex":0,"birthday":"1990-01-01","location":"江苏 南京","company":"南京安元科技有限公司","slogan":"好好学习,天天向上!","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/5db41905-efc1-4e35-94ff-21f5b9e7c625.png?imageMogr2/auto-orient/format/png/crop/!128x128a8a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/5db41905-efc1-4e35-94ff-21f5b9e7c625.png?imageMogr2/auto-orient/format/png/crop/!128x128a8a0","created_at":1417770252000,"last_logined_at":1437008173000,"global_key":"songyiwei","name":"这个人出现在","name_pinyin":"|zgrcxz|zhegerenchuxianzai","updated_at":1417770252000,"path":"/u/songyiwei","status":1,"is_member":0,"id":51246,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437012380000,"content":"这是我第一次这么“讨厌”这个猴子logo"}],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/141\" rel\u003d\"nofollow\"\u003e#抠一段#\u003c/a\u003e 一个程序员忧心忡忡的去找禅师,他虔诚的跪在禅师面前说:禅师啊禅师,coding最近出了一个活动,只要要在微信上回答对了问题,就可以获得大圣归来的电影票两张,可是我不知道答案啊,你能告诉我吗?问题是 coding的最大特点是什么?”禅师看了一眼面前的程序员并没有说话,从旁边拿出coding的LOGO摆在程序员面前,程序员看了看说道:“我知道了禅师,你的意思是coding最大特点就是LOGO上写的,他是一个高大上的云技术产品?”禅师突然站起来脱掉裤子把屁股对着程序员,然后大叫道:“你这么笨怎么当程序员啊?我的意思是CODING最大的特点是可以上去卖屁股!”\u003cbr\u003e \u003ca href\u003d\"https://dn-coding-net-production-pp.qbox.me/8eca012c-a65b-46ef-b07c-c96fdffef515.png\" target\u003d\"_blank\" class\u003d\"bubble-markdown-image-link\" rel\u003d\"nofollow\"\u003e\u003cimg src\u003d\"https://dn-coding-net-production-pp.qbox.me/8eca012c-a65b-46ef-b07c-c96fdffef515.png\" alt\u003d\"图片\" class\u003d\" bubble-markdown-image\"\u003e\u003c/a\u003e\u003c/p\u003e","path":"/u/itsing/pp/59561","activity_id":0,"liked":false,"like_users":[{"sex":0,"birthday":"1990-06-10","location":"深圳","company":"Coding.net","slogan":"\u0026lt;img src\u003d1 onerror\u003dalert(1)\u0026gt;","introduction":"嗯?","avatar":"https://dn-coding-net-avatar.qbox.me/dc57e8be-3355-4c05-b1e1-c5e52be8e205.png","gravatar":"https://dn-coding-net-avatar.qbox.me/dc57e8be-3355-4c05-b1e1-c5e52be8e205.png","lavatar":"https://dn-coding-net-avatar.qbox.me/dc57e8be-3355-4c05-b1e1-c5e52be8e205.png","created_at":1399045331000,"last_logined_at":1437033487000,"global_key":"wzw","name":"wzw","name_pinyin":"","updated_at":1399045331000,"path":"/u/wzw","status":1,"is_member":0,"id":1,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1993-02-18","location":"广东 江门","company":"袂卓建材搬运有限公司","slogan":"散文式php鲁迅都看不懂","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/f4f7314c-c59f-42d4-a9c0-55f098644c79.jpg?imageMogr2/auto-orient/format/jpeg/crop/!251x251a0a25","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/f4f7314c-c59f-42d4-a9c0-55f098644c79.jpg?imageMogr2/auto-orient/format/jpeg/crop/!251x251a0a25","created_at":1409455457000,"last_logined_at":1437010518000,"global_key":"zhlhuang","name":"zhlhuang","name_pinyin":"","updated_at":1409455457000,"path":"/u/zhlhuang","status":1,"is_member":0,"id":29746,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1990-01-01","location":"江苏 南京","company":"南京安元科技有限公司","slogan":"好好学习,天天向上!","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/5db41905-efc1-4e35-94ff-21f5b9e7c625.png?imageMogr2/auto-orient/format/png/crop/!128x128a8a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/5db41905-efc1-4e35-94ff-21f5b9e7c625.png?imageMogr2/auto-orient/format/png/crop/!128x128a8a0","created_at":1417770252000,"last_logined_at":1437008173000,"global_key":"songyiwei","name":"这个人出现在","name_pinyin":"|zgrcxz|zhegerenchuxianzai","updated_at":1417770252000,"path":"/u/songyiwei","status":1,"is_member":0,"id":51246,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},"name":"抠一段","created_at":1430199383000,"id":141,"user_list":[{"sex":0,"birthday":"1983-01-24","location":"四川 成都","company":"成都心动云科技有限公司","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/b8834e515dcb433c20951961967b8d8d.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/b8834e515dcb433c20951961967b8d8d.jpg","created_at":1405563080000,"last_logined_at":1436932265000,"global_key":"itimothy","name":"itimothy","name_pinyin":"","updated_at":1405563080000,"path":"/u/itimothy","status":1,"is_member":0,"id":916,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1970-01-01","location":"上海 浦东新区","company":"","slogan":"即使再渺小,也要不顾一切地成长! http://raoyc.com","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/8dc8714c-5f6f-4e4b-8564-83afda50c712.jpg?imageMogr2/auto-orient/format/jpeg/crop/!363x363a32a15","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/8dc8714c-5f6f-4e4b-8564-83afda50c712.jpg?imageMogr2/auto-orient/format/jpeg/crop/!363x363a32a15","created_at":1405924724000,"last_logined_at":1437028982000,"global_key":"rao","name":"飞扬","name_pinyin":"|fy|feiyang","updated_at":1405924724000,"path":"/u/rao","status":1,"is_member":0,"id":2279,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1998-05-15","location":"孜然麻辣熊黑科技研究中心","company":"孜然麻辣熊黑科技有限公司","slogan":"让懂的人懂,让不懂的人不懂。","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/0b6499da-33ba-489d-99d0-4324c9f53e7c.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/0b6499da-33ba-489d-99d0-4324c9f53e7c.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a0a0","created_at":1409313681000,"last_logined_at":1437046129576,"global_key":"linqun","name":"孜然麻辣熊大大","name_pinyin":"|zrmlxdd|ziranmalaxiongdada","updated_at":1409313681000,"path":"/u/linqun","status":1,"is_member":0,"id":27666,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1992-11-16","location":"","company":"Coding.Net","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/66fbd5f0-9a76-44c7-93c9-9e0e6b7afdd9.jpg?imageMogr2/auto-orient/format/jpeg/crop/!509x509a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/a5ec1d31-c771-4b35-8cd8-ca613b174e83.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/66fbd5f0-9a76-44c7-93c9-9e0e6b7afdd9.jpg?imageMogr2/auto-orient/format/jpeg/crop/!509x509a0a0","created_at":1399056643000,"last_logined_at":1437032308000,"global_key":"Michael","name":"Michael","name_pinyin":"","updated_at":1399056643000,"path":"/u/Michael","status":1,"is_member":0,"id":5,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-13.png","gravatar":"https://dn-coding-net-avatar.qbox.me/706eb577-6a88-464d-b635-e759067019d6.jpg","lavatar":"/static/fruit_avatar/Fruit-13.png","created_at":1434507370000,"last_logined_at":1436411863000,"global_key":"jpr1990","name":"jpr1990","name_pinyin":"","updated_at":1434507370000,"path":"/u/jpr1990","status":1,"is_member":0,"id":108268,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"山西 临汾","company":"无","slogan":"没有座右铭","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/3d16e65a-57e1-4cf3-b721-0e7187183eb3.jpg?imageMogr2/auto-orient/format/jpeg/crop/!572x572a0a14","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/3d16e65a-57e1-4cf3-b721-0e7187183eb3.jpg?imageMogr2/auto-orient/format/jpeg/crop/!572x572a0a14","created_at":1412417441000,"last_logined_at":1437039950000,"global_key":"fiy","name":"我是FT","name_pinyin":"|ws|woshi","updated_at":1412417441000,"path":"/u/fiy","status":1,"is_member":0,"id":33957,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":1,"birthday":"1993-09-03","location":"台湾 宜兰县","company":"Coding.net","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/282e4f85-c279-4bf2-808e-1d45f7f1797d.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/282e4f85-c279-4bf2-808e-1d45f7f1797d.jpg","created_at":1408688496000,"last_logined_at":1436494187000,"global_key":"lichi93","name":"小七七","name_pinyin":"|xqq|xiaoqiqi","updated_at":1408688496000,"path":"/u/lichi93","status":1,"is_member":0,"id":17567,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":2,"birthday":"1994-08-02","location":"山东 烟台","company":"公司","slogan":"にゃにゃん╭( ・ㅂ・)و ̑̑ye","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/669e1714-e6d7-47d6-8984-8de4e5c3d5c1.png?imageMogr2/auto-orient/format/png/crop/!450x450a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/ee4fc3ca-73f8-433e-be09-e67b11610011.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/669e1714-e6d7-47d6-8984-8de4e5c3d5c1.png?imageMogr2/auto-orient/format/png/crop/!450x450a0a0","created_at":1406008158000,"last_logined_at":1436947197000,"global_key":"xin","name":"xin","name_pinyin":"","updated_at":1406008158000,"path":"/u/xin","status":1,"is_member":0,"id":2552,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1111-11-11","location":"北京 西城区","company":"","slogan":"职位:CDO+CZO","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/ec3f4a9d-e6b9-41db-80ec-0ae449a43e10.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/ec3f4a9d-e6b9-41db-80ec-0ae449a43e10.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","created_at":1413647368000,"last_logined_at":1437045443759,"global_key":"itsing","name":"一台一台一台台","name_pinyin":"|ytytytt|yitaiyitaiyitaitai","updated_at":1413647368000,"path":"/u/itsing","status":1,"is_member":0,"id":35907,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1984-10-07","location":"山东 淄博 张店","company":"山东蓝标信息科技有限公司","slogan":"勇者无所畏惧 blog.hainuo.info","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/4cc88a4e-7adc-469f-98a5-6091ef2a35c3.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","created_at":1406871611000,"last_logined_at":1436929956000,"global_key":"hainuo","name":"刘峰","name_pinyin":"|lf|liufeng","updated_at":1406871611000,"path":"/u/hainuo","status":1,"is_member":0,"id":5764,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":46,"hot_tweet":{"id":59614,"owner_id":51190,"owner":{"sex":2,"birthday":"1998-03-04","location":"河北 保定","company":"QiLinYunS","slogan":"名字是潘潘起的,头像是拿ziying的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","created_at":1417764325000,"last_logined_at":1437023057000,"global_key":"TXisfine","name":"小谈谈","name_pinyin":"|xtt|xiaotantan","updated_at":1417764325000,"path":"/u/TXisfine","status":1,"is_member":0,"id":51190,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437023678000,"likes":0,"comments":9,"comment_list":[{"id":133682,"tweet_id":59614,"owner_id":78328,"owner":{"sex":0,"birthday":"1989-07-24","location":"吉林 长春","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-15.png","gravatar":"https://dn-coding-net-avatar.qbox.me/94ca25da-4dfa-44f9-8f94-27bb334a8f31.jpg","lavatar":"/static/fruit_avatar/Fruit-15.png","created_at":1422346827000,"last_logined_at":1437022035000,"global_key":"CarlJia","name":"CarlJia","name_pinyin":"","updated_at":1422346827000,"path":"/u/CarlJia","status":1,"is_member":0,"id":78328,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437047025613,"content":"archlinux"},{"id":133652,"tweet_id":59614,"owner_id":37841,"owner":{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"求知若饥,虚心若愚。","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9dc4bddc-040d-478a-bb31-c7c0b08a029e.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9dc4bddc-040d-478a-bb31-c7c0b08a029e.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","created_at":1414495800000,"last_logined_at":1436875094000,"global_key":"JZQT","name":"JZQT","name_pinyin":"","updated_at":1414495800000,"path":"/u/JZQT","status":1,"is_member":0,"id":37841,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437040624000,"content":"deepin"},{"id":133550,"tweet_id":59614,"owner_id":2279,"owner":{"sex":0,"birthday":"1970-01-01","location":"上海 浦东新区","company":"","slogan":"即使再渺小,也要不顾一切地成长! http://raoyc.com","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/8dc8714c-5f6f-4e4b-8564-83afda50c712.jpg?imageMogr2/auto-orient/format/jpeg/crop/!363x363a32a15","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/8dc8714c-5f6f-4e4b-8564-83afda50c712.jpg?imageMogr2/auto-orient/format/jpeg/crop/!363x363a32a15","created_at":1405924724000,"last_logined_at":1437028982000,"global_key":"rao","name":"飞扬","name_pinyin":"|fy|feiyang","updated_at":1405924724000,"path":"/u/rao","status":1,"is_member":0,"id":2279,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437029214000,"content":"桌面就用乌班图ubuntu,服务器就用centos"},{"id":133537,"tweet_id":59614,"owner_id":89816,"owner":{"sex":0,"birthday":"1989-12-14","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/1a19d540-c936-415d-a837-6061378d94dc.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!128x128a16a57","gravatar":"https://dn-coding-net-avatar.qbox.me/ce7795e8-c3cd-460f-b08d-d2f74d3eb835.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/1a19d540-c936-415d-a837-6061378d94dc.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!128x128a16a57","created_at":1427773948000,"last_logined_at":1437015872000,"global_key":"zhgxun","name":"zhgxun","name_pinyin":"","updated_at":1427773948000,"path":"/u/zhgxun","status":1,"is_member":0,"id":89816,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437028404000,"content":"ubuntu我一直用,就是软件比较好装一些,会出问题,上次突然一直停留在登录界面,图形界面进不去,命令行可以使用,后来直接重装。重装成本太大,环境安装,开发工具,各种,折腾不住,年底准备穷,买苹果系统应该更稳定一些。"},{"id":133531,"tweet_id":59614,"owner_id":17884,"owner":{"sex":0,"birthday":"2014-08-01","location":"江苏 无锡","company":"同程旅游","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-2.png","gravatar":"https://dn-coding-net-avatar.qbox.me/5dc4795c-bbdf-48f2-815f-95cae63b101e.jpg","lavatar":"/static/fruit_avatar/Fruit-2.png","created_at":1408692750000,"last_logined_at":1437016730000,"global_key":"renzhaoxu","name":"renzhao","name_pinyin":"","updated_at":1408692750000,"path":"/u/renzhaoxu","status":1,"is_member":0,"id":17884,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437027830000,"content":"deepin"}],"device":"OPPO Find7","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/200\" rel\u003d\"nofollow\"\u003e#万能的冒泡#\u003c/a\u003e 个人使用Linux,哪个版本较好?\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/100.png\" title\u003d\"100\"\u003e\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/100.png\" title\u003d\"100\"\u003e\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/100.png\" title\u003d\"100\"\u003e\u003c/p\u003e","path":"/u/TXisfine/pp/59614","activity_id":0,"liked":false,"like_users":[]},"name":"万能的冒泡","created_at":1432201941000,"id":200,"user_list":[{"sex":0,"birthday":"1995-08-05","location":"吉林 长春","company":"无","slogan":"呵呵","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/35e124f2-f601-436c-843b-074b146a2e3d.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/c2267416-299b-493f-a4d8-0b6346ad03ea.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/35e124f2-f601-436c-843b-074b146a2e3d.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","created_at":1419831794000,"last_logined_at":1434873688000,"global_key":"f12998765","name":"F_xi","name_pinyin":"","updated_at":1419831794000,"path":"/u/f12998765","status":1,"is_member":0,"id":63693,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"上海 徐汇区","company":"","slogan":"不翻墙搜Google www.886404.org","introduction":"","avatar":"/static/fruit_avatar/Fruit-19.png","gravatar":"","lavatar":"/static/fruit_avatar/Fruit-19.png","created_at":1408153237000,"last_logined_at":1434985959000,"global_key":"fising","name":"fising","name_pinyin":"","updated_at":1408153237000,"path":"/u/fising","status":1,"is_member":0,"id":11977,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":1,"birthday":"1989-08-17","location":"广东深圳","company":"官方打杂妹","slogan":"我就是潘潘潘潘潘哈哈","introduction":"恩","avatar":"https://dn-coding-net-production-static.qbox.me/15efd14d-b90a-44b4-8a3a-63f355330941.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/15efd14d-b90a-44b4-8a3a-63f355330941.jpg","created_at":1399839374000,"last_logined_at":1436491923000,"global_key":"panpan","name":"潘潘","name_pinyin":"|pp|panpan","updated_at":1399839374000,"path":"/u/panpan","status":1,"is_member":0,"id":15,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":1,"birthday":"1992-01-01","location":"上海 ","company":"携程","slogan":"To be better me","introduction":"","avatar":"/static/fruit_avatar/Fruit-7.png","gravatar":"https://dn-coding-net-avatar.qbox.me/a44a2da5-c3fb-4240-80eb-835b3cedffe2.jpg","lavatar":"/static/fruit_avatar/Fruit-7.png","created_at":1432042116000,"last_logined_at":1436925662000,"global_key":"michel","name":"michel","name_pinyin":"","updated_at":1432042116000,"path":"/u/michel","status":1,"is_member":0,"id":102255,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1970-01-01","location":"河南 济源","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/d06af4ba2ffae3614a4bcad606a29c09.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/d06af4ba2ffae3614a4bcad606a29c09.jpg","created_at":1405607752000,"last_logined_at":1436944144000,"global_key":"liu","name":"liu","name_pinyin":"","updated_at":1405607752000,"path":"/u/liu","status":1,"is_member":0,"id":1607,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1988-02-15","location":"上海 杨浦区","company":"dsoon","slogan":"哈哈哈哈^_^","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/615d587c-cef6-4155-af09-9e921291eb0d.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/3663ae0e-548b-4d8f-a841-122873c6a21f.jpg","lavatar":"https://dn-coding-net-avatar.qbox.me/615d587c-cef6-4155-af09-9e921291eb0d.jpg","created_at":1430890572000,"last_logined_at":1437007727000,"global_key":"wqc","name":"王全才","name_pinyin":"|wqc|wangquancai","updated_at":1430890572000,"path":"/u/wqc","status":1,"is_member":0,"id":99742,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"天津 ","company":"科技","slogan":"All for one,one for all","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/8b5fa550-db3d-43f9-a45c-bdaca2dcc491.png?imageMogr2/auto-orient/format/jpg/crop/!484x484a8a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/8b5fa550-db3d-43f9-a45c-bdaca2dcc491.png?imageMogr2/auto-orient/format/jpg/crop/!484x484a8a0","created_at":1414376815000,"last_logined_at":1436167058000,"global_key":"kevinlin","name":"kevinlin","name_pinyin":"","updated_at":1414376815000,"path":"/u/kevinlin","status":1,"is_member":0,"id":37474,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":2,"birthday":"1994-08-02","location":"山东 烟台","company":"公司","slogan":"にゃにゃん╭( ・ㅂ・)و ̑̑ye","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/669e1714-e6d7-47d6-8984-8de4e5c3d5c1.png?imageMogr2/auto-orient/format/png/crop/!450x450a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/ee4fc3ca-73f8-433e-be09-e67b11610011.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/669e1714-e6d7-47d6-8984-8de4e5c3d5c1.png?imageMogr2/auto-orient/format/png/crop/!450x450a0a0","created_at":1406008158000,"last_logined_at":1436947197000,"global_key":"xin","name":"xin","name_pinyin":"","updated_at":1406008158000,"path":"/u/xin","status":1,"is_member":0,"id":2552,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1987-06-09","location":"北京 海淀区","company":"10020","slogan":"个性签名","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/48f2b078-9e3b-4d00-bea5-ecc9d2a2505c.png","gravatar":"https://dn-coding-net-avatar.qbox.me/239c0825-71cf-4d1d-89f6-e7f22ff8db95.png","lavatar":"https://dn-coding-net-avatar.qbox.me/48f2b078-9e3b-4d00-bea5-ecc9d2a2505c.png","created_at":1430019086000,"last_logined_at":1434731377000,"global_key":"z__","name":"_z_","name_pinyin":"","updated_at":1430019086000,"path":"/u/z__","status":1,"is_member":0,"id":97932,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":8,"hot_tweet":{"id":59554,"owner_id":37549,"owner":{"sex":0,"birthday":"1991-01-01","location":"河南 平顶山","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/bd403248-9417-4b4b-b796-9ec87d91199f.png","gravatar":"https://dn-coding-net-avatar.qbox.me/82fd233b-6fc2-4537-8197-69f5b9fc2391.png","lavatar":"https://dn-coding-net-avatar.qbox.me/bd403248-9417-4b4b-b796-9ec87d91199f.png","created_at":1414393497000,"last_logined_at":1435737068000,"global_key":"binsee","name":"杉木","name_pinyin":"|sm|shanmu","updated_at":1414393497000,"path":"/u/binsee","status":1,"is_member":0,"id":37549,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437010073000,"likes":1,"comments":5,"comment_list":[{"id":133490,"tweet_id":59554,"owner_id":37549,"owner":{"sex":0,"birthday":"1991-01-01","location":"河南 平顶山","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/bd403248-9417-4b4b-b796-9ec87d91199f.png","gravatar":"https://dn-coding-net-avatar.qbox.me/82fd233b-6fc2-4537-8197-69f5b9fc2391.png","lavatar":"https://dn-coding-net-avatar.qbox.me/bd403248-9417-4b4b-b796-9ec87d91199f.png","created_at":1414393497000,"last_logined_at":1435737068000,"global_key":"binsee","name":"杉木","name_pinyin":"|sm|shanmu","updated_at":1414393497000,"path":"/u/binsee","status":1,"is_member":0,"id":37549,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437022391000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/jaysun\" rel\u003d\"nofollow\"\u003e@卡基猫\u003c/a\u003e , \u003ca class\u003d\"at-someone\" href\u003d\"/u/liuxey\" rel\u003d\"nofollow\"\u003e@Liuxey\u003c/a\u003e 你们懂的好多..."},{"id":133374,"tweet_id":59554,"owner_id":2530,"owner":{"sex":2,"birthday":"2014-07-22","location":"江苏 苏州","company":"","slogan":"冗码一生(13:28)","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/711ead7c-bda5-4097-ad56-3bc4e535d75e.jpg?imageMogr2/auto-orient/format/jpeg/crop/!600x600a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/a2fbe81e-5f9e-4e55-b09b-87c875c18cd7.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/711ead7c-bda5-4097-ad56-3bc4e535d75e.jpg?imageMogr2/auto-orient/format/jpeg/crop/!600x600a0a0","created_at":1406006889000,"last_logined_at":1437033413000,"global_key":"liuxey","name":"Liuxey","name_pinyin":"","updated_at":1406006889000,"path":"/u/liuxey","status":1,"is_member":0,"id":2530,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437011075000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/jaysun\" rel\u003d\"nofollow\"\u003e@卡基猫\u003c/a\u003e 我的意思就是这个。。。"},{"id":133370,"tweet_id":59554,"owner_id":2455,"owner":{"sex":2,"birthday":"1990-05-04","location":"北京","company":"永希","slogan":"https://a-hope.cn","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/1d3476cac70c29fe779592a42ea7bff2.png","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/1d3476cac70c29fe779592a42ea7bff2.png","created_at":1405998676000,"last_logined_at":1436187451000,"global_key":"jaysun","name":"卡基猫","name_pinyin":"|kjm|kajimao","updated_at":1405998676000,"path":"/u/jaysun","status":1,"is_member":0,"id":2455,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437010921000,"content":"但流血不是七天啊"},{"id":133369,"tweet_id":59554,"owner_id":2455,"owner":{"sex":2,"birthday":"1990-05-04","location":"北京","company":"永希","slogan":"https://a-hope.cn","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/1d3476cac70c29fe779592a42ea7bff2.png","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/1d3476cac70c29fe779592a42ea7bff2.png","created_at":1405998676000,"last_logined_at":1436187451000,"global_key":"jaysun","name":"卡基猫","name_pinyin":"|kjm|kajimao","updated_at":1405998676000,"path":"/u/jaysun","status":1,"is_member":0,"id":2455,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437010910000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/liuxey\" rel\u003d\"nofollow\"\u003e@Liuxey\u003c/a\u003e 经期一般是七天。。"},{"id":133368,"tweet_id":59554,"owner_id":2530,"owner":{"sex":2,"birthday":"2014-07-22","location":"江苏 苏州","company":"","slogan":"冗码一生(13:28)","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/711ead7c-bda5-4097-ad56-3bc4e535d75e.jpg?imageMogr2/auto-orient/format/jpeg/crop/!600x600a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/a2fbe81e-5f9e-4e55-b09b-87c875c18cd7.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/711ead7c-bda5-4097-ad56-3bc4e535d75e.jpg?imageMogr2/auto-orient/format/jpeg/crop/!600x600a0a0","created_at":1406006889000,"last_logined_at":1437033413000,"global_key":"liuxey","name":"Liuxey","name_pinyin":"","updated_at":1406006889000,"path":"/u/liuxey","status":1,"is_member":0,"id":2530,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437010779000,"content":"为什么要七天。。。"}],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/312\" rel\u003d\"nofollow\"\u003e#每日一乐#\u003c/a\u003e   闺蜜说:“这个世界上估计只有男人才会得晕血症吧!”\u003cbr\u003e\u003cbr\u003e  我问:“为什么呢?”\u003cbr\u003e\u003cbr\u003e  闺蜜说:“要是女人得晕血症,一个月要晕7天呢!”\u003c/p\u003e","path":"/u/binsee/pp/59554","activity_id":0,"liked":false,"like_users":[{"sex":0,"birthday":"1985-01-01","location":"广东 广州","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6b1f621a-eef8-45f0-90a5-2b6e4dd257b2.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/ed58d4ae-e17e-48fd-9f49-eeba3b26589a.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/6b1f621a-eef8-45f0-90a5-2b6e4dd257b2.jpg","created_at":1430075407000,"last_logined_at":1436791946000,"global_key":"bumy","name":"riverlong","name_pinyin":"","updated_at":1430075407000,"path":"/u/bumy","status":1,"is_member":0,"id":98041,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},"name":"每日一乐","created_at":1434856286000,"id":312,"user_list":[{"sex":1,"birthday":"1993-08-21","location":"四川 成都","company":"成都方米科技有限公司","slogan":"我是一枚","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9155a097-f4d8-4ee3-91dc-2df92b0954d2.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/d10efda1-73e9-418e-89e2-e0de56f029e7.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/9155a097-f4d8-4ee3-91dc-2df92b0954d2.jpg","created_at":1430990335000,"last_logined_at":1436439646000,"global_key":"abc-com","name":"DaisyYang","name_pinyin":"","updated_at":1430990335000,"path":"/u/abc-com","status":1,"is_member":0,"id":100051,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-13.png","gravatar":"https://dn-coding-net-avatar.qbox.me/706eb577-6a88-464d-b635-e759067019d6.jpg","lavatar":"/static/fruit_avatar/Fruit-13.png","created_at":1434507370000,"last_logined_at":1436411863000,"global_key":"jpr1990","name":"jpr1990","name_pinyin":"","updated_at":1434507370000,"path":"/u/jpr1990","status":1,"is_member":0,"id":108268,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1990-02-28","location":"北京 ","company":"36Kr","slogan":"如果爱我就不要离开我~","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/65b08186-949e-4ece-9fb8-64e640ca0115.png?imageMogr2/auto-orient/format/png/crop/!155x155a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/b902ad6d-e908-4487-b0b7-48795a95d177.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/65b08186-949e-4ece-9fb8-64e640ca0115.png?imageMogr2/auto-orient/format/png/crop/!155x155a0a0","created_at":1431348077000,"last_logined_at":1437029991000,"global_key":"36kr","name":"36kr","name_pinyin":"","updated_at":1431348077000,"path":"/u/36kr","status":1,"is_member":0,"id":100761,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1997-01-28","location":"广东 梅州","company":"盛夏游戏工作室","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/583713de-9669-4f78-85b4-75ee3a7c28ad.jpg?imageMogr2/auto-orient/format/jpeg/crop/!240x240a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/0c96e409-da6b-4a3e-8e05-8a54e14f4ae4.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/583713de-9669-4f78-85b4-75ee3a7c28ad.jpg?imageMogr2/auto-orient/format/jpeg/crop/!240x240a0a0","created_at":1428286874000,"last_logined_at":1436234486000,"global_key":"951203598","name":"951203598","name_pinyin":"","updated_at":1428286874000,"path":"/u/951203598","status":1,"is_member":0,"id":92390,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1990-10-31","location":"江苏 苏州","company":"pinklian","slogan":"Making Love Out of Nothing at All","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/d1002613-b448-4a91-8a5f-16fac8ebdf49.jpg?imageMogr2/auto-orient/format/jpeg/crop/!412x412a16a388","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/d1002613-b448-4a91-8a5f-16fac8ebdf49.jpg?imageMogr2/auto-orient/format/jpeg/crop/!412x412a16a388","created_at":1413989470000,"last_logined_at":1436850094000,"global_key":"desmond","name":"desmond","name_pinyin":"","updated_at":1413989470000,"path":"/u/desmond","status":1,"is_member":0,"id":36755,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1900-01-19","location":"安徽 六安","company":"上海米途信息科技有限公司","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/b42a5fd1-e37e-402a-9a51-dda8d7805035.jpg?imageMogr2/auto-orient/format/jpeg/crop/!390x390a10a10","gravatar":"https://dn-coding-net-avatar.qbox.me/d83bb38d-537a-450d-a219-9633b514bbbf.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/b42a5fd1-e37e-402a-9a51-dda8d7805035.jpg?imageMogr2/auto-orient/format/jpeg/crop/!390x390a10a10","created_at":1432003073000,"last_logined_at":1436783776000,"global_key":"aakng","name":"aakng","name_pinyin":"","updated_at":1432003073000,"path":"/u/aakng","status":1,"is_member":0,"id":102068,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1991-01-01","location":"河南 平顶山","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/bd403248-9417-4b4b-b796-9ec87d91199f.png","gravatar":"https://dn-coding-net-avatar.qbox.me/82fd233b-6fc2-4537-8197-69f5b9fc2391.png","lavatar":"https://dn-coding-net-avatar.qbox.me/bd403248-9417-4b4b-b796-9ec87d91199f.png","created_at":1414393497000,"last_logined_at":1435737068000,"global_key":"binsee","name":"杉木","name_pinyin":"|sm|shanmu","updated_at":1414393497000,"path":"/u/binsee","status":1,"is_member":0,"id":37549,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1995-07-24","location":"四川 成都","company":"打杂集团创始人兼首席执行官兼董事长","slogan":"从众是平庸的开始","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/7e648364-e13b-4d46-9cb4-cfdcec893d38.jpg?imageMogr2/auto-orient/format/jpeg/crop/!281x281a123a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/7e648364-e13b-4d46-9cb4-cfdcec893d38.jpg?imageMogr2/auto-orient/format/jpeg/crop/!281x281a123a0","created_at":1417079181000,"last_logined_at":1437009978000,"global_key":"tian_q","name":"一花一叶是菩提","name_pinyin":"|yhyyspt|yihuayiyeshiputi","updated_at":1417079181000,"path":"/u/tian_q","status":1,"is_member":0,"id":48651,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":30,"hot_tweet":{"id":59550,"owner_id":42283,"owner":{"sex":0,"birthday":"1992-04-26","location":"广东 深圳","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/501148c6-da3e-4312-a3ca-6127211122b3.jpg?imageMogr2/auto-orient/format/jpeg/crop/!543x543a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/501148c6-da3e-4312-a3ca-6127211122b3.jpg?imageMogr2/auto-orient/format/jpeg/crop/!543x543a0a0","created_at":1415842099000,"last_logined_at":1436967252000,"global_key":"cuminlo","name":"cuminlo","name_pinyin":"","updated_at":1415842099000,"path":"/u/cuminlo","status":1,"is_member":0,"id":42283,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437009277000,"likes":0,"comments":3,"comment_list":[{"id":133383,"tweet_id":59550,"owner_id":52103,"owner":{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437012115000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/cuminlo\" rel\u003d\"nofollow\"\u003e@cuminlo\u003c/a\u003e 是水泡没有了,有质量的冒泡还是有推荐得码币的"},{"id":133379,"tweet_id":59550,"owner_id":42283,"owner":{"sex":0,"birthday":"1992-04-26","location":"广东 深圳","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/501148c6-da3e-4312-a3ca-6127211122b3.jpg?imageMogr2/auto-orient/format/jpeg/crop/!543x543a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/501148c6-da3e-4312-a3ca-6127211122b3.jpg?imageMogr2/auto-orient/format/jpeg/crop/!543x543a0a0","created_at":1415842099000,"last_logined_at":1436967252000,"global_key":"cuminlo","name":"cuminlo","name_pinyin":"","updated_at":1415842099000,"path":"/u/cuminlo","status":1,"is_member":0,"id":42283,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437011795000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/kloze\" rel\u003d\"nofollow\"\u003e@kloze\u003c/a\u003e 被你一说发现了。 冒泡没有了么?"},{"id":133360,"tweet_id":59550,"owner_id":52103,"owner":{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437009930000,"content":"难道没发现现在水泡没码币了么"}],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/288\" rel\u003d\"nofollow\"\u003e#为了码币#\u003c/a\u003e ma bi\u003c/p\u003e","path":"/u/cuminlo/pp/59550","activity_id":0,"liked":false,"like_users":[]},"name":"为了码币","created_at":1434204235000,"id":288,"user_list":[{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"不coding非码农","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/b800825d17736051cc68dd6a5343f3ce.png","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/b800825d17736051cc68dd6a5343f3ce.png","created_at":1408324753000,"last_logined_at":1436068674000,"global_key":"zybupt","name":"zybupt","name_pinyin":"","updated_at":1408324753000,"path":"/u/zybupt","status":1,"is_member":0,"id":12620,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-6.png","gravatar":"","lavatar":"/static/fruit_avatar/Fruit-6.png","created_at":1408006885000,"last_logined_at":1436780464000,"global_key":"Mr_right","name":"Mr_right","name_pinyin":"","updated_at":1408006885000,"path":"/u/Mr_right","status":1,"is_member":0,"id":10208,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1983-01-24","location":"四川 成都","company":"成都心动云科技有限公司","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/b8834e515dcb433c20951961967b8d8d.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/b8834e515dcb433c20951961967b8d8d.jpg","created_at":1405563080000,"last_logined_at":1436932265000,"global_key":"itimothy","name":"itimothy","name_pinyin":"","updated_at":1405563080000,"path":"/u/itimothy","status":1,"is_member":0,"id":916,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1984-11-09","location":"北京 海淀区","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-1.png","gravatar":"","lavatar":"/static/fruit_avatar/Fruit-1.png","created_at":1411703062000,"last_logined_at":1436778015000,"global_key":"darren_wang","name":"王伟","name_pinyin":"|wangwei|ww","updated_at":1411703062000,"path":"/u/darren_wang","status":1,"is_member":0,"id":33094,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1990-11-19","location":"","company":"","slogan":"没事瞎折腾","introduction":"","avatar":"/static/fruit_avatar/Fruit-18.png","gravatar":"https://dn-coding-net-avatar.qbox.me/1c6b907a-ad1b-4c85-b3cb-f8e7338d9873.jpg","lavatar":"/static/fruit_avatar/Fruit-18.png","created_at":1427522739000,"last_logined_at":1435660771000,"global_key":"Kepp","name":"Kepp","name_pinyin":"","updated_at":1427522739000,"path":"/u/Kepp","status":1,"is_member":0,"id":89067,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1988-11-05","location":"安徽 合肥","company":"中擎","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-8.png","gravatar":"https://dn-coding-net-avatar.qbox.me/2c6c1af6-e8bd-4f26-9987-2c76d66cb94d.jpg","lavatar":"/static/fruit_avatar/Fruit-8.png","created_at":1433906667000,"last_logined_at":1435224039000,"global_key":"newley1105","name":"newley1105","name_pinyin":"","updated_at":1433906667000,"path":"/u/newley1105","status":1,"is_member":0,"id":107032,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"上海 徐汇区","company":"","slogan":"不翻墙搜Google www.886404.org","introduction":"","avatar":"/static/fruit_avatar/Fruit-19.png","gravatar":"","lavatar":"/static/fruit_avatar/Fruit-19.png","created_at":1408153237000,"last_logined_at":1434985959000,"global_key":"fising","name":"fising","name_pinyin":"","updated_at":1408153237000,"path":"/u/fising","status":1,"is_member":0,"id":11977,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1999-08-18","location":"天津 西青区","company":"打杂","slogan":"打杂","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/ae033658-9214-49b5-97c4-ed5af842be07.jpg?imageMogr2/auto-orient/format/jpeg/crop/!600x600a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/ac1fd523-418b-4cff-a0f8-bcf5f5c31784.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/ae033658-9214-49b5-97c4-ed5af842be07.jpg?imageMogr2/auto-orient/format/jpeg/crop/!600x600a0a0","created_at":1423120668000,"last_logined_at":1437049106313,"global_key":"longsichao","name":"隆斯朝","name_pinyin":"|lsc|longsichao","updated_at":1423120668000,"path":"/u/longsichao","status":1,"is_member":0,"id":79835,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1991-04-30","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/3ff266cd-f806-41dc-bb32-884d4166e5f6.jpg?imageMogr2/auto-orient/format/jpeg/crop/!358x358a160a6","gravatar":"https://dn-coding-net-avatar.qbox.me/4ba3bc8f-351b-46fc-8fa7-88412f49725d.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/3ff266cd-f806-41dc-bb32-884d4166e5f6.jpg?imageMogr2/auto-orient/format/jpeg/crop/!358x358a160a6","created_at":1433751124000,"last_logined_at":1436860265000,"global_key":"Miloer","name":"Miloer","name_pinyin":"","updated_at":1433751124000,"path":"/u/Miloer","status":1,"is_member":0,"id":106695,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":2,"birthday":"1999-01-01","location":"山东 淄博","company":"在校学生","slogan":"Nothing is absolute.","introduction":"","avatar":"/static/fruit_avatar/Fruit-1.png","gravatar":"https://dn-coding-net-avatar.qbox.me/2110b6a2-f244-47c4-8b97-8f5fc3ebe481.jpg","lavatar":"/static/fruit_avatar/Fruit-1.png","created_at":1424637774000,"last_logined_at":1435598200000,"global_key":"ephoton","name":"Apriky","name_pinyin":"","updated_at":1424637774000,"path":"/u/ephoton","status":1,"is_member":0,"id":81669,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":25,"hot_tweet":{"id":59643,"owner_id":79236,"owner":{"sex":0,"birthday":"1985-01-01","location":"山东 临沂","company":"临沂宁可网络","slogan":"有我更精彩","introduction":"","avatar":"/static/fruit_avatar/Fruit-15.png","gravatar":"https://dn-coding-net-avatar.qbox.me/81e0f2cd-dba8-47e7-97c3-7cf728cdf184.jpg","lavatar":"/static/fruit_avatar/Fruit-15.png","created_at":1422840787000,"last_logined_at":1435983829000,"global_key":"lidw","name":"lidw","name_pinyin":"","updated_at":1422840787000,"path":"/u/lidw","status":1,"is_member":0,"id":79236,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437028776000,"likes":0,"comments":0,"comment_list":[],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/391\" rel\u003d\"nofollow\"\u003e#来点音乐#\u003c/a\u003e \u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/sleepy.png\" title\u003d\"sleepy\"\u003e\u003c/p\u003e","path":"/u/lidw/pp/59643","activity_id":0,"liked":false,"like_users":[]},"name":"来点音乐","created_at":1436317386000,"id":391,"user_list":[{"sex":0,"birthday":"1985-01-01","location":"四川 成都","company":"汇通天下","slogan":"用穿越春夏秋冬的坚持,去创造和享受美好的事物","introduction":"","avatar":"/static/fruit_avatar/Fruit-10.png","gravatar":"https://dn-coding-net-avatar.qbox.me/d909aa07-bf14-4d6e-be99-966e1a6e994d.jpg","lavatar":"/static/fruit_avatar/Fruit-10.png","created_at":1422500345000,"last_logined_at":1436867508000,"global_key":"wyqbailey","name":"wyqbailey","name_pinyin":"","updated_at":1422500345000,"path":"/u/wyqbailey","status":1,"is_member":0,"id":78678,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"广东 深圳","company":"Coding.net","slogan":"大圣赐我火眼金睛发现一切BUG 。","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/f0dab52e-10ec-4a1c-ab2a-4e63f84ee9b7.jpg?imageMogr2/auto-orient/format/jpeg/crop/!440x440a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/5c1769a9-9acd-47c5-963b-29a933d910f3.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/f0dab52e-10ec-4a1c-ab2a-4e63f84ee9b7.jpg?imageMogr2/auto-orient/format/jpeg/crop/!440x440a0a0","created_at":1433735819000,"last_logined_at":1437046822137,"global_key":"zhct","name":"zhct","name_pinyin":"","updated_at":1433735819000,"path":"/u/zhct","status":1,"is_member":0,"id":106621,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1990-04-24","location":"河北 廊坊","company":"微度网络科技","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/c7f4d93144536315c0c5d3e2f41502ee.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/c7f4d93144536315c0c5d3e2f41502ee.jpg","created_at":1406170973000,"last_logined_at":1436568771000,"global_key":"widuu","name":"widuu","name_pinyin":"","updated_at":1406170973000,"path":"/u/widuu","status":1,"is_member":0,"id":3405,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1992-07-28","location":"江苏 常州","company":"风豪科技","slogan":"挥舞着大宝剑的屠龙战士","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/b1b923bf-ea48-473f-9907-e76910b088a7.png?imageMogr2/auto-orient/format/png/crop/!476x476a307a18","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/b1b923bf-ea48-473f-9907-e76910b088a7.png?imageMogr2/auto-orient/format/png/crop/!476x476a307a18","created_at":1415925645000,"last_logined_at":1436694267000,"global_key":"sevenbanana","name":"sevenbanana","name_pinyin":"","updated_at":1415925645000,"path":"/u/sevenbanana","status":1,"is_member":0,"id":43183,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1991-11-20","location":"山东 淄博","company":"","slogan":"微笑待人,心中却操翻全世界。","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/505374ef-5edf-4db1-b62f-bfd33256ce22.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!638x638a1a1","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/505374ef-5edf-4db1-b62f-bfd33256ce22.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!638x638a1a1","created_at":1407745110000,"last_logined_at":1437031181000,"global_key":"pangzhen","name":"庞震","name_pinyin":"|pz|pangzhen","updated_at":1407745110000,"path":"/u/pangzhen","status":1,"is_member":0,"id":8459,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1990-05-11","location":"四川 成都","company":"一袋","slogan":"everything will be ok","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/ebe778ec-db00-4304-9675-31f422118ae9.jpg?imageMogr2/auto-orient/format/jpeg/crop/!567x567a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/40f2bc16-26e4-439a-b6f4-d2704975bac8.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/ebe778ec-db00-4304-9675-31f422118ae9.jpg?imageMogr2/auto-orient/format/jpeg/crop/!567x567a0a0","created_at":1409212210000,"last_logined_at":1436620909000,"global_key":"imzhi","name":"imzhi","name_pinyin":"","updated_at":1409212210000,"path":"/u/imzhi","status":1,"is_member":0,"id":25949,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-5.png","gravatar":"https://dn-coding-net-avatar.qbox.me/8c4116e9-17b4-40c4-a291-589c59b70e21.jpg","lavatar":"/static/fruit_avatar/Fruit-5.png","created_at":1426649728000,"last_logined_at":1436665474000,"global_key":"JUN1991","name":"JUN1991","name_pinyin":"","updated_at":1426649728000,"path":"/u/JUN1991","status":1,"is_member":0,"id":85691,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1984-10-07","location":"山东 淄博 张店","company":"山东蓝标信息科技有限公司","slogan":"勇者无所畏惧 blog.hainuo.info","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/4cc88a4e-7adc-469f-98a5-6091ef2a35c3.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","created_at":1406871611000,"last_logined_at":1436929956000,"global_key":"hainuo","name":"刘峰","name_pinyin":"|lf|liufeng","updated_at":1406871611000,"path":"/u/hainuo","status":1,"is_member":0,"id":5764,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-4.png","gravatar":"https://dn-coding-net-avatar.qbox.me/ad51f196-9407-4676-9015-b48c2cb931a1.jpg","lavatar":"/static/fruit_avatar/Fruit-4.png","created_at":1436257583000,"last_logined_at":1436495431000,"global_key":"wangrr","name":"wangrr","name_pinyin":"","updated_at":1436257583000,"path":"/u/wangrr","status":1,"is_member":0,"id":112206,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":27,"hot_tweet":{"id":59677,"owner_id":95080,"owner":{"sex":0,"birthday":"2015-03-13","location":"四川 成都","company":"西南交通大学","slogan":"all for one\u0026one for all","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/13fbf842-10d1-422b-84b5-f010b35a8320.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/13fbf842-10d1-422b-84b5-f010b35a8320.jpg","lavatar":"https://dn-coding-net-avatar.qbox.me/13fbf842-10d1-422b-84b5-f010b35a8320.jpg","created_at":1428937098000,"last_logined_at":1437036414000,"global_key":"leov","name":"leov","name_pinyin":"","updated_at":1428937098000,"path":"/u/leov","status":1,"is_member":0,"id":95080,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437036538000,"likes":0,"comments":0,"comment_list":[],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/383\" rel\u003d\"nofollow\"\u003e#码市#\u003c/a\u003e coding的状态中\u003c/p\u003e","path":"/u/leov/pp/59677","activity_id":0,"liked":false,"like_users":[]},"name":"码市","created_at":1436168268000,"id":383,"user_list":[{"sex":1,"birthday":"1992-08-18","location":"四川 成都","company":"伯德梦想","slogan":"什么事慢慢来,不要催。","introduction":"","avatar":"/static/fruit_avatar/Fruit-10.png","gravatar":"https://dn-coding-net-avatar.qbox.me/fbf8911e-a297-4aff-9372-1cc85bc81a6f.jpg","lavatar":"/static/fruit_avatar/Fruit-10.png","created_at":1428544838000,"last_logined_at":1436083491000,"global_key":"zhaoxiaoling","name":"zhaoxiaoling","name_pinyin":"","updated_at":1428544838000,"path":"/u/zhaoxiaoling","status":1,"is_member":0,"id":93599,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1989-12-07","location":"广东 广州","company":"在路上","slogan":"你猜","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/60d61651-e9c5-4de2-9e84-5c2dd2c375fd.PNG?imageMogr2/auto-orient/format/jpeg/crop/!142x142a4a8","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/60d61651-e9c5-4de2-9e84-5c2dd2c375fd.PNG?imageMogr2/auto-orient/format/jpeg/crop/!142x142a4a8","created_at":1412759505000,"last_logined_at":1437012838000,"global_key":"seekwe","name":"seekwe","name_pinyin":"","updated_at":1412759505000,"path":"/u/seekwe","status":1,"is_member":0,"id":34258,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1989-01-01","location":"广东 深圳","company":"平安科技","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-13.png","gravatar":"https://dn-coding-net-avatar.qbox.me/f0ecaa35-cd7a-4633-8aaa-f10847ed1943.jpg","lavatar":"/static/fruit_avatar/Fruit-13.png","created_at":1435233051000,"last_logined_at":1436420838000,"global_key":"jasondu","name":"jasondu","name_pinyin":"","updated_at":1435233051000,"path":"/u/jasondu","status":1,"is_member":0,"id":109725,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"上海 浦东新区","company":"Hi Team","slogan":"我的代码我做主","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/3ffb4c23-c211-4d07-9021-a9f9bb5ddcef.PNG?imageMogr2/auto-orient/format/png/crop/!387x387a28a5","gravatar":"https://dn-coding-net-avatar.qbox.me/7507595b-7698-4b82-9c1c-30e424e81215.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/3ffb4c23-c211-4d07-9021-a9f9bb5ddcef.PNG?imageMogr2/auto-orient/format/png/crop/!387x387a28a5","created_at":1423468244000,"last_logined_at":1436939408000,"global_key":"peterjc","name":"peterjc","name_pinyin":"","updated_at":1423468244000,"path":"/u/peterjc","status":1,"is_member":0,"id":80427,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-5.png","gravatar":"https://dn-coding-net-avatar.qbox.me/8c4116e9-17b4-40c4-a291-589c59b70e21.jpg","lavatar":"/static/fruit_avatar/Fruit-5.png","created_at":1426649728000,"last_logined_at":1436665474000,"global_key":"JUN1991","name":"JUN1991","name_pinyin":"","updated_at":1426649728000,"path":"/u/JUN1991","status":1,"is_member":0,"id":85691,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1983-01-24","location":"四川 成都","company":"成都心动云科技有限公司","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/b8834e515dcb433c20951961967b8d8d.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/b8834e515dcb433c20951961967b8d8d.jpg","created_at":1405563080000,"last_logined_at":1436932265000,"global_key":"itimothy","name":"itimothy","name_pinyin":"","updated_at":1405563080000,"path":"/u/itimothy","status":1,"is_member":0,"id":916,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1992-10-06","location":"","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-18.png","gravatar":"https://dn-coding-net-avatar.qbox.me/2e57547e-c365-4c32-84cb-69591a24cc62.jpg","lavatar":"/static/fruit_avatar/Fruit-18.png","created_at":1416285401000,"last_logined_at":1436345301000,"global_key":"zhhw9210","name":"沙壤土","name_pinyin":"|srt|sharangtu","updated_at":1416285401000,"path":"/u/zhhw9210","status":1,"is_member":0,"id":45375,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1992-04-26","location":"广东 深圳","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/501148c6-da3e-4312-a3ca-6127211122b3.jpg?imageMogr2/auto-orient/format/jpeg/crop/!543x543a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/501148c6-da3e-4312-a3ca-6127211122b3.jpg?imageMogr2/auto-orient/format/jpeg/crop/!543x543a0a0","created_at":1415842099000,"last_logined_at":1436967252000,"global_key":"cuminlo","name":"cuminlo","name_pinyin":"","updated_at":1415842099000,"path":"/u/cuminlo","status":1,"is_member":0,"id":42283,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":1,"birthday":"1989-08-17","location":"广东深圳","company":"官方打杂妹","slogan":"我就是潘潘潘潘潘哈哈","introduction":"恩","avatar":"https://dn-coding-net-production-static.qbox.me/15efd14d-b90a-44b4-8a3a-63f355330941.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/15efd14d-b90a-44b4-8a3a-63f355330941.jpg","created_at":1399839374000,"last_logined_at":1436491923000,"global_key":"panpan","name":"潘潘","name_pinyin":"|pp|panpan","updated_at":1399839374000,"path":"/u/panpan","status":1,"is_member":0,"id":15,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"2014-02-14","location":"广东 深圳","company":"Coding.net","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/512b2a62-956b-4ef8-8e84-b3c66e71468f.png?imageMogr2/auto-orient/format/png/crop/!300x300a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/512b2a62-956b-4ef8-8e84-b3c66e71468f.png?imageMogr2/auto-orient/format/png/crop/!300x300a0a0","created_at":1403329814000,"last_logined_at":1436261323000,"global_key":"coding","name":"coding","name_pinyin":"","updated_at":1403329814000,"path":"/u/coding","status":1,"is_member":0,"id":93,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":6,"hot_tweet":{"id":59501,"owner_id":41106,"owner":{"sex":0,"birthday":"1975-01-01","location":"河北 石家庄","company":"( ͡° ͜ʖ ͡°) ⌒* ( `灬` )*y。o0○","slogan":"勤","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","gravatar":"https://dn-coding-net-avatar.qbox.me/778054a6-374c-48cc-ae89-524a28af00ff.png","lavatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","created_at":1415687370000,"last_logined_at":1436982735000,"global_key":"fwolf","name":"Fwolf","name_pinyin":"","updated_at":1415687370000,"path":"/u/fwolf","status":1,"is_member":0,"id":41106,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436976162000,"likes":0,"comments":1,"comment_list":[{"id":133270,"tweet_id":59501,"owner_id":41106,"owner":{"sex":0,"birthday":"1975-01-01","location":"河北 石家庄","company":"( ͡° ͜ʖ ͡°) ⌒* ( `灬` )*y。o0○","slogan":"勤","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","gravatar":"https://dn-coding-net-avatar.qbox.me/778054a6-374c-48cc-ae89-524a28af00ff.png","lavatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","created_at":1415687370000,"last_logined_at":1436982735000,"global_key":"fwolf","name":"Fwolf","name_pinyin":"","updated_at":1415687370000,"path":"/u/fwolf","status":1,"is_member":0,"id":41106,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436976327000,"content":"圖過不來…一會兒補上"}],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e綠皮車今非昔比,這節綠皮車不僅是臥鋪,還是軟臥,而且還是高級軟臥!一共八個包廂,每個包廂兩張床,裡面有沙發和衛生間,床腳有個顯示器。 \u003ca class\u003d\"topic\" href\u003d\"/pp/topic/24\" rel\u003d\"nofollow\"\u003e#coding #\u003c/a\u003e 行 \u003ca href\u003d\"http://t.cn/RLtHcFo\" target\u003d\"_blank\" class\u003d\" auto-link\" rel\u003d\"nofollow\"\u003ehttp://t.cn/RLtHcFo\u003c/a\u003e\u003c/p\u003e","path":"/u/fwolf/pp/59501","activity_id":0,"liked":false,"like_users":[]},"name":"coding","created_at":1429625299000,"id":24,"user_list":[{"sex":0,"birthday":"1985-01-01","location":"","company":"sdut","slogan":"sdut","introduction":"","avatar":"/static/fruit_avatar/Fruit-20.png","gravatar":"https://dn-coding-net-avatar.qbox.me/0f58a707-578a-43c8-a35c-d21c14944d94.jpg","lavatar":"/static/fruit_avatar/Fruit-20.png","created_at":1433674552000,"last_logined_at":1436841045000,"global_key":"zhuna","name":"zhuna","name_pinyin":"","updated_at":1433674552000,"path":"/u/zhuna","status":1,"is_member":0,"id":106469,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1988-12-06","location":"江苏 无锡","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/2212a32f00cca72b5561aef00ebb5dc7.png","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/2212a32f00cca72b5561aef00ebb5dc7.png","created_at":1408351432000,"last_logined_at":1436708505000,"global_key":"timothyqiu","name":"timothyqiu","name_pinyin":"","updated_at":1408351432000,"path":"/u/timothyqiu","status":1,"is_member":0,"id":13153,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1996-01-29","location":"吉林 长春","company":"无","slogan":"null","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/5633b9d2-8cbf-497e-b4c3-8bf0bca40ed7.jpg?imageMogr2/auto-orient/format/jpeg/crop/!640x640a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/5633b9d2-8cbf-497e-b4c3-8bf0bca40ed7.jpg?imageMogr2/auto-orient/format/jpeg/crop/!640x640a0a0","created_at":1408532116000,"last_logined_at":1436077557000,"global_key":"kingwl","name":"kingwl","name_pinyin":"","updated_at":1408532116000,"path":"/u/kingwl","status":1,"is_member":0,"id":15134,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1975-01-01","location":"河北 石家庄","company":"( ͡° ͜ʖ ͡°) ⌒* ( `灬` )*y。o0○","slogan":"勤","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","gravatar":"https://dn-coding-net-avatar.qbox.me/778054a6-374c-48cc-ae89-524a28af00ff.png","lavatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","created_at":1415687370000,"last_logined_at":1436982735000,"global_key":"fwolf","name":"Fwolf","name_pinyin":"","updated_at":1415687370000,"path":"/u/fwolf","status":1,"is_member":0,"id":41106,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"Coding my life...","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/65e692ec-66c2-4732-9b8e-937189590f01.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/b89b7a59-3148-4751-a9ff-5f696b1218cc.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/65e692ec-66c2-4732-9b8e-937189590f01.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","created_at":1435375435000,"last_logined_at":1437009402000,"global_key":"donychen","name":"donychen","name_pinyin":"","updated_at":1435375435000,"path":"/u/donychen","status":1,"is_member":0,"id":110001,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"2014-02-14","location":"广东 深圳","company":"Coding.net","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/512b2a62-956b-4ef8-8e84-b3c66e71468f.png?imageMogr2/auto-orient/format/png/crop/!300x300a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/512b2a62-956b-4ef8-8e84-b3c66e71468f.png?imageMogr2/auto-orient/format/png/crop/!300x300a0a0","created_at":1403329814000,"last_logined_at":1436261323000,"global_key":"coding","name":"coding","name_pinyin":"","updated_at":1403329814000,"path":"/u/coding","status":1,"is_member":0,"id":93,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":1,"hot_tweet":{"id":58096,"owner_id":52103,"owner":{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436534710000,"likes":0,"comments":14,"comment_list":[{"id":131485,"tweet_id":58096,"owner_id":41106,"owner":{"sex":0,"birthday":"1975-01-01","location":"河北 石家庄","company":"( ͡° ͜ʖ ͡°) ⌒* ( `灬` )*y。o0○","slogan":"勤","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","gravatar":"https://dn-coding-net-avatar.qbox.me/778054a6-374c-48cc-ae89-524a28af00ff.png","lavatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","created_at":1415687370000,"last_logined_at":1436982735000,"global_key":"fwolf","name":"Fwolf","name_pinyin":"","updated_at":1415687370000,"path":"/u/fwolf","status":1,"is_member":0,"id":41106,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436596385000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/kloze\" rel\u003d\"nofollow\"\u003e@kloze\u003c/a\u003e 不和你們這些遊山玩水的傢伙們夜話…"},{"id":131458,"tweet_id":58096,"owner_id":52103,"owner":{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436587046000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/fwolf\" rel\u003d\"nofollow\"\u003e@Fwolf\u003c/a\u003e 时间是周五晚上 地点还在考虑要不要现场直播"},{"id":131457,"tweet_id":58096,"owner_id":52103,"owner":{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436587012000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/djyuning\" rel\u003d\"nofollow\"\u003e@妖刀\u003c/a\u003e 嘉宾现在正在游山玩水"},{"id":131390,"tweet_id":58096,"owner_id":94169,"owner":{"sex":0,"birthday":"1987-08-20","location":"重庆 大渡口区","company":"tPeriod Tech","slogan":"奇迹总会发生在我身上!","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/b02065e5-c6db-472d-8cff-d3da20da492a.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!541x541a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/aa4592ce-cda4-442a-9abb-4269dc018ce0.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/b02065e5-c6db-472d-8cff-d3da20da492a.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!541x541a0a0","created_at":1428641852000,"last_logined_at":1436495272000,"global_key":"djyuning","name":"妖刀","name_pinyin":"|yd|yaodao","updated_at":1428641852000,"path":"/u/djyuning","status":1,"is_member":0,"id":94169,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436570332000,"content":"嘉宾不会是听错了吧?跑深山架篝火去啦?呵呵"},{"id":131330,"tweet_id":58096,"owner_id":51190,"owner":{"sex":2,"birthday":"1998-03-04","location":"河北 保定","company":"QiLinYunS","slogan":"名字是潘潘起的,头像是拿ziying的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","created_at":1417764325000,"last_logined_at":1437023057000,"global_key":"TXisfine","name":"小谈谈","name_pinyin":"|xtt|xiaotantan","updated_at":1417764325000,"path":"/u/TXisfine","status":1,"is_member":0,"id":51190,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436539688000,"content":"本泡应该浮动在水面\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/joy.png\" title\u003d\"joy\"\u003e\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/joy.png\" title\u003d\"joy\"\u003e"}],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/376\" rel\u003d\"nofollow\"\u003e#Coding 夜话#\u003c/a\u003e \u003c/p\u003e \n\u003ch3 id\u003d\"user-content-coding-夜话推迟一周发布\"\u003eCoding 夜话推迟一周发布\u003c/h3\u003e \n\u003cp\u003e各位泡友,抱歉的通知,由于本期夜话的嘉宾还深陷深山老林,暂时无法回归人类社会,故夜话推迟到下周五。对此我深表歉意和感到遗憾。\u003c/p\u003e","path":"/u/kloze/pp/58096","activity_id":0,"liked":false,"like_users":[]},"name":"Coding 夜话","created_at":1435931535000,"id":376,"user_list":[{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":9,"hot_tweet":{"id":59310,"owner_id":52103,"owner":{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436928380000,"likes":1,"comments":9,"comment_list":[{"id":133015,"tweet_id":59310,"owner_id":54212,"owner":{"sex":0,"birthday":"1994-08-31","location":"江苏 南京","company":"幕(木)游(有)公司","slogan":"做一个简单的人,踏实而务实,不沉溺幻想,不庸人自扰","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/5ae8585e-662b-4bf1-bd53-318c6cec8426.jpg?imageMogr2/auto-orient/format/jpeg/crop/!239x239a0a34","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/5ae8585e-662b-4bf1-bd53-318c6cec8426.jpg?imageMogr2/auto-orient/format/jpeg/crop/!239x239a0a34","created_at":1418705066000,"last_logined_at":1436600011000,"global_key":"Morph_Zhou","name":"Morph_Zhou","name_pinyin":"","updated_at":1418705066000,"path":"/u/Morph_Zhou","status":1,"is_member":0,"id":54212,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436940181000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/kloze\" rel\u003d\"nofollow\"\u003e@kloze\u003c/a\u003e 然而已经没有了.."},{"id":133013,"tweet_id":59310,"owner_id":52103,"owner":{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436940114000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/Morph_Zhou\" rel\u003d\"nofollow\"\u003e@Morph_Zhou\u003c/a\u003e 资源自行搜索。。"},{"id":133000,"tweet_id":59310,"owner_id":54212,"owner":{"sex":0,"birthday":"1994-08-31","location":"江苏 南京","company":"幕(木)游(有)公司","slogan":"做一个简单的人,踏实而务实,不沉溺幻想,不庸人自扰","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/5ae8585e-662b-4bf1-bd53-318c6cec8426.jpg?imageMogr2/auto-orient/format/jpeg/crop/!239x239a0a34","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/5ae8585e-662b-4bf1-bd53-318c6cec8426.jpg?imageMogr2/auto-orient/format/jpeg/crop/!239x239a0a34","created_at":1418705066000,"last_logined_at":1436600011000,"global_key":"Morph_Zhou","name":"Morph_Zhou","name_pinyin":"","updated_at":1418705066000,"path":"/u/Morph_Zhou","status":1,"is_member":0,"id":54212,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436937842000,"content":"资源资源...."},{"id":132952,"tweet_id":59310,"owner_id":107805,"owner":{"sex":1,"birthday":"1990-11-06","location":"广西 柳州","company":"昊客","slogan":"然并卵,微博@爱抠鼻屎的怪大婶","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/2c589fcd-b33f-4688-ac0d-5cc3f88d3ca3.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/0a63d54a-1ab0-4c75-8214-f161423626a5.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/2c589fcd-b33f-4688-ac0d-5cc3f88d3ca3.jpg","created_at":1434335589000,"last_logined_at":1436863461000,"global_key":"annakia","name":"annakia","name_pinyin":"","updated_at":1434335589000,"path":"/u/annakia","status":1,"is_member":0,"id":107805,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436931341000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/kloze\" rel\u003d\"nofollow\"\u003e@kloze\u003c/a\u003e 啊。难道我记错了是4分钟?"},{"id":132949,"tweet_id":59310,"owner_id":52103,"owner":{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436931235000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/annakia\" rel\u003d\"nofollow\"\u003e@annakia\u003c/a\u003e 我擦。。还有10分钟?"}],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/424\" rel\u003d\"nofollow\"\u003e#优衣库#\u003c/a\u003e \u003c/p\u003e \n\u003ch4 id\u003d\"user-content-对于不知道优衣库的同学,这里集合贴\"\u003e对于不知道优衣库的同学,这里集合贴\u003c/h4\u003e \n\u003cp\u003e\u003ca href\u003d\"http://mp.weixin.qq.com/s?__biz\u003dMzA4MTMyMDEwNg\u003d\u003d\u0026amp;mid\u003d208239752\u0026amp;idx\u003d1\u0026amp;sn\u003d62f7df610d36b12fc8ca089561755d1a\u0026amp;scene\u003d1\u0026amp;key\u003dc76941211a49ab58fd8a9a4fb5cb54c29b2fbcd67766f7c8c942aff14ebf902fbe25ab4ea4a53af2ffb38b9d1eac15f4\u0026amp;ascene\u003d0\u0026amp;uin\u003dMjM2MDQwNjU%3D\u0026amp;devicetype\u003diMac+MacBookPro11\" target\u003d\"_blank\" class\u003d\" auto-link\" rel\u003d\"nofollow\"\u003ehttp://mp.weixin.qq.com/s?__biz\u003dMzA4MTMyMDEwNg\u003d\u003d\u0026amp;mid\u003d208239752\u0026amp;idx\u003d1\u0026amp;sn\u003d62f7df610d36b12fc8ca089561755d1a\u0026amp;scene\u003d1\u0026amp;key\u003dc76941211a49ab58fd8a9a4fb5cb54c29b2fbcd67766f7c8c942aff14ebf902fbe25ab4ea4a53af2ffb38b9d1eac15f4\u0026amp;ascene\u003d0\u0026amp;uin\u003dMjM2MDQwNjU%253D%26devicetype%3DiMac+MacBookPro11%2C1+OSX+OSX+10.10.3+build(14D136)\u0026amp;version\u003d11020012\u0026amp;pass_ticket\u003dolGiuWJhoCKfQrMX2WKOUC08QSo4wAJOiAUXi1K7FcM%3D\u003c/a\u003e\u003c/p\u003e","path":"/u/kloze/pp/59310","activity_id":0,"liked":false,"like_users":[{"sex":0,"birthday":"1993-12-03","location":"北京 石景山区","company":"博看文思","slogan":"......","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/0e4d1302-3276-43b4-9ee8-cbbae8fd9633.jpg?imageMogr2/auto-orient/format/jpeg/crop/!640x640a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/76d6805f-0181-4bb4-95a1-82add25d161f.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/0e4d1302-3276-43b4-9ee8-cbbae8fd9633.jpg?imageMogr2/auto-orient/format/jpeg/crop/!640x640a0a0","created_at":1420375111000,"last_logined_at":1436499437000,"global_key":"wangkang","name":"王康","name_pinyin":"|wangkang|wk","updated_at":1420375111000,"path":"/u/wangkang","status":1,"is_member":0,"id":68838,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},"name":"优衣库","created_at":1436927129000,"id":424,"user_list":[{"sex":1,"birthday":"1989-10-13","location":"河南 焦作","company":"","slogan":"前端开发 加油!","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/437af37d-94db-4028-8846-f0cfe8ef46f1.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/28d632af-e4da-4f64-8797-03ef16aee603.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/437af37d-94db-4028-8846-f0cfe8ef46f1.jpg","created_at":1425371492000,"last_logined_at":1437031269000,"global_key":"2ni","name":"2ni","name_pinyin":"","updated_at":1425371492000,"path":"/u/2ni","status":1,"is_member":0,"id":83165,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1970-01-01","location":"上海 浦东新区","company":"","slogan":"即使再渺小,也要不顾一切地成长! http://raoyc.com","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/8dc8714c-5f6f-4e4b-8564-83afda50c712.jpg?imageMogr2/auto-orient/format/jpeg/crop/!363x363a32a15","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/8dc8714c-5f6f-4e4b-8564-83afda50c712.jpg?imageMogr2/auto-orient/format/jpeg/crop/!363x363a32a15","created_at":1405924724000,"last_logined_at":1437028982000,"global_key":"rao","name":"飞扬","name_pinyin":"|fy|feiyang","updated_at":1405924724000,"path":"/u/rao","status":1,"is_member":0,"id":2279,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1990-01-01","location":"江苏 南京","company":"南京安元科技有限公司","slogan":"好好学习,天天向上!","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/5db41905-efc1-4e35-94ff-21f5b9e7c625.png?imageMogr2/auto-orient/format/png/crop/!128x128a8a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/5db41905-efc1-4e35-94ff-21f5b9e7c625.png?imageMogr2/auto-orient/format/png/crop/!128x128a8a0","created_at":1417770252000,"last_logined_at":1437008173000,"global_key":"songyiwei","name":"这个人出现在","name_pinyin":"|zgrcxz|zhegerenchuxianzai","updated_at":1417770252000,"path":"/u/songyiwei","status":1,"is_member":0,"id":51246,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-13.png","gravatar":"https://dn-coding-net-avatar.qbox.me/706eb577-6a88-464d-b635-e759067019d6.jpg","lavatar":"/static/fruit_avatar/Fruit-13.png","created_at":1434507370000,"last_logined_at":1436411863000,"global_key":"jpr1990","name":"jpr1990","name_pinyin":"","updated_at":1434507370000,"path":"/u/jpr1990","status":1,"is_member":0,"id":108268,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1989-12-07","location":"广东 广州","company":"在路上","slogan":"你猜","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/60d61651-e9c5-4de2-9e84-5c2dd2c375fd.PNG?imageMogr2/auto-orient/format/jpeg/crop/!142x142a4a8","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/60d61651-e9c5-4de2-9e84-5c2dd2c375fd.PNG?imageMogr2/auto-orient/format/jpeg/crop/!142x142a4a8","created_at":1412759505000,"last_logined_at":1437012838000,"global_key":"seekwe","name":"seekwe","name_pinyin":"","updated_at":1412759505000,"path":"/u/seekwe","status":1,"is_member":0,"id":34258,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":1,"birthday":"1988-12-18","location":"江西 南昌","company":"上海裁软","slogan":"Study hard and make progress every day","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/d7d4afe4-9440-4d2d-a141-62ff26c9a42b.jpg?imageMogr2/auto-orient/format/jpeg/crop/!480x480a0a8","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/d7d4afe4-9440-4d2d-a141-62ff26c9a42b.jpg?imageMogr2/auto-orient/format/jpeg/crop/!480x480a0a8","created_at":1405580241000,"last_logined_at":1436619815000,"global_key":"yvsh","name":"littleyue","name_pinyin":"","updated_at":1405580241000,"path":"/u/yvsh","status":1,"is_member":0,"id":1292,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":2,"birthday":"1994-08-02","location":"山东 烟台","company":"公司","slogan":"にゃにゃん╭( ・ㅂ・)و ̑̑ye","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/669e1714-e6d7-47d6-8984-8de4e5c3d5c1.png?imageMogr2/auto-orient/format/png/crop/!450x450a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/ee4fc3ca-73f8-433e-be09-e67b11610011.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/669e1714-e6d7-47d6-8984-8de4e5c3d5c1.png?imageMogr2/auto-orient/format/png/crop/!450x450a0a0","created_at":1406008158000,"last_logined_at":1436947197000,"global_key":"xin","name":"xin","name_pinyin":"","updated_at":1406008158000,"path":"/u/xin","status":1,"is_member":0,"id":2552,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1111-11-11","location":"北京 西城区","company":"","slogan":"职位:CDO+CZO","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/ec3f4a9d-e6b9-41db-80ec-0ae449a43e10.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/ec3f4a9d-e6b9-41db-80ec-0ae449a43e10.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","created_at":1413647368000,"last_logined_at":1437045443759,"global_key":"itsing","name":"一台一台一台台","name_pinyin":"|ytytytt|yitaiyitaiyitaitai","updated_at":1413647368000,"path":"/u/itsing","status":1,"is_member":0,"id":35907,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":5,"hot_tweet":{"id":59612,"owner_id":51190,"owner":{"sex":2,"birthday":"1998-03-04","location":"河北 保定","company":"QiLinYunS","slogan":"名字是潘潘起的,头像是拿ziying的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","created_at":1417764325000,"last_logined_at":1437023057000,"global_key":"TXisfine","name":"小谈谈","name_pinyin":"|xtt|xiaotantan","updated_at":1417764325000,"path":"/u/TXisfine","status":1,"is_member":0,"id":51190,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437023631000,"likes":4,"comments":1,"comment_list":[{"id":133523,"tweet_id":59612,"owner_id":52103,"owner":{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437026843000,"content":"新技能 get"}],"device":"OPPO Find7","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/335\" rel\u003d\"nofollow\"\u003e#gif#\u003c/a\u003e 【新技能get√】感觉自己终于能到很多地方了。\u003cbr\u003e \u003ca href\u003d\"https://dn-coding-net-production-pp.qbox.me/dd3a700f-ddb9-4ab9-a866-45b9f932ffad.gif\" target\u003d\"_blank\" class\u003d\"bubble-markdown-image-link\" rel\u003d\"nofollow\"\u003e\u003cimg src\u003d\"https://dn-coding-net-production-pp.qbox.me/dd3a700f-ddb9-4ab9-a866-45b9f932ffad.gif\" alt\u003d\"图片\" class\u003d\" bubble-markdown-image\"\u003e\u003c/a\u003e\u003c/p\u003e","path":"/u/TXisfine/pp/59612","activity_id":0,"liked":false,"like_users":[{"sex":0,"birthday":"1991-10-20","location":"湖北 武汉","company":"undefined,none,error.","slogan":"KISS","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/e4f083cc-d3db-4041-87c0-195979878e46.png?imageMogr2/auto-orient/format/png/crop/!430x430a0a172","gravatar":"https://dn-coding-net-avatar.qbox.me/542aa98c-1183-442e-8744-907750cdddbb.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/e4f083cc-d3db-4041-87c0-195979878e46.png?imageMogr2/auto-orient/format/png/crop/!430x430a0a172","created_at":1419861720000,"last_logined_at":1437038279000,"global_key":"wenki","name":"wenki","name_pinyin":"","updated_at":1419861720000,"path":"/u/wenki","status":1,"is_member":0,"id":64169,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1986-08-16","location":"山东 青岛","company":"保密","slogan":"有点想法很好,有点行动更好","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ea91de1-b5bc-45a0-b972-da612a9c08fb.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/500c922c-1b6b-4408-9296-5fe7c44a43bd.png","lavatar":"https://dn-coding-net-production-static.qbox.me/9ea91de1-b5bc-45a0-b972-da612a9c08fb.jpg","created_at":1409097666000,"last_logined_at":1437031418000,"global_key":"silverwing","name":"愚夫","name_pinyin":"|yf|yufu","updated_at":1409097666000,"path":"/u/silverwing","status":1,"is_member":0,"id":22811,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1975-01-01","location":"河北 石家庄","company":"( ͡° ͜ʖ ͡°) ⌒* ( `灬` )*y。o0○","slogan":"勤","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","gravatar":"https://dn-coding-net-avatar.qbox.me/778054a6-374c-48cc-ae89-524a28af00ff.png","lavatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","created_at":1415687370000,"last_logined_at":1436982735000,"global_key":"fwolf","name":"Fwolf","name_pinyin":"","updated_at":1415687370000,"path":"/u/fwolf","status":1,"is_member":0,"id":41106,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},"name":"gif","created_at":1435323487000,"id":335,"user_list":[{"sex":2,"birthday":"1998-03-04","location":"河北 保定","company":"QiLinYunS","slogan":"名字是潘潘起的,头像是拿ziying的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","created_at":1417764325000,"last_logined_at":1437023057000,"global_key":"TXisfine","name":"小谈谈","name_pinyin":"|xtt|xiaotantan","updated_at":1417764325000,"path":"/u/TXisfine","status":1,"is_member":0,"id":51190,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":2,"birthday":"1990-05-04","location":"北京","company":"永希","slogan":"https://a-hope.cn","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/1d3476cac70c29fe779592a42ea7bff2.png","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/1d3476cac70c29fe779592a42ea7bff2.png","created_at":1405998676000,"last_logined_at":1436187451000,"global_key":"jaysun","name":"卡基猫","name_pinyin":"|kjm|kajimao","updated_at":1405998676000,"path":"/u/jaysun","status":1,"is_member":0,"id":2455,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1111-11-11","location":"北京 西城区","company":"","slogan":"职位:CDO+CZO","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/ec3f4a9d-e6b9-41db-80ec-0ae449a43e10.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/ec3f4a9d-e6b9-41db-80ec-0ae449a43e10.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","created_at":1413647368000,"last_logined_at":1437045443759,"global_key":"itsing","name":"一台一台一台台","name_pinyin":"|ytytytt|yitaiyitaiyitaitai","updated_at":1413647368000,"path":"/u/itsing","status":1,"is_member":0,"id":35907,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1994-09-11","location":"广东 深圳","company":"","slogan":"Simplicity is the ultimate sophistication.","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/d0b84a18-3dde-43d7-b3e0-3ffbe785df90.png?imageMogr2/auto-orient/format/png/crop/!240x240a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/cd9a28a2-b6b6-4883-84ee-af727c01a662.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/d0b84a18-3dde-43d7-b3e0-3ffbe785df90.png?imageMogr2/auto-orient/format/png/crop/!240x240a0a0","created_at":1422087534000,"last_logined_at":1436842049000,"global_key":"chnhyg","name":"小模样儿","name_pinyin":"|xmye|xiaomoyanger","updated_at":1422087534000,"path":"/u/chnhyg","status":1,"is_member":0,"id":77755,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1990-06-10","location":"深圳","company":"Coding.net","slogan":"\u0026lt;img src\u003d1 onerror\u003dalert(1)\u0026gt;","introduction":"嗯?","avatar":"https://dn-coding-net-avatar.qbox.me/dc57e8be-3355-4c05-b1e1-c5e52be8e205.png","gravatar":"https://dn-coding-net-avatar.qbox.me/dc57e8be-3355-4c05-b1e1-c5e52be8e205.png","lavatar":"https://dn-coding-net-avatar.qbox.me/dc57e8be-3355-4c05-b1e1-c5e52be8e205.png","created_at":1399045331000,"last_logined_at":1437033487000,"global_key":"wzw","name":"wzw","name_pinyin":"","updated_at":1399045331000,"path":"/u/wzw","status":1,"is_member":0,"id":1,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":6,"hot_tweet":{"id":56708,"owner_id":65953,"owner":{"sex":0,"birthday":"1991-04-03","location":"江苏 南京","company":"南京厚建","slogan":"Stay Hungry, Stay Foolish! Be a B dever","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9190a6b7-1217-4108-b08b-be7f1819232b.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/89bd6ea6-3e6c-4cee-b44b-3690e3857713.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/9190a6b7-1217-4108-b08b-be7f1819232b.jpg","created_at":1419996323000,"last_logined_at":1436884485000,"global_key":"milker","name":"Milker","name_pinyin":"","updated_at":1419996323000,"path":"/u/milker","status":1,"is_member":0,"id":65953,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436284641000,"likes":0,"comments":0,"comment_list":[],"device":"华为 荣耀6","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/371\" rel\u003d\"nofollow\"\u003e#爱码诗#\u003c/a\u003e \u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/smiley.png\" title\u003d\"smiley\"\u003e\u003cimg class\u003d\"emotion monkey\" src\u003d\"https://coding.net/static/coding-emotions/coding-emoji-09.png\" title\u003d\"内急\"\u003e\u003c/p\u003e","path":"/u/milker/pp/56708","activity_id":0,"liked":false,"like_users":[]},"name":"爱码诗","created_at":1435855932000,"id":371,"user_list":[{"sex":0,"birthday":"1985-01-01","location":"山东 淄博","company":"sdut","slogan":"just coding ,just fun!","introduction":"","avatar":"/static/fruit_avatar/Fruit-11.png","gravatar":"","lavatar":"/static/fruit_avatar/Fruit-11.png","created_at":1416744216000,"last_logined_at":1436710993000,"global_key":"lixinxing","name":"lixinxing","name_pinyin":"","updated_at":1416744216000,"path":"/u/lixinxing","status":1,"is_member":0,"id":47280,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"北京 朝阳区","company":"NSB","slogan":"刚兴趣的","introduction":"","avatar":"/static/fruit_avatar/Fruit-3.png","gravatar":"https://dn-coding-net-avatar.qbox.me/62a91da2-f336-4aac-bc68-b554ab383fc9.jpg","lavatar":"/static/fruit_avatar/Fruit-3.png","created_at":1421161473000,"last_logined_at":1437013178000,"global_key":"zhangyuhan","name":"zhangyuhan","name_pinyin":"","updated_at":1421161473000,"path":"/u/zhangyuhan","status":1,"is_member":0,"id":74975,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"sdut","slogan":"sdut","introduction":"","avatar":"/static/fruit_avatar/Fruit-20.png","gravatar":"https://dn-coding-net-avatar.qbox.me/0f58a707-578a-43c8-a35c-d21c14944d94.jpg","lavatar":"/static/fruit_avatar/Fruit-20.png","created_at":1433674552000,"last_logined_at":1436841045000,"global_key":"zhuna","name":"zhuna","name_pinyin":"","updated_at":1433674552000,"path":"/u/zhuna","status":1,"is_member":0,"id":106469,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1991-05-11","location":"广东 深圳","company":"森普航科","slogan":"xxx","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/8d6da319-d09a-41f9-b90d-28156bedd492.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/f972df9d-67d3-4b55-b845-99c266b10473.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/8d6da319-d09a-41f9-b90d-28156bedd492.jpg","created_at":1433677544000,"last_logined_at":1436939933000,"global_key":"yao1243","name":"yao1243","name_pinyin":"","updated_at":1433677544000,"path":"/u/yao1243","status":1,"is_member":0,"id":106476,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1991-04-03","location":"江苏 南京","company":"南京厚建","slogan":"Stay Hungry, Stay Foolish! Be a B dever","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9190a6b7-1217-4108-b08b-be7f1819232b.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/89bd6ea6-3e6c-4cee-b44b-3690e3857713.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/9190a6b7-1217-4108-b08b-be7f1819232b.jpg","created_at":1419996323000,"last_logined_at":1436884485000,"global_key":"milker","name":"Milker","name_pinyin":"","updated_at":1419996323000,"path":"/u/milker","status":1,"is_member":0,"id":65953,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1996-12-12","location":"江苏 ","company":"卖萌集团","slogan":"LL 大法好!舰C大法好!node大法好!nico大法好!nexus大法好!Coding大法好!","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/15b151ef-2df1-457a-913f-ec62d7b536fd.jpg?imageMogr2/auto-orient/format/jpeg/crop/!800x800a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/15b151ef-2df1-457a-913f-ec62d7b536fd.jpg?imageMogr2/auto-orient/format/jpeg/crop/!800x800a0a0","created_at":1417169502000,"last_logined_at":1436696171000,"global_key":"luojia","name":"天朝冰冻型队长舰QAQ","name_pinyin":"|tcbdxdcj|tianchaobingdongxingduichangjian","updated_at":1417169502000,"path":"/u/luojia","status":1,"is_member":0,"id":49005,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":2,"hot_tweet":{"id":59432,"owner_id":27666,"owner":{"sex":0,"birthday":"1998-05-15","location":"孜然麻辣熊黑科技研究中心","company":"孜然麻辣熊黑科技有限公司","slogan":"让懂的人懂,让不懂的人不懂。","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/0b6499da-33ba-489d-99d0-4324c9f53e7c.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/0b6499da-33ba-489d-99d0-4324c9f53e7c.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a0a0","created_at":1409313681000,"last_logined_at":1437046129576,"global_key":"linqun","name":"孜然麻辣熊大大","name_pinyin":"|zrmlxdd|ziranmalaxiongdada","updated_at":1409313681000,"path":"/u/linqun","status":1,"is_member":0,"id":27666,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436957749000,"likes":1,"comments":5,"comment_list":[{"id":133240,"tweet_id":59432,"owner_id":50262,"owner":{"sex":0,"birthday":"1989-02-03","location":"河南 郑州","company":"郑州信源信息技术股份有限公司","slogan":"为啥不是挣钱的挣?","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/ed0cc43b-3246-4a9c-8eb2-bb578d90c042.gif?imageMogr2/auto-orient/format/jpg/crop/!200x200a82a0","gravatar":"https://dn-coding-net-avatar.qbox.me/a30a816c-b7e9-491d-99ee-80fc41c8a152.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/ed0cc43b-3246-4a9c-8eb2-bb578d90c042.gif?imageMogr2/auto-orient/format/jpg/crop/!200x200a82a0","created_at":1417580750000,"last_logined_at":1436971661000,"global_key":"kevinzheng","name":"啊郑","name_pinyin":"|az|azheng","updated_at":1417580750000,"path":"/u/kevinzheng","status":1,"is_member":0,"id":50262,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436972412000,"content":"0.01 马币到手"},{"id":133237,"tweet_id":59432,"owner_id":64057,"owner":{"sex":0,"birthday":"1988-09-07","location":"上海 嘉定区","company":"","slogan":"程序员分为11种:用Windows、Linux和OS X的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/af567cd7-fcf9-408f-a91f-aac557dfcf93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!500x500a36a30","gravatar":"https://dn-coding-net-avatar.qbox.me/e3c7367b-a89d-4174-b278-5c7d9c3bcb3c.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/af567cd7-fcf9-408f-a91f-aac557dfcf93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!500x500a36a30","created_at":1419852772000,"last_logined_at":1436446665000,"global_key":"sinkcup","name":"sinkcup","name_pinyin":"","updated_at":1419852772000,"path":"/u/sinkcup","status":1,"is_member":0,"id":64057,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436971634000,"content":"赶明天,俺试试"},{"id":133189,"tweet_id":59432,"owner_id":52103,"owner":{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436961310000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/linqun\" rel\u003d\"nofollow\"\u003e@孜然麻辣熊大大\u003c/a\u003e 有点用 每次下他家的软件很烦 必须注册 登录下载"},{"id":133176,"tweet_id":59432,"owner_id":27666,"owner":{"sex":0,"birthday":"1998-05-15","location":"孜然麻辣熊黑科技研究中心","company":"孜然麻辣熊黑科技有限公司","slogan":"让懂的人懂,让不懂的人不懂。","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/0b6499da-33ba-489d-99d0-4324c9f53e7c.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/0b6499da-33ba-489d-99d0-4324c9f53e7c.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a0a0","created_at":1409313681000,"last_logined_at":1437046129576,"global_key":"linqun","name":"孜然麻辣熊大大","name_pinyin":"|zrmlxdd|ziranmalaxiongdada","updated_at":1409313681000,"path":"/u/linqun","status":1,"is_member":0,"id":27666,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436958045000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/kloze\" rel\u003d\"nofollow\"\u003e@kloze\u003c/a\u003e 就是告诉Oracle我已经同意你的霸王条款了"},{"id":133173,"tweet_id":59432,"owner_id":52103,"owner":{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436957797000,"content":"绕过注册 \u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/smile.png\" title\u003d\"smile\"\u003e"}],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/385\" rel\u003d\"nofollow\"\u003e#熊大大小课堂#\u003c/a\u003e 下载Oracle官方JDK\u003cbr\u003e 只需要加个Header就可以了\u003cbr\u003e Example:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003ewget --no-check-certificate --no-cookies --header \"Cookie: oraclelicense\u003daccept-securebackup-cookie\" http://download.oracle.com/otn-pub/java/jdk/8u51-b16/jdk-8u51-linux-x64.rpm\n\u003c/code\u003e\u003c/pre\u003e","path":"/u/linqun/pp/59432","activity_id":0,"liked":false,"like_users":[{"sex":0,"birthday":"1988-09-07","location":"上海 嘉定区","company":"","slogan":"程序员分为11种:用Windows、Linux和OS X的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/af567cd7-fcf9-408f-a91f-aac557dfcf93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!500x500a36a30","gravatar":"https://dn-coding-net-avatar.qbox.me/e3c7367b-a89d-4174-b278-5c7d9c3bcb3c.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/af567cd7-fcf9-408f-a91f-aac557dfcf93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!500x500a36a30","created_at":1419852772000,"last_logined_at":1436446665000,"global_key":"sinkcup","name":"sinkcup","name_pinyin":"","updated_at":1419852772000,"path":"/u/sinkcup","status":1,"is_member":0,"id":64057,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},"name":"熊大大小课堂","created_at":1436238476000,"id":385,"user_list":[{"sex":0,"birthday":"1998-05-15","location":"孜然麻辣熊黑科技研究中心","company":"孜然麻辣熊黑科技有限公司","slogan":"让懂的人懂,让不懂的人不懂。","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/0b6499da-33ba-489d-99d0-4324c9f53e7c.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/0b6499da-33ba-489d-99d0-4324c9f53e7c.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a0a0","created_at":1409313681000,"last_logined_at":1437046129576,"global_key":"linqun","name":"孜然麻辣熊大大","name_pinyin":"|zrmlxdd|ziranmalaxiongdada","updated_at":1409313681000,"path":"/u/linqun","status":1,"is_member":0,"id":27666,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1998-05-15","location":"江苏 苏州","company":"","slogan":"逗比","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/ff6be095-d349-4ce6-94c1-92649f549e53.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a178a0","gravatar":"https://dn-coding-net-avatar.qbox.me/b40d153e-5bc3-49bf-8863-8e607e419a9e.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/ff6be095-d349-4ce6-94c1-92649f549e53.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a178a0","created_at":1410177912000,"last_logined_at":1437029996000,"global_key":"zrmlx","name":"孜然麻辣熊","name_pinyin":"|zrmlx|ziranmalaxiong","updated_at":1410177912000,"path":"/u/zrmlx","status":1,"is_member":0,"id":31525,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":2,"hot_tweet":{"id":58867,"owner_id":8259,"owner":{"sex":0,"birthday":"1991-10-28","location":"广东 广州","company":"广州曦和信息科技有限公司","slogan":"间歇性洗澡忘带内裤综合症","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/0e00f1a8-6450-4f7c-99b5-3cd6508402e4.jpg?imageMogr2/auto-orient/format/png/crop/!374x374a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/0e00f1a8-6450-4f7c-99b5-3cd6508402e4.jpg?imageMogr2/auto-orient/format/png/crop/!374x374a0a0","created_at":1407465734000,"last_logined_at":1436955652000,"global_key":"jackatlas","name":"jackatlas","name_pinyin":"","updated_at":1407465734000,"path":"/u/jackatlas","status":1,"is_member":0,"id":8259,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436776815000,"likes":1,"comments":2,"comment_list":[{"id":132595,"tweet_id":58867,"owner_id":8259,"owner":{"sex":0,"birthday":"1991-10-28","location":"广东 广州","company":"广州曦和信息科技有限公司","slogan":"间歇性洗澡忘带内裤综合症","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/0e00f1a8-6450-4f7c-99b5-3cd6508402e4.jpg?imageMogr2/auto-orient/format/png/crop/!374x374a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/0e00f1a8-6450-4f7c-99b5-3cd6508402e4.jpg?imageMogr2/auto-orient/format/png/crop/!374x374a0a0","created_at":1407465734000,"last_logined_at":1436955652000,"global_key":"jackatlas","name":"jackatlas","name_pinyin":"","updated_at":1407465734000,"path":"/u/jackatlas","status":1,"is_member":0,"id":8259,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436853131000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/panpan\" rel\u003d\"nofollow\"\u003e@潘潘\u003c/a\u003e 没有啦,只是感慨一下~"},{"id":132302,"tweet_id":58867,"owner_id":15,"owner":{"sex":1,"birthday":"1989-08-17","location":"广东深圳","company":"官方打杂妹","slogan":"我就是潘潘潘潘潘哈哈","introduction":"恩","avatar":"https://dn-coding-net-production-static.qbox.me/15efd14d-b90a-44b4-8a3a-63f355330941.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/15efd14d-b90a-44b4-8a3a-63f355330941.jpg","created_at":1399839374000,"last_logined_at":1436491923000,"global_key":"panpan","name":"潘潘","name_pinyin":"|pp|panpan","updated_at":1399839374000,"path":"/u/panpan","status":1,"is_member":0,"id":15,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436780441000,"content":"所以这是个招聘贴?"}],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/314\" rel\u003d\"nofollow\"\u003e#ReactJS#\u003c/a\u003e \u003cbr\u003e 看了 Coding 的《React 构建 WebIDE 的应用实践》ppt,Flux架构、测试,有许多值得学习的地方,遗憾没机会到现场。\u003c/p\u003e \n\u003cp\u003e另,靠谱设计师紧缺啊……\u003c/p\u003e","path":"/u/jackatlas/pp/58867","activity_id":0,"liked":false,"like_users":[{"sex":0,"birthday":"1991-06-03","location":"","company":"SideChef","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/87bcbe6c-c8e9-4cb3-86a1-0733637cbbd9.jpg?imageMogr2/auto-orient/format/jpeg/crop/!738x738a44a0","gravatar":"https://dn-coding-net-avatar.qbox.me/69839658-becc-495a-848d-196474aca65c.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/87bcbe6c-c8e9-4cb3-86a1-0733637cbbd9.jpg?imageMogr2/auto-orient/format/jpeg/crop/!738x738a44a0","created_at":1409075241000,"last_logined_at":1435990113000,"global_key":"xiequan","name":"xiequan","name_pinyin":"","updated_at":1409075241000,"path":"/u/xiequan","status":1,"is_member":0,"id":22789,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},"name":"ReactJS","created_at":1434984022000,"id":314,"user_list":[{"sex":0,"birthday":"1990-02-12","location":"广东 深圳 ","company":"Coding.net","slogan":"新的体验总是好的...","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/e3438bf4-8e93-4a6d-b116-683b9a30c992.jpg?imageMogr2/auto-orient/format/jpeg/crop/!640x640a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/4f0761bd-9dc1-4ce4-8d13-778ad2b16587.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/e3438bf4-8e93-4a6d-b116-683b9a30c992.jpg?imageMogr2/auto-orient/format/jpeg/crop/!640x640a0a0","created_at":1399058281000,"last_logined_at":1437048147982,"global_key":"bluishoul","name":"彭博","name_pinyin":"|pb|pengbo","updated_at":1399058281000,"path":"/u/bluishoul","status":1,"is_member":0,"id":7,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1991-10-28","location":"广东 广州","company":"广州曦和信息科技有限公司","slogan":"间歇性洗澡忘带内裤综合症","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/0e00f1a8-6450-4f7c-99b5-3cd6508402e4.jpg?imageMogr2/auto-orient/format/png/crop/!374x374a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/0e00f1a8-6450-4f7c-99b5-3cd6508402e4.jpg?imageMogr2/auto-orient/format/png/crop/!374x374a0a0","created_at":1407465734000,"last_logined_at":1436955652000,"global_key":"jackatlas","name":"jackatlas","name_pinyin":"","updated_at":1407465734000,"path":"/u/jackatlas","status":1,"is_member":0,"id":8259,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":1,"hot_tweet":{"id":55512,"owner_id":45858,"owner":{"sex":1,"birthday":"1990-11-17","location":"上海 长宁区","company":"coding","slogan":"做个呆萌的吃货","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/35154f1b-2576-40da-b148-bb43634d76e3.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/35154f1b-2576-40da-b148-bb43634d76e3.jpg","created_at":1416369632000,"last_logined_at":1436436740000,"global_key":"wangziying","name":"wangziying","name_pinyin":"","updated_at":1416369632000,"path":"/u/wangziying","status":1,"is_member":0,"id":45858,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436018003000,"likes":9,"comments":26,"comment_list":[{"id":128356,"tweet_id":55512,"owner_id":78571,"owner":{"sex":0,"birthday":"1985-01-01","location":"江苏 南京","company":"四季大通","slogan":"是金子总会发光的,是银子总会花光的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/f81220ce-1b3e-4d00-b8a8-b80718d98f3b.jpg?imageMogr2/auto-orient/format/jpeg/crop/!272x272a85a59","gravatar":"https://dn-coding-net-avatar.qbox.me/3e07669d-6ad8-4a65-91c9-4faa21070006.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/f81220ce-1b3e-4d00-b8a8-b80718d98f3b.jpg?imageMogr2/auto-orient/format/jpeg/crop/!272x272a85a59","created_at":1422436075000,"last_logined_at":1437034333000,"global_key":"steam","name":"steam","name_pinyin":"","updated_at":1422436075000,"path":"/u/steam","status":1,"is_member":0,"id":78571,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436148186000,"content":"卵有用"},{"id":128174,"tweet_id":55512,"owner_id":45858,"owner":{"sex":1,"birthday":"1990-11-17","location":"上海 长宁区","company":"coding","slogan":"做个呆萌的吃货","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/35154f1b-2576-40da-b148-bb43634d76e3.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/35154f1b-2576-40da-b148-bb43634d76e3.jpg","created_at":1416369632000,"last_logined_at":1436436740000,"global_key":"wangziying","name":"wangziying","name_pinyin":"","updated_at":1416369632000,"path":"/u/wangziying","status":1,"is_member":0,"id":45858,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436099482000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/hainuo\" rel\u003d\"nofollow\"\u003e@刘峰\u003c/a\u003e 神马?rio不和饮料一样。。。"},{"id":128120,"tweet_id":55512,"owner_id":5764,"owner":{"sex":0,"birthday":"1984-10-07","location":"山东 淄博 张店","company":"山东蓝标信息科技有限公司","slogan":"勇者无所畏惧 blog.hainuo.info","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/4cc88a4e-7adc-469f-98a5-6091ef2a35c3.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","created_at":1406871611000,"last_logined_at":1436929956000,"global_key":"hainuo","name":"刘峰","name_pinyin":"|lf|liufeng","updated_at":1406871611000,"path":"/u/hainuo","status":1,"is_member":0,"id":5764,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436089125000,"content":"回复了这么多都没有抓住重点 #那朋友是有的# 这才是争论的挤掉"},{"id":128076,"tweet_id":55512,"owner_id":5764,"owner":{"sex":0,"birthday":"1984-10-07","location":"山东 淄博 张店","company":"山东蓝标信息科技有限公司","slogan":"勇者无所畏惧 blog.hainuo.info","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/4cc88a4e-7adc-469f-98a5-6091ef2a35c3.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","created_at":1406871611000,"last_logined_at":1436929956000,"global_key":"hainuo","name":"刘峰","name_pinyin":"|lf|liufeng","updated_at":1406871611000,"path":"/u/hainuo","status":1,"is_member":0,"id":5764,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436078184000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/wangziying\" rel\u003d\"nofollow\"\u003e@wangziying\u003c/a\u003e 论一个女孩子要跟朋友喝酒。。。。。。"},{"id":128074,"tweet_id":55512,"owner_id":34878,"owner":{"sex":0,"birthday":"1985-01-13","location":"上海 长宁区","company":"coding.net","slogan":"将来的你,一定会感谢现在拼命努力的自己!","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/4d643669-e855-4eb1-b49f-ce526194a0e0.jpg?imageMogr2/auto-orient/format/jpeg/crop/!398x398a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/4d643669-e855-4eb1-b49f-ce526194a0e0.jpg?imageMogr2/auto-orient/format/jpeg/crop/!398x398a0a0","created_at":1413187080000,"last_logined_at":1436532041000,"global_key":"duwan","name":"杜万","name_pinyin":"|dw|duwan","updated_at":1413187080000,"path":"/u/duwan","status":1,"is_member":0,"id":34878,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436078028000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/sinkcup\" rel\u003d\"nofollow\"\u003e@sinkcup\u003c/a\u003e 消息真灵通"}],"device":"iPhone 6","location":"","coord":"","address":"","content":"\u003cp\u003e布置的如此少女心。\u003cbr\u003e 都是我一个人逛宜家一个人扛桌子一个人拼。\u003cbr\u003e \u003ca class\u003d\"topic\" href\u003d\"/pp/topic/379\" rel\u003d\"nofollow\"\u003e#男盆友有卵用#\u003c/a\u003e \u003ca href\u003d\"https://dn-coding-net-production-pp.qbox.me/2e7907d4-339a-474c-8505-6ff38f05efe1.jpg\" target\u003d\"_blank\" class\u003d\"bubble-markdown-image-link\" rel\u003d\"nofollow\"\u003e\u003cimg src\u003d\"https://dn-coding-net-production-pp.qbox.me/2e7907d4-339a-474c-8505-6ff38f05efe1.jpg\" alt\u003d\"图片\" class\u003d\" bubble-markdown-image\"\u003e\u003c/a\u003e\u003c/p\u003e","path":"/u/wangziying/pp/55512","activity_id":0,"liked":false,"like_users":[{"sex":0,"birthday":"1985-01-01","location":"湖北 咸宁","company":"","slogan":"座右铭未填写","introduction":"","avatar":"/static/fruit_avatar/Fruit-11.png","gravatar":"https://dn-coding-net-avatar.qbox.me/7d7a75b8-48fe-45d3-9027-7ca6f72c3285.jpg","lavatar":"/static/fruit_avatar/Fruit-11.png","created_at":1419096035000,"last_logined_at":1429602069000,"global_key":"hhhhhzx","name":"hhhhhzx","name_pinyin":"","updated_at":1419096035000,"path":"/u/hhhhhzx","status":1,"is_member":0,"id":57703,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1990-07-01","location":"","company":"","slogan":"为开发疯狂","introduction":"","avatar":"/static/fruit_avatar/Fruit-16.png","gravatar":"https://dn-coding-net-avatar.qbox.me/8067b583-7857-4b88-909e-669d366797c5.jpg","lavatar":"/static/fruit_avatar/Fruit-16.png","created_at":1427784114000,"last_logined_at":1436921948000,"global_key":"497192","name":"GloryMan","name_pinyin":"","updated_at":1427784114000,"path":"/u/497192","status":1,"is_member":0,"id":89867,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"北京 海淀区","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9101209f-8245-4f23-95d8-4acda257fa93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!638x638a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9101209f-8245-4f23-95d8-4acda257fa93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!638x638a0a0","created_at":1414995075000,"last_logined_at":1436928983000,"global_key":"soloist","name":"独奏","name_pinyin":"|dz|duzou","updated_at":1414995075000,"path":"/u/soloist","status":1,"is_member":0,"id":38679,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9bd51290-92b1-41fc-ba90-4aa5e8b37c3e.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9bd51290-92b1-41fc-ba90-4aa5e8b37c3e.jpg","created_at":1407920925000,"last_logined_at":1435399310000,"global_key":"pcmadman","name":"pcmadman","name_pinyin":"","updated_at":1407920925000,"path":"/u/pcmadman","status":1,"is_member":0,"id":8886,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":1,"birthday":"1985-06-07","location":"广东 深圳","company":"","slogan":"只爱自己爱的人","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/f224064d-5a94-456c-b96a-01aabb5c6973.jpg?imageMogr2/auto-orient/format/jpeg/crop/!640x640a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/f224064d-5a94-456c-b96a-01aabb5c6973.jpg?imageMogr2/auto-orient/format/jpeg/crop/!640x640a0a0","created_at":1402474269000,"last_logined_at":1436954777000,"global_key":"lingling","name":"灵灵","name_pinyin":"|ll|lingling","updated_at":1402474269000,"path":"/u/lingling","status":1,"is_member":0,"id":35,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"广东 深圳","company":"Coding.net","slogan":"大圣赐我火眼金睛发现一切BUG 。","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/f0dab52e-10ec-4a1c-ab2a-4e63f84ee9b7.jpg?imageMogr2/auto-orient/format/jpeg/crop/!440x440a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/5c1769a9-9acd-47c5-963b-29a933d910f3.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/f0dab52e-10ec-4a1c-ab2a-4e63f84ee9b7.jpg?imageMogr2/auto-orient/format/jpeg/crop/!440x440a0a0","created_at":1433735819000,"last_logined_at":1437046822137,"global_key":"zhct","name":"zhct","name_pinyin":"","updated_at":1433735819000,"path":"/u/zhct","status":1,"is_member":0,"id":106621,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"2015-06-18","location":"广西 南宁","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/737bcf6e-111d-49a4-8b0e-4de839b4716e.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/07d49a54-cb05-4a21-9b12-ed23f1fa71cf.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/737bcf6e-111d-49a4-8b0e-4de839b4716e.jpg","created_at":1427685305000,"last_logined_at":1437032650000,"global_key":"sophia123456","name":"小罗","name_pinyin":"|xl|xiaoluo","updated_at":1427685305000,"path":"/u/sophia123456","status":1,"is_member":0,"id":89471,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1988-09-07","location":"上海 嘉定区","company":"","slogan":"程序员分为11种:用Windows、Linux和OS X的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/af567cd7-fcf9-408f-a91f-aac557dfcf93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!500x500a36a30","gravatar":"https://dn-coding-net-avatar.qbox.me/e3c7367b-a89d-4174-b278-5c7d9c3bcb3c.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/af567cd7-fcf9-408f-a91f-aac557dfcf93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!500x500a36a30","created_at":1419852772000,"last_logined_at":1436446665000,"global_key":"sinkcup","name":"sinkcup","name_pinyin":"","updated_at":1419852772000,"path":"/u/sinkcup","status":1,"is_member":0,"id":64057,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1111-11-11","location":"北京 西城区","company":"","slogan":"职位:CDO+CZO","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/ec3f4a9d-e6b9-41db-80ec-0ae449a43e10.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/ec3f4a9d-e6b9-41db-80ec-0ae449a43e10.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","created_at":1413647368000,"last_logined_at":1437045443759,"global_key":"itsing","name":"一台一台一台台","name_pinyin":"|ytytytt|yitaiyitaiyitaitai","updated_at":1413647368000,"path":"/u/itsing","status":1,"is_member":0,"id":35907,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},"name":"男盆友有卵用","created_at":1436018003000,"id":379,"user_list":[{"sex":1,"birthday":"1990-11-17","location":"上海 长宁区","company":"coding","slogan":"做个呆萌的吃货","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/35154f1b-2576-40da-b148-bb43634d76e3.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/35154f1b-2576-40da-b148-bb43634d76e3.jpg","created_at":1416369632000,"last_logined_at":1436436740000,"global_key":"wangziying","name":"wangziying","name_pinyin":"","updated_at":1416369632000,"path":"/u/wangziying","status":1,"is_member":0,"id":45858,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":1,"hot_tweet":{"id":59581,"owner_id":58133,"owner":{"sex":0,"birthday":"1990-02-17","location":"浙江 杭州","company":"","slogan":"Talk is cheap, show me the Code !","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/c5332aff-f7bd-4b24-aca3-047136cdd331.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/ce5470f4-ed0b-4803-bf0e-c46b65ea881c.jpg","lavatar":"https://dn-coding-net-avatar.qbox.me/c5332aff-f7bd-4b24-aca3-047136cdd331.jpg","created_at":1419146313000,"last_logined_at":1436445476000,"global_key":"rickytan","name":"rickytan","name_pinyin":"","updated_at":1419146313000,"path":"/u/rickytan","status":1,"is_member":0,"id":58133,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437015856000,"likes":0,"comments":0,"comment_list":[],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/344\" rel\u003d\"nofollow\"\u003e#NSHipster#\u003c/a\u003e ReactiveCocoa是一个将函数响应式编程范例带入Objective-C的开源库。\u003ca href\u003d\"http://nshipster.cn/reactivecocoa/\" target\u003d\"_blank\" class\u003d\" auto-link\" rel\u003d\"nofollow\"\u003ehttp://nshipster.cn/reactivecocoa/\u003c/a\u003e\u003c/p\u003e","path":"/u/rickytan/pp/59581","activity_id":0,"liked":false,"like_users":[]},"name":"NSHipster","created_at":1435499364000,"id":344,"user_list":[{"sex":0,"birthday":"1990-02-17","location":"浙江 杭州","company":"","slogan":"Talk is cheap, show me the Code !","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/c5332aff-f7bd-4b24-aca3-047136cdd331.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/ce5470f4-ed0b-4803-bf0e-c46b65ea881c.jpg","lavatar":"https://dn-coding-net-avatar.qbox.me/c5332aff-f7bd-4b24-aca3-047136cdd331.jpg","created_at":1419146313000,"last_logined_at":1436445476000,"global_key":"rickytan","name":"rickytan","name_pinyin":"","updated_at":1419146313000,"path":"/u/rickytan","status":1,"is_member":0,"id":58133,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":2,"hot_tweet":{"id":58527,"owner_id":51190,"owner":{"sex":2,"birthday":"1998-03-04","location":"河北 保定","company":"QiLinYunS","slogan":"名字是潘潘起的,头像是拿ziying的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","created_at":1417764325000,"last_logined_at":1437023057000,"global_key":"TXisfine","name":"小谈谈","name_pinyin":"|xtt|xiaotantan","updated_at":1417764325000,"path":"/u/TXisfine","status":1,"is_member":0,"id":51190,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436677408000,"likes":6,"comments":4,"comment_list":[{"id":131966,"tweet_id":58527,"owner_id":51190,"owner":{"sex":2,"birthday":"1998-03-04","location":"河北 保定","company":"QiLinYunS","slogan":"名字是潘潘起的,头像是拿ziying的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","created_at":1417764325000,"last_logined_at":1437023057000,"global_key":"TXisfine","name":"小谈谈","name_pinyin":"|xtt|xiaotantan","updated_at":1417764325000,"path":"/u/TXisfine","status":1,"is_member":0,"id":51190,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436711239000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/sinkcup\" rel\u003d\"nofollow\"\u003e@sinkcup\u003c/a\u003e \u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/joy.png\" title\u003d\"joy\"\u003e\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/joy.png\" title\u003d\"joy\"\u003e\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/joy.png\" title\u003d\"joy\"\u003e"},{"id":131964,"tweet_id":58527,"owner_id":51190,"owner":{"sex":2,"birthday":"1998-03-04","location":"河北 保定","company":"QiLinYunS","slogan":"名字是潘潘起的,头像是拿ziying的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","created_at":1417764325000,"last_logined_at":1437023057000,"global_key":"TXisfine","name":"小谈谈","name_pinyin":"|xtt|xiaotantan","updated_at":1417764325000,"path":"/u/TXisfine","status":1,"is_member":0,"id":51190,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436711225000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/lichi93\" rel\u003d\"nofollow\"\u003e@小七七\u003c/a\u003e 我也不知道啊!\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/joy.png\" title\u003d\"joy\"\u003e\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/joy.png\" title\u003d\"joy\"\u003e"},{"id":131927,"tweet_id":58527,"owner_id":64057,"owner":{"sex":0,"birthday":"1988-09-07","location":"上海 嘉定区","company":"","slogan":"程序员分为11种:用Windows、Linux和OS X的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/af567cd7-fcf9-408f-a91f-aac557dfcf93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!500x500a36a30","gravatar":"https://dn-coding-net-avatar.qbox.me/e3c7367b-a89d-4174-b278-5c7d9c3bcb3c.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/af567cd7-fcf9-408f-a91f-aac557dfcf93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!500x500a36a30","created_at":1419852772000,"last_logined_at":1436446665000,"global_key":"sinkcup","name":"sinkcup","name_pinyin":"","updated_at":1419852772000,"path":"/u/sinkcup","status":1,"is_member":0,"id":64057,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436705670000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/lichi93\" rel\u003d\"nofollow\"\u003e@小七七\u003c/a\u003e 北戴河吧……嘿嘿"},{"id":131906,"tweet_id":58527,"owner_id":17567,"owner":{"sex":1,"birthday":"1993-09-03","location":"台湾 宜兰县","company":"Coding.net","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/282e4f85-c279-4bf2-808e-1d45f7f1797d.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/282e4f85-c279-4bf2-808e-1d45f7f1797d.jpg","created_at":1408688496000,"last_logined_at":1436494187000,"global_key":"lichi93","name":"小七七","name_pinyin":"|xqq|xiaoqiqi","updated_at":1408688496000,"path":"/u/lichi93","status":1,"is_member":0,"id":17567,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436700642000,"content":"哈哈哈是吗?这哪\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/joy.png\" title\u003d\"joy\"\u003e"}],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/373\" rel\u003d\"nofollow\"\u003e#Coding壁纸#\u003c/a\u003e 台湾风光\u003c/p\u003e \n\u003cp\u003e\u003ca href\u003d\"https://dn-coding-net-production-pp.qbox.me/fc3d2c22-7d03-4628-80b5-347c6da2382a.jpg\" target\u003d\"_blank\" class\u003d\"bubble-markdown-image-link\" rel\u003d\"nofollow\"\u003e\u003cimg src\u003d\"https://dn-coding-net-production-pp.qbox.me/fc3d2c22-7d03-4628-80b5-347c6da2382a.jpg\" alt\u003d\"图片\" class\u003d\" bubble-markdown-image\"\u003e\u003c/a\u003e\u003c/p\u003e","path":"/u/TXisfine/pp/58527","activity_id":0,"liked":false,"like_users":[{"sex":1,"birthday":"1995-01-01","location":"","company":"","slogan":"把猴子抱回家","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/b09accfe-2dd3-4320-aec3-5a335738ebc5.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/8a8f4840-a7f6-48d2-9a17-6c46e66eb212.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/b09accfe-2dd3-4320-aec3-5a335738ebc5.jpg","created_at":1436779066000,"last_logined_at":1437016596000,"global_key":"mian","name":"豆芽芽","name_pinyin":"|dyy|douyaya","updated_at":1436779066000,"path":"/u/mian","status":1,"is_member":0,"id":113646,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1993-02-04","location":"","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-18.png","gravatar":"","lavatar":"/static/fruit_avatar/Fruit-18.png","created_at":1417670875000,"last_logined_at":1435509299000,"global_key":"appletang","name":"青天黎明","name_pinyin":"|qingtianliming|qtlm","updated_at":1417670875000,"path":"/u/appletang","status":1,"is_member":0,"id":50636,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1984-12-23","location":"广东 深圳 ","company":"Coding.net","slogan":"岂能尽如人意,但求无愧我心","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/ef54d4ed-9c94-4963-bfe0-3bab5b7ab7a8.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/ef54d4ed-9c94-4963-bfe0-3bab5b7ab7a8.jpg","created_at":1399066489000,"last_logined_at":1437047462695,"global_key":"zhlmmc","name":"zhlmmc","name_pinyin":"","updated_at":1399066489000,"path":"/u/zhlmmc","status":1,"is_member":0,"id":8,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":1,"birthday":"1993-09-03","location":"台湾 宜兰县","company":"Coding.net","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/282e4f85-c279-4bf2-808e-1d45f7f1797d.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/282e4f85-c279-4bf2-808e-1d45f7f1797d.jpg","created_at":1408688496000,"last_logined_at":1436494187000,"global_key":"lichi93","name":"小七七","name_pinyin":"|xqq|xiaoqiqi","updated_at":1408688496000,"path":"/u/lichi93","status":1,"is_member":0,"id":17567,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6cfa25fc-794c-4a0d-8695-27c4219a4cda.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/6cfa25fc-794c-4a0d-8695-27c4219a4cda.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","created_at":1416498539000,"last_logined_at":1436770502000,"global_key":"esec","name":"Esec","name_pinyin":"","updated_at":1416498539000,"path":"/u/esec","status":1,"is_member":0,"id":46682,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":1,"birthday":"1985-06-07","location":"广东 深圳","company":"","slogan":"只爱自己爱的人","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/f224064d-5a94-456c-b96a-01aabb5c6973.jpg?imageMogr2/auto-orient/format/jpeg/crop/!640x640a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/f224064d-5a94-456c-b96a-01aabb5c6973.jpg?imageMogr2/auto-orient/format/jpeg/crop/!640x640a0a0","created_at":1402474269000,"last_logined_at":1436954777000,"global_key":"lingling","name":"灵灵","name_pinyin":"|ll|lingling","updated_at":1402474269000,"path":"/u/lingling","status":1,"is_member":0,"id":35,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},"name":"Coding壁纸","created_at":1435882115000,"id":373,"user_list":[{"sex":0,"birthday":"1990-10-17","location":"","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-2.png","gravatar":"https://dn-coding-net-avatar.qbox.me/1431273e-8432-476d-ad4d-e746b477fb86.jpg","lavatar":"/static/fruit_avatar/Fruit-2.png","created_at":1435884228000,"last_logined_at":1435981050000,"global_key":"goudaxiong","name":"goudaxiong","name_pinyin":"","updated_at":1435884228000,"path":"/u/goudaxiong","status":1,"is_member":0,"id":111166,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":2,"birthday":"1998-03-04","location":"河北 保定","company":"QiLinYunS","slogan":"名字是潘潘起的,头像是拿ziying的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","created_at":1417764325000,"last_logined_at":1437023057000,"global_key":"TXisfine","name":"小谈谈","name_pinyin":"|xtt|xiaotantan","updated_at":1417764325000,"path":"/u/TXisfine","status":1,"is_member":0,"id":51190,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":1,"hot_tweet":{"id":58530,"owner_id":17567,"owner":{"sex":1,"birthday":"1993-09-03","location":"台湾 宜兰县","company":"Coding.net","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/282e4f85-c279-4bf2-808e-1d45f7f1797d.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/282e4f85-c279-4bf2-808e-1d45f7f1797d.jpg","created_at":1408688496000,"last_logined_at":1436494187000,"global_key":"lichi93","name":"小七七","name_pinyin":"|xqq|xiaoqiqi","updated_at":1408688496000,"path":"/u/lichi93","status":1,"is_member":0,"id":17567,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436678017000,"likes":12,"comments":14,"comment_list":[{"id":131926,"tweet_id":58530,"owner_id":64057,"owner":{"sex":0,"birthday":"1988-09-07","location":"上海 嘉定区","company":"","slogan":"程序员分为11种:用Windows、Linux和OS X的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/af567cd7-fcf9-408f-a91f-aac557dfcf93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!500x500a36a30","gravatar":"https://dn-coding-net-avatar.qbox.me/e3c7367b-a89d-4174-b278-5c7d9c3bcb3c.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/af567cd7-fcf9-408f-a91f-aac557dfcf93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!500x500a36a30","created_at":1419852772000,"last_logined_at":1436446665000,"global_key":"sinkcup","name":"sinkcup","name_pinyin":"","updated_at":1419852772000,"path":"/u/sinkcup","status":1,"is_member":0,"id":64057,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436705627000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/succubus\" rel\u003d\"nofollow\"\u003e@FJH在这里\u003c/a\u003e 鼓掌^o^"},{"id":131870,"tweet_id":58530,"owner_id":101897,"owner":{"sex":1,"birthday":"1990-05-03","location":"","company":"coding","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/02fec97c-4ddf-4321-97c2-08bd4cf77e6d.png?imageMogr2/auto-orient/format/png/crop/!429x429a10a3","gravatar":"https://dn-coding-net-avatar.qbox.me/c6044d92-1932-492d-b32c-fd701d356884.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/02fec97c-4ddf-4321-97c2-08bd4cf77e6d.png?imageMogr2/auto-orient/format/png/crop/!429x429a10a3","created_at":1431924662000,"last_logined_at":1436975481000,"global_key":"succubus","name":"FJH在这里","name_pinyin":"|zzl|zaizheli","updated_at":1431924662000,"path":"/u/succubus","status":1,"is_member":0,"id":101897,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436690130000,"content":"“谢谢大家我们在一起了”"},{"id":131854,"tweet_id":58530,"owner_id":293,"owner":{"sex":0,"birthday":"1991-07-16","location":"广东 广州","company":"DJI","slogan":"厚积而薄发","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/4e81c8b4-a2af-479f-be17-48ad3d0615b7.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/4e81c8b4-a2af-479f-be17-48ad3d0615b7.jpg","created_at":1404914994000,"last_logined_at":1436071730000,"global_key":"martin","name":"martin","name_pinyin":"","updated_at":1404914994000,"path":"/u/martin","status":1,"is_member":0,"id":293,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436687996000,"content":"在一起!"},{"id":131837,"tweet_id":58530,"owner_id":36142,"owner":{"sex":0,"birthday":"1989-11-09","location":"江苏 苏州","company":"外星","slogan":"像我这样拉风帅气的码农,还能有第二个?~","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/c44d8766-f7cd-44c6-be93-b549727a3d53.jpg?imageMogr2/auto-orient/format/jpeg/crop/!534x534a266a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/c44d8766-f7cd-44c6-be93-b549727a3d53.jpg?imageMogr2/auto-orient/format/jpeg/crop/!534x534a266a0","created_at":1413787731000,"last_logined_at":1436654446000,"global_key":"brainqi","name":"BrainQi","name_pinyin":"","updated_at":1413787731000,"path":"/u/brainqi","status":1,"is_member":0,"id":36142,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436683147000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/fwolf\" rel\u003d\"nofollow\"\u003e@Fwolf\u003c/a\u003e \u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/sweat_smile.png\" title\u003d\"sweat_smile\"\u003e"},{"id":131824,"tweet_id":58530,"owner_id":41106,"owner":{"sex":0,"birthday":"1975-01-01","location":"河北 石家庄","company":"( ͡° ͜ʖ ͡°) ⌒* ( `灬` )*y。o0○","slogan":"勤","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","gravatar":"https://dn-coding-net-avatar.qbox.me/778054a6-374c-48cc-ae89-524a28af00ff.png","lavatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","created_at":1415687370000,"last_logined_at":1436982735000,"global_key":"fwolf","name":"Fwolf","name_pinyin":"","updated_at":1415687370000,"path":"/u/fwolf","status":1,"is_member":0,"id":41106,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436681442000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/brainqi\" rel\u003d\"nofollow\"\u003e@BrainQi\u003c/a\u003e 你這明顯是有企圖的"}],"device":"iPhone 6","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/411\" rel\u003d\"nofollow\"\u003e#JS大会#\u003c/a\u003e 和\u003ca class\u003d\"at-someone\" href\u003d\"/u/tsl0922\" rel\u003d\"nofollow\"\u003e@tsl0922\u003c/a\u003e 情侣装哦\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/grin.png\" title\u003d\"grin\"\u003e \u003ca href\u003d\"https://dn-coding-net-production-pp.qbox.me/2a19507d-bac5-4b27-b353-bd015f7dcfc9.jpg\" target\u003d\"_blank\" class\u003d\"bubble-markdown-image-link\" rel\u003d\"nofollow\"\u003e\u003cimg src\u003d\"https://dn-coding-net-production-pp.qbox.me/2a19507d-bac5-4b27-b353-bd015f7dcfc9.jpg\" alt\u003d\"图片\" class\u003d\" bubble-markdown-image\"\u003e\u003c/a\u003e\u003c/p\u003e","path":"/u/lichi93/pp/58530","activity_id":0,"liked":false,"like_users":[{"sex":0,"birthday":"1993-02-04","location":"","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-18.png","gravatar":"","lavatar":"/static/fruit_avatar/Fruit-18.png","created_at":1417670875000,"last_logined_at":1435509299000,"global_key":"appletang","name":"青天黎明","name_pinyin":"|qingtianliming|qtlm","updated_at":1417670875000,"path":"/u/appletang","status":1,"is_member":0,"id":50636,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1993-09-23","location":"海外 英国","company":"Insititute of Technology, Carlow","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/0ca5a787-e7ce-4c52-8d07-62eb28b2a60a.png?imageMogr2/auto-orient/format/png/crop/!177x177a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/0ca5a787-e7ce-4c52-8d07-62eb28b2a60a.png?imageMogr2/auto-orient/format/png/crop/!177x177a0a0","created_at":1417983021000,"last_logined_at":1436765048000,"global_key":"jerry_shao","name":"小耗子杰瑞","name_pinyin":"|xhzjr|xiaohaozijierui","updated_at":1417983021000,"path":"/u/jerry_shao","status":1,"is_member":0,"id":51643,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1988-09-07","location":"上海 嘉定区","company":"","slogan":"程序员分为11种:用Windows、Linux和OS X的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/af567cd7-fcf9-408f-a91f-aac557dfcf93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!500x500a36a30","gravatar":"https://dn-coding-net-avatar.qbox.me/e3c7367b-a89d-4174-b278-5c7d9c3bcb3c.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/af567cd7-fcf9-408f-a91f-aac557dfcf93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!500x500a36a30","created_at":1419852772000,"last_logined_at":1436446665000,"global_key":"sinkcup","name":"sinkcup","name_pinyin":"","updated_at":1419852772000,"path":"/u/sinkcup","status":1,"is_member":0,"id":64057,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1991-10-20","location":"湖北 武汉","company":"undefined,none,error.","slogan":"KISS","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/e4f083cc-d3db-4041-87c0-195979878e46.png?imageMogr2/auto-orient/format/png/crop/!430x430a0a172","gravatar":"https://dn-coding-net-avatar.qbox.me/542aa98c-1183-442e-8744-907750cdddbb.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/e4f083cc-d3db-4041-87c0-195979878e46.png?imageMogr2/auto-orient/format/png/crop/!430x430a0a172","created_at":1419861720000,"last_logined_at":1437038279000,"global_key":"wenki","name":"wenki","name_pinyin":"","updated_at":1419861720000,"path":"/u/wenki","status":1,"is_member":0,"id":64169,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1988-11-15","location":"","company":"Coding.net","slogan":"这世上所有的不公平都是因为当事人能力的不足。","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/fba26674-8279-4997-be74-3166d74afb74.jpg?imageMogr2/auto-orient/format/jpeg/crop/!564x564a0a142","gravatar":"https://dn-coding-net-avatar.qbox.me/36413eae-4037-40dc-99bc-1aacfb4cd1ef.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/fba26674-8279-4997-be74-3166d74afb74.jpg?imageMogr2/auto-orient/format/jpeg/crop/!564x564a0a142","created_at":1399123736000,"last_logined_at":1437045348475,"global_key":"kin","name":"书一","name_pinyin":"|sy|shuyi","updated_at":1399123736000,"path":"/u/kin","status":1,"is_member":0,"id":10,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":1,"birthday":"1987-08-04","location":"广东 深圳","company":"coding","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/1b9ac59b-9ef3-4328-990a-ed4cbe996476.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/1b9ac59b-9ef3-4328-990a-ed4cbe996476.jpg","created_at":1404874624000,"last_logined_at":1437045840626,"global_key":"guoguo","name":"蝈蝈尹","name_pinyin":"|ggy|guoguoyin","updated_at":1404874624000,"path":"/u/guoguo","status":1,"is_member":0,"id":289,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":1,"birthday":"1985-06-07","location":"广东 深圳","company":"","slogan":"只爱自己爱的人","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/f224064d-5a94-456c-b96a-01aabb5c6973.jpg?imageMogr2/auto-orient/format/jpeg/crop/!640x640a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/f224064d-5a94-456c-b96a-01aabb5c6973.jpg?imageMogr2/auto-orient/format/jpeg/crop/!640x640a0a0","created_at":1402474269000,"last_logined_at":1436954777000,"global_key":"lingling","name":"灵灵","name_pinyin":"|ll|lingling","updated_at":1402474269000,"path":"/u/lingling","status":1,"is_member":0,"id":35,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1988-01-01","location":"山东 济南","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/7633c8636fa4099608191032ac04a295.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/7633c8636fa4099608191032ac04a295.jpg","created_at":1405739267000,"last_logined_at":1436449171000,"global_key":"itfanr","name":"itfanr","name_pinyin":"","updated_at":1405739267000,"path":"/u/itfanr","status":1,"is_member":0,"id":2118,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":2,"birthday":"1998-03-04","location":"河北 保定","company":"QiLinYunS","slogan":"名字是潘潘起的,头像是拿ziying的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","created_at":1417764325000,"last_logined_at":1437023057000,"global_key":"TXisfine","name":"小谈谈","name_pinyin":"|xtt|xiaotantan","updated_at":1417764325000,"path":"/u/TXisfine","status":1,"is_member":0,"id":51190,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1989-11-09","location":"江苏 苏州","company":"外星","slogan":"像我这样拉风帅气的码农,还能有第二个?~","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/c44d8766-f7cd-44c6-be93-b549727a3d53.jpg?imageMogr2/auto-orient/format/jpeg/crop/!534x534a266a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/c44d8766-f7cd-44c6-be93-b549727a3d53.jpg?imageMogr2/auto-orient/format/jpeg/crop/!534x534a266a0","created_at":1413787731000,"last_logined_at":1436654446000,"global_key":"brainqi","name":"BrainQi","name_pinyin":"","updated_at":1413787731000,"path":"/u/brainqi","status":1,"is_member":0,"id":36142,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},"name":"JS大会","created_at":1436678017000,"id":411,"user_list":[{"sex":1,"birthday":"1993-09-03","location":"台湾 宜兰县","company":"Coding.net","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/282e4f85-c279-4bf2-808e-1d45f7f1797d.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/282e4f85-c279-4bf2-808e-1d45f7f1797d.jpg","created_at":1408688496000,"last_logined_at":1436494187000,"global_key":"lichi93","name":"小七七","name_pinyin":"|xqq|xiaoqiqi","updated_at":1408688496000,"path":"/u/lichi93","status":1,"is_member":0,"id":17567,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":4,"hot_tweet":{"id":54362,"owner_id":5764,"owner":{"sex":0,"birthday":"1984-10-07","location":"山东 淄博 张店","company":"山东蓝标信息科技有限公司","slogan":"勇者无所畏惧 blog.hainuo.info","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/4cc88a4e-7adc-469f-98a5-6091ef2a35c3.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","created_at":1406871611000,"last_logined_at":1436929956000,"global_key":"hainuo","name":"刘峰","name_pinyin":"|lf|liufeng","updated_at":1406871611000,"path":"/u/hainuo","status":1,"is_member":0,"id":5764,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1435771908000,"likes":0,"comments":6,"comment_list":[{"id":126416,"tweet_id":54362,"owner_id":27666,"owner":{"sex":0,"birthday":"1998-05-15","location":"孜然麻辣熊黑科技研究中心","company":"孜然麻辣熊黑科技有限公司","slogan":"让懂的人懂,让不懂的人不懂。","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/0b6499da-33ba-489d-99d0-4324c9f53e7c.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/0b6499da-33ba-489d-99d0-4324c9f53e7c.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a0a0","created_at":1409313681000,"last_logined_at":1437046129576,"global_key":"linqun","name":"孜然麻辣熊大大","name_pinyin":"|zrmlxdd|ziranmalaxiongdada","updated_at":1409313681000,"path":"/u/linqun","status":1,"is_member":0,"id":27666,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1435796170000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/hainuo\" rel\u003d\"nofollow\"\u003e@刘峰\u003c/a\u003e 表示每天冒泡8次,推代码数百次"},{"id":126415,"tweet_id":54362,"owner_id":2552,"owner":{"sex":2,"birthday":"1994-08-02","location":"山东 烟台","company":"公司","slogan":"にゃにゃん╭( ・ㅂ・)و ̑̑ye","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/669e1714-e6d7-47d6-8984-8de4e5c3d5c1.png?imageMogr2/auto-orient/format/png/crop/!450x450a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/ee4fc3ca-73f8-433e-be09-e67b11610011.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/669e1714-e6d7-47d6-8984-8de4e5c3d5c1.png?imageMogr2/auto-orient/format/png/crop/!450x450a0a0","created_at":1406008158000,"last_logined_at":1436947197000,"global_key":"xin","name":"xin","name_pinyin":"","updated_at":1406008158000,"path":"/u/xin","status":1,"is_member":0,"id":2552,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1435796122000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/hainuo\" rel\u003d\"nofollow\"\u003e@刘峰\u003c/a\u003e 之前一直在潜水开发好吧 昨天才水了一下 结果又回到榜上了"},{"id":126414,"tweet_id":54362,"owner_id":5764,"owner":{"sex":0,"birthday":"1984-10-07","location":"山东 淄博 张店","company":"山东蓝标信息科技有限公司","slogan":"勇者无所畏惧 blog.hainuo.info","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/4cc88a4e-7adc-469f-98a5-6091ef2a35c3.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","created_at":1406871611000,"last_logined_at":1436929956000,"global_key":"hainuo","name":"刘峰","name_pinyin":"|lf|liufeng","updated_at":1406871611000,"path":"/u/hainuo","status":1,"is_member":0,"id":5764,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1435796089000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/linqun\" rel\u003d\"nofollow\"\u003e@孜然麻辣熊大大\u003c/a\u003e 你也有活跃基因"},{"id":126413,"tweet_id":54362,"owner_id":5764,"owner":{"sex":0,"birthday":"1984-10-07","location":"山东 淄博 张店","company":"山东蓝标信息科技有限公司","slogan":"勇者无所畏惧 blog.hainuo.info","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/4cc88a4e-7adc-469f-98a5-6091ef2a35c3.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","created_at":1406871611000,"last_logined_at":1436929956000,"global_key":"hainuo","name":"刘峰","name_pinyin":"|lf|liufeng","updated_at":1406871611000,"path":"/u/hainuo","status":1,"is_member":0,"id":5764,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1435796068000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/xin\" rel\u003d\"nofollow\"\u003e@xin\u003c/a\u003e 你一直活跃好不好\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/disappointed_relieved.png\" title\u003d\"disappointed_relieved\"\u003e"},{"id":126411,"tweet_id":54362,"owner_id":27666,"owner":{"sex":0,"birthday":"1998-05-15","location":"孜然麻辣熊黑科技研究中心","company":"孜然麻辣熊黑科技有限公司","slogan":"让懂的人懂,让不懂的人不懂。","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/0b6499da-33ba-489d-99d0-4324c9f53e7c.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/0b6499da-33ba-489d-99d0-4324c9f53e7c.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a0a0","created_at":1409313681000,"last_logined_at":1437046129576,"global_key":"linqun","name":"孜然麻辣熊大大","name_pinyin":"|zrmlxdd|ziranmalaxiongdada","updated_at":1409313681000,"path":"/u/linqun","status":1,"is_member":0,"id":27666,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1435795982000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/xin\" rel\u003d\"nofollow\"\u003e@xin\u003c/a\u003e 你有热门用户基因"}],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca href\u003d\"https://dn-coding-net-production-pp.qbox.me/4e648f1d-e497-445d-8762-bff9ad0a5e3c.png\" target\u003d\"_blank\" class\u003d\"bubble-markdown-image-link\" rel\u003d\"nofollow\"\u003e\u003cimg src\u003d\"https://dn-coding-net-production-pp.qbox.me/4e648f1d-e497-445d-8762-bff9ad0a5e3c.png\" alt\u003d\"图片\" class\u003d\" bubble-markdown-image\"\u003e\u003c/a\u003e \u003cbr\u003e 上个排行榜好难,做个备忘把\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/359\" rel\u003d\"nofollow\"\u003e#调戏Coding#\u003c/a\u003e \u003c/p\u003e","path":"/u/hainuo/pp/54362","activity_id":0,"liked":false,"like_users":[]},"name":"调戏Coding","created_at":1435732658000,"id":359,"user_list":[{"sex":2,"birthday":"1994-08-02","location":"山东 烟台","company":"公司","slogan":"にゃにゃん╭( ・ㅂ・)و ̑̑ye","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/669e1714-e6d7-47d6-8984-8de4e5c3d5c1.png?imageMogr2/auto-orient/format/png/crop/!450x450a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/ee4fc3ca-73f8-433e-be09-e67b11610011.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/669e1714-e6d7-47d6-8984-8de4e5c3d5c1.png?imageMogr2/auto-orient/format/png/crop/!450x450a0a0","created_at":1406008158000,"last_logined_at":1436947197000,"global_key":"xin","name":"xin","name_pinyin":"","updated_at":1406008158000,"path":"/u/xin","status":1,"is_member":0,"id":2552,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1994-08-31","location":"江苏 南京","company":"幕(木)游(有)公司","slogan":"做一个简单的人,踏实而务实,不沉溺幻想,不庸人自扰","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/5ae8585e-662b-4bf1-bd53-318c6cec8426.jpg?imageMogr2/auto-orient/format/jpeg/crop/!239x239a0a34","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/5ae8585e-662b-4bf1-bd53-318c6cec8426.jpg?imageMogr2/auto-orient/format/jpeg/crop/!239x239a0a34","created_at":1418705066000,"last_logined_at":1436600011000,"global_key":"Morph_Zhou","name":"Morph_Zhou","name_pinyin":"","updated_at":1418705066000,"path":"/u/Morph_Zhou","status":1,"is_member":0,"id":54212,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1984-10-07","location":"山东 淄博 张店","company":"山东蓝标信息科技有限公司","slogan":"勇者无所畏惧 blog.hainuo.info","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/4cc88a4e-7adc-469f-98a5-6091ef2a35c3.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","created_at":1406871611000,"last_logined_at":1436929956000,"global_key":"hainuo","name":"刘峰","name_pinyin":"|lf|liufeng","updated_at":1406871611000,"path":"/u/hainuo","status":1,"is_member":0,"id":5764,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/1a1873a8-7d76-4927-ae2e-38ad67c99582.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/488fbd75-4307-449c-a2af-d14a1ef61907.jpg","lavatar":"https://dn-coding-net-avatar.qbox.me/1a1873a8-7d76-4927-ae2e-38ad67c99582.jpg","created_at":1435753043000,"last_logined_at":1437031483000,"global_key":"zorji","name":"zorji","name_pinyin":"","updated_at":1435753043000,"path":"/u/zorji","status":1,"is_member":0,"id":110899,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":1,"hot_tweet":{"id":56555,"owner_id":93,"owner":{"sex":0,"birthday":"2014-02-14","location":"广东 深圳","company":"Coding.net","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/512b2a62-956b-4ef8-8e84-b3c66e71468f.png?imageMogr2/auto-orient/format/png/crop/!300x300a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/512b2a62-956b-4ef8-8e84-b3c66e71468f.png?imageMogr2/auto-orient/format/png/crop/!300x300a0a0","created_at":1403329814000,"last_logined_at":1436261323000,"global_key":"coding","name":"coding","name_pinyin":"","updated_at":1403329814000,"path":"/u/coding","status":1,"is_member":0,"id":93,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436254603000,"likes":9,"comments":17,"comment_list":[{"id":129637,"tweet_id":56555,"owner_id":51190,"owner":{"sex":2,"birthday":"1998-03-04","location":"河北 保定","company":"QiLinYunS","slogan":"名字是潘潘起的,头像是拿ziying的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","created_at":1417764325000,"last_logined_at":1437023057000,"global_key":"TXisfine","name":"小谈谈","name_pinyin":"|xtt|xiaotantan","updated_at":1417764325000,"path":"/u/TXisfine","status":1,"is_member":0,"id":51190,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436330193000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/sophia123456\" rel\u003d\"nofollow\"\u003e@小罗\u003c/a\u003e 喔喔~了解。"},{"id":129551,"tweet_id":56555,"owner_id":89471,"owner":{"sex":0,"birthday":"2015-06-18","location":"广西 南宁","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/737bcf6e-111d-49a4-8b0e-4de839b4716e.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/07d49a54-cb05-4a21-9b12-ed23f1fa71cf.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/737bcf6e-111d-49a4-8b0e-4de839b4716e.jpg","created_at":1427685305000,"last_logined_at":1437032650000,"global_key":"sophia123456","name":"小罗","name_pinyin":"|xl|xiaoluo","updated_at":1427685305000,"path":"/u/sophia123456","status":1,"is_member":0,"id":89471,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436324572000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/bumy\" rel\u003d\"nofollow\"\u003e@riverlong\u003c/a\u003e 支付宝私信给我哈"},{"id":129487,"tweet_id":56555,"owner_id":89471,"owner":{"sex":0,"birthday":"2015-06-18","location":"广西 南宁","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/737bcf6e-111d-49a4-8b0e-4de839b4716e.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/07d49a54-cb05-4a21-9b12-ed23f1fa71cf.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/737bcf6e-111d-49a4-8b0e-4de839b4716e.jpg","created_at":1427685305000,"last_logined_at":1437032650000,"global_key":"sophia123456","name":"小罗","name_pinyin":"|xl|xiaoluo","updated_at":1427685305000,"path":"/u/sophia123456","status":1,"is_member":0,"id":89471,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436320778000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/srufeng\" rel\u003d\"nofollow\"\u003e@srufeng\u003c/a\u003e 提bug或者建议 到公开 ios/android 的项目讨论中,可能会有奖励哈~"},{"id":129484,"tweet_id":56555,"owner_id":89471,"owner":{"sex":0,"birthday":"2015-06-18","location":"广西 南宁","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/737bcf6e-111d-49a4-8b0e-4de839b4716e.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/07d49a54-cb05-4a21-9b12-ed23f1fa71cf.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/737bcf6e-111d-49a4-8b0e-4de839b4716e.jpg","created_at":1427685305000,"last_logined_at":1437032650000,"global_key":"sophia123456","name":"小罗","name_pinyin":"|xl|xiaoluo","updated_at":1427685305000,"path":"/u/sophia123456","status":1,"is_member":0,"id":89471,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436320674000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/zeallrm\" rel\u003d\"nofollow\"\u003e@zeallrm\u003c/a\u003e 相互关注,才是好友呢"},{"id":129483,"tweet_id":56555,"owner_id":89471,"owner":{"sex":0,"birthday":"2015-06-18","location":"广西 南宁","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/737bcf6e-111d-49a4-8b0e-4de839b4716e.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/07d49a54-cb05-4a21-9b12-ed23f1fa71cf.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/737bcf6e-111d-49a4-8b0e-4de839b4716e.jpg","created_at":1427685305000,"last_logined_at":1437032650000,"global_key":"sophia123456","name":"小罗","name_pinyin":"|xl|xiaoluo","updated_at":1427685305000,"path":"/u/sophia123456","status":1,"is_member":0,"id":89471,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436320634000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/bumy\" rel\u003d\"nofollow\"\u003e@riverlong\u003c/a\u003e 棒棒哒~"}],"device":"","location":"","coord":"","address":"","content":"\u003ch2 id\u003d\"客户端-v3.0-版本-“赏金码士”-出炉\"\u003e客户端 V3.0 版本 “赏金码士” 出炉\u003c/h2\u003e \n\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/387\" rel\u003d\"nofollow\"\u003e#Coding 客户端#\u003c/a\u003e \u003cbr\u003e 在大家的支持下,客户端 V 3.0 已正式上线~请大家前往各大 app 市场进行更新\u003c/p\u003e \n\u003ch3 id\u003d\"发放赏金\"\u003e发放赏金\u003c/h3\u003e \n\u003cp\u003eiOS 版提交 bug 并通过审核者:\u003c/p\u003e \n\u003ctable\u003e \n \u003ctr\u003e \n \u003cth align\u003d\"center\"\u003e码士\u003c/th\u003e \n \u003cth align\u003d\"center\"\u003e金额\u003c/th\u003e \n \u003c/tr\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003ctd align\u003d\"center\"\u003e\u003ca class\u003d\"at-someone\" href\u003d\"/u/dowell\" rel\u003d\"nofollow\"\u003e@dowell\u003c/a\u003e \u003c/td\u003e \n \u003ctd align\u003d\"center\"\u003e20元\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd align\u003d\"center\"\u003e\u003ca class\u003d\"at-someone\" href\u003d\"/u/CyonLeu\" rel\u003d\"nofollow\"\u003e@cyonleu\u003c/a\u003e \u003c/td\u003e \n \u003ctd align\u003d\"center\"\u003e20元\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd align\u003d\"center\"\u003e\u003ca class\u003d\"at-someone\" href\u003d\"/u/huangyong\" rel\u003d\"nofollow\"\u003e@黄勇\u003c/a\u003e \u003c/td\u003e \n \u003ctd align\u003d\"center\"\u003e20元\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd align\u003d\"center\"\u003e\u003ca class\u003d\"at-someone\" href\u003d\"/u/yaming\" rel\u003d\"nofollow\"\u003e@花开堪折枝\u003c/a\u003e \u003c/td\u003e \n \u003ctd align\u003d\"center\"\u003e20元\u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n\u003c/table\u003e \n\u003cp\u003eAndroid 版提交 bug 并通过审核者:\u003c/p\u003e \n\u003ctable\u003e \n \u003ctr\u003e \n \u003cth align\u003d\"center\"\u003e码士\u003c/th\u003e \n \u003cth align\u003d\"center\"\u003e金额\u003c/th\u003e \n \u003c/tr\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003ctd align\u003d\"center\"\u003e\u003ca class\u003d\"at-someone\" href\u003d\"/u/bumy\" rel\u003d\"nofollow\"\u003e@riverlong\u003c/a\u003e \u003c/td\u003e \n \u003ctd align\u003d\"center\"\u003e100元\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd align\u003d\"center\"\u003e\u003ca class\u003d\"at-someone\" href\u003d\"/u/898745604\" rel\u003d\"nofollow\"\u003e@VDer\u003c/a\u003e \u003c/td\u003e \n \u003ctd align\u003d\"center\"\u003e40元\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd align\u003d\"center\"\u003e\u003ca class\u003d\"at-someone\" href\u003d\"/u/hcrgm\" rel\u003d\"nofollow\"\u003e@hcrgm\u003c/a\u003e \u003c/td\u003e \n \u003ctd align\u003d\"center\"\u003e20元\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd align\u003d\"center\"\u003e\u003ca class\u003d\"at-someone\" href\u003d\"/u/icanghai\" rel\u003d\"nofollow\"\u003e@icanghai\u003c/a\u003e \u003c/td\u003e \n \u003ctd align\u003d\"center\"\u003e20元\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd align\u003d\"center\"\u003e\u003ca class\u003d\"at-someone\" href\u003d\"/u/xiaozhu\" rel\u003d\"nofollow\"\u003e@铂金小猪\u003c/a\u003e \u003c/td\u003e \n \u003ctd align\u003d\"center\"\u003e20元\u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n\u003c/table\u003e \n\u003ch4 id\u003d\"ps:-找-bug-还有赏金拿!这样的好事哪里找?报名参加公测~-请直接私信-\u003ca class\u003d\u0027at-someone\u0027 href\u003d\u0027/u/sophia123456\u0027\u003e@小罗\u003c/a\u003e \"\u003ePS: 找 bug 还有赏金拿!这样的好事哪里找?报名参加公测~ 请直接私信 \u003ca class\u003d\"at-someone\" href\u003d\"/u/sophia123456\" rel\u003d\"nofollow\"\u003e@小罗\u003c/a\u003e \u003c/h4\u003e","path":"/u/coding/pp/56555","activity_id":0,"liked":false,"like_users":[{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-20.png","gravatar":"","lavatar":"/static/fruit_avatar/Fruit-20.png","created_at":1411968342000,"last_logined_at":1436941286000,"global_key":"wenchang","name":"wenchang","name_pinyin":"","updated_at":1411968342000,"path":"/u/wenchang","status":1,"is_member":0,"id":33522,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1988-01-01","location":"山东 济南","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/7633c8636fa4099608191032ac04a295.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/7633c8636fa4099608191032ac04a295.jpg","created_at":1405739267000,"last_logined_at":1436449171000,"global_key":"itfanr","name":"itfanr","name_pinyin":"","updated_at":1405739267000,"path":"/u/itfanr","status":1,"is_member":0,"id":2118,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":1,"birthday":"1990-05-03","location":"","company":"coding","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/02fec97c-4ddf-4321-97c2-08bd4cf77e6d.png?imageMogr2/auto-orient/format/png/crop/!429x429a10a3","gravatar":"https://dn-coding-net-avatar.qbox.me/c6044d92-1932-492d-b32c-fd701d356884.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/02fec97c-4ddf-4321-97c2-08bd4cf77e6d.png?imageMogr2/auto-orient/format/png/crop/!429x429a10a3","created_at":1431924662000,"last_logined_at":1436975481000,"global_key":"succubus","name":"FJH在这里","name_pinyin":"|zzl|zaizheli","updated_at":1431924662000,"path":"/u/succubus","status":1,"is_member":0,"id":101897,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-10.png","gravatar":"https://dn-coding-net-avatar.qbox.me/d9f05231-7871-4dfa-93a5-a1f581ea7f75.jpg","lavatar":"/static/fruit_avatar/Fruit-10.png","created_at":1434642539000,"last_logined_at":1434929202000,"global_key":"zeallrm","name":"zeallrm","name_pinyin":"","updated_at":1434642539000,"path":"/u/zeallrm","status":1,"is_member":0,"id":108626,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"广东 广州","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6b1f621a-eef8-45f0-90a5-2b6e4dd257b2.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/ed58d4ae-e17e-48fd-9f49-eeba3b26589a.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/6b1f621a-eef8-45f0-90a5-2b6e4dd257b2.jpg","created_at":1430075407000,"last_logined_at":1436791946000,"global_key":"bumy","name":"riverlong","name_pinyin":"","updated_at":1430075407000,"path":"/u/bumy","status":1,"is_member":0,"id":98041,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"2015-06-18","location":"广西 南宁","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/737bcf6e-111d-49a4-8b0e-4de839b4716e.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/07d49a54-cb05-4a21-9b12-ed23f1fa71cf.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/737bcf6e-111d-49a4-8b0e-4de839b4716e.jpg","created_at":1427685305000,"last_logined_at":1437032650000,"global_key":"sophia123456","name":"小罗","name_pinyin":"|xl|xiaoluo","updated_at":1427685305000,"path":"/u/sophia123456","status":1,"is_member":0,"id":89471,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"上海 长宁区","company":"shanghai yujing","slogan":"qinfen shi wo weiyi chulu","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/33f34541-d124-415b-bc39-47de5e0bde7f.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/5b92fba2-e22b-46d6-a002-ab5550d91688.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/33f34541-d124-415b-bc39-47de5e0bde7f.jpg","created_at":1426063393000,"last_logined_at":1436429110000,"global_key":"pingtanglu","name":"pingtanglu","name_pinyin":"","updated_at":1426063393000,"path":"/u/pingtanglu","status":1,"is_member":0,"id":84448,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1991-12-01","location":"广东 深圳","company":"CODING","slogan":"只有偏执狂才能生存","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/eece4ae0-233e-4604-a0ad-2ec936b32238.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/df00f228-aa2b-425f-a91a-c46724331dcc.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/eece4ae0-233e-4604-a0ad-2ec936b32238.jpg","created_at":1435320620000,"last_logined_at":1436862521000,"global_key":"miaodesign","name":"MangoCC","name_pinyin":"","updated_at":1435320620000,"path":"/u/miaodesign","status":1,"is_member":0,"id":109929,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":1,"birthday":"1987-08-04","location":"广东 深圳","company":"coding","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/1b9ac59b-9ef3-4328-990a-ed4cbe996476.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/1b9ac59b-9ef3-4328-990a-ed4cbe996476.jpg","created_at":1404874624000,"last_logined_at":1437045840626,"global_key":"guoguo","name":"蝈蝈尹","name_pinyin":"|ggy|guoguoyin","updated_at":1404874624000,"path":"/u/guoguo","status":1,"is_member":0,"id":289,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},"name":"Coding 客户端","created_at":1436254604000,"id":387,"user_list":[{"sex":0,"birthday":"2014-02-14","location":"广东 深圳","company":"Coding.net","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/512b2a62-956b-4ef8-8e84-b3c66e71468f.png?imageMogr2/auto-orient/format/png/crop/!300x300a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/512b2a62-956b-4ef8-8e84-b3c66e71468f.png?imageMogr2/auto-orient/format/png/crop/!300x300a0a0","created_at":1403329814000,"last_logined_at":1436261323000,"global_key":"coding","name":"coding","name_pinyin":"","updated_at":1403329814000,"path":"/u/coding","status":1,"is_member":0,"id":93,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]}]} \ No newline at end of file +{"code":0,"data":[{"watched":false,"user_count":52,"hot_tweet":{"id":59630,"owner_id":446,"owner":{"sex":0,"birthday":"7007-01-01","location":"广东 广州","company":"广州大麦","slogan":"学我者生,似我者死","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/826adb47-69d1-4b80-a05e-5303125d2df6.JPG?imageMogr2/auto-orient/format/jpeg/crop/!559x559a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/826adb47-69d1-4b80-a05e-5303125d2df6.JPG?imageMogr2/auto-orient/format/jpeg/crop/!559x559a0a0","created_at":1405501095000,"last_logined_at":1436405182000,"global_key":"james_cai","name":"james_cai","name_pinyin":"","updated_at":1405501095000,"path":"/u/james_cai","status":1,"is_member":0,"id":446,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437026214000,"likes":0,"comments":0,"comment_list":[],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/218\" rel\u003d\"nofollow\"\u003e#码币#\u003c/a\u003e \u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/smiling_imp.png\" title\u003d\"smiling_imp\"\u003e\u003c/p\u003e","path":"/u/james_cai/pp/59630","activity_id":0,"liked":false,"like_users":[]},"name":"码币","created_at":1433145105000,"id":218,"user_list":[{"sex":0,"birthday":"1983-01-24","location":"四川 成都","company":"成都心动云科技有限公司","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/b8834e515dcb433c20951961967b8d8d.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/b8834e515dcb433c20951961967b8d8d.jpg","created_at":1405563080000,"last_logined_at":1436932265000,"global_key":"itimothy","name":"itimothy","name_pinyin":"","updated_at":1405563080000,"path":"/u/itimothy","status":1,"is_member":0,"id":916,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1993-05-26","location":"广东 广州","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/0735b8c9-e4f6-49e4-b947-0dfee78e842e.jpg?imageMogr2/auto-orient/format/jpeg/crop/!534x534a0a50","gravatar":"https://dn-coding-net-avatar.qbox.me/fbb695ba-7023-47c6-b84b-dd813a0219c3.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/0735b8c9-e4f6-49e4-b947-0dfee78e842e.jpg?imageMogr2/auto-orient/format/jpeg/crop/!534x534a0a50","created_at":1433598571000,"last_logined_at":1436266893000,"global_key":"poorguy","name":"poorguy","name_pinyin":"","updated_at":1433598571000,"path":"/u/poorguy","status":1,"is_member":0,"id":106315,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1970-01-01","location":"江西 南昌","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/45e59eef-7421-4f00-93bb-45c4fd3119f5.png?imageMogr2/auto-orient/format/png/crop/!280x280a0a31","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/45e59eef-7421-4f00-93bb-45c4fd3119f5.png?imageMogr2/auto-orient/format/png/crop/!280x280a0a31","created_at":1405577422000,"last_logined_at":1436511843000,"global_key":"hvsy","name":"苏梦华","name_pinyin":"|smh|sumenghua","updated_at":1405577422000,"path":"/u/hvsy","status":1,"is_member":0,"id":1231,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-07-27","location":"北京 朝阳区","company":"cnepay","slogan":"世界那么大, 我想去看看","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/dedb067ecae8155b87428ac7920dd0ae.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/dedb067ecae8155b87428ac7920dd0ae.jpg","created_at":1405659032000,"last_logined_at":1434873266000,"global_key":"yinheli","name":"yinheli","name_pinyin":"","updated_at":1405659032000,"path":"/u/yinheli","status":1,"is_member":0,"id":1890,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1990-10-31","location":"江苏 苏州","company":"pinklian","slogan":"Making Love Out of Nothing at All","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/d1002613-b448-4a91-8a5f-16fac8ebdf49.jpg?imageMogr2/auto-orient/format/jpeg/crop/!412x412a16a388","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/d1002613-b448-4a91-8a5f-16fac8ebdf49.jpg?imageMogr2/auto-orient/format/jpeg/crop/!412x412a16a388","created_at":1413989470000,"last_logined_at":1436850094000,"global_key":"desmond","name":"desmond","name_pinyin":"","updated_at":1413989470000,"path":"/u/desmond","status":1,"is_member":0,"id":36755,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1991-06-21","location":"江苏 南京","company":"viva tech","slogan":"KEEP SIMPLE","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9081b035-427f-40cb-89f4-8cff6664da6f.jpg?imageMogr2/auto-orient/format/jpeg/crop/!400x400a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9081b035-427f-40cb-89f4-8cff6664da6f.jpg?imageMogr2/auto-orient/format/jpeg/crop/!400x400a0a0","created_at":1406882231000,"last_logined_at":1436504747000,"global_key":"dr2009","name":"dr2009","name_pinyin":"","updated_at":1406882231000,"path":"/u/dr2009","status":1,"is_member":0,"id":5814,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1992-11-08","location":"广东 广州","company":"sponia","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/7cc9d1d9-5ba4-478c-96ae-5ca39e715bfd.jpg?imageMogr2/auto-orient/format/jpeg/crop/!506x506a0a3","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/7cc9d1d9-5ba4-478c-96ae-5ca39e715bfd.jpg?imageMogr2/auto-orient/format/jpeg/crop/!506x506a0a3","created_at":1414399181000,"last_logined_at":1436755097000,"global_key":"whisky","name":"whisky","name_pinyin":"","updated_at":1414399181000,"path":"/u/whisky","status":1,"is_member":0,"id":37581,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1992-04-09","location":"江苏 无锡","company":"南京帆软软件有限公司","slogan":"然而这并没有什么卵用","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/802c48fc-a9c7-43d0-9b08-930767f56b2a.png?imageMogr2/auto-orient/format/png/crop/!512x512a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/e11eca9e-6c35-4ca8-98ef-c433416b3f38.png","lavatar":"https://dn-coding-net-production-static.qbox.me/802c48fc-a9c7-43d0-9b08-930767f56b2a.png?imageMogr2/auto-orient/format/png/crop/!512x512a0a0","created_at":1429069193000,"last_logined_at":1434631207000,"global_key":"huhamhire","name":"huhamhire","name_pinyin":"","updated_at":1429069193000,"path":"/u/huhamhire","status":1,"is_member":0,"id":95452,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":1,"birthday":"1992-01-01","location":"上海 ","company":"携程","slogan":"To be better me","introduction":"","avatar":"/static/fruit_avatar/Fruit-7.png","gravatar":"https://dn-coding-net-avatar.qbox.me/a44a2da5-c3fb-4240-80eb-835b3cedffe2.jpg","lavatar":"/static/fruit_avatar/Fruit-7.png","created_at":1432042116000,"last_logined_at":1436925662000,"global_key":"michel","name":"michel","name_pinyin":"","updated_at":1432042116000,"path":"/u/michel","status":1,"is_member":0,"id":102255,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":2,"birthday":"2014-07-22","location":"江苏 苏州","company":"","slogan":"冗码一生(13:28)","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/711ead7c-bda5-4097-ad56-3bc4e535d75e.jpg?imageMogr2/auto-orient/format/jpeg/crop/!600x600a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/a2fbe81e-5f9e-4e55-b09b-87c875c18cd7.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/711ead7c-bda5-4097-ad56-3bc4e535d75e.jpg?imageMogr2/auto-orient/format/jpeg/crop/!600x600a0a0","created_at":1406006889000,"last_logined_at":1437033413000,"global_key":"liuxey","name":"Liuxey","name_pinyin":"","updated_at":1406006889000,"path":"/u/liuxey","status":1,"is_member":0,"id":2530,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":28,"hot_tweet":{"id":59561,"owner_id":35907,"owner":{"sex":0,"birthday":"1111-11-11","location":"北京 西城区","company":"","slogan":"职位:CDO+CZO","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/ec3f4a9d-e6b9-41db-80ec-0ae449a43e10.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/ec3f4a9d-e6b9-41db-80ec-0ae449a43e10.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","created_at":1413647368000,"last_logined_at":1437045443759,"global_key":"itsing","name":"一台一台一台台","name_pinyin":"|ytytytt|yitaiyitaiyitaitai","updated_at":1413647368000,"path":"/u/itsing","status":1,"is_member":0,"id":35907,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437012241000,"likes":3,"comments":6,"comment_list":[{"id":133573,"tweet_id":59561,"owner_id":2279,"owner":{"sex":0,"birthday":"1970-01-01","location":"上海 浦东新区","company":"","slogan":"即使再渺小,也要不顾一切地成长! http://raoyc.com","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/8dc8714c-5f6f-4e4b-8564-83afda50c712.jpg?imageMogr2/auto-orient/format/jpeg/crop/!363x363a32a15","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/8dc8714c-5f6f-4e4b-8564-83afda50c712.jpg?imageMogr2/auto-orient/format/jpeg/crop/!363x363a32a15","created_at":1405924724000,"last_logined_at":1437028982000,"global_key":"rao","name":"飞扬","name_pinyin":"|fy|feiyang","updated_at":1405924724000,"path":"/u/rao","status":1,"is_member":0,"id":2279,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437029897000,"content":"P的一手好图啊"},{"id":133482,"tweet_id":59561,"owner_id":51190,"owner":{"sex":2,"birthday":"1998-03-04","location":"河北 保定","company":"QiLinYunS","slogan":"名字是潘潘起的,头像是拿ziying的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","created_at":1417764325000,"last_logined_at":1437023057000,"global_key":"TXisfine","name":"小谈谈","name_pinyin":"|xtt|xiaotantan","updated_at":1417764325000,"path":"/u/TXisfine","status":1,"is_member":0,"id":51190,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437022090000,"content":"0.02\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/persevere.png\" title\u003d\"persevere\"\u003e"},{"id":133407,"tweet_id":59561,"owner_id":41106,"owner":{"sex":0,"birthday":"1975-01-01","location":"河北 石家庄","company":"( ͡° ͜ʖ ͡°) ⌒* ( `灬` )*y。o0○","slogan":"勤","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","gravatar":"https://dn-coding-net-avatar.qbox.me/778054a6-374c-48cc-ae89-524a28af00ff.png","lavatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","created_at":1415687370000,"last_logined_at":1436982735000,"global_key":"fwolf","name":"Fwolf","name_pinyin":"","updated_at":1415687370000,"path":"/u/fwolf","status":1,"is_member":0,"id":41106,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437015144000,"content":"你這讓我們還怎麼抱猴子啊…"},{"id":133389,"tweet_id":59561,"owner_id":113646,"owner":{"sex":1,"birthday":"1995-01-01","location":"","company":"","slogan":"把猴子抱回家","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/b09accfe-2dd3-4320-aec3-5a335738ebc5.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/8a8f4840-a7f6-48d2-9a17-6c46e66eb212.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/b09accfe-2dd3-4320-aec3-5a335738ebc5.jpg","created_at":1436779066000,"last_logined_at":1437016596000,"global_key":"mian","name":"豆芽芽","name_pinyin":"|dyy|douyaya","updated_at":1436779066000,"path":"/u/mian","status":1,"is_member":0,"id":113646,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437012523000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/songyiwei\" rel\u003d\"nofollow\"\u003e@这个人出现在\u003c/a\u003e 黑我洋葱猴\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/joy.png\" title\u003d\"joy\"\u003e"},{"id":133385,"tweet_id":59561,"owner_id":51246,"owner":{"sex":0,"birthday":"1990-01-01","location":"江苏 南京","company":"南京安元科技有限公司","slogan":"好好学习,天天向上!","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/5db41905-efc1-4e35-94ff-21f5b9e7c625.png?imageMogr2/auto-orient/format/png/crop/!128x128a8a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/5db41905-efc1-4e35-94ff-21f5b9e7c625.png?imageMogr2/auto-orient/format/png/crop/!128x128a8a0","created_at":1417770252000,"last_logined_at":1437008173000,"global_key":"songyiwei","name":"这个人出现在","name_pinyin":"|zgrcxz|zhegerenchuxianzai","updated_at":1417770252000,"path":"/u/songyiwei","status":1,"is_member":0,"id":51246,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437012380000,"content":"这是我第一次这么“讨厌”这个猴子logo"}],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/141\" rel\u003d\"nofollow\"\u003e#抠一段#\u003c/a\u003e 一个程序员忧心忡忡的去找禅师,他虔诚的跪在禅师面前说:禅师啊禅师,coding最近出了一个活动,只要要在微信上回答对了问题,就可以获得大圣归来的电影票两张,可是我不知道答案啊,你能告诉我吗?问题是 coding的最大特点是什么?”禅师看了一眼面前的程序员并没有说话,从旁边拿出coding的LOGO摆在程序员面前,程序员看了看说道:“我知道了禅师,你的意思是coding最大特点就是LOGO上写的,他是一个高大上的云技术产品?”禅师突然站起来脱掉裤子把屁股对着程序员,然后大叫道:“你这么笨怎么当程序员啊?我的意思是CODING最大的特点是可以上去卖屁股!”\u003cbr\u003e \u003ca href\u003d\"https://dn-coding-net-production-pp.qbox.me/8eca012c-a65b-46ef-b07c-c96fdffef515.png\" target\u003d\"_blank\" class\u003d\"bubble-markdown-image-link\" rel\u003d\"nofollow\"\u003e\u003cimg src\u003d\"https://dn-coding-net-production-pp.qbox.me/8eca012c-a65b-46ef-b07c-c96fdffef515.png\" alt\u003d\"图片\" class\u003d\" bubble-markdown-image\"\u003e\u003c/a\u003e\u003c/p\u003e","path":"/u/itsing/pp/59561","activity_id":0,"liked":false,"like_users":[{"sex":0,"birthday":"1990-06-10","location":"深圳","company":"Coding.net","slogan":"\u0026lt;img src\u003d1 onerror\u003dalert(1)\u0026gt;","introduction":"嗯?","avatar":"https://dn-coding-net-avatar.qbox.me/dc57e8be-3355-4c05-b1e1-c5e52be8e205.png","gravatar":"https://dn-coding-net-avatar.qbox.me/dc57e8be-3355-4c05-b1e1-c5e52be8e205.png","lavatar":"https://dn-coding-net-avatar.qbox.me/dc57e8be-3355-4c05-b1e1-c5e52be8e205.png","created_at":1399045331000,"last_logined_at":1437033487000,"global_key":"wzw","name":"wzw","name_pinyin":"","updated_at":1399045331000,"path":"/u/wzw","status":1,"is_member":0,"id":1,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1993-02-18","location":"广东 江门","company":"袂卓建材搬运有限公司","slogan":"散文式php鲁迅都看不懂","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/f4f7314c-c59f-42d4-a9c0-55f098644c79.jpg?imageMogr2/auto-orient/format/jpeg/crop/!251x251a0a25","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/f4f7314c-c59f-42d4-a9c0-55f098644c79.jpg?imageMogr2/auto-orient/format/jpeg/crop/!251x251a0a25","created_at":1409455457000,"last_logined_at":1437010518000,"global_key":"zhlhuang","name":"zhlhuang","name_pinyin":"","updated_at":1409455457000,"path":"/u/zhlhuang","status":1,"is_member":0,"id":29746,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1990-01-01","location":"江苏 南京","company":"南京安元科技有限公司","slogan":"好好学习,天天向上!","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/5db41905-efc1-4e35-94ff-21f5b9e7c625.png?imageMogr2/auto-orient/format/png/crop/!128x128a8a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/5db41905-efc1-4e35-94ff-21f5b9e7c625.png?imageMogr2/auto-orient/format/png/crop/!128x128a8a0","created_at":1417770252000,"last_logined_at":1437008173000,"global_key":"songyiwei","name":"这个人出现在","name_pinyin":"|zgrcxz|zhegerenchuxianzai","updated_at":1417770252000,"path":"/u/songyiwei","status":1,"is_member":0,"id":51246,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},"name":"抠一段","created_at":1430199383000,"id":141,"user_list":[{"sex":0,"birthday":"1983-01-24","location":"四川 成都","company":"成都心动云科技有限公司","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/b8834e515dcb433c20951961967b8d8d.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/b8834e515dcb433c20951961967b8d8d.jpg","created_at":1405563080000,"last_logined_at":1436932265000,"global_key":"itimothy","name":"itimothy","name_pinyin":"","updated_at":1405563080000,"path":"/u/itimothy","status":1,"is_member":0,"id":916,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1970-01-01","location":"上海 浦东新区","company":"","slogan":"即使再渺小,也要不顾一切地成长! http://raoyc.com","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/8dc8714c-5f6f-4e4b-8564-83afda50c712.jpg?imageMogr2/auto-orient/format/jpeg/crop/!363x363a32a15","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/8dc8714c-5f6f-4e4b-8564-83afda50c712.jpg?imageMogr2/auto-orient/format/jpeg/crop/!363x363a32a15","created_at":1405924724000,"last_logined_at":1437028982000,"global_key":"rao","name":"飞扬","name_pinyin":"|fy|feiyang","updated_at":1405924724000,"path":"/u/rao","status":1,"is_member":0,"id":2279,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1998-05-15","location":"孜然麻辣熊黑科技研究中心","company":"孜然麻辣熊黑科技有限公司","slogan":"让懂的人懂,让不懂的人不懂。","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/0b6499da-33ba-489d-99d0-4324c9f53e7c.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/0b6499da-33ba-489d-99d0-4324c9f53e7c.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a0a0","created_at":1409313681000,"last_logined_at":1437046129576,"global_key":"linqun","name":"孜然麻辣熊大大","name_pinyin":"|zrmlxdd|ziranmalaxiongdada","updated_at":1409313681000,"path":"/u/linqun","status":1,"is_member":0,"id":27666,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1992-11-16","location":"","company":"Coding.Net","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/66fbd5f0-9a76-44c7-93c9-9e0e6b7afdd9.jpg?imageMogr2/auto-orient/format/jpeg/crop/!509x509a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/a5ec1d31-c771-4b35-8cd8-ca613b174e83.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/66fbd5f0-9a76-44c7-93c9-9e0e6b7afdd9.jpg?imageMogr2/auto-orient/format/jpeg/crop/!509x509a0a0","created_at":1399056643000,"last_logined_at":1437032308000,"global_key":"Michael","name":"Michael","name_pinyin":"","updated_at":1399056643000,"path":"/u/Michael","status":1,"is_member":0,"id":5,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-13.png","gravatar":"https://dn-coding-net-avatar.qbox.me/706eb577-6a88-464d-b635-e759067019d6.jpg","lavatar":"/static/fruit_avatar/Fruit-13.png","created_at":1434507370000,"last_logined_at":1436411863000,"global_key":"jpr1990","name":"jpr1990","name_pinyin":"","updated_at":1434507370000,"path":"/u/jpr1990","status":1,"is_member":0,"id":108268,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"山西 临汾","company":"无","slogan":"没有座右铭","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/3d16e65a-57e1-4cf3-b721-0e7187183eb3.jpg?imageMogr2/auto-orient/format/jpeg/crop/!572x572a0a14","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/3d16e65a-57e1-4cf3-b721-0e7187183eb3.jpg?imageMogr2/auto-orient/format/jpeg/crop/!572x572a0a14","created_at":1412417441000,"last_logined_at":1437039950000,"global_key":"fiy","name":"我是FT","name_pinyin":"|ws|woshi","updated_at":1412417441000,"path":"/u/fiy","status":1,"is_member":0,"id":33957,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":1,"birthday":"1993-09-03","location":"台湾 宜兰县","company":"Coding.net","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/282e4f85-c279-4bf2-808e-1d45f7f1797d.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/282e4f85-c279-4bf2-808e-1d45f7f1797d.jpg","created_at":1408688496000,"last_logined_at":1436494187000,"global_key":"lichi93","name":"小七七","name_pinyin":"|xqq|xiaoqiqi","updated_at":1408688496000,"path":"/u/lichi93","status":1,"is_member":0,"id":17567,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":2,"birthday":"1994-08-02","location":"山东 烟台","company":"公司","slogan":"にゃにゃん╭( ・ㅂ・)و ̑̑ye","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/669e1714-e6d7-47d6-8984-8de4e5c3d5c1.png?imageMogr2/auto-orient/format/png/crop/!450x450a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/ee4fc3ca-73f8-433e-be09-e67b11610011.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/669e1714-e6d7-47d6-8984-8de4e5c3d5c1.png?imageMogr2/auto-orient/format/png/crop/!450x450a0a0","created_at":1406008158000,"last_logined_at":1436947197000,"global_key":"xin","name":"xin","name_pinyin":"","updated_at":1406008158000,"path":"/u/xin","status":1,"is_member":0,"id":2552,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1111-11-11","location":"北京 西城区","company":"","slogan":"职位:CDO+CZO","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/ec3f4a9d-e6b9-41db-80ec-0ae449a43e10.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/ec3f4a9d-e6b9-41db-80ec-0ae449a43e10.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","created_at":1413647368000,"last_logined_at":1437045443759,"global_key":"itsing","name":"一台一台一台台","name_pinyin":"|ytytytt|yitaiyitaiyitaitai","updated_at":1413647368000,"path":"/u/itsing","status":1,"is_member":0,"id":35907,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1984-10-07","location":"山东 淄博 张店","company":"山东蓝标信息科技有限公司","slogan":"勇者无所畏惧 blog.hainuo.info","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/4cc88a4e-7adc-469f-98a5-6091ef2a35c3.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","created_at":1406871611000,"last_logined_at":1436929956000,"global_key":"hainuo","name":"刘峰","name_pinyin":"|lf|liufeng","updated_at":1406871611000,"path":"/u/hainuo","status":1,"is_member":0,"id":5764,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":46,"hot_tweet":{"id":59614,"owner_id":51190,"owner":{"sex":2,"birthday":"1998-03-04","location":"河北 保定","company":"QiLinYunS","slogan":"名字是潘潘起的,头像是拿ziying的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","created_at":1417764325000,"last_logined_at":1437023057000,"global_key":"TXisfine","name":"小谈谈","name_pinyin":"|xtt|xiaotantan","updated_at":1417764325000,"path":"/u/TXisfine","status":1,"is_member":0,"id":51190,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437023678000,"likes":0,"comments":9,"comment_list":[{"id":133682,"tweet_id":59614,"owner_id":78328,"owner":{"sex":0,"birthday":"1989-07-24","location":"吉林 长春","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-15.png","gravatar":"https://dn-coding-net-avatar.qbox.me/94ca25da-4dfa-44f9-8f94-27bb334a8f31.jpg","lavatar":"/static/fruit_avatar/Fruit-15.png","created_at":1422346827000,"last_logined_at":1437022035000,"global_key":"CarlJia","name":"CarlJia","name_pinyin":"","updated_at":1422346827000,"path":"/u/CarlJia","status":1,"is_member":0,"id":78328,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437047025613,"content":"archlinux"},{"id":133652,"tweet_id":59614,"owner_id":37841,"owner":{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"求知若饥,虚心若愚。","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9dc4bddc-040d-478a-bb31-c7c0b08a029e.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9dc4bddc-040d-478a-bb31-c7c0b08a029e.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","created_at":1414495800000,"last_logined_at":1436875094000,"global_key":"JZQT","name":"JZQT","name_pinyin":"","updated_at":1414495800000,"path":"/u/JZQT","status":1,"is_member":0,"id":37841,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437040624000,"content":"deepin"},{"id":133550,"tweet_id":59614,"owner_id":2279,"owner":{"sex":0,"birthday":"1970-01-01","location":"上海 浦东新区","company":"","slogan":"即使再渺小,也要不顾一切地成长! http://raoyc.com","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/8dc8714c-5f6f-4e4b-8564-83afda50c712.jpg?imageMogr2/auto-orient/format/jpeg/crop/!363x363a32a15","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/8dc8714c-5f6f-4e4b-8564-83afda50c712.jpg?imageMogr2/auto-orient/format/jpeg/crop/!363x363a32a15","created_at":1405924724000,"last_logined_at":1437028982000,"global_key":"rao","name":"飞扬","name_pinyin":"|fy|feiyang","updated_at":1405924724000,"path":"/u/rao","status":1,"is_member":0,"id":2279,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437029214000,"content":"桌面就用乌班图ubuntu,服务器就用centos"},{"id":133537,"tweet_id":59614,"owner_id":89816,"owner":{"sex":0,"birthday":"1989-12-14","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/1a19d540-c936-415d-a837-6061378d94dc.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!128x128a16a57","gravatar":"https://dn-coding-net-avatar.qbox.me/ce7795e8-c3cd-460f-b08d-d2f74d3eb835.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/1a19d540-c936-415d-a837-6061378d94dc.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!128x128a16a57","created_at":1427773948000,"last_logined_at":1437015872000,"global_key":"zhgxun","name":"zhgxun","name_pinyin":"","updated_at":1427773948000,"path":"/u/zhgxun","status":1,"is_member":0,"id":89816,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437028404000,"content":"ubuntu我一直用,就是软件比较好装一些,会出问题,上次突然一直停留在登录界面,图形界面进不去,命令行可以使用,后来直接重装。重装成本太大,环境安装,开发工具,各种,折腾不住,年底准备穷,买苹果系统应该更稳定一些。"},{"id":133531,"tweet_id":59614,"owner_id":17884,"owner":{"sex":0,"birthday":"2014-08-01","location":"江苏 无锡","company":"同程旅游","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-2.png","gravatar":"https://dn-coding-net-avatar.qbox.me/5dc4795c-bbdf-48f2-815f-95cae63b101e.jpg","lavatar":"/static/fruit_avatar/Fruit-2.png","created_at":1408692750000,"last_logined_at":1437016730000,"global_key":"renzhaoxu","name":"renzhao","name_pinyin":"","updated_at":1408692750000,"path":"/u/renzhaoxu","status":1,"is_member":0,"id":17884,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437027830000,"content":"deepin"}],"device":"OPPO Find7","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/200\" rel\u003d\"nofollow\"\u003e#万能的冒泡#\u003c/a\u003e 个人使用Linux,哪个版本较好?\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/100.png\" title\u003d\"100\"\u003e\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/100.png\" title\u003d\"100\"\u003e\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/100.png\" title\u003d\"100\"\u003e\u003c/p\u003e","path":"/u/TXisfine/pp/59614","activity_id":0,"liked":false,"like_users":[]},"name":"万能的冒泡","created_at":1432201941000,"id":200,"user_list":[{"sex":0,"birthday":"1995-08-05","location":"吉林 长春","company":"无","slogan":"呵呵","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/35e124f2-f601-436c-843b-074b146a2e3d.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/c2267416-299b-493f-a4d8-0b6346ad03ea.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/35e124f2-f601-436c-843b-074b146a2e3d.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","created_at":1419831794000,"last_logined_at":1434873688000,"global_key":"f12998765","name":"F_xi","name_pinyin":"","updated_at":1419831794000,"path":"/u/f12998765","status":1,"is_member":0,"id":63693,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"上海 徐汇区","company":"","slogan":"不翻墙搜Google www.886404.org","introduction":"","avatar":"/static/fruit_avatar/Fruit-19.png","gravatar":"","lavatar":"/static/fruit_avatar/Fruit-19.png","created_at":1408153237000,"last_logined_at":1434985959000,"global_key":"fising","name":"fising","name_pinyin":"","updated_at":1408153237000,"path":"/u/fising","status":1,"is_member":0,"id":11977,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":1,"birthday":"1989-08-17","location":"广东深圳","company":"官方打杂妹","slogan":"我就是潘潘潘潘潘哈哈","introduction":"恩","avatar":"https://dn-coding-net-production-static.qbox.me/15efd14d-b90a-44b4-8a3a-63f355330941.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/15efd14d-b90a-44b4-8a3a-63f355330941.jpg","created_at":1399839374000,"last_logined_at":1436491923000,"global_key":"panpan","name":"潘潘","name_pinyin":"|pp|panpan","updated_at":1399839374000,"path":"/u/panpan","status":1,"is_member":0,"id":15,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":1,"birthday":"1992-01-01","location":"上海 ","company":"携程","slogan":"To be better me","introduction":"","avatar":"/static/fruit_avatar/Fruit-7.png","gravatar":"https://dn-coding-net-avatar.qbox.me/a44a2da5-c3fb-4240-80eb-835b3cedffe2.jpg","lavatar":"/static/fruit_avatar/Fruit-7.png","created_at":1432042116000,"last_logined_at":1436925662000,"global_key":"michel","name":"michel","name_pinyin":"","updated_at":1432042116000,"path":"/u/michel","status":1,"is_member":0,"id":102255,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1970-01-01","location":"河南 济源","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/d06af4ba2ffae3614a4bcad606a29c09.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/d06af4ba2ffae3614a4bcad606a29c09.jpg","created_at":1405607752000,"last_logined_at":1436944144000,"global_key":"liu","name":"liu","name_pinyin":"","updated_at":1405607752000,"path":"/u/liu","status":1,"is_member":0,"id":1607,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1988-02-15","location":"上海 杨浦区","company":"dsoon","slogan":"哈哈哈哈^_^","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/615d587c-cef6-4155-af09-9e921291eb0d.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/3663ae0e-548b-4d8f-a841-122873c6a21f.jpg","lavatar":"https://dn-coding-net-avatar.qbox.me/615d587c-cef6-4155-af09-9e921291eb0d.jpg","created_at":1430890572000,"last_logined_at":1437007727000,"global_key":"wqc","name":"王全才","name_pinyin":"|wqc|wangquancai","updated_at":1430890572000,"path":"/u/wqc","status":1,"is_member":0,"id":99742,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"天津 ","company":"科技","slogan":"All for one,one for all","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/8b5fa550-db3d-43f9-a45c-bdaca2dcc491.png?imageMogr2/auto-orient/format/jpg/crop/!484x484a8a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/8b5fa550-db3d-43f9-a45c-bdaca2dcc491.png?imageMogr2/auto-orient/format/jpg/crop/!484x484a8a0","created_at":1414376815000,"last_logined_at":1436167058000,"global_key":"kevinlin","name":"kevinlin","name_pinyin":"","updated_at":1414376815000,"path":"/u/kevinlin","status":1,"is_member":0,"id":37474,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":2,"birthday":"1994-08-02","location":"山东 烟台","company":"公司","slogan":"にゃにゃん╭( ・ㅂ・)و ̑̑ye","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/669e1714-e6d7-47d6-8984-8de4e5c3d5c1.png?imageMogr2/auto-orient/format/png/crop/!450x450a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/ee4fc3ca-73f8-433e-be09-e67b11610011.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/669e1714-e6d7-47d6-8984-8de4e5c3d5c1.png?imageMogr2/auto-orient/format/png/crop/!450x450a0a0","created_at":1406008158000,"last_logined_at":1436947197000,"global_key":"xin","name":"xin","name_pinyin":"","updated_at":1406008158000,"path":"/u/xin","status":1,"is_member":0,"id":2552,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1987-06-09","location":"北京 海淀区","company":"10020","slogan":"个性签名","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/48f2b078-9e3b-4d00-bea5-ecc9d2a2505c.png","gravatar":"https://dn-coding-net-avatar.qbox.me/239c0825-71cf-4d1d-89f6-e7f22ff8db95.png","lavatar":"https://dn-coding-net-avatar.qbox.me/48f2b078-9e3b-4d00-bea5-ecc9d2a2505c.png","created_at":1430019086000,"last_logined_at":1434731377000,"global_key":"z__","name":"_z_","name_pinyin":"","updated_at":1430019086000,"path":"/u/z__","status":1,"is_member":0,"id":97932,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":8,"hot_tweet":{"id":59554,"owner_id":37549,"owner":{"sex":0,"birthday":"1991-01-01","location":"河南 平顶山","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/bd403248-9417-4b4b-b796-9ec87d91199f.png","gravatar":"https://dn-coding-net-avatar.qbox.me/82fd233b-6fc2-4537-8197-69f5b9fc2391.png","lavatar":"https://dn-coding-net-avatar.qbox.me/bd403248-9417-4b4b-b796-9ec87d91199f.png","created_at":1414393497000,"last_logined_at":1435737068000,"global_key":"binsee","name":"杉木","name_pinyin":"|sm|shanmu","updated_at":1414393497000,"path":"/u/binsee","status":1,"is_member":0,"id":37549,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437010073000,"likes":1,"comments":5,"comment_list":[{"id":133490,"tweet_id":59554,"owner_id":37549,"owner":{"sex":0,"birthday":"1991-01-01","location":"河南 平顶山","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/bd403248-9417-4b4b-b796-9ec87d91199f.png","gravatar":"https://dn-coding-net-avatar.qbox.me/82fd233b-6fc2-4537-8197-69f5b9fc2391.png","lavatar":"https://dn-coding-net-avatar.qbox.me/bd403248-9417-4b4b-b796-9ec87d91199f.png","created_at":1414393497000,"last_logined_at":1435737068000,"global_key":"binsee","name":"杉木","name_pinyin":"|sm|shanmu","updated_at":1414393497000,"path":"/u/binsee","status":1,"is_member":0,"id":37549,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437022391000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/jaysun\" rel\u003d\"nofollow\"\u003e@卡基猫\u003c/a\u003e , \u003ca class\u003d\"at-someone\" href\u003d\"/u/liuxey\" rel\u003d\"nofollow\"\u003e@Liuxey\u003c/a\u003e 你们懂的好多..."},{"id":133374,"tweet_id":59554,"owner_id":2530,"owner":{"sex":2,"birthday":"2014-07-22","location":"江苏 苏州","company":"","slogan":"冗码一生(13:28)","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/711ead7c-bda5-4097-ad56-3bc4e535d75e.jpg?imageMogr2/auto-orient/format/jpeg/crop/!600x600a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/a2fbe81e-5f9e-4e55-b09b-87c875c18cd7.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/711ead7c-bda5-4097-ad56-3bc4e535d75e.jpg?imageMogr2/auto-orient/format/jpeg/crop/!600x600a0a0","created_at":1406006889000,"last_logined_at":1437033413000,"global_key":"liuxey","name":"Liuxey","name_pinyin":"","updated_at":1406006889000,"path":"/u/liuxey","status":1,"is_member":0,"id":2530,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437011075000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/jaysun\" rel\u003d\"nofollow\"\u003e@卡基猫\u003c/a\u003e 我的意思就是这个。。。"},{"id":133370,"tweet_id":59554,"owner_id":2455,"owner":{"sex":2,"birthday":"1990-05-04","location":"北京","company":"永希","slogan":"https://a-hope.cn","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/1d3476cac70c29fe779592a42ea7bff2.png","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/1d3476cac70c29fe779592a42ea7bff2.png","created_at":1405998676000,"last_logined_at":1436187451000,"global_key":"jaysun","name":"卡基猫","name_pinyin":"|kjm|kajimao","updated_at":1405998676000,"path":"/u/jaysun","status":1,"is_member":0,"id":2455,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437010921000,"content":"但流血不是七天啊"},{"id":133369,"tweet_id":59554,"owner_id":2455,"owner":{"sex":2,"birthday":"1990-05-04","location":"北京","company":"永希","slogan":"https://a-hope.cn","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/1d3476cac70c29fe779592a42ea7bff2.png","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/1d3476cac70c29fe779592a42ea7bff2.png","created_at":1405998676000,"last_logined_at":1436187451000,"global_key":"jaysun","name":"卡基猫","name_pinyin":"|kjm|kajimao","updated_at":1405998676000,"path":"/u/jaysun","status":1,"is_member":0,"id":2455,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437010910000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/liuxey\" rel\u003d\"nofollow\"\u003e@Liuxey\u003c/a\u003e 经期一般是七天。。"},{"id":133368,"tweet_id":59554,"owner_id":2530,"owner":{"sex":2,"birthday":"2014-07-22","location":"江苏 苏州","company":"","slogan":"冗码一生(13:28)","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/711ead7c-bda5-4097-ad56-3bc4e535d75e.jpg?imageMogr2/auto-orient/format/jpeg/crop/!600x600a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/a2fbe81e-5f9e-4e55-b09b-87c875c18cd7.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/711ead7c-bda5-4097-ad56-3bc4e535d75e.jpg?imageMogr2/auto-orient/format/jpeg/crop/!600x600a0a0","created_at":1406006889000,"last_logined_at":1437033413000,"global_key":"liuxey","name":"Liuxey","name_pinyin":"","updated_at":1406006889000,"path":"/u/liuxey","status":1,"is_member":0,"id":2530,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437010779000,"content":"为什么要七天。。。"}],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/312\" rel\u003d\"nofollow\"\u003e#每日一乐#\u003c/a\u003e   闺蜜说:“这个世界上估计只有男人才会得晕血症吧!”\u003cbr\u003e\u003cbr\u003e  我问:“为什么呢?”\u003cbr\u003e\u003cbr\u003e  闺蜜说:“要是女人得晕血症,一个月要晕7天呢!”\u003c/p\u003e","path":"/u/binsee/pp/59554","activity_id":0,"liked":false,"like_users":[{"sex":0,"birthday":"1985-01-01","location":"广东 广州","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6b1f621a-eef8-45f0-90a5-2b6e4dd257b2.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/ed58d4ae-e17e-48fd-9f49-eeba3b26589a.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/6b1f621a-eef8-45f0-90a5-2b6e4dd257b2.jpg","created_at":1430075407000,"last_logined_at":1436791946000,"global_key":"bumy","name":"riverlong","name_pinyin":"","updated_at":1430075407000,"path":"/u/bumy","status":1,"is_member":0,"id":98041,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},"name":"每日一乐","created_at":1434856286000,"id":312,"user_list":[{"sex":1,"birthday":"1993-08-21","location":"四川 成都","company":"成都方米科技有限公司","slogan":"我是一枚","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9155a097-f4d8-4ee3-91dc-2df92b0954d2.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/d10efda1-73e9-418e-89e2-e0de56f029e7.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/9155a097-f4d8-4ee3-91dc-2df92b0954d2.jpg","created_at":1430990335000,"last_logined_at":1436439646000,"global_key":"abc-com","name":"DaisyYang","name_pinyin":"","updated_at":1430990335000,"path":"/u/abc-com","status":1,"is_member":0,"id":100051,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-13.png","gravatar":"https://dn-coding-net-avatar.qbox.me/706eb577-6a88-464d-b635-e759067019d6.jpg","lavatar":"/static/fruit_avatar/Fruit-13.png","created_at":1434507370000,"last_logined_at":1436411863000,"global_key":"jpr1990","name":"jpr1990","name_pinyin":"","updated_at":1434507370000,"path":"/u/jpr1990","status":1,"is_member":0,"id":108268,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1990-02-28","location":"北京 ","company":"36Kr","slogan":"如果爱我就不要离开我~","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/65b08186-949e-4ece-9fb8-64e640ca0115.png?imageMogr2/auto-orient/format/png/crop/!155x155a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/b902ad6d-e908-4487-b0b7-48795a95d177.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/65b08186-949e-4ece-9fb8-64e640ca0115.png?imageMogr2/auto-orient/format/png/crop/!155x155a0a0","created_at":1431348077000,"last_logined_at":1437029991000,"global_key":"36kr","name":"36kr","name_pinyin":"","updated_at":1431348077000,"path":"/u/36kr","status":1,"is_member":0,"id":100761,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1997-01-28","location":"广东 梅州","company":"盛夏游戏工作室","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/583713de-9669-4f78-85b4-75ee3a7c28ad.jpg?imageMogr2/auto-orient/format/jpeg/crop/!240x240a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/0c96e409-da6b-4a3e-8e05-8a54e14f4ae4.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/583713de-9669-4f78-85b4-75ee3a7c28ad.jpg?imageMogr2/auto-orient/format/jpeg/crop/!240x240a0a0","created_at":1428286874000,"last_logined_at":1436234486000,"global_key":"951203598","name":"951203598","name_pinyin":"","updated_at":1428286874000,"path":"/u/951203598","status":1,"is_member":0,"id":92390,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1990-10-31","location":"江苏 苏州","company":"pinklian","slogan":"Making Love Out of Nothing at All","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/d1002613-b448-4a91-8a5f-16fac8ebdf49.jpg?imageMogr2/auto-orient/format/jpeg/crop/!412x412a16a388","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/d1002613-b448-4a91-8a5f-16fac8ebdf49.jpg?imageMogr2/auto-orient/format/jpeg/crop/!412x412a16a388","created_at":1413989470000,"last_logined_at":1436850094000,"global_key":"desmond","name":"desmond","name_pinyin":"","updated_at":1413989470000,"path":"/u/desmond","status":1,"is_member":0,"id":36755,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1900-01-19","location":"安徽 六安","company":"上海米途信息科技有限公司","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/b42a5fd1-e37e-402a-9a51-dda8d7805035.jpg?imageMogr2/auto-orient/format/jpeg/crop/!390x390a10a10","gravatar":"https://dn-coding-net-avatar.qbox.me/d83bb38d-537a-450d-a219-9633b514bbbf.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/b42a5fd1-e37e-402a-9a51-dda8d7805035.jpg?imageMogr2/auto-orient/format/jpeg/crop/!390x390a10a10","created_at":1432003073000,"last_logined_at":1436783776000,"global_key":"aakng","name":"aakng","name_pinyin":"","updated_at":1432003073000,"path":"/u/aakng","status":1,"is_member":0,"id":102068,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1991-01-01","location":"河南 平顶山","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/bd403248-9417-4b4b-b796-9ec87d91199f.png","gravatar":"https://dn-coding-net-avatar.qbox.me/82fd233b-6fc2-4537-8197-69f5b9fc2391.png","lavatar":"https://dn-coding-net-avatar.qbox.me/bd403248-9417-4b4b-b796-9ec87d91199f.png","created_at":1414393497000,"last_logined_at":1435737068000,"global_key":"binsee","name":"杉木","name_pinyin":"|sm|shanmu","updated_at":1414393497000,"path":"/u/binsee","status":1,"is_member":0,"id":37549,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1995-07-24","location":"四川 成都","company":"打杂集团创始人兼首席执行官兼董事长","slogan":"从众是平庸的开始","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/7e648364-e13b-4d46-9cb4-cfdcec893d38.jpg?imageMogr2/auto-orient/format/jpeg/crop/!281x281a123a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/7e648364-e13b-4d46-9cb4-cfdcec893d38.jpg?imageMogr2/auto-orient/format/jpeg/crop/!281x281a123a0","created_at":1417079181000,"last_logined_at":1437009978000,"global_key":"tian_q","name":"一花一叶是菩提","name_pinyin":"|yhyyspt|yihuayiyeshiputi","updated_at":1417079181000,"path":"/u/tian_q","status":1,"is_member":0,"id":48651,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":30,"hot_tweet":{"id":59550,"owner_id":42283,"owner":{"sex":0,"birthday":"1992-04-26","location":"广东 深圳","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/501148c6-da3e-4312-a3ca-6127211122b3.jpg?imageMogr2/auto-orient/format/jpeg/crop/!543x543a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/501148c6-da3e-4312-a3ca-6127211122b3.jpg?imageMogr2/auto-orient/format/jpeg/crop/!543x543a0a0","created_at":1415842099000,"last_logined_at":1436967252000,"global_key":"cuminlo","name":"cuminlo","name_pinyin":"","updated_at":1415842099000,"path":"/u/cuminlo","status":1,"is_member":0,"id":42283,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437009277000,"likes":0,"comments":3,"comment_list":[{"id":133383,"tweet_id":59550,"owner_id":52103,"owner":{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437012115000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/cuminlo\" rel\u003d\"nofollow\"\u003e@cuminlo\u003c/a\u003e 是水泡没有了,有质量的冒泡还是有推荐得码币的"},{"id":133379,"tweet_id":59550,"owner_id":42283,"owner":{"sex":0,"birthday":"1992-04-26","location":"广东 深圳","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/501148c6-da3e-4312-a3ca-6127211122b3.jpg?imageMogr2/auto-orient/format/jpeg/crop/!543x543a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/501148c6-da3e-4312-a3ca-6127211122b3.jpg?imageMogr2/auto-orient/format/jpeg/crop/!543x543a0a0","created_at":1415842099000,"last_logined_at":1436967252000,"global_key":"cuminlo","name":"cuminlo","name_pinyin":"","updated_at":1415842099000,"path":"/u/cuminlo","status":1,"is_member":0,"id":42283,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437011795000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/kloze\" rel\u003d\"nofollow\"\u003e@kloze\u003c/a\u003e 被你一说发现了。 冒泡没有了么?"},{"id":133360,"tweet_id":59550,"owner_id":52103,"owner":{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437009930000,"content":"难道没发现现在水泡没码币了么"}],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/288\" rel\u003d\"nofollow\"\u003e#为了码币#\u003c/a\u003e ma bi\u003c/p\u003e","path":"/u/cuminlo/pp/59550","activity_id":0,"liked":false,"like_users":[]},"name":"为了码币","created_at":1434204235000,"id":288,"user_list":[{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"不coding非码农","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/b800825d17736051cc68dd6a5343f3ce.png","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/b800825d17736051cc68dd6a5343f3ce.png","created_at":1408324753000,"last_logined_at":1436068674000,"global_key":"zybupt","name":"zybupt","name_pinyin":"","updated_at":1408324753000,"path":"/u/zybupt","status":1,"is_member":0,"id":12620,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-6.png","gravatar":"","lavatar":"/static/fruit_avatar/Fruit-6.png","created_at":1408006885000,"last_logined_at":1436780464000,"global_key":"Mr_right","name":"Mr_right","name_pinyin":"","updated_at":1408006885000,"path":"/u/Mr_right","status":1,"is_member":0,"id":10208,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1983-01-24","location":"四川 成都","company":"成都心动云科技有限公司","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/b8834e515dcb433c20951961967b8d8d.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/b8834e515dcb433c20951961967b8d8d.jpg","created_at":1405563080000,"last_logined_at":1436932265000,"global_key":"itimothy","name":"itimothy","name_pinyin":"","updated_at":1405563080000,"path":"/u/itimothy","status":1,"is_member":0,"id":916,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1984-11-09","location":"北京 海淀区","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-1.png","gravatar":"","lavatar":"/static/fruit_avatar/Fruit-1.png","created_at":1411703062000,"last_logined_at":1436778015000,"global_key":"darren_wang","name":"王伟","name_pinyin":"|wangwei|ww","updated_at":1411703062000,"path":"/u/darren_wang","status":1,"is_member":0,"id":33094,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1990-11-19","location":"","company":"","slogan":"没事瞎折腾","introduction":"","avatar":"/static/fruit_avatar/Fruit-18.png","gravatar":"https://dn-coding-net-avatar.qbox.me/1c6b907a-ad1b-4c85-b3cb-f8e7338d9873.jpg","lavatar":"/static/fruit_avatar/Fruit-18.png","created_at":1427522739000,"last_logined_at":1435660771000,"global_key":"Kepp","name":"Kepp","name_pinyin":"","updated_at":1427522739000,"path":"/u/Kepp","status":1,"is_member":0,"id":89067,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1988-11-05","location":"安徽 合肥","company":"中擎","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-8.png","gravatar":"https://dn-coding-net-avatar.qbox.me/2c6c1af6-e8bd-4f26-9987-2c76d66cb94d.jpg","lavatar":"/static/fruit_avatar/Fruit-8.png","created_at":1433906667000,"last_logined_at":1435224039000,"global_key":"newley1105","name":"newley1105","name_pinyin":"","updated_at":1433906667000,"path":"/u/newley1105","status":1,"is_member":0,"id":107032,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"上海 徐汇区","company":"","slogan":"不翻墙搜Google www.886404.org","introduction":"","avatar":"/static/fruit_avatar/Fruit-19.png","gravatar":"","lavatar":"/static/fruit_avatar/Fruit-19.png","created_at":1408153237000,"last_logined_at":1434985959000,"global_key":"fising","name":"fising","name_pinyin":"","updated_at":1408153237000,"path":"/u/fising","status":1,"is_member":0,"id":11977,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1999-08-18","location":"天津 西青区","company":"打杂","slogan":"打杂","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/ae033658-9214-49b5-97c4-ed5af842be07.jpg?imageMogr2/auto-orient/format/jpeg/crop/!600x600a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/ac1fd523-418b-4cff-a0f8-bcf5f5c31784.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/ae033658-9214-49b5-97c4-ed5af842be07.jpg?imageMogr2/auto-orient/format/jpeg/crop/!600x600a0a0","created_at":1423120668000,"last_logined_at":1437049106313,"global_key":"longsichao","name":"隆斯朝","name_pinyin":"|lsc|longsichao","updated_at":1423120668000,"path":"/u/longsichao","status":1,"is_member":0,"id":79835,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1991-04-30","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/3ff266cd-f806-41dc-bb32-884d4166e5f6.jpg?imageMogr2/auto-orient/format/jpeg/crop/!358x358a160a6","gravatar":"https://dn-coding-net-avatar.qbox.me/4ba3bc8f-351b-46fc-8fa7-88412f49725d.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/3ff266cd-f806-41dc-bb32-884d4166e5f6.jpg?imageMogr2/auto-orient/format/jpeg/crop/!358x358a160a6","created_at":1433751124000,"last_logined_at":1436860265000,"global_key":"Miloer","name":"Miloer","name_pinyin":"","updated_at":1433751124000,"path":"/u/Miloer","status":1,"is_member":0,"id":106695,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":2,"birthday":"1999-01-01","location":"山东 淄博","company":"在校学生","slogan":"Nothing is absolute.","introduction":"","avatar":"/static/fruit_avatar/Fruit-1.png","gravatar":"https://dn-coding-net-avatar.qbox.me/2110b6a2-f244-47c4-8b97-8f5fc3ebe481.jpg","lavatar":"/static/fruit_avatar/Fruit-1.png","created_at":1424637774000,"last_logined_at":1435598200000,"global_key":"ephoton","name":"Apriky","name_pinyin":"","updated_at":1424637774000,"path":"/u/ephoton","status":1,"is_member":0,"id":81669,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":25,"hot_tweet":{"id":59643,"owner_id":79236,"owner":{"sex":0,"birthday":"1985-01-01","location":"山东 临沂","company":"临沂宁可网络","slogan":"有我更精彩","introduction":"","avatar":"/static/fruit_avatar/Fruit-15.png","gravatar":"https://dn-coding-net-avatar.qbox.me/81e0f2cd-dba8-47e7-97c3-7cf728cdf184.jpg","lavatar":"/static/fruit_avatar/Fruit-15.png","created_at":1422840787000,"last_logined_at":1435983829000,"global_key":"lidw","name":"lidw","name_pinyin":"","updated_at":1422840787000,"path":"/u/lidw","status":1,"is_member":0,"id":79236,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437028776000,"likes":0,"comments":0,"comment_list":[],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/391\" rel\u003d\"nofollow\"\u003e#来点音乐#\u003c/a\u003e \u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/sleepy.png\" title\u003d\"sleepy\"\u003e\u003c/p\u003e","path":"/u/lidw/pp/59643","activity_id":0,"liked":false,"like_users":[]},"name":"来点音乐","created_at":1436317386000,"id":391,"user_list":[{"sex":0,"birthday":"1985-01-01","location":"四川 成都","company":"汇通天下","slogan":"用穿越春夏秋冬的坚持,去创造和享受美好的事物","introduction":"","avatar":"/static/fruit_avatar/Fruit-10.png","gravatar":"https://dn-coding-net-avatar.qbox.me/d909aa07-bf14-4d6e-be99-966e1a6e994d.jpg","lavatar":"/static/fruit_avatar/Fruit-10.png","created_at":1422500345000,"last_logined_at":1436867508000,"global_key":"wyqbailey","name":"wyqbailey","name_pinyin":"","updated_at":1422500345000,"path":"/u/wyqbailey","status":1,"is_member":0,"id":78678,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"广东 深圳","company":"Coding.net","slogan":"大圣赐我火眼金睛发现一切BUG 。","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/f0dab52e-10ec-4a1c-ab2a-4e63f84ee9b7.jpg?imageMogr2/auto-orient/format/jpeg/crop/!440x440a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/5c1769a9-9acd-47c5-963b-29a933d910f3.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/f0dab52e-10ec-4a1c-ab2a-4e63f84ee9b7.jpg?imageMogr2/auto-orient/format/jpeg/crop/!440x440a0a0","created_at":1433735819000,"last_logined_at":1437046822137,"global_key":"zhct","name":"zhct","name_pinyin":"","updated_at":1433735819000,"path":"/u/zhct","status":1,"is_member":0,"id":106621,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1990-04-24","location":"河北 廊坊","company":"微度网络科技","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/c7f4d93144536315c0c5d3e2f41502ee.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/c7f4d93144536315c0c5d3e2f41502ee.jpg","created_at":1406170973000,"last_logined_at":1436568771000,"global_key":"widuu","name":"widuu","name_pinyin":"","updated_at":1406170973000,"path":"/u/widuu","status":1,"is_member":0,"id":3405,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1992-07-28","location":"江苏 常州","company":"风豪科技","slogan":"挥舞着大宝剑的屠龙战士","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/b1b923bf-ea48-473f-9907-e76910b088a7.png?imageMogr2/auto-orient/format/png/crop/!476x476a307a18","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/b1b923bf-ea48-473f-9907-e76910b088a7.png?imageMogr2/auto-orient/format/png/crop/!476x476a307a18","created_at":1415925645000,"last_logined_at":1436694267000,"global_key":"sevenbanana","name":"sevenbanana","name_pinyin":"","updated_at":1415925645000,"path":"/u/sevenbanana","status":1,"is_member":0,"id":43183,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1991-11-20","location":"山东 淄博","company":"","slogan":"微笑待人,心中却操翻全世界。","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/505374ef-5edf-4db1-b62f-bfd33256ce22.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!638x638a1a1","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/505374ef-5edf-4db1-b62f-bfd33256ce22.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!638x638a1a1","created_at":1407745110000,"last_logined_at":1437031181000,"global_key":"pangzhen","name":"庞震","name_pinyin":"|pz|pangzhen","updated_at":1407745110000,"path":"/u/pangzhen","status":1,"is_member":0,"id":8459,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1990-05-11","location":"四川 成都","company":"一袋","slogan":"everything will be ok","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/ebe778ec-db00-4304-9675-31f422118ae9.jpg?imageMogr2/auto-orient/format/jpeg/crop/!567x567a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/40f2bc16-26e4-439a-b6f4-d2704975bac8.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/ebe778ec-db00-4304-9675-31f422118ae9.jpg?imageMogr2/auto-orient/format/jpeg/crop/!567x567a0a0","created_at":1409212210000,"last_logined_at":1436620909000,"global_key":"imzhi","name":"imzhi","name_pinyin":"","updated_at":1409212210000,"path":"/u/imzhi","status":1,"is_member":0,"id":25949,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-5.png","gravatar":"https://dn-coding-net-avatar.qbox.me/8c4116e9-17b4-40c4-a291-589c59b70e21.jpg","lavatar":"/static/fruit_avatar/Fruit-5.png","created_at":1426649728000,"last_logined_at":1436665474000,"global_key":"JUN1991","name":"JUN1991","name_pinyin":"","updated_at":1426649728000,"path":"/u/JUN1991","status":1,"is_member":0,"id":85691,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1984-10-07","location":"山东 淄博 张店","company":"山东蓝标信息科技有限公司","slogan":"勇者无所畏惧 blog.hainuo.info","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/4cc88a4e-7adc-469f-98a5-6091ef2a35c3.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","created_at":1406871611000,"last_logined_at":1436929956000,"global_key":"hainuo","name":"刘峰","name_pinyin":"|lf|liufeng","updated_at":1406871611000,"path":"/u/hainuo","status":1,"is_member":0,"id":5764,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-4.png","gravatar":"https://dn-coding-net-avatar.qbox.me/ad51f196-9407-4676-9015-b48c2cb931a1.jpg","lavatar":"/static/fruit_avatar/Fruit-4.png","created_at":1436257583000,"last_logined_at":1436495431000,"global_key":"wangrr","name":"wangrr","name_pinyin":"","updated_at":1436257583000,"path":"/u/wangrr","status":1,"is_member":0,"id":112206,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":27,"hot_tweet":{"id":59677,"owner_id":95080,"owner":{"sex":0,"birthday":"2015-03-13","location":"四川 成都","company":"西南交通大学","slogan":"all for one\u0026one for all","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/13fbf842-10d1-422b-84b5-f010b35a8320.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/13fbf842-10d1-422b-84b5-f010b35a8320.jpg","lavatar":"https://dn-coding-net-avatar.qbox.me/13fbf842-10d1-422b-84b5-f010b35a8320.jpg","created_at":1428937098000,"last_logined_at":1437036414000,"global_key":"leov","name":"leov","name_pinyin":"","updated_at":1428937098000,"path":"/u/leov","status":1,"is_member":0,"id":95080,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437036538000,"likes":0,"comments":0,"comment_list":[],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/383\" rel\u003d\"nofollow\"\u003e#码市#\u003c/a\u003e coding的状态中\u003c/p\u003e","path":"/u/leov/pp/59677","activity_id":0,"liked":false,"like_users":[]},"name":"码市","created_at":1436168268000,"id":383,"user_list":[{"sex":1,"birthday":"1992-08-18","location":"四川 成都","company":"伯德梦想","slogan":"什么事慢慢来,不要催。","introduction":"","avatar":"/static/fruit_avatar/Fruit-10.png","gravatar":"https://dn-coding-net-avatar.qbox.me/fbf8911e-a297-4aff-9372-1cc85bc81a6f.jpg","lavatar":"/static/fruit_avatar/Fruit-10.png","created_at":1428544838000,"last_logined_at":1436083491000,"global_key":"zhaoxiaoling","name":"zhaoxiaoling","name_pinyin":"","updated_at":1428544838000,"path":"/u/zhaoxiaoling","status":1,"is_member":0,"id":93599,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1989-12-07","location":"广东 广州","company":"在路上","slogan":"你猜","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/60d61651-e9c5-4de2-9e84-5c2dd2c375fd.PNG?imageMogr2/auto-orient/format/jpeg/crop/!142x142a4a8","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/60d61651-e9c5-4de2-9e84-5c2dd2c375fd.PNG?imageMogr2/auto-orient/format/jpeg/crop/!142x142a4a8","created_at":1412759505000,"last_logined_at":1437012838000,"global_key":"seekwe","name":"seekwe","name_pinyin":"","updated_at":1412759505000,"path":"/u/seekwe","status":1,"is_member":0,"id":34258,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1989-01-01","location":"广东 深圳","company":"平安科技","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-13.png","gravatar":"https://dn-coding-net-avatar.qbox.me/f0ecaa35-cd7a-4633-8aaa-f10847ed1943.jpg","lavatar":"/static/fruit_avatar/Fruit-13.png","created_at":1435233051000,"last_logined_at":1436420838000,"global_key":"jasondu","name":"jasondu","name_pinyin":"","updated_at":1435233051000,"path":"/u/jasondu","status":1,"is_member":0,"id":109725,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"上海 浦东新区","company":"Hi Team","slogan":"我的代码我做主","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/3ffb4c23-c211-4d07-9021-a9f9bb5ddcef.PNG?imageMogr2/auto-orient/format/png/crop/!387x387a28a5","gravatar":"https://dn-coding-net-avatar.qbox.me/7507595b-7698-4b82-9c1c-30e424e81215.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/3ffb4c23-c211-4d07-9021-a9f9bb5ddcef.PNG?imageMogr2/auto-orient/format/png/crop/!387x387a28a5","created_at":1423468244000,"last_logined_at":1436939408000,"global_key":"peterjc","name":"peterjc","name_pinyin":"","updated_at":1423468244000,"path":"/u/peterjc","status":1,"is_member":0,"id":80427,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-5.png","gravatar":"https://dn-coding-net-avatar.qbox.me/8c4116e9-17b4-40c4-a291-589c59b70e21.jpg","lavatar":"/static/fruit_avatar/Fruit-5.png","created_at":1426649728000,"last_logined_at":1436665474000,"global_key":"JUN1991","name":"JUN1991","name_pinyin":"","updated_at":1426649728000,"path":"/u/JUN1991","status":1,"is_member":0,"id":85691,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1983-01-24","location":"四川 成都","company":"成都心动云科技有限公司","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/b8834e515dcb433c20951961967b8d8d.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/b8834e515dcb433c20951961967b8d8d.jpg","created_at":1405563080000,"last_logined_at":1436932265000,"global_key":"itimothy","name":"itimothy","name_pinyin":"","updated_at":1405563080000,"path":"/u/itimothy","status":1,"is_member":0,"id":916,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1992-10-06","location":"","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-18.png","gravatar":"https://dn-coding-net-avatar.qbox.me/2e57547e-c365-4c32-84cb-69591a24cc62.jpg","lavatar":"/static/fruit_avatar/Fruit-18.png","created_at":1416285401000,"last_logined_at":1436345301000,"global_key":"zhhw9210","name":"沙壤土","name_pinyin":"|srt|sharangtu","updated_at":1416285401000,"path":"/u/zhhw9210","status":1,"is_member":0,"id":45375,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1992-04-26","location":"广东 深圳","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/501148c6-da3e-4312-a3ca-6127211122b3.jpg?imageMogr2/auto-orient/format/jpeg/crop/!543x543a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/501148c6-da3e-4312-a3ca-6127211122b3.jpg?imageMogr2/auto-orient/format/jpeg/crop/!543x543a0a0","created_at":1415842099000,"last_logined_at":1436967252000,"global_key":"cuminlo","name":"cuminlo","name_pinyin":"","updated_at":1415842099000,"path":"/u/cuminlo","status":1,"is_member":0,"id":42283,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":1,"birthday":"1989-08-17","location":"广东深圳","company":"官方打杂妹","slogan":"我就是潘潘潘潘潘哈哈","introduction":"恩","avatar":"https://dn-coding-net-production-static.qbox.me/15efd14d-b90a-44b4-8a3a-63f355330941.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/15efd14d-b90a-44b4-8a3a-63f355330941.jpg","created_at":1399839374000,"last_logined_at":1436491923000,"global_key":"panpan","name":"潘潘","name_pinyin":"|pp|panpan","updated_at":1399839374000,"path":"/u/panpan","status":1,"is_member":0,"id":15,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"2014-02-14","location":"广东 深圳","company":"Coding.net","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/512b2a62-956b-4ef8-8e84-b3c66e71468f.png?imageMogr2/auto-orient/format/png/crop/!300x300a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/512b2a62-956b-4ef8-8e84-b3c66e71468f.png?imageMogr2/auto-orient/format/png/crop/!300x300a0a0","created_at":1403329814000,"last_logined_at":1436261323000,"global_key":"coding","name":"coding","name_pinyin":"","updated_at":1403329814000,"path":"/u/coding","status":1,"is_member":0,"id":93,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":6,"hot_tweet":{"id":59501,"owner_id":41106,"owner":{"sex":0,"birthday":"1975-01-01","location":"河北 石家庄","company":"( ͡° ͜ʖ ͡°) ⌒* ( `灬` )*y。o0○","slogan":"勤","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","gravatar":"https://dn-coding-net-avatar.qbox.me/778054a6-374c-48cc-ae89-524a28af00ff.png","lavatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","created_at":1415687370000,"last_logined_at":1436982735000,"global_key":"fwolf","name":"Fwolf","name_pinyin":"","updated_at":1415687370000,"path":"/u/fwolf","status":1,"is_member":0,"id":41106,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436976162000,"likes":0,"comments":1,"comment_list":[{"id":133270,"tweet_id":59501,"owner_id":41106,"owner":{"sex":0,"birthday":"1975-01-01","location":"河北 石家庄","company":"( ͡° ͜ʖ ͡°) ⌒* ( `灬` )*y。o0○","slogan":"勤","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","gravatar":"https://dn-coding-net-avatar.qbox.me/778054a6-374c-48cc-ae89-524a28af00ff.png","lavatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","created_at":1415687370000,"last_logined_at":1436982735000,"global_key":"fwolf","name":"Fwolf","name_pinyin":"","updated_at":1415687370000,"path":"/u/fwolf","status":1,"is_member":0,"id":41106,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436976327000,"content":"圖過不來…一會兒補上"}],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e綠皮車今非昔比,這節綠皮車不僅是臥鋪,還是軟臥,而且還是高級軟臥!一共八個包廂,每個包廂兩張床,裡面有沙發和衛生間,床腳有個顯示器。 \u003ca class\u003d\"topic\" href\u003d\"/pp/topic/24\" rel\u003d\"nofollow\"\u003e#coding #\u003c/a\u003e 行 \u003ca href\u003d\"http://t.cn/RLtHcFo\" target\u003d\"_blank\" class\u003d\" auto-link\" rel\u003d\"nofollow\"\u003ehttp://t.cn/RLtHcFo\u003c/a\u003e\u003c/p\u003e","path":"/u/fwolf/pp/59501","activity_id":0,"liked":false,"like_users":[]},"name":"coding","created_at":1429625299000,"id":24,"user_list":[{"sex":0,"birthday":"1985-01-01","location":"","company":"sdut","slogan":"sdut","introduction":"","avatar":"/static/fruit_avatar/Fruit-20.png","gravatar":"https://dn-coding-net-avatar.qbox.me/0f58a707-578a-43c8-a35c-d21c14944d94.jpg","lavatar":"/static/fruit_avatar/Fruit-20.png","created_at":1433674552000,"last_logined_at":1436841045000,"global_key":"zhuna","name":"zhuna","name_pinyin":"","updated_at":1433674552000,"path":"/u/zhuna","status":1,"is_member":0,"id":106469,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1988-12-06","location":"江苏 无锡","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/2212a32f00cca72b5561aef00ebb5dc7.png","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/2212a32f00cca72b5561aef00ebb5dc7.png","created_at":1408351432000,"last_logined_at":1436708505000,"global_key":"timothyqiu","name":"timothyqiu","name_pinyin":"","updated_at":1408351432000,"path":"/u/timothyqiu","status":1,"is_member":0,"id":13153,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1996-01-29","location":"吉林 长春","company":"无","slogan":"null","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/5633b9d2-8cbf-497e-b4c3-8bf0bca40ed7.jpg?imageMogr2/auto-orient/format/jpeg/crop/!640x640a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/5633b9d2-8cbf-497e-b4c3-8bf0bca40ed7.jpg?imageMogr2/auto-orient/format/jpeg/crop/!640x640a0a0","created_at":1408532116000,"last_logined_at":1436077557000,"global_key":"kingwl","name":"kingwl","name_pinyin":"","updated_at":1408532116000,"path":"/u/kingwl","status":1,"is_member":0,"id":15134,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1975-01-01","location":"河北 石家庄","company":"( ͡° ͜ʖ ͡°) ⌒* ( `灬` )*y。o0○","slogan":"勤","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","gravatar":"https://dn-coding-net-avatar.qbox.me/778054a6-374c-48cc-ae89-524a28af00ff.png","lavatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","created_at":1415687370000,"last_logined_at":1436982735000,"global_key":"fwolf","name":"Fwolf","name_pinyin":"","updated_at":1415687370000,"path":"/u/fwolf","status":1,"is_member":0,"id":41106,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"Coding my life...","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/65e692ec-66c2-4732-9b8e-937189590f01.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/b89b7a59-3148-4751-a9ff-5f696b1218cc.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/65e692ec-66c2-4732-9b8e-937189590f01.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","created_at":1435375435000,"last_logined_at":1437009402000,"global_key":"donychen","name":"donychen","name_pinyin":"","updated_at":1435375435000,"path":"/u/donychen","status":1,"is_member":0,"id":110001,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"2014-02-14","location":"广东 深圳","company":"Coding.net","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/512b2a62-956b-4ef8-8e84-b3c66e71468f.png?imageMogr2/auto-orient/format/png/crop/!300x300a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/512b2a62-956b-4ef8-8e84-b3c66e71468f.png?imageMogr2/auto-orient/format/png/crop/!300x300a0a0","created_at":1403329814000,"last_logined_at":1436261323000,"global_key":"coding","name":"coding","name_pinyin":"","updated_at":1403329814000,"path":"/u/coding","status":1,"is_member":0,"id":93,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":1,"hot_tweet":{"id":58096,"owner_id":52103,"owner":{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436534710000,"likes":0,"comments":14,"comment_list":[{"id":131485,"tweet_id":58096,"owner_id":41106,"owner":{"sex":0,"birthday":"1975-01-01","location":"河北 石家庄","company":"( ͡° ͜ʖ ͡°) ⌒* ( `灬` )*y。o0○","slogan":"勤","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","gravatar":"https://dn-coding-net-avatar.qbox.me/778054a6-374c-48cc-ae89-524a28af00ff.png","lavatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","created_at":1415687370000,"last_logined_at":1436982735000,"global_key":"fwolf","name":"Fwolf","name_pinyin":"","updated_at":1415687370000,"path":"/u/fwolf","status":1,"is_member":0,"id":41106,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436596385000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/kloze\" rel\u003d\"nofollow\"\u003e@kloze\u003c/a\u003e 不和你們這些遊山玩水的傢伙們夜話…"},{"id":131458,"tweet_id":58096,"owner_id":52103,"owner":{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436587046000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/fwolf\" rel\u003d\"nofollow\"\u003e@Fwolf\u003c/a\u003e 时间是周五晚上 地点还在考虑要不要现场直播"},{"id":131457,"tweet_id":58096,"owner_id":52103,"owner":{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436587012000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/djyuning\" rel\u003d\"nofollow\"\u003e@妖刀\u003c/a\u003e 嘉宾现在正在游山玩水"},{"id":131390,"tweet_id":58096,"owner_id":94169,"owner":{"sex":0,"birthday":"1987-08-20","location":"重庆 大渡口区","company":"tPeriod Tech","slogan":"奇迹总会发生在我身上!","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/b02065e5-c6db-472d-8cff-d3da20da492a.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!541x541a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/aa4592ce-cda4-442a-9abb-4269dc018ce0.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/b02065e5-c6db-472d-8cff-d3da20da492a.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!541x541a0a0","created_at":1428641852000,"last_logined_at":1436495272000,"global_key":"djyuning","name":"妖刀","name_pinyin":"|yd|yaodao","updated_at":1428641852000,"path":"/u/djyuning","status":1,"is_member":0,"id":94169,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436570332000,"content":"嘉宾不会是听错了吧?跑深山架篝火去啦?呵呵"},{"id":131330,"tweet_id":58096,"owner_id":51190,"owner":{"sex":2,"birthday":"1998-03-04","location":"河北 保定","company":"QiLinYunS","slogan":"名字是潘潘起的,头像是拿ziying的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","created_at":1417764325000,"last_logined_at":1437023057000,"global_key":"TXisfine","name":"小谈谈","name_pinyin":"|xtt|xiaotantan","updated_at":1417764325000,"path":"/u/TXisfine","status":1,"is_member":0,"id":51190,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436539688000,"content":"本泡应该浮动在水面\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/joy.png\" title\u003d\"joy\"\u003e\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/joy.png\" title\u003d\"joy\"\u003e"}],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/376\" rel\u003d\"nofollow\"\u003e#Coding 夜话#\u003c/a\u003e \u003c/p\u003e \n\u003ch3 id\u003d\"user-content-coding-夜话推迟一周发布\"\u003eCoding 夜话推迟一周发布\u003c/h3\u003e \n\u003cp\u003e各位泡友,抱歉的通知,由于本期夜话的嘉宾还深陷深山老林,暂时无法回归人类社会,故夜话推迟到下周五。对此我深表歉意和感到遗憾。\u003c/p\u003e","path":"/u/kloze/pp/58096","activity_id":0,"liked":false,"like_users":[]},"name":"Coding 夜话","created_at":1435931535000,"id":376,"user_list":[{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":9,"hot_tweet":{"id":59310,"owner_id":52103,"owner":{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436928380000,"likes":1,"comments":9,"comment_list":[{"id":133015,"tweet_id":59310,"owner_id":54212,"owner":{"sex":0,"birthday":"1994-08-31","location":"江苏 南京","company":"幕(木)游(有)公司","slogan":"做一个简单的人,踏实而务实,不沉溺幻想,不庸人自扰","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/5ae8585e-662b-4bf1-bd53-318c6cec8426.jpg?imageMogr2/auto-orient/format/jpeg/crop/!239x239a0a34","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/5ae8585e-662b-4bf1-bd53-318c6cec8426.jpg?imageMogr2/auto-orient/format/jpeg/crop/!239x239a0a34","created_at":1418705066000,"last_logined_at":1436600011000,"global_key":"Morph_Zhou","name":"Morph_Zhou","name_pinyin":"","updated_at":1418705066000,"path":"/u/Morph_Zhou","status":1,"is_member":0,"id":54212,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436940181000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/kloze\" rel\u003d\"nofollow\"\u003e@kloze\u003c/a\u003e 然而已经没有了.."},{"id":133013,"tweet_id":59310,"owner_id":52103,"owner":{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436940114000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/Morph_Zhou\" rel\u003d\"nofollow\"\u003e@Morph_Zhou\u003c/a\u003e 资源自行搜索。。"},{"id":133000,"tweet_id":59310,"owner_id":54212,"owner":{"sex":0,"birthday":"1994-08-31","location":"江苏 南京","company":"幕(木)游(有)公司","slogan":"做一个简单的人,踏实而务实,不沉溺幻想,不庸人自扰","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/5ae8585e-662b-4bf1-bd53-318c6cec8426.jpg?imageMogr2/auto-orient/format/jpeg/crop/!239x239a0a34","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/5ae8585e-662b-4bf1-bd53-318c6cec8426.jpg?imageMogr2/auto-orient/format/jpeg/crop/!239x239a0a34","created_at":1418705066000,"last_logined_at":1436600011000,"global_key":"Morph_Zhou","name":"Morph_Zhou","name_pinyin":"","updated_at":1418705066000,"path":"/u/Morph_Zhou","status":1,"is_member":0,"id":54212,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436937842000,"content":"资源资源...."},{"id":132952,"tweet_id":59310,"owner_id":107805,"owner":{"sex":1,"birthday":"1990-11-06","location":"广西 柳州","company":"昊客","slogan":"然并卵,微博@爱抠鼻屎的怪大婶","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/2c589fcd-b33f-4688-ac0d-5cc3f88d3ca3.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/0a63d54a-1ab0-4c75-8214-f161423626a5.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/2c589fcd-b33f-4688-ac0d-5cc3f88d3ca3.jpg","created_at":1434335589000,"last_logined_at":1436863461000,"global_key":"annakia","name":"annakia","name_pinyin":"","updated_at":1434335589000,"path":"/u/annakia","status":1,"is_member":0,"id":107805,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436931341000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/kloze\" rel\u003d\"nofollow\"\u003e@kloze\u003c/a\u003e 啊。难道我记错了是4分钟?"},{"id":132949,"tweet_id":59310,"owner_id":52103,"owner":{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436931235000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/annakia\" rel\u003d\"nofollow\"\u003e@annakia\u003c/a\u003e 我擦。。还有10分钟?"}],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/424\" rel\u003d\"nofollow\"\u003e#优衣库#\u003c/a\u003e \u003c/p\u003e \n\u003ch4 id\u003d\"user-content-对于不知道优衣库的同学,这里集合贴\"\u003e对于不知道优衣库的同学,这里集合贴\u003c/h4\u003e \n\u003cp\u003e\u003ca href\u003d\"http://mp.weixin.qq.com/s?__biz\u003dMzA4MTMyMDEwNg\u003d\u003d\u0026amp;mid\u003d208239752\u0026amp;idx\u003d1\u0026amp;sn\u003d62f7df610d36b12fc8ca089561755d1a\u0026amp;scene\u003d1\u0026amp;key\u003dc76941211a49ab58fd8a9a4fb5cb54c29b2fbcd67766f7c8c942aff14ebf902fbe25ab4ea4a53af2ffb38b9d1eac15f4\u0026amp;ascene\u003d0\u0026amp;uin\u003dMjM2MDQwNjU%3D\u0026amp;devicetype\u003diMac+MacBookPro11\" target\u003d\"_blank\" class\u003d\" auto-link\" rel\u003d\"nofollow\"\u003ehttp://mp.weixin.qq.com/s?__biz\u003dMzA4MTMyMDEwNg\u003d\u003d\u0026amp;mid\u003d208239752\u0026amp;idx\u003d1\u0026amp;sn\u003d62f7df610d36b12fc8ca089561755d1a\u0026amp;scene\u003d1\u0026amp;key\u003dc76941211a49ab58fd8a9a4fb5cb54c29b2fbcd67766f7c8c942aff14ebf902fbe25ab4ea4a53af2ffb38b9d1eac15f4\u0026amp;ascene\u003d0\u0026amp;uin\u003dMjM2MDQwNjU%253D%26devicetype%3DiMac+MacBookPro11%2C1+OSX+OSX+10.10.3+build(14D136)\u0026amp;version\u003d11020012\u0026amp;pass_ticket\u003dolGiuWJhoCKfQrMX2WKOUC08QSo4wAJOiAUXi1K7FcM%3D\u003c/a\u003e\u003c/p\u003e","path":"/u/kloze/pp/59310","activity_id":0,"liked":false,"like_users":[{"sex":0,"birthday":"1993-12-03","location":"北京 石景山区","company":"博看文思","slogan":"......","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/0e4d1302-3276-43b4-9ee8-cbbae8fd9633.jpg?imageMogr2/auto-orient/format/jpeg/crop/!640x640a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/76d6805f-0181-4bb4-95a1-82add25d161f.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/0e4d1302-3276-43b4-9ee8-cbbae8fd9633.jpg?imageMogr2/auto-orient/format/jpeg/crop/!640x640a0a0","created_at":1420375111000,"last_logined_at":1436499437000,"global_key":"wangkang","name":"王康","name_pinyin":"|wangkang|wk","updated_at":1420375111000,"path":"/u/wangkang","status":1,"is_member":0,"id":68838,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},"name":"优衣库","created_at":1436927129000,"id":424,"user_list":[{"sex":1,"birthday":"1989-10-13","location":"河南 焦作","company":"","slogan":"前端开发 加油!","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/437af37d-94db-4028-8846-f0cfe8ef46f1.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/28d632af-e4da-4f64-8797-03ef16aee603.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/437af37d-94db-4028-8846-f0cfe8ef46f1.jpg","created_at":1425371492000,"last_logined_at":1437031269000,"global_key":"2ni","name":"2ni","name_pinyin":"","updated_at":1425371492000,"path":"/u/2ni","status":1,"is_member":0,"id":83165,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1970-01-01","location":"上海 浦东新区","company":"","slogan":"即使再渺小,也要不顾一切地成长! http://raoyc.com","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/8dc8714c-5f6f-4e4b-8564-83afda50c712.jpg?imageMogr2/auto-orient/format/jpeg/crop/!363x363a32a15","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/8dc8714c-5f6f-4e4b-8564-83afda50c712.jpg?imageMogr2/auto-orient/format/jpeg/crop/!363x363a32a15","created_at":1405924724000,"last_logined_at":1437028982000,"global_key":"rao","name":"飞扬","name_pinyin":"|fy|feiyang","updated_at":1405924724000,"path":"/u/rao","status":1,"is_member":0,"id":2279,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1990-01-01","location":"江苏 南京","company":"南京安元科技有限公司","slogan":"好好学习,天天向上!","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/5db41905-efc1-4e35-94ff-21f5b9e7c625.png?imageMogr2/auto-orient/format/png/crop/!128x128a8a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/5db41905-efc1-4e35-94ff-21f5b9e7c625.png?imageMogr2/auto-orient/format/png/crop/!128x128a8a0","created_at":1417770252000,"last_logined_at":1437008173000,"global_key":"songyiwei","name":"这个人出现在","name_pinyin":"|zgrcxz|zhegerenchuxianzai","updated_at":1417770252000,"path":"/u/songyiwei","status":1,"is_member":0,"id":51246,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-13.png","gravatar":"https://dn-coding-net-avatar.qbox.me/706eb577-6a88-464d-b635-e759067019d6.jpg","lavatar":"/static/fruit_avatar/Fruit-13.png","created_at":1434507370000,"last_logined_at":1436411863000,"global_key":"jpr1990","name":"jpr1990","name_pinyin":"","updated_at":1434507370000,"path":"/u/jpr1990","status":1,"is_member":0,"id":108268,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1989-12-07","location":"广东 广州","company":"在路上","slogan":"你猜","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/60d61651-e9c5-4de2-9e84-5c2dd2c375fd.PNG?imageMogr2/auto-orient/format/jpeg/crop/!142x142a4a8","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/60d61651-e9c5-4de2-9e84-5c2dd2c375fd.PNG?imageMogr2/auto-orient/format/jpeg/crop/!142x142a4a8","created_at":1412759505000,"last_logined_at":1437012838000,"global_key":"seekwe","name":"seekwe","name_pinyin":"","updated_at":1412759505000,"path":"/u/seekwe","status":1,"is_member":0,"id":34258,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":1,"birthday":"1988-12-18","location":"江西 南昌","company":"上海裁软","slogan":"Study hard and make progress every day","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/d7d4afe4-9440-4d2d-a141-62ff26c9a42b.jpg?imageMogr2/auto-orient/format/jpeg/crop/!480x480a0a8","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/d7d4afe4-9440-4d2d-a141-62ff26c9a42b.jpg?imageMogr2/auto-orient/format/jpeg/crop/!480x480a0a8","created_at":1405580241000,"last_logined_at":1436619815000,"global_key":"yvsh","name":"littleyue","name_pinyin":"","updated_at":1405580241000,"path":"/u/yvsh","status":1,"is_member":0,"id":1292,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":2,"birthday":"1994-08-02","location":"山东 烟台","company":"公司","slogan":"にゃにゃん╭( ・ㅂ・)و ̑̑ye","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/669e1714-e6d7-47d6-8984-8de4e5c3d5c1.png?imageMogr2/auto-orient/format/png/crop/!450x450a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/ee4fc3ca-73f8-433e-be09-e67b11610011.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/669e1714-e6d7-47d6-8984-8de4e5c3d5c1.png?imageMogr2/auto-orient/format/png/crop/!450x450a0a0","created_at":1406008158000,"last_logined_at":1436947197000,"global_key":"xin","name":"xin","name_pinyin":"","updated_at":1406008158000,"path":"/u/xin","status":1,"is_member":0,"id":2552,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1111-11-11","location":"北京 西城区","company":"","slogan":"职位:CDO+CZO","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/ec3f4a9d-e6b9-41db-80ec-0ae449a43e10.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/ec3f4a9d-e6b9-41db-80ec-0ae449a43e10.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","created_at":1413647368000,"last_logined_at":1437045443759,"global_key":"itsing","name":"一台一台一台台","name_pinyin":"|ytytytt|yitaiyitaiyitaitai","updated_at":1413647368000,"path":"/u/itsing","status":1,"is_member":0,"id":35907,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":5,"hot_tweet":{"id":59612,"owner_id":51190,"owner":{"sex":2,"birthday":"1998-03-04","location":"河北 保定","company":"QiLinYunS","slogan":"名字是潘潘起的,头像是拿ziying的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","created_at":1417764325000,"last_logined_at":1437023057000,"global_key":"TXisfine","name":"小谈谈","name_pinyin":"|xtt|xiaotantan","updated_at":1417764325000,"path":"/u/TXisfine","status":1,"is_member":0,"id":51190,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437023631000,"likes":4,"comments":1,"comment_list":[{"id":133523,"tweet_id":59612,"owner_id":52103,"owner":{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437026843000,"content":"新技能 get"}],"device":"OPPO Find7","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/335\" rel\u003d\"nofollow\"\u003e#gif#\u003c/a\u003e 【新技能get√】感觉自己终于能到很多地方了。\u003cbr\u003e \u003ca href\u003d\"https://dn-coding-net-production-pp.qbox.me/dd3a700f-ddb9-4ab9-a866-45b9f932ffad.gif\" target\u003d\"_blank\" class\u003d\"bubble-markdown-image-link\" rel\u003d\"nofollow\"\u003e\u003cimg src\u003d\"https://dn-coding-net-production-pp.qbox.me/dd3a700f-ddb9-4ab9-a866-45b9f932ffad.gif\" alt\u003d\"图片\" class\u003d\" bubble-markdown-image\"\u003e\u003c/a\u003e\u003c/p\u003e","path":"/u/TXisfine/pp/59612","activity_id":0,"liked":false,"like_users":[{"sex":0,"birthday":"1991-10-20","location":"湖北 武汉","company":"undefined,none,error.","slogan":"KISS","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/e4f083cc-d3db-4041-87c0-195979878e46.png?imageMogr2/auto-orient/format/png/crop/!430x430a0a172","gravatar":"https://dn-coding-net-avatar.qbox.me/542aa98c-1183-442e-8744-907750cdddbb.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/e4f083cc-d3db-4041-87c0-195979878e46.png?imageMogr2/auto-orient/format/png/crop/!430x430a0a172","created_at":1419861720000,"last_logined_at":1437038279000,"global_key":"wenki","name":"wenki","name_pinyin":"","updated_at":1419861720000,"path":"/u/wenki","status":1,"is_member":0,"id":64169,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1986-08-16","location":"山东 青岛","company":"保密","slogan":"有点想法很好,有点行动更好","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ea91de1-b5bc-45a0-b972-da612a9c08fb.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/500c922c-1b6b-4408-9296-5fe7c44a43bd.png","lavatar":"https://dn-coding-net-production-static.qbox.me/9ea91de1-b5bc-45a0-b972-da612a9c08fb.jpg","created_at":1409097666000,"last_logined_at":1437031418000,"global_key":"silverwing","name":"愚夫","name_pinyin":"|yf|yufu","updated_at":1409097666000,"path":"/u/silverwing","status":1,"is_member":0,"id":22811,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1975-01-01","location":"河北 石家庄","company":"( ͡° ͜ʖ ͡°) ⌒* ( `灬` )*y。o0○","slogan":"勤","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","gravatar":"https://dn-coding-net-avatar.qbox.me/778054a6-374c-48cc-ae89-524a28af00ff.png","lavatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","created_at":1415687370000,"last_logined_at":1436982735000,"global_key":"fwolf","name":"Fwolf","name_pinyin":"","updated_at":1415687370000,"path":"/u/fwolf","status":1,"is_member":0,"id":41106,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},"name":"gif","created_at":1435323487000,"id":335,"user_list":[{"sex":2,"birthday":"1998-03-04","location":"河北 保定","company":"QiLinYunS","slogan":"名字是潘潘起的,头像是拿ziying的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","created_at":1417764325000,"last_logined_at":1437023057000,"global_key":"TXisfine","name":"小谈谈","name_pinyin":"|xtt|xiaotantan","updated_at":1417764325000,"path":"/u/TXisfine","status":1,"is_member":0,"id":51190,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":2,"birthday":"1990-05-04","location":"北京","company":"永希","slogan":"https://a-hope.cn","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/1d3476cac70c29fe779592a42ea7bff2.png","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/1d3476cac70c29fe779592a42ea7bff2.png","created_at":1405998676000,"last_logined_at":1436187451000,"global_key":"jaysun","name":"卡基猫","name_pinyin":"|kjm|kajimao","updated_at":1405998676000,"path":"/u/jaysun","status":1,"is_member":0,"id":2455,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1111-11-11","location":"北京 西城区","company":"","slogan":"职位:CDO+CZO","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/ec3f4a9d-e6b9-41db-80ec-0ae449a43e10.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/ec3f4a9d-e6b9-41db-80ec-0ae449a43e10.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","created_at":1413647368000,"last_logined_at":1437045443759,"global_key":"itsing","name":"一台一台一台台","name_pinyin":"|ytytytt|yitaiyitaiyitaitai","updated_at":1413647368000,"path":"/u/itsing","status":1,"is_member":0,"id":35907,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1994-09-11","location":"广东 深圳","company":"","slogan":"Simplicity is the ultimate sophistication.","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/d0b84a18-3dde-43d7-b3e0-3ffbe785df90.png?imageMogr2/auto-orient/format/png/crop/!240x240a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/cd9a28a2-b6b6-4883-84ee-af727c01a662.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/d0b84a18-3dde-43d7-b3e0-3ffbe785df90.png?imageMogr2/auto-orient/format/png/crop/!240x240a0a0","created_at":1422087534000,"last_logined_at":1436842049000,"global_key":"chnhyg","name":"小模样儿","name_pinyin":"|xmye|xiaomoyanger","updated_at":1422087534000,"path":"/u/chnhyg","status":1,"is_member":0,"id":77755,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1990-06-10","location":"深圳","company":"Coding.net","slogan":"\u0026lt;img src\u003d1 onerror\u003dalert(1)\u0026gt;","introduction":"嗯?","avatar":"https://dn-coding-net-avatar.qbox.me/dc57e8be-3355-4c05-b1e1-c5e52be8e205.png","gravatar":"https://dn-coding-net-avatar.qbox.me/dc57e8be-3355-4c05-b1e1-c5e52be8e205.png","lavatar":"https://dn-coding-net-avatar.qbox.me/dc57e8be-3355-4c05-b1e1-c5e52be8e205.png","created_at":1399045331000,"last_logined_at":1437033487000,"global_key":"wzw","name":"wzw","name_pinyin":"","updated_at":1399045331000,"path":"/u/wzw","status":1,"is_member":0,"id":1,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":6,"hot_tweet":{"id":56708,"owner_id":65953,"owner":{"sex":0,"birthday":"1991-04-03","location":"江苏 南京","company":"南京厚建","slogan":"Stay Hungry, Stay Foolish! Be a B dever","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9190a6b7-1217-4108-b08b-be7f1819232b.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/89bd6ea6-3e6c-4cee-b44b-3690e3857713.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/9190a6b7-1217-4108-b08b-be7f1819232b.jpg","created_at":1419996323000,"last_logined_at":1436884485000,"global_key":"milker","name":"Milker","name_pinyin":"","updated_at":1419996323000,"path":"/u/milker","status":1,"is_member":0,"id":65953,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436284641000,"likes":0,"comments":0,"comment_list":[],"device":"华为 荣耀6","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/371\" rel\u003d\"nofollow\"\u003e#爱码诗#\u003c/a\u003e \u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/smiley.png\" title\u003d\"smiley\"\u003e\u003cimg class\u003d\"emotion monkey\" src\u003d\"https://coding.net/static/coding-emotions/coding-emoji-09.png\" title\u003d\"内急\"\u003e\u003c/p\u003e","path":"/u/milker/pp/56708","activity_id":0,"liked":false,"like_users":[]},"name":"爱码诗","created_at":1435855932000,"id":371,"user_list":[{"sex":0,"birthday":"1985-01-01","location":"山东 淄博","company":"sdut","slogan":"just coding ,just fun!","introduction":"","avatar":"/static/fruit_avatar/Fruit-11.png","gravatar":"","lavatar":"/static/fruit_avatar/Fruit-11.png","created_at":1416744216000,"last_logined_at":1436710993000,"global_key":"lixinxing","name":"lixinxing","name_pinyin":"","updated_at":1416744216000,"path":"/u/lixinxing","status":1,"is_member":0,"id":47280,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"北京 朝阳区","company":"NSB","slogan":"刚兴趣的","introduction":"","avatar":"/static/fruit_avatar/Fruit-3.png","gravatar":"https://dn-coding-net-avatar.qbox.me/62a91da2-f336-4aac-bc68-b554ab383fc9.jpg","lavatar":"/static/fruit_avatar/Fruit-3.png","created_at":1421161473000,"last_logined_at":1437013178000,"global_key":"zhangyuhan","name":"zhangyuhan","name_pinyin":"","updated_at":1421161473000,"path":"/u/zhangyuhan","status":1,"is_member":0,"id":74975,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"sdut","slogan":"sdut","introduction":"","avatar":"/static/fruit_avatar/Fruit-20.png","gravatar":"https://dn-coding-net-avatar.qbox.me/0f58a707-578a-43c8-a35c-d21c14944d94.jpg","lavatar":"/static/fruit_avatar/Fruit-20.png","created_at":1433674552000,"last_logined_at":1436841045000,"global_key":"zhuna","name":"zhuna","name_pinyin":"","updated_at":1433674552000,"path":"/u/zhuna","status":1,"is_member":0,"id":106469,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1991-05-11","location":"广东 深圳","company":"森普航科","slogan":"xxx","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/8d6da319-d09a-41f9-b90d-28156bedd492.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/f972df9d-67d3-4b55-b845-99c266b10473.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/8d6da319-d09a-41f9-b90d-28156bedd492.jpg","created_at":1433677544000,"last_logined_at":1436939933000,"global_key":"yao1243","name":"yao1243","name_pinyin":"","updated_at":1433677544000,"path":"/u/yao1243","status":1,"is_member":0,"id":106476,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1991-04-03","location":"江苏 南京","company":"南京厚建","slogan":"Stay Hungry, Stay Foolish! Be a B dever","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9190a6b7-1217-4108-b08b-be7f1819232b.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/89bd6ea6-3e6c-4cee-b44b-3690e3857713.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/9190a6b7-1217-4108-b08b-be7f1819232b.jpg","created_at":1419996323000,"last_logined_at":1436884485000,"global_key":"milker","name":"Milker","name_pinyin":"","updated_at":1419996323000,"path":"/u/milker","status":1,"is_member":0,"id":65953,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1996-12-12","location":"江苏 ","company":"卖萌集团","slogan":"LL 大法好!舰C大法好!node大法好!nico大法好!nexus大法好!Coding大法好!","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/15b151ef-2df1-457a-913f-ec62d7b536fd.jpg?imageMogr2/auto-orient/format/jpeg/crop/!800x800a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/15b151ef-2df1-457a-913f-ec62d7b536fd.jpg?imageMogr2/auto-orient/format/jpeg/crop/!800x800a0a0","created_at":1417169502000,"last_logined_at":1436696171000,"global_key":"luojia","name":"天朝冰冻型队长舰QAQ","name_pinyin":"|tcbdxdcj|tianchaobingdongxingduichangjian","updated_at":1417169502000,"path":"/u/luojia","status":1,"is_member":0,"id":49005,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":2,"hot_tweet":{"id":59432,"owner_id":27666,"owner":{"sex":0,"birthday":"1998-05-15","location":"孜然麻辣熊黑科技研究中心","company":"孜然麻辣熊黑科技有限公司","slogan":"让懂的人懂,让不懂的人不懂。","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/0b6499da-33ba-489d-99d0-4324c9f53e7c.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/0b6499da-33ba-489d-99d0-4324c9f53e7c.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a0a0","created_at":1409313681000,"last_logined_at":1437046129576,"global_key":"linqun","name":"孜然麻辣熊大大","name_pinyin":"|zrmlxdd|ziranmalaxiongdada","updated_at":1409313681000,"path":"/u/linqun","status":1,"is_member":0,"id":27666,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436957749000,"likes":1,"comments":5,"comment_list":[{"id":133240,"tweet_id":59432,"owner_id":50262,"owner":{"sex":0,"birthday":"1989-02-03","location":"河南 郑州","company":"郑州信源信息技术股份有限公司","slogan":"为啥不是挣钱的挣?","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/ed0cc43b-3246-4a9c-8eb2-bb578d90c042.gif?imageMogr2/auto-orient/format/jpg/crop/!200x200a82a0","gravatar":"https://dn-coding-net-avatar.qbox.me/a30a816c-b7e9-491d-99ee-80fc41c8a152.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/ed0cc43b-3246-4a9c-8eb2-bb578d90c042.gif?imageMogr2/auto-orient/format/jpg/crop/!200x200a82a0","created_at":1417580750000,"last_logined_at":1436971661000,"global_key":"kevinzheng","name":"啊郑","name_pinyin":"|az|azheng","updated_at":1417580750000,"path":"/u/kevinzheng","status":1,"is_member":0,"id":50262,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436972412000,"content":"0.01 马币到手"},{"id":133237,"tweet_id":59432,"owner_id":64057,"owner":{"sex":0,"birthday":"1988-09-07","location":"上海 嘉定区","company":"","slogan":"程序员分为11种:用Windows、Linux和OS X的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/af567cd7-fcf9-408f-a91f-aac557dfcf93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!500x500a36a30","gravatar":"https://dn-coding-net-avatar.qbox.me/e3c7367b-a89d-4174-b278-5c7d9c3bcb3c.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/af567cd7-fcf9-408f-a91f-aac557dfcf93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!500x500a36a30","created_at":1419852772000,"last_logined_at":1436446665000,"global_key":"sinkcup","name":"sinkcup","name_pinyin":"","updated_at":1419852772000,"path":"/u/sinkcup","status":1,"is_member":0,"id":64057,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436971634000,"content":"赶明天,俺试试"},{"id":133189,"tweet_id":59432,"owner_id":52103,"owner":{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436961310000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/linqun\" rel\u003d\"nofollow\"\u003e@孜然麻辣熊大大\u003c/a\u003e 有点用 每次下他家的软件很烦 必须注册 登录下载"},{"id":133176,"tweet_id":59432,"owner_id":27666,"owner":{"sex":0,"birthday":"1998-05-15","location":"孜然麻辣熊黑科技研究中心","company":"孜然麻辣熊黑科技有限公司","slogan":"让懂的人懂,让不懂的人不懂。","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/0b6499da-33ba-489d-99d0-4324c9f53e7c.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/0b6499da-33ba-489d-99d0-4324c9f53e7c.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a0a0","created_at":1409313681000,"last_logined_at":1437046129576,"global_key":"linqun","name":"孜然麻辣熊大大","name_pinyin":"|zrmlxdd|ziranmalaxiongdada","updated_at":1409313681000,"path":"/u/linqun","status":1,"is_member":0,"id":27666,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436958045000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/kloze\" rel\u003d\"nofollow\"\u003e@kloze\u003c/a\u003e 就是告诉Oracle我已经同意你的霸王条款了"},{"id":133173,"tweet_id":59432,"owner_id":52103,"owner":{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9ed11de3-65e3-4cd8-b6aa-5abe7285ab43.jpeg?imageMogr2/auto-orient/format/jpeg/crop/!209x209a0a0","created_at":1418124831000,"last_logined_at":1437045624844,"global_key":"kloze","name":"kloze","name_pinyin":"","updated_at":1418124831000,"path":"/u/kloze","status":1,"is_member":0,"id":52103,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436957797000,"content":"绕过注册 \u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/smile.png\" title\u003d\"smile\"\u003e"}],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/385\" rel\u003d\"nofollow\"\u003e#熊大大小课堂#\u003c/a\u003e 下载Oracle官方JDK\u003cbr\u003e 只需要加个Header就可以了\u003cbr\u003e Example:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003ewget --no-check-certificate --no-cookies --header \"Cookie: oraclelicense\u003daccept-securebackup-cookie\" http://download.oracle.com/otn-pub/java/jdk/8u51-b16/jdk-8u51-linux-x64.rpm\n\u003c/code\u003e\u003c/pre\u003e","path":"/u/linqun/pp/59432","activity_id":0,"liked":false,"like_users":[{"sex":0,"birthday":"1988-09-07","location":"上海 嘉定区","company":"","slogan":"程序员分为11种:用Windows、Linux和OS X的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/af567cd7-fcf9-408f-a91f-aac557dfcf93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!500x500a36a30","gravatar":"https://dn-coding-net-avatar.qbox.me/e3c7367b-a89d-4174-b278-5c7d9c3bcb3c.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/af567cd7-fcf9-408f-a91f-aac557dfcf93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!500x500a36a30","created_at":1419852772000,"last_logined_at":1436446665000,"global_key":"sinkcup","name":"sinkcup","name_pinyin":"","updated_at":1419852772000,"path":"/u/sinkcup","status":1,"is_member":0,"id":64057,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},"name":"熊大大小课堂","created_at":1436238476000,"id":385,"user_list":[{"sex":0,"birthday":"1998-05-15","location":"孜然麻辣熊黑科技研究中心","company":"孜然麻辣熊黑科技有限公司","slogan":"让懂的人懂,让不懂的人不懂。","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/0b6499da-33ba-489d-99d0-4324c9f53e7c.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/0b6499da-33ba-489d-99d0-4324c9f53e7c.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a0a0","created_at":1409313681000,"last_logined_at":1437046129576,"global_key":"linqun","name":"孜然麻辣熊大大","name_pinyin":"|zrmlxdd|ziranmalaxiongdada","updated_at":1409313681000,"path":"/u/linqun","status":1,"is_member":0,"id":27666,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1998-05-15","location":"江苏 苏州","company":"","slogan":"逗比","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/ff6be095-d349-4ce6-94c1-92649f549e53.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a178a0","gravatar":"https://dn-coding-net-avatar.qbox.me/b40d153e-5bc3-49bf-8863-8e607e419a9e.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/ff6be095-d349-4ce6-94c1-92649f549e53.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a178a0","created_at":1410177912000,"last_logined_at":1437029996000,"global_key":"zrmlx","name":"孜然麻辣熊","name_pinyin":"|zrmlx|ziranmalaxiong","updated_at":1410177912000,"path":"/u/zrmlx","status":1,"is_member":0,"id":31525,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":2,"hot_tweet":{"id":58867,"owner_id":8259,"owner":{"sex":0,"birthday":"1991-10-28","location":"广东 广州","company":"广州曦和信息科技有限公司","slogan":"间歇性洗澡忘带内裤综合症","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/0e00f1a8-6450-4f7c-99b5-3cd6508402e4.jpg?imageMogr2/auto-orient/format/png/crop/!374x374a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/0e00f1a8-6450-4f7c-99b5-3cd6508402e4.jpg?imageMogr2/auto-orient/format/png/crop/!374x374a0a0","created_at":1407465734000,"last_logined_at":1436955652000,"global_key":"jackatlas","name":"jackatlas","name_pinyin":"","updated_at":1407465734000,"path":"/u/jackatlas","status":1,"is_member":0,"id":8259,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436776815000,"likes":1,"comments":2,"comment_list":[{"id":132595,"tweet_id":58867,"owner_id":8259,"owner":{"sex":0,"birthday":"1991-10-28","location":"广东 广州","company":"广州曦和信息科技有限公司","slogan":"间歇性洗澡忘带内裤综合症","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/0e00f1a8-6450-4f7c-99b5-3cd6508402e4.jpg?imageMogr2/auto-orient/format/png/crop/!374x374a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/0e00f1a8-6450-4f7c-99b5-3cd6508402e4.jpg?imageMogr2/auto-orient/format/png/crop/!374x374a0a0","created_at":1407465734000,"last_logined_at":1436955652000,"global_key":"jackatlas","name":"jackatlas","name_pinyin":"","updated_at":1407465734000,"path":"/u/jackatlas","status":1,"is_member":0,"id":8259,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436853131000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/panpan\" rel\u003d\"nofollow\"\u003e@潘潘\u003c/a\u003e 没有啦,只是感慨一下~"},{"id":132302,"tweet_id":58867,"owner_id":15,"owner":{"sex":1,"birthday":"1989-08-17","location":"广东深圳","company":"官方打杂妹","slogan":"我就是潘潘潘潘潘哈哈","introduction":"恩","avatar":"https://dn-coding-net-production-static.qbox.me/15efd14d-b90a-44b4-8a3a-63f355330941.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/15efd14d-b90a-44b4-8a3a-63f355330941.jpg","created_at":1399839374000,"last_logined_at":1436491923000,"global_key":"panpan","name":"潘潘","name_pinyin":"|pp|panpan","updated_at":1399839374000,"path":"/u/panpan","status":1,"is_member":0,"id":15,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436780441000,"content":"所以这是个招聘贴?"}],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/314\" rel\u003d\"nofollow\"\u003e#ReactJS#\u003c/a\u003e \u003cbr\u003e 看了 Coding 的《React 构建 WebIDE 的应用实践》ppt,Flux架构、测试,有许多值得学习的地方,遗憾没机会到现场。\u003c/p\u003e \n\u003cp\u003e另,靠谱设计师紧缺啊……\u003c/p\u003e","path":"/u/jackatlas/pp/58867","activity_id":0,"liked":false,"like_users":[{"sex":0,"birthday":"1991-06-03","location":"","company":"SideChef","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/87bcbe6c-c8e9-4cb3-86a1-0733637cbbd9.jpg?imageMogr2/auto-orient/format/jpeg/crop/!738x738a44a0","gravatar":"https://dn-coding-net-avatar.qbox.me/69839658-becc-495a-848d-196474aca65c.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/87bcbe6c-c8e9-4cb3-86a1-0733637cbbd9.jpg?imageMogr2/auto-orient/format/jpeg/crop/!738x738a44a0","created_at":1409075241000,"last_logined_at":1435990113000,"global_key":"xiequan","name":"xiequan","name_pinyin":"","updated_at":1409075241000,"path":"/u/xiequan","status":1,"is_member":0,"id":22789,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},"name":"ReactJS","created_at":1434984022000,"id":314,"user_list":[{"sex":0,"birthday":"1990-02-12","location":"广东 深圳 ","company":"Coding.net","slogan":"新的体验总是好的...","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/e3438bf4-8e93-4a6d-b116-683b9a30c992.jpg?imageMogr2/auto-orient/format/jpeg/crop/!640x640a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/4f0761bd-9dc1-4ce4-8d13-778ad2b16587.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/e3438bf4-8e93-4a6d-b116-683b9a30c992.jpg?imageMogr2/auto-orient/format/jpeg/crop/!640x640a0a0","created_at":1399058281000,"last_logined_at":1437048147982,"global_key":"bluishoul","name":"彭博","name_pinyin":"|pb|pengbo","updated_at":1399058281000,"path":"/u/bluishoul","status":1,"is_member":0,"id":7,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1991-10-28","location":"广东 广州","company":"广州曦和信息科技有限公司","slogan":"间歇性洗澡忘带内裤综合症","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/0e00f1a8-6450-4f7c-99b5-3cd6508402e4.jpg?imageMogr2/auto-orient/format/png/crop/!374x374a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/0e00f1a8-6450-4f7c-99b5-3cd6508402e4.jpg?imageMogr2/auto-orient/format/png/crop/!374x374a0a0","created_at":1407465734000,"last_logined_at":1436955652000,"global_key":"jackatlas","name":"jackatlas","name_pinyin":"","updated_at":1407465734000,"path":"/u/jackatlas","status":1,"is_member":0,"id":8259,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":1,"hot_tweet":{"id":55512,"owner_id":45858,"owner":{"sex":1,"birthday":"1990-11-17","location":"上海 长宁区","company":"coding","slogan":"做个呆萌的吃货","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/35154f1b-2576-40da-b148-bb43634d76e3.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/35154f1b-2576-40da-b148-bb43634d76e3.jpg","created_at":1416369632000,"last_logined_at":1436436740000,"global_key":"wangziying","name":"wangziying","name_pinyin":"","updated_at":1416369632000,"path":"/u/wangziying","status":1,"is_member":0,"id":45858,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436018003000,"likes":9,"comments":26,"comment_list":[{"id":128356,"tweet_id":55512,"owner_id":78571,"owner":{"sex":0,"birthday":"1985-01-01","location":"江苏 南京","company":"四季大通","slogan":"是金子总会发光的,是银子总会花光的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/f81220ce-1b3e-4d00-b8a8-b80718d98f3b.jpg?imageMogr2/auto-orient/format/jpeg/crop/!272x272a85a59","gravatar":"https://dn-coding-net-avatar.qbox.me/3e07669d-6ad8-4a65-91c9-4faa21070006.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/f81220ce-1b3e-4d00-b8a8-b80718d98f3b.jpg?imageMogr2/auto-orient/format/jpeg/crop/!272x272a85a59","created_at":1422436075000,"last_logined_at":1437034333000,"global_key":"steam","name":"steam","name_pinyin":"","updated_at":1422436075000,"path":"/u/steam","status":1,"is_member":0,"id":78571,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436148186000,"content":"卵有用"},{"id":128174,"tweet_id":55512,"owner_id":45858,"owner":{"sex":1,"birthday":"1990-11-17","location":"上海 长宁区","company":"coding","slogan":"做个呆萌的吃货","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/35154f1b-2576-40da-b148-bb43634d76e3.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/35154f1b-2576-40da-b148-bb43634d76e3.jpg","created_at":1416369632000,"last_logined_at":1436436740000,"global_key":"wangziying","name":"wangziying","name_pinyin":"","updated_at":1416369632000,"path":"/u/wangziying","status":1,"is_member":0,"id":45858,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436099482000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/hainuo\" rel\u003d\"nofollow\"\u003e@刘峰\u003c/a\u003e 神马?rio不和饮料一样。。。"},{"id":128120,"tweet_id":55512,"owner_id":5764,"owner":{"sex":0,"birthday":"1984-10-07","location":"山东 淄博 张店","company":"山东蓝标信息科技有限公司","slogan":"勇者无所畏惧 blog.hainuo.info","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/4cc88a4e-7adc-469f-98a5-6091ef2a35c3.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","created_at":1406871611000,"last_logined_at":1436929956000,"global_key":"hainuo","name":"刘峰","name_pinyin":"|lf|liufeng","updated_at":1406871611000,"path":"/u/hainuo","status":1,"is_member":0,"id":5764,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436089125000,"content":"回复了这么多都没有抓住重点 #那朋友是有的# 这才是争论的挤掉"},{"id":128076,"tweet_id":55512,"owner_id":5764,"owner":{"sex":0,"birthday":"1984-10-07","location":"山东 淄博 张店","company":"山东蓝标信息科技有限公司","slogan":"勇者无所畏惧 blog.hainuo.info","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/4cc88a4e-7adc-469f-98a5-6091ef2a35c3.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","created_at":1406871611000,"last_logined_at":1436929956000,"global_key":"hainuo","name":"刘峰","name_pinyin":"|lf|liufeng","updated_at":1406871611000,"path":"/u/hainuo","status":1,"is_member":0,"id":5764,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436078184000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/wangziying\" rel\u003d\"nofollow\"\u003e@wangziying\u003c/a\u003e 论一个女孩子要跟朋友喝酒。。。。。。"},{"id":128074,"tweet_id":55512,"owner_id":34878,"owner":{"sex":0,"birthday":"1985-01-13","location":"上海 长宁区","company":"coding.net","slogan":"将来的你,一定会感谢现在拼命努力的自己!","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/4d643669-e855-4eb1-b49f-ce526194a0e0.jpg?imageMogr2/auto-orient/format/jpeg/crop/!398x398a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/4d643669-e855-4eb1-b49f-ce526194a0e0.jpg?imageMogr2/auto-orient/format/jpeg/crop/!398x398a0a0","created_at":1413187080000,"last_logined_at":1436532041000,"global_key":"duwan","name":"杜万","name_pinyin":"|dw|duwan","updated_at":1413187080000,"path":"/u/duwan","status":1,"is_member":0,"id":34878,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436078028000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/sinkcup\" rel\u003d\"nofollow\"\u003e@sinkcup\u003c/a\u003e 消息真灵通"}],"device":"iPhone 6","location":"","coord":"","address":"","content":"\u003cp\u003e布置的如此少女心。\u003cbr\u003e 都是我一个人逛宜家一个人扛桌子一个人拼。\u003cbr\u003e \u003ca class\u003d\"topic\" href\u003d\"/pp/topic/379\" rel\u003d\"nofollow\"\u003e#男盆友有卵用#\u003c/a\u003e \u003ca href\u003d\"https://dn-coding-net-production-pp.qbox.me/2e7907d4-339a-474c-8505-6ff38f05efe1.jpg\" target\u003d\"_blank\" class\u003d\"bubble-markdown-image-link\" rel\u003d\"nofollow\"\u003e\u003cimg src\u003d\"https://dn-coding-net-production-pp.qbox.me/2e7907d4-339a-474c-8505-6ff38f05efe1.jpg\" alt\u003d\"图片\" class\u003d\" bubble-markdown-image\"\u003e\u003c/a\u003e\u003c/p\u003e","path":"/u/wangziying/pp/55512","activity_id":0,"liked":false,"like_users":[{"sex":0,"birthday":"1985-01-01","location":"湖北 咸宁","company":"","slogan":"座右铭未填写","introduction":"","avatar":"/static/fruit_avatar/Fruit-11.png","gravatar":"https://dn-coding-net-avatar.qbox.me/7d7a75b8-48fe-45d3-9027-7ca6f72c3285.jpg","lavatar":"/static/fruit_avatar/Fruit-11.png","created_at":1419096035000,"last_logined_at":1429602069000,"global_key":"hhhhhzx","name":"hhhhhzx","name_pinyin":"","updated_at":1419096035000,"path":"/u/hhhhhzx","status":1,"is_member":0,"id":57703,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1990-07-01","location":"","company":"","slogan":"为开发疯狂","introduction":"","avatar":"/static/fruit_avatar/Fruit-16.png","gravatar":"https://dn-coding-net-avatar.qbox.me/8067b583-7857-4b88-909e-669d366797c5.jpg","lavatar":"/static/fruit_avatar/Fruit-16.png","created_at":1427784114000,"last_logined_at":1436921948000,"global_key":"497192","name":"GloryMan","name_pinyin":"","updated_at":1427784114000,"path":"/u/497192","status":1,"is_member":0,"id":89867,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"北京 海淀区","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9101209f-8245-4f23-95d8-4acda257fa93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!638x638a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9101209f-8245-4f23-95d8-4acda257fa93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!638x638a0a0","created_at":1414995075000,"last_logined_at":1436928983000,"global_key":"soloist","name":"独奏","name_pinyin":"|dz|duzou","updated_at":1414995075000,"path":"/u/soloist","status":1,"is_member":0,"id":38679,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/9bd51290-92b1-41fc-ba90-4aa5e8b37c3e.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/9bd51290-92b1-41fc-ba90-4aa5e8b37c3e.jpg","created_at":1407920925000,"last_logined_at":1435399310000,"global_key":"pcmadman","name":"pcmadman","name_pinyin":"","updated_at":1407920925000,"path":"/u/pcmadman","status":1,"is_member":0,"id":8886,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":1,"birthday":"1985-06-07","location":"广东 深圳","company":"","slogan":"只爱自己爱的人","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/f224064d-5a94-456c-b96a-01aabb5c6973.jpg?imageMogr2/auto-orient/format/jpeg/crop/!640x640a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/f224064d-5a94-456c-b96a-01aabb5c6973.jpg?imageMogr2/auto-orient/format/jpeg/crop/!640x640a0a0","created_at":1402474269000,"last_logined_at":1436954777000,"global_key":"lingling","name":"灵灵","name_pinyin":"|ll|lingling","updated_at":1402474269000,"path":"/u/lingling","status":1,"is_member":0,"id":35,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"广东 深圳","company":"Coding.net","slogan":"大圣赐我火眼金睛发现一切BUG 。","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/f0dab52e-10ec-4a1c-ab2a-4e63f84ee9b7.jpg?imageMogr2/auto-orient/format/jpeg/crop/!440x440a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/5c1769a9-9acd-47c5-963b-29a933d910f3.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/f0dab52e-10ec-4a1c-ab2a-4e63f84ee9b7.jpg?imageMogr2/auto-orient/format/jpeg/crop/!440x440a0a0","created_at":1433735819000,"last_logined_at":1437046822137,"global_key":"zhct","name":"zhct","name_pinyin":"","updated_at":1433735819000,"path":"/u/zhct","status":1,"is_member":0,"id":106621,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"2015-06-18","location":"广西 南宁","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/737bcf6e-111d-49a4-8b0e-4de839b4716e.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/07d49a54-cb05-4a21-9b12-ed23f1fa71cf.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/737bcf6e-111d-49a4-8b0e-4de839b4716e.jpg","created_at":1427685305000,"last_logined_at":1437032650000,"global_key":"sophia123456","name":"小罗","name_pinyin":"|xl|xiaoluo","updated_at":1427685305000,"path":"/u/sophia123456","status":1,"is_member":0,"id":89471,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1988-09-07","location":"上海 嘉定区","company":"","slogan":"程序员分为11种:用Windows、Linux和OS X的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/af567cd7-fcf9-408f-a91f-aac557dfcf93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!500x500a36a30","gravatar":"https://dn-coding-net-avatar.qbox.me/e3c7367b-a89d-4174-b278-5c7d9c3bcb3c.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/af567cd7-fcf9-408f-a91f-aac557dfcf93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!500x500a36a30","created_at":1419852772000,"last_logined_at":1436446665000,"global_key":"sinkcup","name":"sinkcup","name_pinyin":"","updated_at":1419852772000,"path":"/u/sinkcup","status":1,"is_member":0,"id":64057,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1111-11-11","location":"北京 西城区","company":"","slogan":"职位:CDO+CZO","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/ec3f4a9d-e6b9-41db-80ec-0ae449a43e10.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/ec3f4a9d-e6b9-41db-80ec-0ae449a43e10.jpg?imageMogr2/auto-orient/format/jpeg/crop/!200x200a0a0","created_at":1413647368000,"last_logined_at":1437045443759,"global_key":"itsing","name":"一台一台一台台","name_pinyin":"|ytytytt|yitaiyitaiyitaitai","updated_at":1413647368000,"path":"/u/itsing","status":1,"is_member":0,"id":35907,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},"name":"男盆友有卵用","created_at":1436018003000,"id":379,"user_list":[{"sex":1,"birthday":"1990-11-17","location":"上海 长宁区","company":"coding","slogan":"做个呆萌的吃货","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/35154f1b-2576-40da-b148-bb43634d76e3.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/35154f1b-2576-40da-b148-bb43634d76e3.jpg","created_at":1416369632000,"last_logined_at":1436436740000,"global_key":"wangziying","name":"wangziying","name_pinyin":"","updated_at":1416369632000,"path":"/u/wangziying","status":1,"is_member":0,"id":45858,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":1,"hot_tweet":{"id":59581,"owner_id":58133,"owner":{"sex":0,"birthday":"1990-02-17","location":"浙江 杭州","company":"","slogan":"Talk is cheap, show me the Code !","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/c5332aff-f7bd-4b24-aca3-047136cdd331.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/ce5470f4-ed0b-4803-bf0e-c46b65ea881c.jpg","lavatar":"https://dn-coding-net-avatar.qbox.me/c5332aff-f7bd-4b24-aca3-047136cdd331.jpg","created_at":1419146313000,"last_logined_at":1436445476000,"global_key":"rickytan","name":"rickytan","name_pinyin":"","updated_at":1419146313000,"path":"/u/rickytan","status":1,"is_member":0,"id":58133,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1437015856000,"likes":0,"comments":0,"comment_list":[],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/344\" rel\u003d\"nofollow\"\u003e#NSHipster#\u003c/a\u003e ReactiveCocoa是一个将函数响应式编程范例带入Objective-C的开源库。\u003ca href\u003d\"http://nshipster.cn/reactivecocoa/\" target\u003d\"_blank\" class\u003d\" auto-link\" rel\u003d\"nofollow\"\u003ehttp://nshipster.cn/reactivecocoa/\u003c/a\u003e\u003c/p\u003e","path":"/u/rickytan/pp/59581","activity_id":0,"liked":false,"like_users":[]},"name":"NSHipster","created_at":1435499364000,"id":344,"user_list":[{"sex":0,"birthday":"1990-02-17","location":"浙江 杭州","company":"","slogan":"Talk is cheap, show me the Code !","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/c5332aff-f7bd-4b24-aca3-047136cdd331.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/ce5470f4-ed0b-4803-bf0e-c46b65ea881c.jpg","lavatar":"https://dn-coding-net-avatar.qbox.me/c5332aff-f7bd-4b24-aca3-047136cdd331.jpg","created_at":1419146313000,"last_logined_at":1436445476000,"global_key":"rickytan","name":"rickytan","name_pinyin":"","updated_at":1419146313000,"path":"/u/rickytan","status":1,"is_member":0,"id":58133,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":2,"hot_tweet":{"id":58527,"owner_id":51190,"owner":{"sex":2,"birthday":"1998-03-04","location":"河北 保定","company":"QiLinYunS","slogan":"名字是潘潘起的,头像是拿ziying的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","created_at":1417764325000,"last_logined_at":1437023057000,"global_key":"TXisfine","name":"小谈谈","name_pinyin":"|xtt|xiaotantan","updated_at":1417764325000,"path":"/u/TXisfine","status":1,"is_member":0,"id":51190,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436677408000,"likes":6,"comments":4,"comment_list":[{"id":131966,"tweet_id":58527,"owner_id":51190,"owner":{"sex":2,"birthday":"1998-03-04","location":"河北 保定","company":"QiLinYunS","slogan":"名字是潘潘起的,头像是拿ziying的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","created_at":1417764325000,"last_logined_at":1437023057000,"global_key":"TXisfine","name":"小谈谈","name_pinyin":"|xtt|xiaotantan","updated_at":1417764325000,"path":"/u/TXisfine","status":1,"is_member":0,"id":51190,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436711239000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/sinkcup\" rel\u003d\"nofollow\"\u003e@sinkcup\u003c/a\u003e \u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/joy.png\" title\u003d\"joy\"\u003e\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/joy.png\" title\u003d\"joy\"\u003e\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/joy.png\" title\u003d\"joy\"\u003e"},{"id":131964,"tweet_id":58527,"owner_id":51190,"owner":{"sex":2,"birthday":"1998-03-04","location":"河北 保定","company":"QiLinYunS","slogan":"名字是潘潘起的,头像是拿ziying的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","created_at":1417764325000,"last_logined_at":1437023057000,"global_key":"TXisfine","name":"小谈谈","name_pinyin":"|xtt|xiaotantan","updated_at":1417764325000,"path":"/u/TXisfine","status":1,"is_member":0,"id":51190,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436711225000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/lichi93\" rel\u003d\"nofollow\"\u003e@小七七\u003c/a\u003e 我也不知道啊!\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/joy.png\" title\u003d\"joy\"\u003e\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/joy.png\" title\u003d\"joy\"\u003e"},{"id":131927,"tweet_id":58527,"owner_id":64057,"owner":{"sex":0,"birthday":"1988-09-07","location":"上海 嘉定区","company":"","slogan":"程序员分为11种:用Windows、Linux和OS X的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/af567cd7-fcf9-408f-a91f-aac557dfcf93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!500x500a36a30","gravatar":"https://dn-coding-net-avatar.qbox.me/e3c7367b-a89d-4174-b278-5c7d9c3bcb3c.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/af567cd7-fcf9-408f-a91f-aac557dfcf93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!500x500a36a30","created_at":1419852772000,"last_logined_at":1436446665000,"global_key":"sinkcup","name":"sinkcup","name_pinyin":"","updated_at":1419852772000,"path":"/u/sinkcup","status":1,"is_member":0,"id":64057,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436705670000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/lichi93\" rel\u003d\"nofollow\"\u003e@小七七\u003c/a\u003e 北戴河吧……嘿嘿"},{"id":131906,"tweet_id":58527,"owner_id":17567,"owner":{"sex":1,"birthday":"1993-09-03","location":"台湾 宜兰县","company":"Coding.net","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/282e4f85-c279-4bf2-808e-1d45f7f1797d.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/282e4f85-c279-4bf2-808e-1d45f7f1797d.jpg","created_at":1408688496000,"last_logined_at":1436494187000,"global_key":"lichi93","name":"小七七","name_pinyin":"|xqq|xiaoqiqi","updated_at":1408688496000,"path":"/u/lichi93","status":1,"is_member":0,"id":17567,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436700642000,"content":"哈哈哈是吗?这哪\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/joy.png\" title\u003d\"joy\"\u003e"}],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/373\" rel\u003d\"nofollow\"\u003e#Coding壁纸#\u003c/a\u003e 台湾风光\u003c/p\u003e \n\u003cp\u003e\u003ca href\u003d\"https://dn-coding-net-production-pp.qbox.me/fc3d2c22-7d03-4628-80b5-347c6da2382a.jpg\" target\u003d\"_blank\" class\u003d\"bubble-markdown-image-link\" rel\u003d\"nofollow\"\u003e\u003cimg src\u003d\"https://dn-coding-net-production-pp.qbox.me/fc3d2c22-7d03-4628-80b5-347c6da2382a.jpg\" alt\u003d\"图片\" class\u003d\" bubble-markdown-image\"\u003e\u003c/a\u003e\u003c/p\u003e","path":"/u/TXisfine/pp/58527","activity_id":0,"liked":false,"like_users":[{"sex":1,"birthday":"1995-01-01","location":"","company":"","slogan":"把猴子抱回家","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/b09accfe-2dd3-4320-aec3-5a335738ebc5.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/8a8f4840-a7f6-48d2-9a17-6c46e66eb212.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/b09accfe-2dd3-4320-aec3-5a335738ebc5.jpg","created_at":1436779066000,"last_logined_at":1437016596000,"global_key":"mian","name":"豆芽芽","name_pinyin":"|dyy|douyaya","updated_at":1436779066000,"path":"/u/mian","status":1,"is_member":0,"id":113646,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1993-02-04","location":"","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-18.png","gravatar":"","lavatar":"/static/fruit_avatar/Fruit-18.png","created_at":1417670875000,"last_logined_at":1435509299000,"global_key":"appletang","name":"青天黎明","name_pinyin":"|qingtianliming|qtlm","updated_at":1417670875000,"path":"/u/appletang","status":1,"is_member":0,"id":50636,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1984-12-23","location":"广东 深圳 ","company":"Coding.net","slogan":"岂能尽如人意,但求无愧我心","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/ef54d4ed-9c94-4963-bfe0-3bab5b7ab7a8.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/ef54d4ed-9c94-4963-bfe0-3bab5b7ab7a8.jpg","created_at":1399066489000,"last_logined_at":1437047462695,"global_key":"zhlmmc","name":"zhlmmc","name_pinyin":"","updated_at":1399066489000,"path":"/u/zhlmmc","status":1,"is_member":0,"id":8,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":1,"birthday":"1993-09-03","location":"台湾 宜兰县","company":"Coding.net","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/282e4f85-c279-4bf2-808e-1d45f7f1797d.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/282e4f85-c279-4bf2-808e-1d45f7f1797d.jpg","created_at":1408688496000,"last_logined_at":1436494187000,"global_key":"lichi93","name":"小七七","name_pinyin":"|xqq|xiaoqiqi","updated_at":1408688496000,"path":"/u/lichi93","status":1,"is_member":0,"id":17567,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6cfa25fc-794c-4a0d-8695-27c4219a4cda.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/6cfa25fc-794c-4a0d-8695-27c4219a4cda.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","created_at":1416498539000,"last_logined_at":1436770502000,"global_key":"esec","name":"Esec","name_pinyin":"","updated_at":1416498539000,"path":"/u/esec","status":1,"is_member":0,"id":46682,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":1,"birthday":"1985-06-07","location":"广东 深圳","company":"","slogan":"只爱自己爱的人","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/f224064d-5a94-456c-b96a-01aabb5c6973.jpg?imageMogr2/auto-orient/format/jpeg/crop/!640x640a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/f224064d-5a94-456c-b96a-01aabb5c6973.jpg?imageMogr2/auto-orient/format/jpeg/crop/!640x640a0a0","created_at":1402474269000,"last_logined_at":1436954777000,"global_key":"lingling","name":"灵灵","name_pinyin":"|ll|lingling","updated_at":1402474269000,"path":"/u/lingling","status":1,"is_member":0,"id":35,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},"name":"Coding壁纸","created_at":1435882115000,"id":373,"user_list":[{"sex":0,"birthday":"1990-10-17","location":"","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-2.png","gravatar":"https://dn-coding-net-avatar.qbox.me/1431273e-8432-476d-ad4d-e746b477fb86.jpg","lavatar":"/static/fruit_avatar/Fruit-2.png","created_at":1435884228000,"last_logined_at":1435981050000,"global_key":"goudaxiong","name":"goudaxiong","name_pinyin":"","updated_at":1435884228000,"path":"/u/goudaxiong","status":1,"is_member":0,"id":111166,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":2,"birthday":"1998-03-04","location":"河北 保定","company":"QiLinYunS","slogan":"名字是潘潘起的,头像是拿ziying的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","created_at":1417764325000,"last_logined_at":1437023057000,"global_key":"TXisfine","name":"小谈谈","name_pinyin":"|xtt|xiaotantan","updated_at":1417764325000,"path":"/u/TXisfine","status":1,"is_member":0,"id":51190,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":1,"hot_tweet":{"id":58530,"owner_id":17567,"owner":{"sex":1,"birthday":"1993-09-03","location":"台湾 宜兰县","company":"Coding.net","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/282e4f85-c279-4bf2-808e-1d45f7f1797d.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/282e4f85-c279-4bf2-808e-1d45f7f1797d.jpg","created_at":1408688496000,"last_logined_at":1436494187000,"global_key":"lichi93","name":"小七七","name_pinyin":"|xqq|xiaoqiqi","updated_at":1408688496000,"path":"/u/lichi93","status":1,"is_member":0,"id":17567,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436678017000,"likes":12,"comments":14,"comment_list":[{"id":131926,"tweet_id":58530,"owner_id":64057,"owner":{"sex":0,"birthday":"1988-09-07","location":"上海 嘉定区","company":"","slogan":"程序员分为11种:用Windows、Linux和OS X的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/af567cd7-fcf9-408f-a91f-aac557dfcf93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!500x500a36a30","gravatar":"https://dn-coding-net-avatar.qbox.me/e3c7367b-a89d-4174-b278-5c7d9c3bcb3c.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/af567cd7-fcf9-408f-a91f-aac557dfcf93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!500x500a36a30","created_at":1419852772000,"last_logined_at":1436446665000,"global_key":"sinkcup","name":"sinkcup","name_pinyin":"","updated_at":1419852772000,"path":"/u/sinkcup","status":1,"is_member":0,"id":64057,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436705627000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/succubus\" rel\u003d\"nofollow\"\u003e@FJH在这里\u003c/a\u003e 鼓掌^o^"},{"id":131870,"tweet_id":58530,"owner_id":101897,"owner":{"sex":1,"birthday":"1990-05-03","location":"","company":"coding","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/02fec97c-4ddf-4321-97c2-08bd4cf77e6d.png?imageMogr2/auto-orient/format/png/crop/!429x429a10a3","gravatar":"https://dn-coding-net-avatar.qbox.me/c6044d92-1932-492d-b32c-fd701d356884.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/02fec97c-4ddf-4321-97c2-08bd4cf77e6d.png?imageMogr2/auto-orient/format/png/crop/!429x429a10a3","created_at":1431924662000,"last_logined_at":1436975481000,"global_key":"succubus","name":"FJH在这里","name_pinyin":"|zzl|zaizheli","updated_at":1431924662000,"path":"/u/succubus","status":1,"is_member":0,"id":101897,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436690130000,"content":"“谢谢大家我们在一起了”"},{"id":131854,"tweet_id":58530,"owner_id":293,"owner":{"sex":0,"birthday":"1991-07-16","location":"广东 广州","company":"DJI","slogan":"厚积而薄发","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/4e81c8b4-a2af-479f-be17-48ad3d0615b7.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/4e81c8b4-a2af-479f-be17-48ad3d0615b7.jpg","created_at":1404914994000,"last_logined_at":1436071730000,"global_key":"martin","name":"martin","name_pinyin":"","updated_at":1404914994000,"path":"/u/martin","status":1,"is_member":0,"id":293,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436687996000,"content":"在一起!"},{"id":131837,"tweet_id":58530,"owner_id":36142,"owner":{"sex":0,"birthday":"1989-11-09","location":"江苏 苏州","company":"外星","slogan":"像我这样拉风帅气的码农,还能有第二个?~","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/c44d8766-f7cd-44c6-be93-b549727a3d53.jpg?imageMogr2/auto-orient/format/jpeg/crop/!534x534a266a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/c44d8766-f7cd-44c6-be93-b549727a3d53.jpg?imageMogr2/auto-orient/format/jpeg/crop/!534x534a266a0","created_at":1413787731000,"last_logined_at":1436654446000,"global_key":"brainqi","name":"BrainQi","name_pinyin":"","updated_at":1413787731000,"path":"/u/brainqi","status":1,"is_member":0,"id":36142,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436683147000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/fwolf\" rel\u003d\"nofollow\"\u003e@Fwolf\u003c/a\u003e \u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/sweat_smile.png\" title\u003d\"sweat_smile\"\u003e"},{"id":131824,"tweet_id":58530,"owner_id":41106,"owner":{"sex":0,"birthday":"1975-01-01","location":"河北 石家庄","company":"( ͡° ͜ʖ ͡°) ⌒* ( `灬` )*y。o0○","slogan":"勤","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","gravatar":"https://dn-coding-net-avatar.qbox.me/778054a6-374c-48cc-ae89-524a28af00ff.png","lavatar":"https://dn-coding-net-avatar.qbox.me/de0b3864-c6f5-4ac4-813a-9c7433816ec7.png","created_at":1415687370000,"last_logined_at":1436982735000,"global_key":"fwolf","name":"Fwolf","name_pinyin":"","updated_at":1415687370000,"path":"/u/fwolf","status":1,"is_member":0,"id":41106,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436681442000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/brainqi\" rel\u003d\"nofollow\"\u003e@BrainQi\u003c/a\u003e 你這明顯是有企圖的"}],"device":"iPhone 6","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/411\" rel\u003d\"nofollow\"\u003e#JS大会#\u003c/a\u003e 和\u003ca class\u003d\"at-someone\" href\u003d\"/u/tsl0922\" rel\u003d\"nofollow\"\u003e@tsl0922\u003c/a\u003e 情侣装哦\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/grin.png\" title\u003d\"grin\"\u003e \u003ca href\u003d\"https://dn-coding-net-production-pp.qbox.me/2a19507d-bac5-4b27-b353-bd015f7dcfc9.jpg\" target\u003d\"_blank\" class\u003d\"bubble-markdown-image-link\" rel\u003d\"nofollow\"\u003e\u003cimg src\u003d\"https://dn-coding-net-production-pp.qbox.me/2a19507d-bac5-4b27-b353-bd015f7dcfc9.jpg\" alt\u003d\"图片\" class\u003d\" bubble-markdown-image\"\u003e\u003c/a\u003e\u003c/p\u003e","path":"/u/lichi93/pp/58530","activity_id":0,"liked":false,"like_users":[{"sex":0,"birthday":"1993-02-04","location":"","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-18.png","gravatar":"","lavatar":"/static/fruit_avatar/Fruit-18.png","created_at":1417670875000,"last_logined_at":1435509299000,"global_key":"appletang","name":"青天黎明","name_pinyin":"|qingtianliming|qtlm","updated_at":1417670875000,"path":"/u/appletang","status":1,"is_member":0,"id":50636,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1993-09-23","location":"海外 英国","company":"Insititute of Technology, Carlow","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/0ca5a787-e7ce-4c52-8d07-62eb28b2a60a.png?imageMogr2/auto-orient/format/png/crop/!177x177a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/0ca5a787-e7ce-4c52-8d07-62eb28b2a60a.png?imageMogr2/auto-orient/format/png/crop/!177x177a0a0","created_at":1417983021000,"last_logined_at":1436765048000,"global_key":"jerry_shao","name":"小耗子杰瑞","name_pinyin":"|xhzjr|xiaohaozijierui","updated_at":1417983021000,"path":"/u/jerry_shao","status":1,"is_member":0,"id":51643,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1988-09-07","location":"上海 嘉定区","company":"","slogan":"程序员分为11种:用Windows、Linux和OS X的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/af567cd7-fcf9-408f-a91f-aac557dfcf93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!500x500a36a30","gravatar":"https://dn-coding-net-avatar.qbox.me/e3c7367b-a89d-4174-b278-5c7d9c3bcb3c.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/af567cd7-fcf9-408f-a91f-aac557dfcf93.jpg?imageMogr2/auto-orient/format/jpeg/crop/!500x500a36a30","created_at":1419852772000,"last_logined_at":1436446665000,"global_key":"sinkcup","name":"sinkcup","name_pinyin":"","updated_at":1419852772000,"path":"/u/sinkcup","status":1,"is_member":0,"id":64057,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1991-10-20","location":"湖北 武汉","company":"undefined,none,error.","slogan":"KISS","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/e4f083cc-d3db-4041-87c0-195979878e46.png?imageMogr2/auto-orient/format/png/crop/!430x430a0a172","gravatar":"https://dn-coding-net-avatar.qbox.me/542aa98c-1183-442e-8744-907750cdddbb.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/e4f083cc-d3db-4041-87c0-195979878e46.png?imageMogr2/auto-orient/format/png/crop/!430x430a0a172","created_at":1419861720000,"last_logined_at":1437038279000,"global_key":"wenki","name":"wenki","name_pinyin":"","updated_at":1419861720000,"path":"/u/wenki","status":1,"is_member":0,"id":64169,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1988-11-15","location":"","company":"Coding.net","slogan":"这世上所有的不公平都是因为当事人能力的不足。","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/fba26674-8279-4997-be74-3166d74afb74.jpg?imageMogr2/auto-orient/format/jpeg/crop/!564x564a0a142","gravatar":"https://dn-coding-net-avatar.qbox.me/36413eae-4037-40dc-99bc-1aacfb4cd1ef.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/fba26674-8279-4997-be74-3166d74afb74.jpg?imageMogr2/auto-orient/format/jpeg/crop/!564x564a0a142","created_at":1399123736000,"last_logined_at":1437045348475,"global_key":"kin","name":"书一","name_pinyin":"|sy|shuyi","updated_at":1399123736000,"path":"/u/kin","status":1,"is_member":0,"id":10,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":1,"birthday":"1987-08-04","location":"广东 深圳","company":"coding","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/1b9ac59b-9ef3-4328-990a-ed4cbe996476.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/1b9ac59b-9ef3-4328-990a-ed4cbe996476.jpg","created_at":1404874624000,"last_logined_at":1437045840626,"global_key":"guoguo","name":"蝈蝈尹","name_pinyin":"|ggy|guoguoyin","updated_at":1404874624000,"path":"/u/guoguo","status":1,"is_member":0,"id":289,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":1,"birthday":"1985-06-07","location":"广东 深圳","company":"","slogan":"只爱自己爱的人","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/f224064d-5a94-456c-b96a-01aabb5c6973.jpg?imageMogr2/auto-orient/format/jpeg/crop/!640x640a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/f224064d-5a94-456c-b96a-01aabb5c6973.jpg?imageMogr2/auto-orient/format/jpeg/crop/!640x640a0a0","created_at":1402474269000,"last_logined_at":1436954777000,"global_key":"lingling","name":"灵灵","name_pinyin":"|ll|lingling","updated_at":1402474269000,"path":"/u/lingling","status":1,"is_member":0,"id":35,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1988-01-01","location":"山东 济南","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/7633c8636fa4099608191032ac04a295.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/7633c8636fa4099608191032ac04a295.jpg","created_at":1405739267000,"last_logined_at":1436449171000,"global_key":"itfanr","name":"itfanr","name_pinyin":"","updated_at":1405739267000,"path":"/u/itfanr","status":1,"is_member":0,"id":2118,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":2,"birthday":"1998-03-04","location":"河北 保定","company":"QiLinYunS","slogan":"名字是潘潘起的,头像是拿ziying的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","created_at":1417764325000,"last_logined_at":1437023057000,"global_key":"TXisfine","name":"小谈谈","name_pinyin":"|xtt|xiaotantan","updated_at":1417764325000,"path":"/u/TXisfine","status":1,"is_member":0,"id":51190,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1989-11-09","location":"江苏 苏州","company":"外星","slogan":"像我这样拉风帅气的码农,还能有第二个?~","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/c44d8766-f7cd-44c6-be93-b549727a3d53.jpg?imageMogr2/auto-orient/format/jpeg/crop/!534x534a266a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/c44d8766-f7cd-44c6-be93-b549727a3d53.jpg?imageMogr2/auto-orient/format/jpeg/crop/!534x534a266a0","created_at":1413787731000,"last_logined_at":1436654446000,"global_key":"brainqi","name":"BrainQi","name_pinyin":"","updated_at":1413787731000,"path":"/u/brainqi","status":1,"is_member":0,"id":36142,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},"name":"JS大会","created_at":1436678017000,"id":411,"user_list":[{"sex":1,"birthday":"1993-09-03","location":"台湾 宜兰县","company":"Coding.net","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/282e4f85-c279-4bf2-808e-1d45f7f1797d.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/282e4f85-c279-4bf2-808e-1d45f7f1797d.jpg","created_at":1408688496000,"last_logined_at":1436494187000,"global_key":"lichi93","name":"小七七","name_pinyin":"|xqq|xiaoqiqi","updated_at":1408688496000,"path":"/u/lichi93","status":1,"is_member":0,"id":17567,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":4,"hot_tweet":{"id":54362,"owner_id":5764,"owner":{"sex":0,"birthday":"1984-10-07","location":"山东 淄博 张店","company":"山东蓝标信息科技有限公司","slogan":"勇者无所畏惧 blog.hainuo.info","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/4cc88a4e-7adc-469f-98a5-6091ef2a35c3.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","created_at":1406871611000,"last_logined_at":1436929956000,"global_key":"hainuo","name":"刘峰","name_pinyin":"|lf|liufeng","updated_at":1406871611000,"path":"/u/hainuo","status":1,"is_member":0,"id":5764,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1435771908000,"likes":0,"comments":6,"comment_list":[{"id":126416,"tweet_id":54362,"owner_id":27666,"owner":{"sex":0,"birthday":"1998-05-15","location":"孜然麻辣熊黑科技研究中心","company":"孜然麻辣熊黑科技有限公司","slogan":"让懂的人懂,让不懂的人不懂。","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/0b6499da-33ba-489d-99d0-4324c9f53e7c.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/0b6499da-33ba-489d-99d0-4324c9f53e7c.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a0a0","created_at":1409313681000,"last_logined_at":1437046129576,"global_key":"linqun","name":"孜然麻辣熊大大","name_pinyin":"|zrmlxdd|ziranmalaxiongdada","updated_at":1409313681000,"path":"/u/linqun","status":1,"is_member":0,"id":27666,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1435796170000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/hainuo\" rel\u003d\"nofollow\"\u003e@刘峰\u003c/a\u003e 表示每天冒泡8次,推代码数百次"},{"id":126415,"tweet_id":54362,"owner_id":2552,"owner":{"sex":2,"birthday":"1994-08-02","location":"山东 烟台","company":"公司","slogan":"にゃにゃん╭( ・ㅂ・)و ̑̑ye","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/669e1714-e6d7-47d6-8984-8de4e5c3d5c1.png?imageMogr2/auto-orient/format/png/crop/!450x450a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/ee4fc3ca-73f8-433e-be09-e67b11610011.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/669e1714-e6d7-47d6-8984-8de4e5c3d5c1.png?imageMogr2/auto-orient/format/png/crop/!450x450a0a0","created_at":1406008158000,"last_logined_at":1436947197000,"global_key":"xin","name":"xin","name_pinyin":"","updated_at":1406008158000,"path":"/u/xin","status":1,"is_member":0,"id":2552,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1435796122000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/hainuo\" rel\u003d\"nofollow\"\u003e@刘峰\u003c/a\u003e 之前一直在潜水开发好吧 昨天才水了一下 结果又回到榜上了"},{"id":126414,"tweet_id":54362,"owner_id":5764,"owner":{"sex":0,"birthday":"1984-10-07","location":"山东 淄博 张店","company":"山东蓝标信息科技有限公司","slogan":"勇者无所畏惧 blog.hainuo.info","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/4cc88a4e-7adc-469f-98a5-6091ef2a35c3.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","created_at":1406871611000,"last_logined_at":1436929956000,"global_key":"hainuo","name":"刘峰","name_pinyin":"|lf|liufeng","updated_at":1406871611000,"path":"/u/hainuo","status":1,"is_member":0,"id":5764,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1435796089000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/linqun\" rel\u003d\"nofollow\"\u003e@孜然麻辣熊大大\u003c/a\u003e 你也有活跃基因"},{"id":126413,"tweet_id":54362,"owner_id":5764,"owner":{"sex":0,"birthday":"1984-10-07","location":"山东 淄博 张店","company":"山东蓝标信息科技有限公司","slogan":"勇者无所畏惧 blog.hainuo.info","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/4cc88a4e-7adc-469f-98a5-6091ef2a35c3.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","created_at":1406871611000,"last_logined_at":1436929956000,"global_key":"hainuo","name":"刘峰","name_pinyin":"|lf|liufeng","updated_at":1406871611000,"path":"/u/hainuo","status":1,"is_member":0,"id":5764,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1435796068000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/xin\" rel\u003d\"nofollow\"\u003e@xin\u003c/a\u003e 你一直活跃好不好\u003cimg class\u003d\"emotion emoji\" src\u003d\"https://coding.net/static/emojis/disappointed_relieved.png\" title\u003d\"disappointed_relieved\"\u003e"},{"id":126411,"tweet_id":54362,"owner_id":27666,"owner":{"sex":0,"birthday":"1998-05-15","location":"孜然麻辣熊黑科技研究中心","company":"孜然麻辣熊黑科技有限公司","slogan":"让懂的人懂,让不懂的人不懂。","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/0b6499da-33ba-489d-99d0-4324c9f53e7c.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/0b6499da-33ba-489d-99d0-4324c9f53e7c.jpg?imageMogr2/auto-orient/format/jpeg/crop/!450x450a0a0","created_at":1409313681000,"last_logined_at":1437046129576,"global_key":"linqun","name":"孜然麻辣熊大大","name_pinyin":"|zrmlxdd|ziranmalaxiongdada","updated_at":1409313681000,"path":"/u/linqun","status":1,"is_member":0,"id":27666,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1435795982000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/xin\" rel\u003d\"nofollow\"\u003e@xin\u003c/a\u003e 你有热门用户基因"}],"device":"","location":"","coord":"","address":"","content":"\u003cp\u003e\u003ca href\u003d\"https://dn-coding-net-production-pp.qbox.me/4e648f1d-e497-445d-8762-bff9ad0a5e3c.png\" target\u003d\"_blank\" class\u003d\"bubble-markdown-image-link\" rel\u003d\"nofollow\"\u003e\u003cimg src\u003d\"https://dn-coding-net-production-pp.qbox.me/4e648f1d-e497-445d-8762-bff9ad0a5e3c.png\" alt\u003d\"图片\" class\u003d\" bubble-markdown-image\"\u003e\u003c/a\u003e \u003cbr\u003e 上个排行榜好难,做个备忘把\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/359\" rel\u003d\"nofollow\"\u003e#调戏Coding#\u003c/a\u003e \u003c/p\u003e","path":"/u/hainuo/pp/54362","activity_id":0,"liked":false,"like_users":[]},"name":"调戏CODING","created_at":1435732658000,"id":359,"user_list":[{"sex":2,"birthday":"1994-08-02","location":"山东 烟台","company":"公司","slogan":"にゃにゃん╭( ・ㅂ・)و ̑̑ye","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/669e1714-e6d7-47d6-8984-8de4e5c3d5c1.png?imageMogr2/auto-orient/format/png/crop/!450x450a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/ee4fc3ca-73f8-433e-be09-e67b11610011.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/669e1714-e6d7-47d6-8984-8de4e5c3d5c1.png?imageMogr2/auto-orient/format/png/crop/!450x450a0a0","created_at":1406008158000,"last_logined_at":1436947197000,"global_key":"xin","name":"xin","name_pinyin":"","updated_at":1406008158000,"path":"/u/xin","status":1,"is_member":0,"id":2552,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1994-08-31","location":"江苏 南京","company":"幕(木)游(有)公司","slogan":"做一个简单的人,踏实而务实,不沉溺幻想,不庸人自扰","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/5ae8585e-662b-4bf1-bd53-318c6cec8426.jpg?imageMogr2/auto-orient/format/jpeg/crop/!239x239a0a34","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/5ae8585e-662b-4bf1-bd53-318c6cec8426.jpg?imageMogr2/auto-orient/format/jpeg/crop/!239x239a0a34","created_at":1418705066000,"last_logined_at":1436600011000,"global_key":"Morph_Zhou","name":"Morph_Zhou","name_pinyin":"","updated_at":1418705066000,"path":"/u/Morph_Zhou","status":1,"is_member":0,"id":54212,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1984-10-07","location":"山东 淄博 张店","company":"山东蓝标信息科技有限公司","slogan":"勇者无所畏惧 blog.hainuo.info","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","gravatar":"https://dn-coding-net-avatar.qbox.me/4cc88a4e-7adc-469f-98a5-6091ef2a35c3.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/fd75e8fa-9345-4e66-9bf0-d6370f3c515c.png?imageMogr2/auto-orient/format/png/crop/!128x128a0a0","created_at":1406871611000,"last_logined_at":1436929956000,"global_key":"hainuo","name":"刘峰","name_pinyin":"|lf|liufeng","updated_at":1406871611000,"path":"/u/hainuo","status":1,"is_member":0,"id":5764,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-avatar.qbox.me/1a1873a8-7d76-4927-ae2e-38ad67c99582.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/488fbd75-4307-449c-a2af-d14a1ef61907.jpg","lavatar":"https://dn-coding-net-avatar.qbox.me/1a1873a8-7d76-4927-ae2e-38ad67c99582.jpg","created_at":1435753043000,"last_logined_at":1437031483000,"global_key":"zorji","name":"zorji","name_pinyin":"","updated_at":1435753043000,"path":"/u/zorji","status":1,"is_member":0,"id":110899,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},{"watched":false,"user_count":1,"hot_tweet":{"id":56555,"owner_id":93,"owner":{"sex":0,"birthday":"2014-02-14","location":"广东 深圳","company":"Coding.net","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/512b2a62-956b-4ef8-8e84-b3c66e71468f.png?imageMogr2/auto-orient/format/png/crop/!300x300a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/512b2a62-956b-4ef8-8e84-b3c66e71468f.png?imageMogr2/auto-orient/format/png/crop/!300x300a0a0","created_at":1403329814000,"last_logined_at":1436261323000,"global_key":"coding","name":"coding","name_pinyin":"","updated_at":1403329814000,"path":"/u/coding","status":1,"is_member":0,"id":93,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436254603000,"likes":9,"comments":17,"comment_list":[{"id":129637,"tweet_id":56555,"owner_id":51190,"owner":{"sex":2,"birthday":"1998-03-04","location":"河北 保定","company":"QiLinYunS","slogan":"名字是潘潘起的,头像是拿ziying的","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/6f086f94-130e-4ad3-8afd-f2b088ce2459.jpg","created_at":1417764325000,"last_logined_at":1437023057000,"global_key":"TXisfine","name":"小谈谈","name_pinyin":"|xtt|xiaotantan","updated_at":1417764325000,"path":"/u/TXisfine","status":1,"is_member":0,"id":51190,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436330193000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/sophia123456\" rel\u003d\"nofollow\"\u003e@小罗\u003c/a\u003e 喔喔~了解。"},{"id":129551,"tweet_id":56555,"owner_id":89471,"owner":{"sex":0,"birthday":"2015-06-18","location":"广西 南宁","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/737bcf6e-111d-49a4-8b0e-4de839b4716e.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/07d49a54-cb05-4a21-9b12-ed23f1fa71cf.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/737bcf6e-111d-49a4-8b0e-4de839b4716e.jpg","created_at":1427685305000,"last_logined_at":1437032650000,"global_key":"sophia123456","name":"小罗","name_pinyin":"|xl|xiaoluo","updated_at":1427685305000,"path":"/u/sophia123456","status":1,"is_member":0,"id":89471,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436324572000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/bumy\" rel\u003d\"nofollow\"\u003e@riverlong\u003c/a\u003e 支付宝私信给我哈"},{"id":129487,"tweet_id":56555,"owner_id":89471,"owner":{"sex":0,"birthday":"2015-06-18","location":"广西 南宁","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/737bcf6e-111d-49a4-8b0e-4de839b4716e.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/07d49a54-cb05-4a21-9b12-ed23f1fa71cf.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/737bcf6e-111d-49a4-8b0e-4de839b4716e.jpg","created_at":1427685305000,"last_logined_at":1437032650000,"global_key":"sophia123456","name":"小罗","name_pinyin":"|xl|xiaoluo","updated_at":1427685305000,"path":"/u/sophia123456","status":1,"is_member":0,"id":89471,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436320778000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/srufeng\" rel\u003d\"nofollow\"\u003e@srufeng\u003c/a\u003e 提bug或者建议 到公开 ios/android 的项目讨论中,可能会有奖励哈~"},{"id":129484,"tweet_id":56555,"owner_id":89471,"owner":{"sex":0,"birthday":"2015-06-18","location":"广西 南宁","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/737bcf6e-111d-49a4-8b0e-4de839b4716e.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/07d49a54-cb05-4a21-9b12-ed23f1fa71cf.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/737bcf6e-111d-49a4-8b0e-4de839b4716e.jpg","created_at":1427685305000,"last_logined_at":1437032650000,"global_key":"sophia123456","name":"小罗","name_pinyin":"|xl|xiaoluo","updated_at":1427685305000,"path":"/u/sophia123456","status":1,"is_member":0,"id":89471,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436320674000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/zeallrm\" rel\u003d\"nofollow\"\u003e@zeallrm\u003c/a\u003e 相互关注,才是好友呢"},{"id":129483,"tweet_id":56555,"owner_id":89471,"owner":{"sex":0,"birthday":"2015-06-18","location":"广西 南宁","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/737bcf6e-111d-49a4-8b0e-4de839b4716e.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/07d49a54-cb05-4a21-9b12-ed23f1fa71cf.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/737bcf6e-111d-49a4-8b0e-4de839b4716e.jpg","created_at":1427685305000,"last_logined_at":1437032650000,"global_key":"sophia123456","name":"小罗","name_pinyin":"|xl|xiaoluo","updated_at":1427685305000,"path":"/u/sophia123456","status":1,"is_member":0,"id":89471,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},"created_at":1436320634000,"content":"\u003ca class\u003d\"at-someone\" href\u003d\"/u/bumy\" rel\u003d\"nofollow\"\u003e@riverlong\u003c/a\u003e 棒棒哒~"}],"device":"","location":"","coord":"","address":"","content":"\u003ch2 id\u003d\"客户端-v3.0-版本-“赏金码士”-出炉\"\u003e客户端 V3.0 版本 “赏金码士” 出炉\u003c/h2\u003e \n\u003cp\u003e\u003ca class\u003d\"topic\" href\u003d\"/pp/topic/387\" rel\u003d\"nofollow\"\u003e#Coding 客户端#\u003c/a\u003e \u003cbr\u003e 在大家的支持下,客户端 V 3.0 已正式上线~请大家前往各大 app 市场进行更新\u003c/p\u003e \n\u003ch3 id\u003d\"发放赏金\"\u003e发放赏金\u003c/h3\u003e \n\u003cp\u003eiOS 版提交 bug 并通过审核者:\u003c/p\u003e \n\u003ctable\u003e \n \u003ctr\u003e \n \u003cth align\u003d\"center\"\u003e码士\u003c/th\u003e \n \u003cth align\u003d\"center\"\u003e金额\u003c/th\u003e \n \u003c/tr\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003ctd align\u003d\"center\"\u003e\u003ca class\u003d\"at-someone\" href\u003d\"/u/dowell\" rel\u003d\"nofollow\"\u003e@dowell\u003c/a\u003e \u003c/td\u003e \n \u003ctd align\u003d\"center\"\u003e20元\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd align\u003d\"center\"\u003e\u003ca class\u003d\"at-someone\" href\u003d\"/u/CyonLeu\" rel\u003d\"nofollow\"\u003e@cyonleu\u003c/a\u003e \u003c/td\u003e \n \u003ctd align\u003d\"center\"\u003e20元\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd align\u003d\"center\"\u003e\u003ca class\u003d\"at-someone\" href\u003d\"/u/huangyong\" rel\u003d\"nofollow\"\u003e@黄勇\u003c/a\u003e \u003c/td\u003e \n \u003ctd align\u003d\"center\"\u003e20元\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd align\u003d\"center\"\u003e\u003ca class\u003d\"at-someone\" href\u003d\"/u/yaming\" rel\u003d\"nofollow\"\u003e@花开堪折枝\u003c/a\u003e \u003c/td\u003e \n \u003ctd align\u003d\"center\"\u003e20元\u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n\u003c/table\u003e \n\u003cp\u003eAndroid 版提交 bug 并通过审核者:\u003c/p\u003e \n\u003ctable\u003e \n \u003ctr\u003e \n \u003cth align\u003d\"center\"\u003e码士\u003c/th\u003e \n \u003cth align\u003d\"center\"\u003e金额\u003c/th\u003e \n \u003c/tr\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003ctd align\u003d\"center\"\u003e\u003ca class\u003d\"at-someone\" href\u003d\"/u/bumy\" rel\u003d\"nofollow\"\u003e@riverlong\u003c/a\u003e \u003c/td\u003e \n \u003ctd align\u003d\"center\"\u003e100元\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd align\u003d\"center\"\u003e\u003ca class\u003d\"at-someone\" href\u003d\"/u/898745604\" rel\u003d\"nofollow\"\u003e@VDer\u003c/a\u003e \u003c/td\u003e \n \u003ctd align\u003d\"center\"\u003e40元\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd align\u003d\"center\"\u003e\u003ca class\u003d\"at-someone\" href\u003d\"/u/hcrgm\" rel\u003d\"nofollow\"\u003e@hcrgm\u003c/a\u003e \u003c/td\u003e \n \u003ctd align\u003d\"center\"\u003e20元\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd align\u003d\"center\"\u003e\u003ca class\u003d\"at-someone\" href\u003d\"/u/icanghai\" rel\u003d\"nofollow\"\u003e@icanghai\u003c/a\u003e \u003c/td\u003e \n \u003ctd align\u003d\"center\"\u003e20元\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd align\u003d\"center\"\u003e\u003ca class\u003d\"at-someone\" href\u003d\"/u/xiaozhu\" rel\u003d\"nofollow\"\u003e@铂金小猪\u003c/a\u003e \u003c/td\u003e \n \u003ctd align\u003d\"center\"\u003e20元\u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n\u003c/table\u003e \n\u003ch4 id\u003d\"ps:-找-bug-还有赏金拿!这样的好事哪里找?报名参加公测~-请直接私信-\u003ca class\u003d\u0027at-someone\u0027 href\u003d\u0027/u/sophia123456\u0027\u003e@小罗\u003c/a\u003e \"\u003ePS: 找 bug 还有赏金拿!这样的好事哪里找?报名参加公测~ 请直接私信 \u003ca class\u003d\"at-someone\" href\u003d\"/u/sophia123456\" rel\u003d\"nofollow\"\u003e@小罗\u003c/a\u003e \u003c/h4\u003e","path":"/u/coding/pp/56555","activity_id":0,"liked":false,"like_users":[{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-20.png","gravatar":"","lavatar":"/static/fruit_avatar/Fruit-20.png","created_at":1411968342000,"last_logined_at":1436941286000,"global_key":"wenchang","name":"wenchang","name_pinyin":"","updated_at":1411968342000,"path":"/u/wenchang","status":1,"is_member":0,"id":33522,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1988-01-01","location":"山东 济南","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/7633c8636fa4099608191032ac04a295.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/7633c8636fa4099608191032ac04a295.jpg","created_at":1405739267000,"last_logined_at":1436449171000,"global_key":"itfanr","name":"itfanr","name_pinyin":"","updated_at":1405739267000,"path":"/u/itfanr","status":1,"is_member":0,"id":2118,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":1,"birthday":"1990-05-03","location":"","company":"coding","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/02fec97c-4ddf-4321-97c2-08bd4cf77e6d.png?imageMogr2/auto-orient/format/png/crop/!429x429a10a3","gravatar":"https://dn-coding-net-avatar.qbox.me/c6044d92-1932-492d-b32c-fd701d356884.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/02fec97c-4ddf-4321-97c2-08bd4cf77e6d.png?imageMogr2/auto-orient/format/png/crop/!429x429a10a3","created_at":1431924662000,"last_logined_at":1436975481000,"global_key":"succubus","name":"FJH在这里","name_pinyin":"|zzl|zaizheli","updated_at":1431924662000,"path":"/u/succubus","status":1,"is_member":0,"id":101897,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"","company":"","slogan":"","introduction":"","avatar":"/static/fruit_avatar/Fruit-10.png","gravatar":"https://dn-coding-net-avatar.qbox.me/d9f05231-7871-4dfa-93a5-a1f581ea7f75.jpg","lavatar":"/static/fruit_avatar/Fruit-10.png","created_at":1434642539000,"last_logined_at":1434929202000,"global_key":"zeallrm","name":"zeallrm","name_pinyin":"","updated_at":1434642539000,"path":"/u/zeallrm","status":1,"is_member":0,"id":108626,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"广东 广州","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/6b1f621a-eef8-45f0-90a5-2b6e4dd257b2.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/ed58d4ae-e17e-48fd-9f49-eeba3b26589a.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/6b1f621a-eef8-45f0-90a5-2b6e4dd257b2.jpg","created_at":1430075407000,"last_logined_at":1436791946000,"global_key":"bumy","name":"riverlong","name_pinyin":"","updated_at":1430075407000,"path":"/u/bumy","status":1,"is_member":0,"id":98041,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"2015-06-18","location":"广西 南宁","company":"","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/737bcf6e-111d-49a4-8b0e-4de839b4716e.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/07d49a54-cb05-4a21-9b12-ed23f1fa71cf.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/737bcf6e-111d-49a4-8b0e-4de839b4716e.jpg","created_at":1427685305000,"last_logined_at":1437032650000,"global_key":"sophia123456","name":"小罗","name_pinyin":"|xl|xiaoluo","updated_at":1427685305000,"path":"/u/sophia123456","status":1,"is_member":0,"id":89471,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1985-01-01","location":"上海 长宁区","company":"shanghai yujing","slogan":"qinfen shi wo weiyi chulu","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/33f34541-d124-415b-bc39-47de5e0bde7f.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/5b92fba2-e22b-46d6-a002-ab5550d91688.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/33f34541-d124-415b-bc39-47de5e0bde7f.jpg","created_at":1426063393000,"last_logined_at":1436429110000,"global_key":"pingtanglu","name":"pingtanglu","name_pinyin":"","updated_at":1426063393000,"path":"/u/pingtanglu","status":1,"is_member":0,"id":84448,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":0,"birthday":"1991-12-01","location":"广东 深圳","company":"CODING","slogan":"只有偏执狂才能生存","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/eece4ae0-233e-4604-a0ad-2ec936b32238.jpg","gravatar":"https://dn-coding-net-avatar.qbox.me/df00f228-aa2b-425f-a91a-c46724331dcc.jpg","lavatar":"https://dn-coding-net-production-static.qbox.me/eece4ae0-233e-4604-a0ad-2ec936b32238.jpg","created_at":1435320620000,"last_logined_at":1436862521000,"global_key":"miaodesign","name":"MangoCC","name_pinyin":"","updated_at":1435320620000,"path":"/u/miaodesign","status":1,"is_member":0,"id":109929,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false},{"sex":1,"birthday":"1987-08-04","location":"广东 深圳","company":"coding","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/1b9ac59b-9ef3-4328-990a-ed4cbe996476.jpg","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/1b9ac59b-9ef3-4328-990a-ed4cbe996476.jpg","created_at":1404874624000,"last_logined_at":1437045840626,"global_key":"guoguo","name":"蝈蝈尹","name_pinyin":"|ggy|guoguoyin","updated_at":1404874624000,"path":"/u/guoguo","status":1,"is_member":0,"id":289,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]},"name":"Coding 客户端","created_at":1436254604000,"id":387,"user_list":[{"sex":0,"birthday":"2014-02-14","location":"广东 深圳","company":"Coding.net","slogan":"","introduction":"","avatar":"https://dn-coding-net-production-static.qbox.me/512b2a62-956b-4ef8-8e84-b3c66e71468f.png?imageMogr2/auto-orient/format/png/crop/!300x300a0a0","gravatar":"","lavatar":"https://dn-coding-net-production-static.qbox.me/512b2a62-956b-4ef8-8e84-b3c66e71468f.png?imageMogr2/auto-orient/format/png/crop/!300x300a0a0","created_at":1403329814000,"last_logined_at":1436261323000,"global_key":"coding","name":"coding","name_pinyin":"","updated_at":1403329814000,"path":"/u/coding","status":1,"is_member":0,"id":93,"follows_count":0,"fans_count":0,"tweets_count":0,"followed":false,"follow":false}]}]} diff --git a/Coding_iOS/Controllers/SearchViewController.m b/Coding_iOS/Controllers/SearchViewController.m index 567d1656b..5c970702d 100644 --- a/Coding_iOS/Controllers/SearchViewController.m +++ b/Coding_iOS/Controllers/SearchViewController.m @@ -8,18 +8,15 @@ #import "SearchViewController.h" #import "CategorySearchBar.h" -#import "KxMenu.h" #import "AllSearchDisplayVC.h" #import "FileViewController.h" @interface SearchViewController () @property (nonatomic,strong)UIView *searchView; -@property (strong, nonatomic) NSMutableArray *statusList; @property (strong, nonatomic) CategorySearchBar *mySearchBar; @property (strong, nonatomic) AllSearchDisplayVC *searchDisplayVC; @property (nonatomic,strong) UITableView *tableview; @property (nonatomic,strong) NSMutableArray *dataSource; -@property (nonatomic,assign) NSInteger selectIndex; @property (nonatomic,assign) BOOL firstLoad; @end @@ -28,15 +25,6 @@ @implementation SearchViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. - _selectIndex=0; - _statusList = @[@"项目", - @"任务", - @"讨论", - @"冒泡", - @"文档", - @"用户", - @"合并请求", - @"pull 请求"].mutableCopy; _firstLoad = TRUE; [self buildUI]; } @@ -45,69 +33,32 @@ -(void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; [self loadData]; [self.navigationController.navigationBar addSubview:_mySearchBar]; + [(BaseNavigationController *)self.navigationController hideNavBottomLine]; if (_firstLoad) { [_mySearchBar becomeFirstResponder]; } } --(void)viewWillDisappear:(BOOL)animated -{ +-(void)viewWillDisappear:(BOOL)animated{ [super viewWillDisappear:animated]; [_mySearchBar resignFirstResponder]; [_mySearchBar removeFromSuperview]; + [(BaseNavigationController *)self.navigationController showNavBottomLine]; _firstLoad = FALSE; } //基础化UI布局 -(void)buildUI{ -// self.view.backgroundColor=[UIColor colorWithHexString:@"0xeeeeee"]; - - //添加搜索框 _mySearchBar = ({ - CategorySearchBar *searchBar = [[CategorySearchBar alloc] initWithFrame:CGRectMake(20, 7, kScreen_Width-75, 31)]; - searchBar.layer.cornerRadius = 2; - searchBar.layer.masksToBounds = TRUE; - [searchBar insertBGColor:kColorTableSectionBg]; - [searchBar setSearchFieldBackgroundImage:[UIImage imageWithColor:kColorTableSectionBg] forState:UIControlStateNormal]; - [searchBar setHeight:30]; - [searchBar setPlaceholder:@"项目、任务、冒泡等"]; + CategorySearchBar *searchBar = [[CategorySearchBar alloc] initWithFrame:CGRectMake(20, 7, kScreen_Width-(80 * kScreen_Width / 375), 31)]; + [searchBar setPlaceholder:@" 搜索"]; searchBar; }); - - - //初始化选项 - NSMutableArray *menuItems = @[].mutableCopy; - [_statusList enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { - KxMenuItem *menuItem = [KxMenuItem menuItem:obj image:nil target:self action:@selector(menuItemClicked:)]; - menuItem.alignment = NSTextAlignmentLeft; - menuItem.foreColor = kColorNavTitle; - [menuItems addObject:menuItem]; - }]; - - - __weak typeof(self) weakSelf = self; - [_mySearchBar patchWithCategoryWithSelectBlock:^{ - if ([KxMenu isShowingInView:[UIApplication sharedApplication].keyWindow]) { - [KxMenu dismissMenu:YES]; - [weakSelf.mySearchBar becomeFirstResponder]; - }else{ - [weakSelf.mySearchBar resignFirstResponder]; - [KxMenu setTitleFont:[UIFont systemFontOfSize:14]]; - [KxMenu setTintColor:kColorNavBG]; - [KxMenu setOverlayColor:[UIColor clearColor]]; - - CGRect senderFrame = CGRectMake(weakSelf.searchView.frame.origin.x+50, 64, 0, 0); - [KxMenu showMenuInView:[UIApplication sharedApplication].keyWindow fromRect:senderFrame menuItems:menuItems]; - } - }]; - [_mySearchBar setSearchCategory:[_statusList objectAtIndex:_selectIndex]]; - if (!_searchDisplayVC) { _searchDisplayVC = ({ AllSearchDisplayVC *searchVC = [[AllSearchDisplayVC alloc] initWithSearchBar:_mySearchBar contentsController:self]; - //自定义uisearchbar 要在这里重新申明 - //需要重新调整下大小 - searchVC.searchBar.frame = CGRectMake(20, 7, kScreen_Width-75, 31); + //uisearchbar 需要重新调整下大小 + searchVC.searchBar.frame = CGRectMake(20, 7, kScreen_Width-(80 * kScreen_Width / 375), 31); searchVC.displaysSearchBarInNavigationBar = NO; searchVC.parentVC = self; searchVC.delegate = self; @@ -129,25 +80,4 @@ -(void)popToMainVCAction{ [self dismissViewControllerAnimated:NO completion:nil]; } -- (void)menuItemClicked:(KxMenuItem *)item{ - [MobClick event:kUmeng_Event_Request_ActionOfLocal label:[NSString stringWithFormat:@"全局搜索_%@", item.title]]; - NSInteger nowSelectIndex = [_statusList indexOfObject:item.title]; - if (nowSelectIndex == NSNotFound || nowSelectIndex == _selectIndex) { - return; - } - _selectIndex = nowSelectIndex; - - _searchDisplayVC.curSearchType=_selectIndex; - NSString *showStr=([[_statusList objectAtIndex:_selectIndex] length]>2)?[[_statusList objectAtIndex:_selectIndex] substringToIndex:[[_statusList objectAtIndex:_selectIndex] length]-2]:[_statusList objectAtIndex:_selectIndex]; - [_mySearchBar setSearchCategory:showStr]; - - if (_searchDisplayVC.active&&(_mySearchBar.text.length>0)) { - NSLog(@"active And can search"); - [_searchDisplayVC reloadDisplayData]; - }else{ - [_mySearchBar becomeFirstResponder]; - } -} - - @end diff --git a/Coding_iOS/Controllers/Shop/ExchangeGoodsViewController.m b/Coding_iOS/Controllers/Shop/ExchangeGoodsViewController.m index 3852bc7db..990a8580e 100644 --- a/Coding_iOS/Controllers/Shop/ExchangeGoodsViewController.m +++ b/Coding_iOS/Controllers/Shop/ExchangeGoodsViewController.m @@ -15,8 +15,8 @@ #import "LocationViewController.h" #import "ShopMutileValueCell.h" #import "ActionSheetStringPicker.h" - -#define kCellIdentifier_ShopOrderTextFieldCell @"ShopOrderTextFieldCell.h" +#import "ShopSwitchCell.h" +#import "EAPayViewController.h" @interface ExchangeGoodsViewController () { @@ -24,10 +24,12 @@ @interface ExchangeGoodsViewController () 0? 6: 5; + NSInteger row = section == 0? self.shopGoods.options.count > 0? 6: 5: 1; return row; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - if (indexPath.row == 1 || indexPath.row == 5) { - ShopMutileValueCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_ShopMutileValueCell forIndexPath:indexPath]; - if (indexPath.row == 1) { - cell.titleL.text = @"所在地 *"; - cell.valueF.text = [[self.locations valueForKey:@"name"] componentsJoinedByString:@" - "]; - }else{ - cell.titleL.text = @"选项"; - cell.valueF.text = self.option.name; - } - return cell; - } - else{ - ShopOrderTextFieldCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_ShopOrderTextFieldCell forIndexPath:indexPath]; - - switch (indexPath.row) { - case 0: - { - cell.nameLabel.text = @"收货人 *"; - cell.textField.placeholder = @"小王"; - cell.textField.text = self.receiverName; - RAC(self, receiverName) = [cell.textField.rac_textSignal takeUntil:cell.rac_prepareForReuseSignal]; - break; - } - case 2: - { - cell.nameLabel.text = @"详细地址 *"; - cell.textField.placeholder = @"街道地址"; - cell.textField.text = self.receiverAddress; - RAC(self, receiverAddress) = [cell.textField.rac_textSignal takeUntil:cell.rac_prepareForReuseSignal]; - break; - } - case 3: - { - cell.nameLabel.text = @"联系电话 *"; - cell.textField.placeholder = @"电话"; - cell.textField.text = self.receiverPhone; - RAC(self, receiverPhone) = [cell.textField.rac_textSignal takeUntil:cell.rac_prepareForReuseSignal]; - break; + if (indexPath.section == 0) { + if (indexPath.row == 1 || indexPath.row == 5) { + ShopMutileValueCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_ShopMutileValueCell forIndexPath:indexPath]; + if (indexPath.row == 1) { + cell.titleL.text = @"所在地 *"; + cell.valueF.text = [[self.locations valueForKey:@"name"] componentsJoinedByString:@" - "]; + }else{ + cell.titleL.text = @"选项"; + cell.valueF.text = self.option.name; } - case 4: - { - cell.nameLabel.text = @"备注"; - cell.textField.placeholder = @"备注信息如:衣服码数XXL"; - cell.textField.text = self.remark; - RAC(self, remark) = [cell.textField.rac_textSignal takeUntil:cell.rac_prepareForReuseSignal]; - break; + return cell; + } + else{ + ShopOrderTextFieldCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_ShopOrderTextFieldCell forIndexPath:indexPath]; + + switch (indexPath.row) { + case 0: + { + cell.nameLabel.text = @"收货人 *"; + cell.textField.placeholder = @"小王"; + cell.textField.text = self.receiverName; + RAC(self, receiverName) = [cell.textField.rac_textSignal takeUntil:cell.rac_prepareForReuseSignal]; + break; + } + case 2: + { + cell.nameLabel.text = @"详细地址 *"; + cell.textField.placeholder = @"街道地址"; + cell.textField.text = self.receiverAddress; + RAC(self, receiverAddress) = [cell.textField.rac_textSignal takeUntil:cell.rac_prepareForReuseSignal]; + break; + } + case 3: + { + cell.nameLabel.text = @"联系电话 *"; + cell.textField.placeholder = @"电话"; + cell.textField.text = self.receiverPhone; + __weak typeof(self) weakSelf = self; + [[cell.textField.rac_textSignal takeUntil:cell.rac_prepareForReuseSignal] subscribeNext:^(NSString *x) { + weakSelf.receiverPhone = x; + }]; +// 诡异的崩溃 +// RAC(self, receiverPhone) = [cell.textField.rac_textSignal takeUntil:cell.rac_prepareForReuseSignal]; + break; + } + case 4: + { + cell.nameLabel.text = @"备注"; + cell.textField.placeholder = @"备注信息如:衣服码数XXL"; + cell.textField.text = self.remark; + RAC(self, remark) = [cell.textField.rac_textSignal takeUntil:cell.rac_prepareForReuseSignal]; + break; + } + default: + break; } - default: - break; + return cell; } + }else{ + ShopSwitchCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_ShopSwitchCell forIndexPath:indexPath]; + cell.shopGoods = _shopGoods; + __weak typeof(self) weakSelf = self; + cell.updateBlock = ^{ + [weakSelf p_updatePriceUI]; + }; return cell; } } #pragma mark - UITableViewDelegate -- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section -{ - return @"填写并核对订单信息"; +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ + if (section == 0) { + UIView *headerV = [UIView new]; + UILabel *headerL = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDark7]; + headerL.text = @"填写并核对订单信息"; + [headerV addSubview:headerL]; + [headerL mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.offset(15); + make.bottom.offset(-10); + }]; + return headerV; + } + return nil; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { - if (indexPath.row == 1 || indexPath.row == 5) { - return [ShopMutileValueCell cellHeight]; + if (indexPath.section == 0) { + if (indexPath.row == 1 || indexPath.row == 5) { + return [ShopMutileValueCell cellHeight]; + }else{ + return [ShopOrderTextFieldCell cellHeight]; + } }else{ - return [ShopOrderTextFieldCell cellHeight]; + return 50; } } - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { - return 42; + return section == 0? 50: kLine_MinHeight; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ + return 20; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:YES]; - if (indexPath.row == 1) { - [self goToLocationVC]; - }else if (indexPath.row == 5){ - NSArray *rows = [self.shopGoods.options valueForKey:@"name"]; - NSInteger index = self.option? [self.shopGoods.options indexOfObject:self.option]: 0; - __weak typeof(self) weakSelf = self; - [ActionSheetStringPicker showPickerWithTitle:nil rows:@[rows] initialSelection:@[@(index)] doneBlock:^(ActionSheetStringPicker *picker, NSArray *selectedIndex, NSArray *selectedValue) { - NSInteger newIndex = [(NSNumber *)selectedIndex.firstObject integerValue]; - if (weakSelf.shopGoods.options.count > newIndex) { - weakSelf.option = weakSelf.shopGoods.options[newIndex]; - [weakSelf.myTableView reloadData]; - } - } cancelBlock:nil origin:self.view]; + if (indexPath.section == 0) { + if (indexPath.row == 1) { + [self goToLocationVC]; + }else if (indexPath.row == 5){ + NSArray *rows = [self.shopGoods.options valueForKey:@"name"]; + NSInteger index = self.option? [self.shopGoods.options indexOfObject:self.option]: 0; + __weak typeof(self) weakSelf = self; + [ActionSheetStringPicker showPickerWithTitle:nil rows:@[rows] initialSelection:@[@(index)] doneBlock:^(ActionSheetStringPicker *picker, NSArray *selectedIndex, NSArray *selectedValue) { + NSInteger newIndex = [(NSNumber *)selectedIndex.firstObject integerValue]; + if (weakSelf.shopGoods.options.count > newIndex) { + weakSelf.option = weakSelf.shopGoods.options[newIndex]; + [weakSelf.myTableView reloadData]; + } + } cancelBlock:nil origin:self.view]; + } } } @@ -266,6 +325,9 @@ - (void)goToLocationVC{ #pragma mark- #pragma mark---------------------- AlertView --------------------------- +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + - (void)showPwdAlertView { UIAlertView *_pwdAlertView = [[UIAlertView alloc] initWithTitle:@"确认订单" message:@"请输入密码以确认兑换" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确认", nil]; @@ -285,6 +347,8 @@ - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger) } } +#pragma clang diagnostic pop + - (void)exchangeActionRquest:(NSString *)pwd { __weak typeof(self) weakSelf = self; @@ -327,6 +391,55 @@ - (void)exchangeActionRquest:(NSString *)pwd }]; } +- (void)exchangeActionClicked{ + NSMutableDictionary *mparms = @{}.mutableCopy; + mparms[@"receiverName"] = _receiverName; + if (_locations.count >= 2) { + mparms[@"province"] = _locations[0][@"id"]; + mparms[@"city"] = _locations[1][@"id"]; + mparms[@"district"] = _locations.count >= 3? _locations[2][@"id"]: nil; + }else{ + mparms[@"province"] = + mparms[@"city"] = + mparms[@"district"] = nil; + } + if (self.option.id) { + mparms[@"option_id"] = self.option.id; + } + mparms[@"receiverAddress"] = _receiverAddress; + mparms[@"receiverPhone"] = _receiverPhone; + mparms[@"remark"] = _remark; + mparms[@"giftId"] = _shopGoods.id; +// mparms[@"payment_amount"] = _shopGoods.curPrice; + mparms[@"point_discount"] = _shopGoods.curPointWillUse; +// mparms[@"pay_method"] = @"Alipay"; +// mparms[@"password"] = [pwd sha1Str]; + [NSObject showHUDQueryStr:@"正在创建订单..."]; + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_shop_orderWithParms:mparms andBlock:^(ShopOrder *shopOrder, NSError *error) { + [NSObject hideHUDQuery];; + if (shopOrder) { + [weakSelf goToOrder:shopOrder]; + } + }]; +} + +- (void)goToOrder:(ShopOrder *)shopOrder{ + UINavigationController *nav = self.navigationController; + [nav popViewControllerAnimated:NO]; + ShopOrderViewController *orderViewController = [[ShopOrderViewController alloc] init]; + if (self.shopGoods.needToPay) {//支付 + EAPayViewController *vc = [EAPayViewController new]; + vc.shopOrder = shopOrder; + [nav pushViewController:orderViewController animated:NO]; + [nav pushViewController:vc animated:YES]; + }else{//码币兑换,直接成功 + [NSObject hideHUDQuery];; + [NSObject showHudTipStr:@"恭喜你,提交订单成功!"]; + [nav pushViewController:orderViewController animated:YES]; + } +} + - (void)dealloc { _myTableView.dataSource = nil; diff --git a/Coding_iOS/Controllers/Shop/LocationViewController.m b/Coding_iOS/Controllers/Shop/LocationViewController.m index 1e9b06da9..66298de6c 100644 --- a/Coding_iOS/Controllers/Shop/LocationViewController.m +++ b/Coding_iOS/Controllers/Shop/LocationViewController.m @@ -32,12 +32,15 @@ - (void)viewDidLoad{ tableView.dataSource = self; [tableView registerClass:[LocationCell class] forCellReuseIdentifier:kCellIdentifier_LocationCell]; tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; - tableView.separatorColor = [UIColor colorWithHexString:@"0xDDDDDD"]; + tableView.separatorColor = kColorDDD; tableView.separatorInset = UIEdgeInsetsMake(0, 12, 0, 12); [self.view addSubview:tableView]; [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); diff --git a/Coding_iOS/Controllers/Shop/ShopOrderViewController.m b/Coding_iOS/Controllers/Shop/ShopOrderViewController.m index 711ff2990..dab0abcb3 100644 --- a/Coding_iOS/Controllers/Shop/ShopOrderViewController.m +++ b/Coding_iOS/Controllers/Shop/ShopOrderViewController.m @@ -37,6 +37,12 @@ - (void)viewDidLoad _myOrder.orderType = ShopOrderAll; [self setUpView]; +// [self loadData]; +} + +- (void)viewWillAppear:(BOOL)animated{ + [super viewWillAppear:animated]; + [self loadData]; } @@ -44,16 +50,13 @@ - (void)loadData { __weak typeof(self) weakSelf = self; __weak typeof(iCarousel) *weakCarosel = _myCarousel; - - [self.view beginLoading]; + if (_myOrder.dateSource.count == 0) { + [self.view beginLoading]; + } [[Coding_NetAPIManager sharedManager] request_shop_OrderListWithOrder:_myOrder andBlock:^(id data, NSError *error) { [weakSelf.view endLoading]; if (data) { - [weakSelf carouselCurrentItemIndexDidChange:weakCarosel]; -// weakSelf.myOrder.orderType = ShopOrderAll; -// ShopOrderListView *listView = (ShopOrderListView *)[weakSelf.myCarousel itemViewAtIndex:weakSelf.myOrder.orderType]; -// [listView reloadData]; } }]; } @@ -90,7 +93,7 @@ - (void)setUpView - (NSArray*)titlesArray { if (nil == _titlesArray) { - _titlesArray = @[@"全部订单", @"未发货", @"已发货",]; + _titlesArray = @[@"全部订单", @"待付款", @"未发货", @"已发货",]; } return _titlesArray; } @@ -135,6 +138,9 @@ - (void)carouselCurrentItemIndexDidChange:(iCarousel *)carousel{ }else if (_myOrder.orderType == ShopOrderUnSend) { _orderEmptyType = EaseBlankPageTypeShopUnSendOrders; + }else if (_myOrder.orderType == ShopOrderUnSend) + { + _orderEmptyType = EaseBlankPageTypeShopUnPayOrders; }else _orderEmptyType = EaseBlankPageTypeShopOrders; @@ -145,7 +151,6 @@ - (void)carouselCurrentItemIndexDidChange:(iCarousel *)carousel{ _mySegmentControl.currentIndex = carousel.currentItemIndex; } - [carousel.visibleItemViews enumerateObjectsUsingBlock:^(UIView *obj, NSUInteger idx, BOOL *stop) { [obj setSubScrollsToTop:(obj == carousel.currentItemView)]; }]; diff --git a/Coding_iOS/Controllers/Shop/ShopViewController.m b/Coding_iOS/Controllers/Shop/ShopViewController.m index 40f0f3e7e..e63db16b1 100644 --- a/Coding_iOS/Controllers/Shop/ShopViewController.m +++ b/Coding_iOS/Controllers/Shop/ShopViewController.m @@ -103,10 +103,10 @@ - (void)bannerClicked:(NSString *)linkStr{ #pragma mark---------------------- ShopListViewDelegate -------------------- - (void)didSelectGoodItem:(ShopGoods *)model { - if (!model.exchangeable) { - [NSObject showHudTipStr:@"您的码币余额不足,不能兑换该商品"]; - return; - } +// if (!model.exchangeable) { +// [NSObject showHudTipStr:@"您的码币余额不足,不能兑换该商品"]; +// return; +// } ExchangeGoodsViewController *exChangeViewController = [[ExchangeGoodsViewController alloc] init]; exChangeViewController.shopGoods = model; [self.navigationController pushViewController:exChangeViewController animated:YES]; @@ -138,10 +138,12 @@ - (void)viewDidLoad { - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; - if (!_isRequest) { - _isRequest = YES; - [self requestgiftsList]; - } + [self requestgiftsList]; + +// if (!_isRequest) { +// _isRequest = YES; +// [self requestgiftsList]; +// } } #pragma mark- @@ -157,18 +159,20 @@ - (void)refreshMore{ } - (void)requestgiftsList { - - [self.view beginLoading]; - __weak typeof(self) weakSelf = self; + if (_shopObject.dateSource.count == 0) { + [self.view beginLoading]; + } +// __weak typeof(self) weakSelf = self; // [[Coding_NetAPIManager sharedManager] request_shop_bannersWithBlock:^(id data, NSError *error) { // weakSelf.shopObject.shopBannerArray = data; // }]; - [[Coding_NetAPIManager sharedManager] request_shop_userPointWithShop:_shopObject andBlock:^(id data, NSError *error) { - if (data) { - [weakSelf loadGiftsList]; - } - }]; +// [[Coding_NetAPIManager sharedManager] request_shop_userPointWithShop:_shopObject andBlock:^(id data, NSError *error) { +// if (data) { +// [weakSelf loadGiftsList]; +// } +// }]; + [self loadGiftsList]; } - (void)loadGiftsList @@ -178,7 +182,12 @@ - (void)loadGiftsList [weakSelf.view endLoading]; if (data) { ShopListView *listView = (ShopListView *)[weakSelf.myCarousel currentItemView]; - listView.dataSource = weakSelf.shopObject.dateSource; + if (weakSelf.myCarousel.currentItemIndex == 0) { + listView.dataSource = weakSelf.shopObject.dateSource; + }else if(weakSelf.myCarousel.currentItemIndex == 1) + { + listView.dataSource = [weakSelf.shopObject getExchangeGiftData]; + } }else [NSObject showHudTipStr:@"Error"]; }]; @@ -302,13 +311,15 @@ - (instancetype)initWithFrame:(CGRect)frame - (void)setUpCollectionView { UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; - CGFloat itemW = (kScreen_Width - 12 * 3) / 2; - CGFloat itemH = itemW * (175.0/284.0) + 10 +21 +5 +13 +5; +// CGFloat itemW = (kScreen_Width - 12 * 3) / 2; +// CGFloat itemH = itemW * (175.0/284.0) + 10 +21 +5 +13 +5; + CGFloat itemW = kScreen_Width; + CGFloat itemH = 110; layout.itemSize = CGSizeMake(itemW, itemH); - layout.sectionInset = UIEdgeInsetsMake(20, 12, 20, 12); - layout.minimumInteritemSpacing = 5; - layout.minimumLineSpacing = 20; + layout.sectionInset = UIEdgeInsetsMake(20, 0, 20, 0); + layout.minimumInteritemSpacing = 0; + layout.minimumLineSpacing = 0; _collectionView = [[UICollectionView alloc] initWithFrame:self.bounds collectionViewLayout:layout]; _collectionView.backgroundColor = [UIColor clearColor]; @@ -317,6 +328,7 @@ - (void)setUpCollectionView _collectionView.dataSource = self; _collectionView.delegate = self; _collectionView.layer.masksToBounds = NO; + _collectionView.alwaysBounceVertical = YES; [self addSubview:_collectionView]; _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:_collectionView]; @@ -356,6 +368,9 @@ - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cell return cell; } +- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath{ + [cell addLineUp:NO andDown:YES andColor:kColorDDD andLeftSpace:kPaddingLeftWidth]; +} #pragma mark - UICollectionViewDelegate diff --git a/Coding_iOS/Controllers/TaskBoardsViewController.h b/Coding_iOS/Controllers/TaskBoardsViewController.h new file mode 100644 index 000000000..cca1d0ff2 --- /dev/null +++ b/Coding_iOS/Controllers/TaskBoardsViewController.h @@ -0,0 +1,14 @@ +// +// TaskBoardsViewController.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/4/25. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "BaseViewController.h" +#import "Project.h" + +@interface TaskBoardsViewController : BaseViewController +@property (strong, nonatomic) Project *myProject; +@end diff --git a/Coding_iOS/Controllers/TaskBoardsViewController.m b/Coding_iOS/Controllers/TaskBoardsViewController.m new file mode 100644 index 000000000..7ff5f16d4 --- /dev/null +++ b/Coding_iOS/Controllers/TaskBoardsViewController.m @@ -0,0 +1,173 @@ +// +// TaskBoardsViewController.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/4/25. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "TaskBoardsViewController.h" +#import "iCarousel.h" +#import "EABoardTaskListView.h" +#import "Coding_NetAPIManager.h" +#import "EditTaskViewController.h" +#import "SMPageControl.h" + +@interface TaskBoardsViewController () + +@property (strong, nonatomic) iCarousel *myCarousel; +@property (strong, nonatomic) UIBarButtonItem *addItem; +@property (strong, nonatomic) SMPageControl *myPageControl; + +@property (strong, nonatomic) NSArray *myBoardTLs; + +@end + +@implementation TaskBoardsViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + self.title = @"任务看板"; + //添加myCarousel + self.myCarousel = ({ + iCarousel *icarousel = [[iCarousel alloc] init]; + icarousel.dataSource = self; + icarousel.delegate = self; + icarousel.decelerationRate = 1.0; + icarousel.scrollSpeed = 1.0; + icarousel.type = iCarouselTypeLinear; + icarousel.pagingEnabled = YES; + icarousel.clipsToBounds = YES; + icarousel.bounceDistance = 0.2; + [self.view addSubview:icarousel]; + [icarousel mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view).insets(UIEdgeInsetsMake(0, 0, 49, 0)); + }]; + icarousel; + }); + self.addItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"addBtn_Nav"] style:UIBarButtonItemStylePlain target:self action:@selector(addItemClicked:)]; +} + +- (void)addItemClicked:(id)sender{ + EditTaskViewController *vc = [EditTaskViewController new]; + EABoardTaskList *curBoardTL = ((EABoardTaskListView *)_myCarousel.currentItemView).myBoardTL; + vc.myTask = [Task taskWithBoardTaskList:curBoardTL andUser:[Login curLoginUser]]; + [self.navigationController pushViewController:vc animated:YES]; +} + +- (void)viewWillAppear:(BOOL)animated{ + [super viewWillAppear:animated]; + if (!_myBoardTLs) { + [self refresh]; + }else{ + [(EABoardTaskListView *)_myCarousel.currentItemView refresh]; + } +} + +- (void)refresh{ + if (!_myBoardTLs) { + [self.view beginLoading]; + } + __weak typeof(self) weakSelf = self;; + [[Coding_NetAPIManager sharedManager] request_BoardTaskListsInPro:_myProject andBlock:^(NSArray *data, NSError *error) { + [weakSelf.view endLoading]; + if (data) { + weakSelf.myBoardTLs = data; + } + [weakSelf.view configBlankPage:EaseBlankPageTypeView hasData:weakSelf.myBoardTLs.count > 0 hasError:(error != nil) reloadButtonBlock:^(id sender) { + [weakSelf refresh]; + }]; + }]; +} + +- (void)setMyBoardTLs:(NSArray *)myBoardTLs{ + NSMutableArray *freshBoardTLs = myBoardTLs.mutableCopy ?: @[].mutableCopy; + if (freshBoardTLs.count == 2 && !_myProject.hasEverHandledBoard) { + freshBoardTLs = @[[EABoardTaskList blankBoardTLWithProject:_myProject]].mutableCopy; + }else{ + [freshBoardTLs addObject:[EABoardTaskList blankBoardTLWithProject:_myProject]]; + } + BOOL needReloadCarousel = NO; + if (!_myBoardTLs) { + needReloadCarousel = YES; + }else{ + NSSet *oldSet = [NSSet setWithArray:[_myBoardTLs valueForKey:@"id"]]; + NSSet *freshSet = [NSSet setWithArray:[freshBoardTLs valueForKey:@"id"]]; + if (![freshSet isEqualToSet:oldSet]) { + needReloadCarousel = YES; + } + } + if (needReloadCarousel) { + _myBoardTLs = freshBoardTLs.copy; + [_myCarousel reloadData]; + [self configPageControl]; + [self configNavItem]; + self.view.backgroundColor = _myBoardTLs.count == 1? kColorTableBG: kColorTableSectionBg; + self.myPageControl.hidden = (_myBoardTLs.count == 1); + }else{ + [(EABoardTaskListView *)_myCarousel.currentItemView refresh]; + } +} + +- (void)configNavItem{ + if (_myBoardTLs.count <= _myCarousel.currentItemIndex) { + self.navigationItem.rightBarButtonItem = nil; + }else{ + EABoardTaskList *curBoardTL = _myBoardTLs[_myCarousel.currentItemIndex]; + self.navigationItem.rightBarButtonItem = (curBoardTL.isBlankType || curBoardTL.type == EABoardTaskListDone)? nil: self.addItem; + } +} + +- (void)configPageControl{ + if (!_myPageControl) { + _myPageControl = ({ + SMPageControl *pageControl = [SMPageControl new]; + pageControl.userInteractionEnabled = NO; + pageControl.backgroundColor = [UIColor clearColor]; + [self.view addSubview:pageControl]; + [pageControl mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.equalTo(self.view); + make.height.mas_equalTo(10); + make.bottom.offset(-(50 - 10)/ 2); + }]; + pageControl; + }); + } + NSInteger numberOfPages = _myBoardTLs.count; + _myPageControl.numberOfPages = numberOfPages; + for (NSInteger index = 0; index < numberOfPages; index++) { + [_myPageControl setImage:[UIImage imageNamed:(index == numberOfPages - 1)? @"taskboard_add_page_unselected": @"taskboard_normal_page_unselected"] forPage:index]; + [_myPageControl setCurrentImage:[UIImage imageNamed:(index == numberOfPages - 1)? @"taskboard_add_page_selected": @"taskboard_normal_page_selected"] forPage:index]; + } + _myPageControl.currentPage = _myCarousel.currentItemIndex; +} + +#pragma mark iCarousel M +- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel{ + return _myBoardTLs.count; +} +- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view{ + EABoardTaskListView *listView = (EABoardTaskListView *)view; + if (!listView) { + listView = [EABoardTaskListView new]; + __weak typeof(self) weakSelf = self; + listView.boardTLsChangedBlock = ^{ + [weakSelf refresh]; + }; + } + listView.frame = carousel.bounds; + listView.myBoardTL = _myBoardTLs[index]; + [listView setSubScrollsToTop:(index == carousel.currentItemIndex)]; + return listView; +} + +- (void)carouselCurrentItemIndexDidChange:(iCarousel *)carousel{ + [carousel.visibleItemViews enumerateObjectsUsingBlock:^(UIView *obj, NSUInteger idx, BOOL *stop) { + [obj setSubScrollsToTop:(obj == carousel.currentItemView)]; + }]; + _myPageControl.currentPage = carousel.currentItemIndex; + [self configNavItem]; +} + +@end diff --git a/Coding_iOS/Controllers/TaskDescriptionViewController.m b/Coding_iOS/Controllers/TaskDescriptionViewController.m index 3584a277b..f1694a1b8 100644 --- a/Coding_iOS/Controllers/TaskDescriptionViewController.m +++ b/Coding_iOS/Controllers/TaskDescriptionViewController.m @@ -176,8 +176,10 @@ - (void)saveBtnClicked{ NSString *mdStr = self.editView.text; if (_curTask.handleType == TaskHandleTypeEdit) {//编辑任务 + [NSObject showHUDQueryStr:@"正在保存..."]; @weakify(self); [[Coding_NetAPIManager sharedManager] request_EditTask:_curTask withDescriptionStr:mdStr andBlock:^(id data, NSError *error) { + [NSObject hideHUDQuery]; @strongify(self); if (data) { if (self.savedNewTDBlock) { diff --git a/Coding_iOS/Controllers/TaskResourceReferenceViewController.m b/Coding_iOS/Controllers/TaskResourceReferenceViewController.m index 5b3a4503b..8e3432387 100644 --- a/Coding_iOS/Controllers/TaskResourceReferenceViewController.m +++ b/Coding_iOS/Controllers/TaskResourceReferenceViewController.m @@ -33,6 +33,9 @@ - (void)viewDidLoad { [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); @@ -71,7 +74,7 @@ - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEd if (editingStyle == UITableViewCellEditingStyleDelete) { ResourceReferenceItem *item = self.resourceReference.itemList[indexPath.row]; __weak typeof(self) weakSelf = self; - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:[NSString stringWithFormat:@"确定取消关联:%@", item.title] buttonTitles:nil destructiveTitle:@"确定" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + UIAlertController *actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:[NSString stringWithFormat:@"确定取消关联:%@", item.title] buttonTitles:nil destructiveTitle:@"确定" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf deleteItem:item]; } diff --git a/Coding_iOS/Controllers/TeamListViewController.m b/Coding_iOS/Controllers/TeamListViewController.m index 285303b4e..63071811e 100644 --- a/Coding_iOS/Controllers/TeamListViewController.m +++ b/Coding_iOS/Controllers/TeamListViewController.m @@ -35,6 +35,9 @@ - (void)viewDidLoad{ [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; @@ -54,7 +57,7 @@ - (void)refresh{ weakSelf.teamList = data; [weakSelf.myTableView reloadData]; } - [weakSelf.myTableView configBlankPage:EaseBlankPageTypeView hasData:(weakSelf.teamList.count > 0) hasError:(error != nil) reloadButtonBlock:^(id sender) { + [weakSelf.myTableView configBlankPage:EaseBlankPageTypeTeam hasData:(weakSelf.teamList.count > 0) hasError:(error != nil) reloadButtonBlock:^(id sender) { [weakSelf refresh]; }]; }]; diff --git a/Coding_iOS/Controllers/TeamMembersViewController.m b/Coding_iOS/Controllers/TeamMembersViewController.m index ddb8cea08..d18b2da76 100644 --- a/Coding_iOS/Controllers/TeamMembersViewController.m +++ b/Coding_iOS/Controllers/TeamMembersViewController.m @@ -11,9 +11,17 @@ #import "Coding_NetAPIManager.h" #import "TeamMemberCell.h" #import "UserInfoViewController.h" +#import "ValueListViewController.h" +#import "EditMemberTypeProjectListViewController.h" +#import +#import +#import +#import "ProjectDeleteAlertControllerVisualStyle.h" +#import "Ease_2FA.h" -@interface TeamMembersViewController () + +@interface TeamMembersViewController () @property (strong, nonatomic) UISearchBar *mySearchBar; @property (strong, nonatomic) UISearchDisplayController *mySearchDisplayController; @property (strong, nonatomic) UITableView *myTableView; @@ -21,13 +29,29 @@ @interface TeamMembersViewController ()= 100 && mem.role.integerValue <= 90) { + [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:@"0xD8DDE4"] icon:[UIImage imageNamed:@"team_cell_edit_team"]]; + } + [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:@"0xF2F4F6"] icon:[UIImage imageNamed:@"team_cell_edit_pro"]]; + if (_selfRoleType.integerValue > mem.role.integerValue) { + [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:@"0xF56061"] icon:[UIImage imageNamed:@"team_cell_edit_delete"]]; + } + return rightUtilityButtons; +} +- (BOOL)swipeableTableViewCellShouldHideUtilityButtonsOnSwipe:(SWTableViewCell *)cell{ + return YES; +} + +- (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerRightUtilityButtonWithIndex:(NSInteger)index { + [cell hideUtilityButtonsAnimated:YES]; + TeamMember *mem = [(TeamMemberCell *)cell curMember]; + if (_selfRoleType.integerValue >= 100 && mem.role.integerValue <= 90) { + if (index == 0) { + [self editTeamTypeOfMember:mem]; + }else if (index == 1){ + [self editProTypeOfMember:mem]; + }else{ + [self removeMember:mem]; + } + }else{ + if (index == 0) { + [self editProTypeOfMember:mem]; + }else{ + [self removeMember:mem]; + } + } +} + +- (void)editTeamTypeOfMember:(TeamMember *)curMember{ + __weak typeof(self) weakSelf = self; + __weak typeof(curMember) weakMember = curMember; + ValueListViewController *vc = [ValueListViewController new]; + NSMutableArray *valueList = @[@"管理员", @"普通成员"].mutableCopy; + NSArray *typeRawList = @[@90, @80]; + [vc setTitle:@"设置企业角色" valueList:valueList defaultSelectIndex:[typeRawList indexOfObject:curMember.editRole] type:ValueListTypeTeamMemberType selectBlock:^(NSInteger index) { + weakMember.editRole = typeRawList[index]; + if (![weakMember.role isEqualToNumber:weakMember.editRole]) { + [[Coding_NetAPIManager sharedManager] request_EditTeamTypeOfMember:weakMember andBlock:^(id data, NSError *error) { + if (data) { + weakMember.role = weakMember.editRole; + [weakSelf.myTableView reloadData]; + [weakSelf.mySearchDisplayController.searchResultsTableView reloadData]; + } + }]; + } + }]; + [self.navigationController pushViewController:vc animated:YES]; +} + +- (void)editProTypeOfMember:(TeamMember *)curMember{ + EditMemberTypeProjectListViewController *vc = [EditMemberTypeProjectListViewController new]; + vc.curTeam = _curTeam; + vc.curMember = curMember; + [self.navigationController pushViewController:vc animated:YES]; +} + +- (void)removeMember:(TeamMember *)curMember{ + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_VerifyTypeWithBlock:^(VerifyType type, NSError *error) { + if (!error) { + [weakSelf showDeleteAlertWithType:type toDeleteMember:curMember]; + } + }]; + // __weak typeof(self) weakSelf = self; + // [[Coding_NetAPIManager sharedManager] request_TeamMember_Quit:curMember andBlock:^(id data, NSError *error) { + // if (data) { + // [weakSelf.myMemberArray removeObject:data]; + // if (weakSelf.searchResults) { + // [weakSelf.searchResults removeObject:data]; + // } + // [weakSelf.myTableView reloadData]; + // [weakSelf.mySearchDisplayController.searchResultsTableView reloadData]; + // } + // }]; +} + +- (void)showDeleteAlertWithType:(VerifyType)type toDeleteMember:(TeamMember *)curMember{ + if (self.alert) {//正在显示 + return; + } + NSString *title, *message, *placeHolder; + if (type == VerifyTypePassword) { + title = @"需要密码验证"; + message = @"这是一个危险操作,需要进行身份验证"; + placeHolder = @"请输入密码"; + }else if (type == VerifyTypeTotp){ + title = @"需要动态验证码"; + message = @"这是一个危险操作,需要进行身份验证"; + placeHolder = @"请输入动态验证码"; + }else{//不知道啥类型,不处理 + return; + } + + _alert = [SDCAlertController alertControllerWithTitle:title message:message preferredStyle:SDCAlertControllerStyleAlert]; + + UITextField *passwordTextField = [[UITextField alloc] initWithFrame:CGRectMake(15, 0, 240.0, 30.0)]; + passwordTextField.font = [UIFont systemFontOfSize:13]; + passwordTextField.leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 30)]; + passwordTextField.leftViewMode = UITextFieldViewModeAlways; + passwordTextField.layer.borderColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.6].CGColor; + passwordTextField.layer.borderWidth = 1; + passwordTextField.secureTextEntry = (type == VerifyTypePassword); + passwordTextField.backgroundColor = [UIColor whiteColor]; + passwordTextField.placeholder = placeHolder; + if (type == VerifyTypeTotp) { + passwordTextField.text = [OTPListViewController otpCodeWithGK:[Login curLoginUser].global_key]; + } + passwordTextField.delegate = self; + + [_alert.contentView addSubview:passwordTextField]; + + NSDictionary* passwordViews = NSDictionaryOfVariableBindings(passwordTextField); + + [_alert.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[passwordTextField]-(>=14)-|" options:0 metrics:nil views:passwordViews]]; + + // Style + _alert.visualStyle = [ProjectDeleteAlertControllerVisualStyle new]; + + // 添加密码框 + // [alert addTextFieldWithConfigurationHandler:^(UITextField *textField) { + // textField.secureTextEntry = YES; + // }]; + + // 添加按钮 + @weakify(self); + _alert.actionLayout = SDCAlertControllerActionLayoutHorizontal; + [_alert addAction:[SDCAlertAction actionWithTitle:@"取消" style:SDCAlertActionStyleDefault handler:^(SDCAlertAction *action) { + @strongify(self); + self.alert = nil; + }]]; + [_alert addAction:[SDCAlertAction actionWithTitle:@"确定" style:SDCAlertActionStyleDefault handler:^(SDCAlertAction *action) { + @strongify(self); + self.alert = nil; + NSString *passCode = passwordTextField.text; + if ([passCode length] > 0) { + // 删除成员 + [[Coding_NetAPIManager sharedManager] request_DeleteTeamMember:curMember.user.global_key passCode:passCode type:type andBlock:^(id data, NSError *error) { + @strongify(self); + if (!error) { + [self refresh]; + } + }]; + } + }]]; + + [_alert presentWithCompletion:^{ + [passwordTextField becomeFirstResponder]; + }]; +} + +-(BOOL)textFieldShouldReturn:(UITextField *)textField{ + [textField resignFirstResponder]; + return YES; } #pragma mark UISearchDisplayDelegate M - (void)searchDisplayController:(UISearchDisplayController *)controller willShowSearchResultsTableView:(UITableView *)tableView{ -// if (_type == ProMemTypeProject) { -// [tableView setContentInset:UIEdgeInsetsMake(kHigher_iOS_6_1_DIS(44), 0, 0, 0)]; -// } + // if (_type == ProMemTypeProject) { + // [tableView setContentInset:UIEdgeInsetsMake(kHigher_iOS_6_1_DIS(44), 0, 0, 0)]; + // } } - (void)searchDisplayController:(UISearchDisplayController *)controller willHideSearchResultsTableView:(UITableView *)tableView{ [self.myTableView reloadData]; @@ -176,7 +372,7 @@ - (void)updateFilteredContentForSearchString:(NSString *)searchString{ type:NSContainsPredicateOperatorType options:NSCaseInsensitivePredicateOption]; [searchItemsPredicate addObject:finalPredicate]; -// pinyin + // pinyin lhs = [NSExpression expressionForKeyPath:@"user.pinyinName"]; rhs = [NSExpression expressionForConstantValue:searchString]; finalPredicate = [NSComparisonPredicate diff --git a/Coding_iOS/Controllers/TeamProjectsViewController.m b/Coding_iOS/Controllers/TeamProjectsViewController.m index 3f3b76c35..010fc4276 100644 --- a/Coding_iOS/Controllers/TeamProjectsViewController.m +++ b/Coding_iOS/Controllers/TeamProjectsViewController.m @@ -12,18 +12,26 @@ #import "ProjectListCell.h" #import "NProjectViewController.h" #import "Login.h" +#import +#import +#import +#import "ProjectDeleteAlertControllerVisualStyle.h" -@interface TeamProjectsViewController () +#import "Ease_2FA.h" + +@interface TeamProjectsViewController () @property (strong, nonatomic) UITableView *myTableView; @property (strong, nonatomic) ODRefreshControl *myRefreshControl; @property (strong, nonatomic) NSArray *joinedList, *unjoinedList; +@property (strong, nonatomic) SDCAlertController *alert; + @end @implementation TeamProjectsViewController - (void)viewDidLoad{ [super viewDidLoad]; - self.title = _curTeam.name; + self.title = @"项目管理"; _myTableView = ({ UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; tableView.separatorStyle = UITableViewCellSeparatorStyleNone; @@ -36,6 +44,9 @@ - (void)viewDidLoad{ [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; @@ -100,7 +111,9 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N ProjectListCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_ProjectList forIndexPath:indexPath]; Project *curPro = indexPath.section == 0? _joinedList[indexPath.row]: _unjoinedList[indexPath.row]; - [cell setProject:curPro hasSWButtons:NO hasBadgeTip:YES hasIndicator:YES]; + [cell setProject:curPro hasSWButtons:NO hasBadgeTip:NO hasIndicator:NO]; + cell.hasDeleteBtn = YES; + cell.delegate = self; cell.backgroundColor = kColorTableBG; [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; return cell; @@ -112,7 +125,10 @@ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPa - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ [tableView deselectRowAtIndexPath:indexPath animated:YES]; - + if (indexPath.section == 1) { + [NSObject showHudTipStr:@"无权进行此操作"]; + return; + } Project *curPro = indexPath.section == 0? _joinedList[indexPath.row]: _unjoinedList[indexPath.row]; NProjectViewController *vc = [NProjectViewController new]; vc.myProject = curPro; @@ -120,4 +136,103 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath } +#pragma mark SWTableViewCellDelegate + +- (BOOL)swipeableTableViewCellShouldHideUtilityButtonsOnSwipe:(SWTableViewCell *)cell{ + return YES; +} + +- (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerRightUtilityButtonWithIndex:(NSInteger)index{ + [cell hideUtilityButtonsAnimated:YES]; + NSIndexPath *indexPath = [self.myTableView indexPathForCell:cell]; + Project *curPro = indexPath.section == 0? _joinedList[indexPath.row]: _unjoinedList[indexPath.row]; + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_VerifyTypeWithBlock:^(VerifyType type, NSError *error) { + if (!error) { + [weakSelf showDeleteAlertWithType:type toDeletePro:curPro]; + } + }]; +} + +- (void)showDeleteAlertWithType:(VerifyType)type toDeletePro:(Project *)toDeletePro{ + if (self.alert) {//正在显示 + return; + } + + NSString *title, *message, *placeHolder; + if (type == VerifyTypePassword) { + title = @"需要密码验证"; + message = @"这是一个危险操作,需要进行身份验证"; + placeHolder = @"请输入密码"; + }else if (type == VerifyTypeTotp){ + title = @"需要动态验证码"; + message = @"这是一个危险操作,需要进行身份验证"; + placeHolder = @"请输入动态验证码"; + }else{//不知道啥类型,不处理 + return; + } + + _alert = [SDCAlertController alertControllerWithTitle:title message:message preferredStyle:SDCAlertControllerStyleAlert]; + + UITextField *passwordTextField = [[UITextField alloc] initWithFrame:CGRectMake(15, 0, 240.0, 30.0)]; + passwordTextField.font = [UIFont systemFontOfSize:13]; + passwordTextField.leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 30)]; + passwordTextField.leftViewMode = UITextFieldViewModeAlways; + passwordTextField.layer.borderColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.6].CGColor; + passwordTextField.layer.borderWidth = 1; + passwordTextField.secureTextEntry = (type == VerifyTypePassword); + passwordTextField.backgroundColor = [UIColor whiteColor]; + passwordTextField.placeholder = placeHolder; + if (type == VerifyTypeTotp) { + passwordTextField.text = [OTPListViewController otpCodeWithGK:[Login curLoginUser].global_key]; + } + passwordTextField.delegate = self; + + [_alert.contentView addSubview:passwordTextField]; + + NSDictionary* passwordViews = NSDictionaryOfVariableBindings(passwordTextField); + + [_alert.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[passwordTextField]-(>=14)-|" options:0 metrics:nil views:passwordViews]]; + + // Style + _alert.visualStyle = [ProjectDeleteAlertControllerVisualStyle new]; + + // 添加密码框 + // [alert addTextFieldWithConfigurationHandler:^(UITextField *textField) { + // textField.secureTextEntry = YES; + // }]; + + // 添加按钮 + @weakify(self); + _alert.actionLayout = SDCAlertControllerActionLayoutHorizontal; + [_alert addAction:[SDCAlertAction actionWithTitle:@"取消" style:SDCAlertActionStyleDefault handler:^(SDCAlertAction *action) { + @strongify(self); + self.alert = nil; + }]]; + [_alert addAction:[SDCAlertAction actionWithTitle:@"确定" style:SDCAlertActionStyleDefault handler:^(SDCAlertAction *action) { + @strongify(self); + self.alert = nil; + NSString *passCode = passwordTextField.text; + if ([passCode length] > 0) { + // 删除项目 + [[Coding_NetAPIManager sharedManager] request_DeleteProject_WithObj:toDeletePro passCode:passCode type:type andBlock:^(Project *data, NSError *error) { + @strongify(self); + if (!error) { + [NSObject showHudTipStr:@"删除项目成功"]; + [self refresh]; + } + }]; + } + }]]; + + [_alert presentWithCompletion:^{ + [passwordTextField becomeFirstResponder]; + }]; +} + +-(BOOL)textFieldShouldReturn:(UITextField *)textField{ + [textField resignFirstResponder]; + return YES; +} + @end diff --git a/Coding_iOS/Controllers/TeamPurchaseViewController.h b/Coding_iOS/Controllers/TeamPurchaseViewController.h new file mode 100644 index 000000000..20b037080 --- /dev/null +++ b/Coding_iOS/Controllers/TeamPurchaseViewController.h @@ -0,0 +1,15 @@ +// +// TeamPurchaseViewController.h +// Coding_Enterprise_iOS +// +// Created by Ease on 2017/3/7. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "BaseViewController.h" +#import "Team.h" + +@interface TeamPurchaseViewController : BaseViewController +@property (strong, nonatomic) Team *curTeam; + +@end diff --git a/Coding_iOS/Controllers/TeamPurchaseViewController.m b/Coding_iOS/Controllers/TeamPurchaseViewController.m new file mode 100644 index 000000000..6c567b5c9 --- /dev/null +++ b/Coding_iOS/Controllers/TeamPurchaseViewController.m @@ -0,0 +1,216 @@ +// +// TeamPurchaseViewController.m +// Coding_Enterprise_iOS +// +// Created by Ease on 2017/3/7. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "TeamPurchaseViewController.h" +#import "XTSegmentControl.h" +#import "ODRefreshControl.h" +#import "TeamPurchaseTopCell.h" +#import "TeamPurchaseOrderCell.h" +#import "TeamPurchaseBillingCell.h" +#import "Coding_NetAPIManager.h" + +@interface TeamPurchaseViewController () +@property (nonatomic, strong, readonly) UITableView *myTableView; +@property (nonatomic, strong, readonly) ODRefreshControl *refreshControl; +@property (strong, nonatomic) UIView *sectionHeaderView; + +@property (assign, nonatomic) NSInteger dataIndex; +@property (strong, nonatomic) NSMutableDictionary *dataDict; +@property (strong, nonatomic, readonly) NSArray *dataList, *orderList, *billingList; + +@end + +@implementation TeamPurchaseViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + self.title = @"订购状态"; + __weak typeof(self) weakSelf = self; + // 添加myTableView + _myTableView = ({ + UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; + tableView.backgroundColor = [UIColor clearColor]; + tableView.dataSource = self; + tableView.delegate = self; + tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + [tableView registerClass:[TeamPurchaseTopCell class] forCellReuseIdentifier:kCellIdentifier_TeamPurchaseTopCell]; + [tableView registerClass:[TeamPurchaseOrderCell class] forCellReuseIdentifier:kCellIdentifier_TeamPurchaseOrderCell]; + [tableView registerClass:[TeamPurchaseBillingCell class] forCellReuseIdentifier:kCellIdentifier_TeamPurchaseBillingCell]; + [self.view addSubview:tableView]; + [tableView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; + tableView; + }); + if (!_sectionHeaderView) { + _sectionHeaderView = [[XTSegmentControl alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 44.0) Items:@[@"充值订单", @"账户流水"] selectedBlock:^(NSInteger index) { + weakSelf.dataIndex = index; + }]; + [_sectionHeaderView addLineUp:NO andDown:YES]; + _sectionHeaderView.backgroundColor = kColorTableBG; + } + _refreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; + [_refreshControl addTarget:self action:@selector(refresh) forControlEvents:UIControlEventValueChanged]; + + _dataDict = @{}.mutableCopy; + self.dataIndex = 0;//set 方法里面带刷新了 +} + +- (void)viewWillAppear:(BOOL)animated{ + [super viewWillAppear:animated]; + _curTeam.hasDismissWebTip = NO; +} + +- (NSArray *)dataList{ + return _dataIndex == 0? self.orderList: self.billingList; +} + +- (NSArray *)orderList{ +// return @[]; + return _dataDict[@(0)]; +} + +- (NSArray *)billingList{//不要你了 + return @[]; +// return _dataDict[@(1)]; +} + +- (void)setDataIndex:(NSInteger)dataIndex{ + _dataIndex = dataIndex; + [self.myTableView reloadData]; + if (!_dataDict[@(_dataIndex)]) { + [self refresh]; + } +} + +- (void)refresh{ + __weak typeof(self) weakSelf = self; + void (^queryFinishedBlock)(NSError *) = ^(NSError *error){ + if (weakSelf.orderList.count == 0 && weakSelf.billingList.count > 0) { + [weakSelf setDataIndex:1]; + } + [weakSelf.myTableView reloadData]; + [weakSelf.view endLoading]; + [weakSelf.refreshControl endRefreshing]; + [weakSelf.view configBlankPage:EaseBlankPageTypeViewPurchase hasData:weakSelf.dataList.count > 0 hasError:(error != nil) offsetY:([TeamPurchaseTopCell cellHeightWithObj:_curTeam] + 15) reloadButtonBlock:^(id sender) { + [weakSelf refresh]; + }]; + }; + if (self.dataList.count <= 0) { + [self.view beginLoading]; + } + [[Coding_NetAPIManager sharedManager] request_OrderListOfTeam:_curTeam andBlock:^(id dataO, NSError *errorO) { + if (dataO) { + weakSelf.dataDict[@(0)] = dataO; + } + queryFinishedBlock(errorO); +// if (dataO) { +// weakSelf.dataDict[@(0)] = dataO; +// [[Coding_NetAPIManager sharedManager] request_BillingListOfTeam:_curTeam andBlock:^(id dataB, NSError *errorB) { +// if (dataB) { +// weakSelf.dataDict[@(1)] = dataB; +// } +// queryFinishedBlock(errorB); +// }]; +// }else{ +// queryFinishedBlock(errorO); +// } + }]; +} + +#pragma mark TableM +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ + return 2; +} + +- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{ + return [UIView new]; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ + if (section == 0 && self.orderList.count > 0 && self.billingList.count > 0) { + return 15; + }else{ + return 0; + } +} + +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ + if (section == 1) { + if (self.orderList.count > 0 && self.billingList.count > 0) { + return self.sectionHeaderView; + }else if (self.orderList.count > 0 || self.billingList.count > 0){ + UIView *headerV = [UIView new]; + headerV.backgroundColor = kColorTableSectionBg; + UILabel *headerL = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDark7]; + headerL.text = self.orderList.count > 0? @"充值订单": @"账户流水"; + [headerV addSubview:headerL]; + [headerL mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(headerV).offset(kPaddingLeftWidth); + make.right.equalTo(headerV).offset(-kPaddingLeftWidth); + make.centerY.equalTo(headerV); + }]; + UIView *lineV = [UIView lineViewWithPointYY:43.5]; + [headerV addSubview:lineV]; + return headerV; + } + } + return [UIView new]; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ + return (section == 1 && self.dataList.count > 0)? 44.0: 0; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + return section == 0? 1: self.dataList.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + __weak typeof(self) weakSelf = self; + if (indexPath.section == 0) { + TeamPurchaseTopCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_TeamPurchaseTopCell forIndexPath:indexPath]; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:0]; + cell.curTeam = _curTeam; + cell.closeWebTipBlock = ^(){ + weakSelf.curTeam.hasDismissWebTip = YES; + [weakSelf.myTableView reloadData]; + weakSelf.view.blankPageView.y = ([TeamPurchaseTopCell cellHeightWithObj:_curTeam] + 15); + }; + return cell; + } else { + if (_dataIndex == 0) { + TeamPurchaseOrderCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_TeamPurchaseOrderCell forIndexPath:indexPath]; + cell.curOrder = self.dataList[indexPath.row]; + return cell; + }else{ + TeamPurchaseBillingCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_TeamPurchaseBillingCell forIndexPath:indexPath]; + cell.curBilling = self.dataList[indexPath.row]; + cell.expandBlock = ^(TeamPurchaseBilling *billing){ + billing.isExpanded = !billing.isExpanded; + [weakSelf.myTableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; + }; + return cell; + } + } +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ + if (indexPath.section == 0) { + return [TeamPurchaseTopCell cellHeightWithObj:_curTeam]; + } else { + if (_dataIndex == 0) { + return [TeamPurchaseOrderCell cellHeight]; + }else{ + return [TeamPurchaseBillingCell cellHeightWithObj:self.dataList[indexPath.row]]; + } + } +} + +@end diff --git a/Coding_iOS/Controllers/TeamSettingViewController.h b/Coding_iOS/Controllers/TeamSettingViewController.h new file mode 100644 index 000000000..99b16031d --- /dev/null +++ b/Coding_iOS/Controllers/TeamSettingViewController.h @@ -0,0 +1,15 @@ +// +// TeamSettingViewController.h +// Coding_Enterprise_iOS +// +// Created by Ease on 2017/2/17. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "BaseViewController.h" +#import "Team.h" + +@interface TeamSettingViewController : BaseViewController +@property (strong, nonatomic) Team *curTeam; + +@end diff --git a/Coding_iOS/Controllers/TeamSettingViewController.m b/Coding_iOS/Controllers/TeamSettingViewController.m new file mode 100644 index 000000000..2bd5bd4bd --- /dev/null +++ b/Coding_iOS/Controllers/TeamSettingViewController.m @@ -0,0 +1,167 @@ +// +// TeamSettingViewController.m +// Coding_Enterprise_iOS +// +// Created by Ease on 2017/2/17. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "TeamSettingViewController.h" +#import "SettingTextViewController.h" +#import "TitleValueMoreCell.h" +#import "TitleRImageMoreCell.h" +#import "JDStatusBarNotification.h" +#import "Helper.h" +#import "Coding_NetAPIManager.h" + +@interface TeamSettingViewController () +@property (strong, nonatomic) UITableView *myTableView; + +@end + +@implementation TeamSettingViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + self.title = @"企业设置"; + _myTableView = ({ + UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; + tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + tableView.backgroundColor = kColorTableSectionBg; + tableView.tableFooterView = [UIView new]; + tableView.delegate = self; + tableView.dataSource = self; + [tableView registerClass:[TitleValueMoreCell class] forCellReuseIdentifier:kCellIdentifier_TitleValueMore]; + [tableView registerClass:[TitleRImageMoreCell class] forCellReuseIdentifier:kCellIdentifier_TitleRImageMore]; + [self.view addSubview:tableView]; + [tableView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; + tableView; + }); +} + +#pragma mark Table +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ + return 2; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ + return 20; +} + +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ + return [UIView new]; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + return section == 0? 1: 2; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + if (indexPath.section == 0) { + TitleRImageMoreCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_TitleRImageMore forIndexPath:indexPath]; + cell.curTeam = _curTeam; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; + return cell; + }else{ + TitleValueMoreCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_TitleValueMore forIndexPath:indexPath]; + (indexPath.row == 0? [cell setTitleStr:@"企业名称" valueStr:_curTeam.name]: + [cell setTitleStr:@"企业域名" valueStr:[NSURL URLWithString:[NSObject baseURLStr]].host]); + cell.accessoryType = indexPath.row == 0? UITableViewCellAccessoryDisclosureIndicator: UITableViewCellAccessoryNone; + cell.selectionStyle = UITableViewCellSelectionStyleNone; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; + return cell; + } +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ + return indexPath.section == 0? [TitleRImageMoreCell cellHeight]: [TitleValueMoreCell cellHeight]; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + if (indexPath.section == 0) { + //头像 + if (![JDStatusBarNotification isVisible]) { + __weak typeof(self) weakSelf = self; + [[UIAlertController ea_actionSheetCustomWithTitle:@"更换头像" buttonTitles:@[@"拍照", @"从相册选择"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + [weakSelf actionSheetDidDismissWithButtonIndex:index]; + }] showInView:self.view]; + } + }else if (indexPath.section == 1){ + if (indexPath.row == 0) { + //企业名称 + __weak typeof(self) weakSelf = self; + SettingTextViewController *vc = [SettingTextViewController settingTextVCWithTitle:@"企业名称" textValue:_curTeam.name doneBlock:^(NSString *textValue) { + NSString *preValue = weakSelf.curTeam.name; + weakSelf.curTeam.name = textValue; + [weakSelf.myTableView reloadData]; + [[Coding_NetAPIManager sharedManager] request_UpdateTeamInfo_WithObj:weakSelf.curTeam andBlock:^(id data, NSError *error) { + if (data) { + weakSelf.curTeam = data; + }else{ + weakSelf.curTeam.name = preValue; + } + [weakSelf.myTableView reloadData]; + }]; + }]; + [self.navigationController pushViewController:vc animated:YES]; + } + } +} + +#pragma mark UIActionSheetDelegate M +- (void)actionSheetDidDismissWithButtonIndex:(NSInteger)buttonIndex{ + if (buttonIndex == 2) { + return; + } + UIImagePickerController *picker = [[UIImagePickerController alloc] init]; + picker.delegate = self; + picker.allowsEditing = YES;//设置可编辑 + + if (buttonIndex == 0) { + // 拍照 + if (![Helper checkCameraAuthorizationStatus]) { + return; + } + picker.sourceType = UIImagePickerControllerSourceTypeCamera; + }else if (buttonIndex == 1){ + // 相册 + if (![Helper checkPhotoLibraryAuthorizationStatus]) { + return; + } + picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum; + } + [self presentViewController:picker animated:YES completion:nil];//进入照相界面 +} + +#pragma mark UIImagePickerControllerDelegate +- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{ + [picker dismissViewControllerAnimated:YES completion:^{ + UIImage *editedImage, *originalImage; + editedImage = [info objectForKey:UIImagePickerControllerEditedImage]; + __weak typeof(self) weakSelf = self; + + [[Coding_NetAPIManager sharedManager] request_UpdateTeamIconImage:editedImage successBlock:^(id responseObj) { + weakSelf.curTeam.avatar = [(Team *)responseObj avatar]; + [weakSelf.myTableView reloadData]; + } failureBlock:^(NSError *error) { + [NSObject showError:error]; + } progerssBlock:^(CGFloat progressValue) { + }]; + + // 保存原图片到相册中 + if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) { + originalImage = [info objectForKey:UIImagePickerControllerOriginalImage]; + UIImageWriteToSavedPhotosAlbum(originalImage, self, nil, NULL); + } + }]; +} + +- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{ + [picker dismissViewControllerAnimated:YES completion:nil]; +} + +@end diff --git a/Coding_iOS/Controllers/TeamSupportViewController.h b/Coding_iOS/Controllers/TeamSupportViewController.h new file mode 100644 index 000000000..515784f1a --- /dev/null +++ b/Coding_iOS/Controllers/TeamSupportViewController.h @@ -0,0 +1,13 @@ +// +// TeamSupportViewController.h +// Coding_Enterprise_iOS +// +// Created by Easeeeeeeeee on 2018/3/15. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "BaseViewController.h" + +@interface TeamSupportViewController : BaseViewController + +@end diff --git a/Coding_iOS/Controllers/TeamSupportViewController.m b/Coding_iOS/Controllers/TeamSupportViewController.m new file mode 100644 index 000000000..91029977c --- /dev/null +++ b/Coding_iOS/Controllers/TeamSupportViewController.m @@ -0,0 +1,98 @@ +// +// TeamSupportViewController.m +// Coding_Enterprise_iOS +// +// Created by Easeeeeeeeee on 2018/3/15. +// Copyright © 2018年 Coding. All rights reserved. +// + +#define kTeamSupport_Phone @"400-930-9163" +#define kTeamSupport_Mail @"Enterprise@coding.net" +#define kTeamSupport_QQ @"2847276903" + +#import "TeamSupportViewController.h" + +#import "TeamSupportCell.h" + +@interface TeamSupportViewController () +@property (strong, nonatomic) UITableView *myTableView; + +@end + +@implementation TeamSupportViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + self.title = @"售后支持"; + _myTableView = ({ + UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; + tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + tableView.backgroundColor = kColorTableSectionBg; + tableView.tableFooterView = [UIView new]; + tableView.delegate = self; + tableView.dataSource = self; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; + [tableView registerClass:[TeamSupportCell class] forCellReuseIdentifier:kCellIdentifier_TeamSupportCell]; + [self.view addSubview:tableView]; + [tableView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; + tableView; + }); +} + +#pragma mark Table +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ + return 15; +} + +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ + return [UIView new]; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + return 3; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + TeamSupportCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_TeamSupportCell forIndexPath:indexPath]; + if (indexPath.row == 0) { + cell.leftL.text = @"联系电话"; + cell.rightL.text = kTeamSupport_Phone; + }else if (indexPath.row == 1){ + cell.leftL.text = @"联系邮箱"; + cell.rightL.text = kTeamSupport_Mail; + }else{ + cell.leftL.text = @"技术支持"; + cell.rightL.text = [NSString stringWithFormat:@"QQ:%@", kTeamSupport_QQ]; + } + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; + return cell; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ + return 50; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + NSURL *destinationURL; + if (indexPath.row == 0) { + destinationURL = [NSURL URLWithString:[NSString stringWithFormat:@"tel://%@", kTeamSupport_Phone]]; + }else if (indexPath.row == 1){ + destinationURL = [NSURL URLWithString:[NSString stringWithFormat:@"mailto://%@", kTeamSupport_Mail]]; + }else{ + destinationURL = [NSURL URLWithString:[NSString stringWithFormat:@"mqq://im/chat?chat_type=wpa&uin=%@&version=1&src_type=web", kTeamSupport_QQ]]; + } + if ([[UIApplication sharedApplication] canOpenURL:destinationURL]) { + [[UIApplication sharedApplication] openURL:destinationURL]; + }else{ + [[UIPasteboard generalPasteboard] setString:(indexPath.row == 0? kTeamSupport_Phone: indexPath.row == 1? kTeamSupport_Mail: kTeamSupport_QQ)]; + [NSObject showHudTipStr:@"已复制"]; + } +} + +@end diff --git a/Coding_iOS/Controllers/TeamViewController.h b/Coding_iOS/Controllers/TeamViewController.h index 9bb0edba7..0784e82d4 100644 --- a/Coding_iOS/Controllers/TeamViewController.h +++ b/Coding_iOS/Controllers/TeamViewController.h @@ -12,3 +12,9 @@ @interface TeamViewController : BaseViewController @property (strong, nonatomic) Team *curTeam; @end + +@interface EATeamHeaderView : UIView +@property (strong, nonatomic) UIImageView *bgV; + +@property (strong, nonatomic) Team *curTeam; +@end diff --git a/Coding_iOS/Controllers/TeamViewController.m b/Coding_iOS/Controllers/TeamViewController.m index 214f16d89..635a99784 100644 --- a/Coding_iOS/Controllers/TeamViewController.m +++ b/Coding_iOS/Controllers/TeamViewController.m @@ -9,22 +9,26 @@ #import "TeamViewController.h" #import "ODRefreshControl.h" #import "TeamTopCell.h" -#import "TitleDisclosureCell.h" #import "Coding_NetAPIManager.h" #import "TeamProjectsViewController.h" #import "TeamMembersViewController.h" +#import "UserInfoIconCell.h" +#import "TeamSettingViewController.h" +#import "UIImageView+WebCache.h" +#import "TeamPurchaseViewController.h" +#import "TeamSupportViewController.h" @interface TeamViewController () @property (strong, nonatomic) UITableView *myTableView; @property (strong, nonatomic) ODRefreshControl *myRefreshControl; +@property (strong, nonatomic) EATeamHeaderView *tableHeaderV; @end @implementation TeamViewController - (void)viewDidLoad{ [super viewDidLoad]; - self.title = @"团队首页"; _myTableView = ({ UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; tableView.separatorStyle = UITableViewCellSeparatorStyleNone; @@ -33,36 +37,105 @@ - (void)viewDidLoad{ tableView.delegate = self; tableView.dataSource = self; [tableView registerClass:[TeamTopCell class] forCellReuseIdentifier:kCellIdentifier_TeamTopCell]; - [tableView registerClass:[TitleDisclosureCell class] forCellReuseIdentifier:kCellIdentifier_TitleDisclosure]; + [tableView registerClass:[UserInfoIconCell class] forCellReuseIdentifier:kCellIdentifier_UserInfoIconCell]; [self.view addSubview:tableView]; [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); - _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; - [_myRefreshControl addTarget:self action:@selector(refresh) forControlEvents:UIControlEventValueChanged]; + + {//tableHeaderV + _tableHeaderV = [EATeamHeaderView new]; + _tableHeaderV.curTeam = _curTeam; + _myTableView.tableHeaderView = _tableHeaderV; + } + {//UINavigationBar + UINavigationBar *navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, kSafeArea_Top, kScreen_Width, 44)]; + navBar.shadowImage = [UIImage new]; + navBar.tintColor = [UIColor whiteColor]; + [navBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault]; + UINavigationItem *item = [UINavigationItem new]; +// UIBarButtonItem *backSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; +// backSpace.width = -7; + UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"back_T_Nav"] style:UIBarButtonItemStylePlain target:self action:@selector(leftNavBtnClicked)]; +// item.leftBarButtonItems = @[backSpace, backItem]; + item.leftBarButtonItems = @[backItem]; + item.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"settingBtn_Nav"] style:UIBarButtonItemStylePlain target:self action:@selector(rightNavBtnClicked)]; + [navBar pushNavigationItem:item animated:NO]; + [self.view addSubview:navBar]; + } +} + +- (void)viewWillAppear:(BOOL)animated{ + [super viewWillAppear:animated]; [self refresh]; + + [self.navigationController addFullscreenPopGesture]; + [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES]; + [self.navigationController setNavigationBarHidden:YES animated:animated]; +} + +- (UIStatusBarStyle)preferredStatusBarStyle{ + return UIStatusBarStyleLightContent; +} + +- (void)viewWillDisappear:(BOOL)animated{ + [super viewWillDisappear:animated]; + + [self.navigationController setNavigationBarHidden:NO animated:animated]; +} + +- (void)viewDidDisappear:(BOOL)animated{ + [super viewDidDisappear:animated]; + + [self.navigationController removeFullscreenPopGesture]; } - (void)refresh{ ESWeak(self, weakSelf); - [[Coding_NetAPIManager sharedManager] request_DetailOfTeam:_curTeam andBlock:^(id data, NSError *error) { + [[Coding_NetAPIManager sharedManager] request_InfoOfTeam:_curTeam andBlock:^(id data, NSError *error) { [weakSelf.myRefreshControl endRefreshing]; if (data) { - weakSelf.curTeam = data; + weakSelf.curTeam = [Login curLoginCompany]; + weakSelf.curTeam.info = data; + weakSelf.tableHeaderV.curTeam = weakSelf.curTeam; [weakSelf.myTableView reloadData]; } }]; } +#pragma mark Action +- (void)leftNavBtnClicked{ + [self.navigationController popViewControllerAnimated:YES]; +} +- (void)rightNavBtnClicked{ + TeamSettingViewController *vc = [TeamSettingViewController new]; + vc.curTeam = _curTeam; + [self.navigationController pushViewController:vc animated:YES]; +} + +#pragma mark Scroll + +- (void)scrollViewDidScroll:(UIScrollView *)scrollView{ + if (scrollView == _myTableView) { + [_tableHeaderV.bgV mas_updateConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(_tableHeaderV).offset(scrollView.contentOffset.y); + }]; + } +} + #pragma mark Table - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ - return 2; + return 3; } - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ - return section == 0? 0: 20; + return section == 0? 0: 15; + // return 20; } - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ @@ -70,7 +143,8 @@ - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ - return section == 0? 1: 2; + return section == 0? 1: section == 1? 2: 1; + // return section == 0? 0: 2; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ @@ -79,21 +153,31 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N cell.curTeam = _curTeam; [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; return cell; - }else{ - TitleDisclosureCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_TitleDisclosure forIndexPath:indexPath]; - [cell setTitleStr:indexPath.row == 0? @"团队项目": @"团队成员"]; + }else if (indexPath.section == 1){ + UserInfoIconCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_UserInfoIconCell forIndexPath:indexPath]; + (indexPath.row == 0? [cell setTitle:@"项目管理" icon:@"team_info_pro"]: + [cell setTitle:@"成员管理" icon:@"team_info_mem"]); [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; return cell; + }else{ + UserInfoIconCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_UserInfoIconCell forIndexPath:indexPath]; + [cell setTitle:@"售后支持" icon:@"team_info_sup"]; + return cell; } } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ - return indexPath.section == 0? [TeamTopCell cellHeight]: 44; + return indexPath.section == 0? [NSObject isPrivateCloud].boolValue? 0: [TeamTopCell cellHeight]: [UserInfoIconCell cellHeight]; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ [tableView deselectRowAtIndexPath:indexPath animated:YES]; - if (indexPath.section == 1) { + + if (indexPath.section == 0) { + TeamPurchaseViewController *vc = [TeamPurchaseViewController new]; + vc.curTeam = _curTeam; + [self.navigationController pushViewController:vc animated:YES]; + }else if (indexPath.section == 1) { if (indexPath.row == 0) { TeamProjectsViewController *vc = [TeamProjectsViewController new]; vc.curTeam = _curTeam; @@ -103,7 +187,57 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath vc.curTeam = _curTeam; [self.navigationController pushViewController:vc animated:YES]; } + }else{ + [self.navigationController pushViewController:[TeamSupportViewController new] animated:YES]; + } +} + +@end + +@interface EATeamHeaderView () +@property (strong, nonatomic) UIImageView *iconV; +@property (strong, nonatomic) UILabel *titleL; +@end + +@implementation EATeamHeaderView + +- (instancetype)init{ + self = [super init]; + if (self) { + self.frame = CGRectMake(0, 0, kScreen_Width, 212); + _bgV = [UIImageView new]; + _bgV.backgroundColor = [UIColor colorWithHexString:@"0x425063"]; + // _bgV.image = [[UIImage imageNamed:@"team_bg"] resizableImageWithCapInsets:UIEdgeInsetsMake(10, 0, 200, 0) resizingMode:UIImageResizingModeStretch]; + [self addSubview:_bgV]; + [_bgV mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.bottom.equalTo(self); + make.top.equalTo(self); + }]; + + _iconV = [YLImageView new]; + [_iconV doBorderWidth:0 color:nil cornerRadius:75.0/2]; + [self addSubview:_iconV]; + _titleL = [UILabel labelWithSystemFontSize:17 textColorHexString:@"0xFFFFFF"]; + _titleL.textAlignment = NSTextAlignmentCenter; + [self addSubview:_titleL]; + + [_iconV mas_makeConstraints:^(MASConstraintMaker *make) { + make.size.mas_equalTo(CGSizeMake(75, 75)); + make.centerX.equalTo(self); + make.bottom.equalTo(self).offset(-90); + }]; + [_titleL mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self); + make.top.equalTo(_iconV.mas_bottom).offset(20); + }]; } + return self; +} + +- (void)setCurTeam:(Team *)curTeam{ + _curTeam = curTeam; + [_iconV sd_setImageWithURL:[_curTeam.avatar urlImageWithCodePathResize:75 * 2] placeholderImage:kPlaceholderMonkeyRoundWidth(50.0)]; + _titleL.text = _curTeam.name; } @end diff --git a/Coding_iOS/Controllers/TipsViewController.m b/Coding_iOS/Controllers/TipsViewController.m index 659b3a229..4e33aaf19 100755 --- a/Coding_iOS/Controllers/TipsViewController.m +++ b/Coding_iOS/Controllers/TipsViewController.m @@ -52,6 +52,7 @@ - (void)viewDidLoad titleStr = @"系统通知"; break; default: + titleStr = @"通知"; break; } self.title = titleStr; @@ -69,6 +70,9 @@ - (void)viewDidLoad [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _refreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; @@ -172,22 +176,22 @@ - (void)rightNavBtnClicked{ if ([KxMenu isShowingInView:self.view]) { [KxMenu dismissMenu:YES]; }else{ - [KxMenu setTitleFont:[UIFont systemFontOfSize:14]]; + [KxMenu setTitleFont:[UIFont systemFontOfSize:15]]; [KxMenu setTintColor:[UIColor whiteColor]]; [KxMenu setLineColor:kColorDDD]; NSArray *menuItems = @[ [KxMenuItem menuItem:_myCodingTips.onlyUnread? @"查看全部": @"查看未读" image:[UIImage imageNamed:@"tips_menu_icon_status"] target:self action:@selector(p_changeTipStatus)], [KxMenuItem menuItem:@"全部标注已读" image:[UIImage imageNamed:@"tips_menu_icon_mkread"] target:self action:@selector(p_markReadAll)], ]; - [menuItems setValue:kColor222 forKey:@"foreColor"]; - CGRect senderFrame = CGRectMake(kScreen_Width - (kDevice_Is_iPhone6Plus? 30: 26), 0, 0, 0); + [menuItems setValue:kColorDark4 forKey:@"foreColor"]; + CGRect senderFrame = CGRectMake(kScreen_Width - (kDevice_Is_iPhone6Plus? 30: 26), 5, 0, 0); [KxMenu showMenuInView:self.view fromRect:senderFrame menuItems:menuItems]; } // @weakify(self); -// [[UIActionSheet bk_actionSheetCustomWithTitle:@"将本页的未读通知全部标记为已读?" buttonTitles:@[@"全部标为已读"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { +// [[UIAlertController ea_actionSheetCustomWithTitle:@"将本页的未读通知全部标记为已读?" buttonTitles:@[@"全部标为已读"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { // if (index == 0) { // @strongify(self); // [self p_markReadAll]; @@ -224,7 +228,12 @@ - (void)analyseHtmlMediaItem:(HtmlMediaItem *)item andTip:(CodingTip *)tip{ NSString *linkStr = item.href; UIViewController *vc = [BaseViewController analyseVCFromLinkStr:linkStr]; if (vc) { - [self.navigationController pushViewController:vc animated:YES]; + if ([vc isKindOfClass:NSClassFromString(@"TeamViewController")] && + ![Login curLoginUser].isAdministrator.boolValue) { + [NSObject showHudTipStr:@"无权访问企业账户"]; + }else{ + [self.navigationController pushViewController:vc animated:YES]; + } }else{ //网页 WebViewController *webVc = [WebViewController webVCWithUrlStr:linkStr]; diff --git a/Coding_iOS/Controllers/Topic/CSHotTopicPagesVC.m b/Coding_iOS/Controllers/Topic/CSHotTopicPagesVC.m index 21851bf06..6ac8d4c27 100644 --- a/Coding_iOS/Controllers/Topic/CSHotTopicPagesVC.m +++ b/Coding_iOS/Controllers/Topic/CSHotTopicPagesVC.m @@ -59,18 +59,20 @@ - (void)searchItemClicked:(id)sender{ if(!_searchBar) { _searchBar = ({ - UISearchBar *searchBar = [[UISearchBar alloc] init]; searchBar.delegate = self; [searchBar sizeToFit]; [searchBar setPlaceholder:@"搜索冒泡、用户名、话题"]; - [searchBar setTintColor:[UIColor whiteColor]]; + [searchBar setTintColor:kColorBrandBlue]; [searchBar setTranslucent:NO]; [searchBar insertBGColor:kColorNavBG]; + UIView *bgV = [[UIView alloc] initWithFrame:CGRectMake(0, -kSafeArea_Top, kScreen_Width, kSafeArea_Top)]; + bgV.backgroundColor = kColorNavBG; + [searchBar addSubview:bgV]; searchBar; }); [self.navigationController.view addSubview:_searchBar]; - [_searchBar setY:20]; + [_searchBar setY:kSafeArea_Top]; } if (!_searchDisplayVC) { diff --git a/Coding_iOS/Controllers/Topic/CSHotTopicView.m b/Coding_iOS/Controllers/Topic/CSHotTopicView.m index f3a45f917..379ecc2cf 100644 --- a/Coding_iOS/Controllers/Topic/CSHotTopicView.m +++ b/Coding_iOS/Controllers/Topic/CSHotTopicView.m @@ -52,6 +52,9 @@ - (id)initWithFrame:(CGRect)frame { [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); diff --git a/Coding_iOS/Controllers/Topic/CSLikesVC.m b/Coding_iOS/Controllers/Topic/CSLikesVC.m index 615d737c6..5ebb75e7d 100644 --- a/Coding_iOS/Controllers/Topic/CSLikesVC.m +++ b/Coding_iOS/Controllers/Topic/CSLikesVC.m @@ -39,6 +39,9 @@ - (void)viewDidLoad { [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); diff --git a/Coding_iOS/Controllers/Topic/CSScrollview.m b/Coding_iOS/Controllers/Topic/CSScrollview.m index c5ddf0e21..9f6d2a9ca 100644 --- a/Coding_iOS/Controllers/Topic/CSScrollview.m +++ b/Coding_iOS/Controllers/Topic/CSScrollview.m @@ -176,7 +176,7 @@ @implementation CSScrollUnit { - (void)setRefIteml:(CSScrollItem*)refIteml { if (!_imgView) { - _imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.width, self.height)]; + _imgView = [[YLImageView alloc] initWithFrame:CGRectMake(0, 0, self.width, self.height)]; _imgView.backgroundColor = kColorTableBG; [self.contentView addSubview:_imgView]; } diff --git a/Coding_iOS/Controllers/Topic/CSTopicCreateVC.m b/Coding_iOS/Controllers/Topic/CSTopicCreateVC.m index 844887f36..3730b99ab 100644 --- a/Coding_iOS/Controllers/Topic/CSTopicCreateVC.m +++ b/Coding_iOS/Controllers/Topic/CSTopicCreateVC.m @@ -55,6 +55,9 @@ - (void)viewDidLoad { [tableView setContentInset:UIEdgeInsetsZero]; [tableView setScrollIndicatorInsets:UIEdgeInsetsZero]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _searchBar = ({ diff --git a/Coding_iOS/Controllers/Topic/CSTopicDetailVC.m b/Coding_iOS/Controllers/Topic/CSTopicDetailVC.m index 6da81380b..65fb8b1a5 100644 --- a/Coding_iOS/Controllers/Topic/CSTopicDetailVC.m +++ b/Coding_iOS/Controllers/Topic/CSTopicDetailVC.m @@ -191,7 +191,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N if ([Login isLoginUserGlobalKey:weakSelf.commentToUser.global_key]) { ESWeakSelf - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"删除此评论" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + UIAlertController *actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"删除此评论" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { ESStrongSelf if (index == 0 && _self.commentIndex >= 0) { Comment *comment = [_self.commentTweet.comment_list objectAtIndex:_self.commentIndex]; @@ -230,7 +230,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N if ([self.myMsgInputView isAndResignFirstResponder]) { return ; } - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"删除此冒泡" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + UIAlertController *actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"删除此冒泡" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf deleteTweet:curTweet]; } @@ -314,7 +314,7 @@ - (void)messageInputView:(UIMessageInputView *)inputView sendText:(NSString *)te - (void)messageInputView:(UIMessageInputView *)inputView heightToBottomChenged:(CGFloat)heightToBottom{ [UIView animateWithDuration:0.25 delay:0.0f options:UIViewAnimationOptionTransitionFlipFromBottom animations:^{ UIEdgeInsets contentInsets= UIEdgeInsetsMake(0.0, 0.0, heightToBottom, 0.0);; - CGFloat msgInputY = kScreen_Height - heightToBottom - 64; + CGFloat msgInputY = kScreen_Height - heightToBottom - (44 + kSafeArea_Top); self.myTableView.contentInset = contentInsets; self.myTableView.scrollIndicatorInsets = contentInsets; @@ -401,6 +401,9 @@ - (void) setupUI { make.edges.equalTo(self.view); }]; _tableHeader = header; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); @@ -417,11 +420,12 @@ - (void)sendTweet{ __weak typeof(self) weakSelf = self; TweetSendViewController *vc = [[TweetSendViewController alloc] init]; vc.sendNextTweet = ^(Tweet *nextTweet){ - [nextTweet saveSendData];//发送前保存草稿 [[Coding_NetAPIManager sharedManager] request_Tweet_DoTweet_WithObj:nextTweet andBlock:^(id data, NSError *error) { if (data) { [Tweet deleteSendData];//发送成功后删除草稿 [weakSelf refresh]; + }else{ + [nextTweet saveSendData];//发送失败,保存草稿 } }]; }; diff --git a/Coding_iOS/Controllers/Topic/CSTopicHeaderView.m b/Coding_iOS/Controllers/Topic/CSTopicHeaderView.m index 92dfc9642..d6d34ccdc 100644 --- a/Coding_iOS/Controllers/Topic/CSTopicHeaderView.m +++ b/Coding_iOS/Controllers/Topic/CSTopicHeaderView.m @@ -84,7 +84,7 @@ - (void)updateWithJoinedUsers:(NSArray*)userlist { for (int i=0; i kScreen_Width) { @@ -95,6 +95,15 @@ - (void)updateWithJoinedUsers:(NSArray*)userlist { [iconView sd_setImageWithURL:[user.avatar urlImageWithCodePathResizeToView:iconView] placeholderImage:[UIImage imageNamed:@"placeholder_monkey_round_48"]]; + { + UIImageView *vipV = [UIImageView new]; + [self addSubview:vipV]; + [vipV mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.bottom.equalTo(iconView); + }]; + vipV.image = [UIImage imageNamed:[NSString stringWithFormat:@"vip_%@_40", user.vip]]; + } + [_avatalist addObject:iconView]; } } diff --git a/Coding_iOS/Controllers/Topic/CSTopiclistView.m b/Coding_iOS/Controllers/Topic/CSTopiclistView.m index 29cc887ce..0f0fb733d 100644 --- a/Coding_iOS/Controllers/Topic/CSTopiclistView.m +++ b/Coding_iOS/Controllers/Topic/CSTopiclistView.m @@ -68,6 +68,9 @@ - (id)initWithFrame:(CGRect)frame globalKey:(NSString *)key type:(CSMyTopicsType // tableView.contentInset = insets; // tableView.scrollIndicatorInsets = insets; // } + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); diff --git a/Coding_iOS/Controllers/TopicAnswerDetailViewController.m b/Coding_iOS/Controllers/TopicAnswerDetailViewController.m index c9665dd66..4ed59b287 100644 --- a/Coding_iOS/Controllers/TopicAnswerDetailViewController.m +++ b/Coding_iOS/Controllers/TopicAnswerDetailViewController.m @@ -43,6 +43,9 @@ - (void)viewDidLoad{ [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; @@ -111,7 +114,7 @@ - (void)messageInputView:(UIMessageInputView *)inputView heightToBottomChenged:( { [UIView animateWithDuration:0.25 delay:0.0f options:UIViewAnimationOptionTransitionFlipFromBottom animations:^{ UIEdgeInsets contentInsets= UIEdgeInsetsMake(0.0, 0.0, MAX(CGRectGetHeight(inputView.frame), heightToBottom), 0.0);; - CGFloat msgInputY = kScreen_Height - heightToBottom - 64; + CGFloat msgInputY = kScreen_Height - heightToBottom - (44 + kSafeArea_Top); self.myTableView.contentInset = contentInsets; self.myTableView.scrollIndicatorInsets = contentInsets; @@ -193,7 +196,7 @@ - (void)doCommentToTopic:(ProjectTopic *)toComment ofAnswer:(ProjectTopic *)answ if (_toComment) { if ([Login isLoginUserGlobalKey:_toComment.owner.global_key]) { ESWeakSelf - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"删除此评论" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + UIAlertController *actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"删除此评论" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { ESStrongSelf if (index == 0) { [_self deleteTopic:_self.toComment ofAnswer:answer isComment:YES]; diff --git a/Coding_iOS/Controllers/TopicDetailViewController.m b/Coding_iOS/Controllers/TopicDetailViewController.m index 507fdd1d1..c14a49457 100755 --- a/Coding_iOS/Controllers/TopicDetailViewController.m +++ b/Coding_iOS/Controllers/TopicDetailViewController.m @@ -66,6 +66,9 @@ - (void)viewDidLoad [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _refreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; @@ -123,7 +126,8 @@ - (void)viewDidAppear:(BOOL)animated - (void)addtitleBtnClick { EditLabelViewController *vc = [[EditLabelViewController alloc] init]; - vc.curProject = self.curTopic.project; +// vc.curProject = self.curTopic.project; + vc.curProject = self.curTopic.project ?: ({Project *p = [Project new]; p.id = self.curTopic.project_id; p;}); vc.orignalTags = self.curTopic.mdLabels; @weakify(self); vc.tagsSelectedBlock = ^(EditLabelViewController *vc, NSMutableArray *selectedTags){ @@ -176,7 +180,7 @@ - (void)messageInputView:(UIMessageInputView *)inputView heightToBottomChenged:( { [UIView animateWithDuration:0.25 delay:0.0f options:UIViewAnimationOptionTransitionFlipFromBottom animations:^{ UIEdgeInsets contentInsets= UIEdgeInsetsMake(0.0, 0.0, MAX(CGRectGetHeight(inputView.frame), heightToBottom), 0.0);; - CGFloat msgInputY = kScreen_Height - heightToBottom - 64; + CGFloat msgInputY = kScreen_Height - heightToBottom - (44 + kSafeArea_Top); self.myTableView.contentInset = contentInsets; self.myTableView.scrollIndicatorInsets = contentInsets; @@ -260,11 +264,11 @@ - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView #pragma mark Table header footer - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ - return section == 0? 1.0/[UIScreen mainScreen].scale: _curTopic.watchers.count > 0? 142: 88; + return section == 0? kLine_MinHeight: _curTopic.watchers.count > 0? 142: 88; } - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ - return section == 0? 10: 1.0/[UIScreen mainScreen].scale; + return section == 0? 10: kLine_MinHeight; } - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{ @@ -288,7 +292,7 @@ - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger [weakSelf doCommentToTopic:nil ofAnswer:nil sender:sender]; }; _headerV.deleteBlock = ^(ProjectTopic *curTopic){ - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"删除此讨论" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + UIAlertController *actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"删除此讨论" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf deleteTopic:weakSelf.curTopic ofAnswer:nil isComment:NO]; } @@ -389,7 +393,7 @@ - (void)doCommentToTopic:(ProjectTopic *)toComment ofAnswer:(ProjectTopic *)answ if (_toComment) { if ([Login isLoginUserGlobalKey:_toComment.owner.global_key]) { ESWeakSelf - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"删除此评论" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + UIAlertController *actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"删除此评论" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { ESStrongSelf if (index == 0) { [_self deleteTopic:_self.toComment ofAnswer:answer isComment:YES]; @@ -544,7 +548,7 @@ - (instancetype)init _tipL = [UILabel new]; _tipL.textColor = kColor999; _tipL.font = [UIFont systemFontOfSize:12]; - [_tipL setAttrStrWithStr:@"尚未添加任何关注者,去添加" diffColorStr:@"去添加" diffColor:kColorBrandGreen]; + [_tipL setAttrStrWithStr:@"尚未添加任何关注者,去添加" diffColorStr:@"去添加" diffColor:kColorBrandBlue]; _tipL.userInteractionEnabled = YES; [_tipL bk_whenTapped:^{ if (weakSelf.goToUserBlock) { @@ -555,6 +559,7 @@ - (instancetype)init } if (!_addBtn) { _addBtn = [UIButton buttonWithType:UIButtonTypeCustom]; + _addBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight; [_addBtn setImage:[UIImage imageNamed:@"topic_add_watcher_btn"] forState:UIControlStateNormal]; [_addBtn bk_addEventHandler:^(id sender) { if (weakSelf.goToUserBlock) { @@ -580,6 +585,7 @@ - (instancetype)init } if (!_commentBtn) { _commentBtn = [UIButton buttonWithType:UIButtonTypeCustom]; + _commentBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight; [_commentBtn setImage:[UIImage imageNamed:@"tweet_comment_btn"] forState:UIControlStateNormal]; [_commentBtn bk_addEventHandler:^(id sender) { if (weakSelf.commentBlock) { @@ -591,7 +597,7 @@ - (instancetype)init if (!_deleteBtn) { _deleteBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [_deleteBtn setTitle:@"删除" forState:UIControlStateNormal]; - [_deleteBtn setTitleColor:kColorBrandGreen forState:UIControlStateNormal]; + [_deleteBtn setTitleColor:kColorBrandBlue forState:UIControlStateNormal]; [_deleteBtn setTitleColor:[UIColor darkGrayColor] forState:UIControlStateHighlighted]; _deleteBtn.titleLabel.font = [UIFont boldSystemFontOfSize:12]; [_deleteBtn bk_addEventHandler:^(id sender) { @@ -676,7 +682,7 @@ - (void)setCurTopic:(ProjectTopic *)curTopic{ - (UIView *)makeViewForUser:(User *)user{ CGFloat width = 30.0; - UIImageView *imageV = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, width, width)]; + UIImageView *imageV = [[YLImageView alloc] initWithFrame:CGRectMake(0, 0, width, width)]; imageV.layer.masksToBounds = YES; imageV.layer.cornerRadius = width/2; imageV.layer.borderColor = [UIColor colorWithHexString:@"0xFFAE03"].CGColor; diff --git a/Coding_iOS/Controllers/TweetDetailViewController.h b/Coding_iOS/Controllers/TweetDetailViewController.h index bf1526aaa..f3ee2e31b 100755 --- a/Coding_iOS/Controllers/TweetDetailViewController.h +++ b/Coding_iOS/Controllers/TweetDetailViewController.h @@ -14,6 +14,7 @@ @interface TweetDetailViewController : BaseViewController @property (strong, nonatomic) Tweet *curTweet; +@property (strong, nonatomic) Project *curProject;//项目内冒泡有这个,@ 人的时候用 @property (copy, nonatomic) void(^deleteTweetBlock)(Tweet *); - (void)refreshTweet; diff --git a/Coding_iOS/Controllers/TweetDetailViewController.m b/Coding_iOS/Controllers/TweetDetailViewController.m index 397d084d8..2199aad3d 100644 --- a/Coding_iOS/Controllers/TweetDetailViewController.m +++ b/Coding_iOS/Controllers/TweetDetailViewController.m @@ -21,6 +21,7 @@ #import "ReportIllegalViewController.h" #import "TweetSendLocationDetailViewController.h" #import "CodingShareView.h" +#import "ProjectTweetSendViewController.h" @interface TweetDetailViewController () @property (nonatomic, strong) UITableView *myTableView; @@ -68,30 +69,25 @@ - (void)viewDidLoad [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _refreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; [_refreshControl addTarget:self action:@selector(refreshTweet) forControlEvents:UIControlEventValueChanged]; - //评论 - _myMsgInputView = [UIMessageInputView messageInputViewWithType:UIMessageInputViewContentTypeTweet]; - _myMsgInputView.isAlwaysShow = YES; - _myMsgInputView.delegate = self; - - UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0,CGRectGetHeight(_myMsgInputView.frame), 0.0); - self.myTableView.contentInset = contentInsets; - self.myTableView.scrollIndicatorInsets = contentInsets; +// //评论 +// _myMsgInputView = [UIMessageInputView messageInputViewWithType:UIMessageInputViewContentTypeTweet]; +// _myMsgInputView.isAlwaysShow = YES; +// _myMsgInputView.delegate = self; +// _myMsgInputView.curProject = _curProject; +// +// UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0,CGRectGetHeight(_myMsgInputView.frame), 0.0); +// self.myTableView.contentInset = contentInsets; +// self.myTableView.scrollIndicatorInsets = contentInsets; - if (!_curTweet.content - || (_curTweet.likes.integerValue > 0 && _curTweet.like_users.count == 0)) { - [self refreshTweet]; - }else{ - _myMsgInputView.commentOfId = _curTweet.id; - - if (_curTweet.comments.integerValue > _curTweet.comment_list.count) { - [self refreshComments];//加载等多评论 - } - } + [self refreshTweet]; } - (void)viewWillDisappear:(BOOL)animated{ @@ -112,29 +108,37 @@ - (void)viewDidAppear:(BOOL)animated{ } } -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. +- (void)setCurTweet:(Tweet *)curTweet{ + _curTweet = curTweet; + if ([_curTweet isProjectTweet]) { + _myMsgInputView = nil; + }else{ + //评论 + _myMsgInputView = [UIMessageInputView messageInputViewWithType:UIMessageInputViewContentTypeTweet]; + _myMsgInputView.isAlwaysShow = YES; + _myMsgInputView.delegate = self; + _myMsgInputView.curProject = _curProject; + } + UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0,CGRectGetHeight(_myMsgInputView.frame), 0.0); + self.myTableView.contentInset = contentInsets; + self.myTableView.scrollIndicatorInsets = contentInsets; } - (void)rightNavBtnClicked{ if (self.curTweet.id && [self.curTweet.id isKindOfClass:[NSNumber class]]) { - [_myMsgInputView isAndResignFirstResponder]; - -// if (_curTweet.project_id != nil) { -// [NSObject showHudTipStr:@"项目内冒泡,不能分享"]; -// return; -// } - [CodingShareView showShareViewWithObj:_curTweet]; - -// @weakify(self); -// [[UIActionSheet bk_actionSheetCustomWithTitle:nil buttonTitles:@[@"举报"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { -// if (index == 0) { -// @strongify(self); -// [self goToReport]; -// } -// }] showInView:self.view]; + if (_curTweet.isProjectTweet) { + ProjectTweetSendViewController *vc = [ProjectTweetSendViewController new]; + vc.curPro = _curProject; + vc.curTweet = _curTweet; + __weak typeof(self) weakSelf = self; + vc.sentBlock = ^(Tweet *tweet){ + [weakSelf refreshTweet]; + }; + [self.navigationController pushViewController:vc animated:YES]; + }else{ + [_myMsgInputView isAndResignFirstResponder]; + [CodingShareView showShareViewWithObj:_curTweet]; + } } } @@ -155,7 +159,7 @@ - (void)messageInputView:(UIMessageInputView *)inputView sendText:(NSString *)te - (void)messageInputView:(UIMessageInputView *)inputView heightToBottomChenged:(CGFloat)heightToBottom{ [UIView animateWithDuration:0.25 delay:0.0f options:UIViewAnimationOptionTransitionFlipFromBottom animations:^{ UIEdgeInsets contentInsets= UIEdgeInsetsMake(0.0, 0.0, MAX(CGRectGetHeight(inputView.frame), heightToBottom), 0.0);; - CGFloat msgInputY = kScreen_Height - heightToBottom - 64; + CGFloat msgInputY = kScreen_Height - heightToBottom - (44 + kSafeArea_Top); self.myTableView.contentInset = contentInsets; self.myTableView.scrollIndicatorInsets = contentInsets; @@ -172,7 +176,7 @@ - (void)messageInputView:(UIMessageInputView *)inputView heightToBottomChenged:( #pragma mark refresh - (void)refreshTweet{ __weak typeof(self) weakSelf = self; - if (_curTweet.project && !_curTweet.project_id) { + if (_curTweet.isProjectTweet && !_curTweet.project.current_user_role_id) { [[Coding_NetAPIManager sharedManager] request_ProjectDetail_WithObj:_curTweet.project andBlock:^(id data, NSError *error) { if (data) { weakSelf.curTweet.project = data; @@ -197,6 +201,11 @@ - (void)refreshTweet{ weakSelf.myMsgInputView.toUser = nil; [weakSelf.myTableView reloadData]; [weakSelf refreshComments]; + if (weakSelf.curTweet.isProjectTweet && + (weakSelf.curTweet.project.current_user_role_id.integerValue >= 90 || + [Login isLoginUserGlobalKey:weakSelf.curTweet.owner.global_key])) { + [self.navigationItem setRightBarButtonItem:[UIBarButtonItem itemWithBtnTitle:@"编辑" target:self action:@selector(rightNavBtnClicked)] animated:YES]; + } }else{ [weakSelf.refreshControl endRefreshing]; } @@ -223,7 +232,8 @@ - (void)refreshComments{ #pragma mark TableM - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ NSInteger row = 0; - if (_curTweet && _curTweet.comment_list) { +// if (_curTweet && _curTweet.comment_list) { + if (_curTweet && _curTweet.comment_list && ![_curTweet isProjectTweet]) { row = 1+ [_curTweet.comment_list count]; }else{ row = 1; @@ -246,7 +256,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N return ; } ESWeakSelf; - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"删除此冒泡" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + UIAlertController *actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:self.curTweet.isProjectTweet? @"删除此公告": @"删除此冒泡" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { ESStrongSelf if (index == 0) { [_self deleteTweet:_self.curTweet]; @@ -278,9 +288,9 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N cell.commentToCommentBlock = ^(Comment *toComment, id sender){ [self doCommentToComment:toComment sender:sender]; }; - [cell.ownerIconView addTapBlock:^(id obj) { - [self goToUserInfo:curComment.owner]; - }]; +// [cell.ownerIconView addTapBlock:^(id obj) { +// [self goToUserInfo:curComment.owner]; +// }]; cell.contentLabel.delegate = self; [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; return cell; @@ -344,7 +354,7 @@ - (void)doCommentToComment:(Comment *)toComment sender:(id)sender{ if (_toComment) { if ([Login isLoginUserGlobalKey:_toComment.owner.global_key]) { ESWeakSelf; - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"删除此评论" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + UIAlertController *actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"删除此评论" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { ESStrongSelf if (index == 0) { [_self deleteComment:_self.toComment ofTweet:_self.curTweet]; @@ -428,9 +438,15 @@ - (void)attributedLabel:(TTTAttributedLabel *)label didSelectLinkWithTransitInfo #pragma mark to VC - (void)goToUserInfo:(User *)curUser{ - UserInfoViewController *vc = [[UserInfoViewController alloc] init]; - vc.curUser = curUser; - [self.navigationController pushViewController:vc animated:YES]; + if (kTarget_Enterprise) { + UserInfoDetailViewController *vc = [UserInfoDetailViewController new]; + vc.curUser = curUser; + [self.navigationController pushViewController:vc animated:YES]; + }else{ + UserInfoViewController *vc = [[UserInfoViewController alloc] init]; + vc.curUser = curUser; + [self.navigationController pushViewController:vc animated:YES]; + } } #pragma mark loadCellRequest diff --git a/Coding_iOS/Controllers/TweetSendLocationViewController.m b/Coding_iOS/Controllers/TweetSendLocationViewController.m index b9a56d373..46265a35b 100644 --- a/Coding_iOS/Controllers/TweetSendLocationViewController.m +++ b/Coding_iOS/Controllers/TweetSendLocationViewController.m @@ -725,14 +725,13 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N cell.detailTextLabel.font = [UIFont systemFontOfSize:12.0]; cell.detailTextLabel.textColor = kColor999; } - cell.tintColor = kColorBrandGreen; //如果为自定义数据 if([self.locationArray[indexPath.row][@"cellType"] isEqualToString:@"defualt"]) { switch (indexPath.row) { case 0: cell.textLabel.text = self.locationArray[indexPath.row][@"title"]; - cell.textLabel.textColor = kColorBrandGreen; + cell.textLabel.textColor = kColorBrandBlue; if ([self.locationArray[indexPath.row][@"checkmark"] isEqualToString:@"YES"]) { cell.accessoryType = UITableViewCellAccessoryCheckmark; }else { diff --git a/Coding_iOS/Controllers/TweetSendViewController.m b/Coding_iOS/Controllers/TweetSendViewController.m index 17dec5ec6..18934c734 100755 --- a/Coding_iOS/Controllers/TweetSendViewController.m +++ b/Coding_iOS/Controllers/TweetSendViewController.m @@ -39,7 +39,7 @@ + (instancetype)presentWithParams:(NSDictionary *)params{ curTweet.callback = callback; curTweet.tweetContent = content; if (image) { - curTweet.tweetImages = @[[TweetImage tweetImageWithAssetURL:nil andImage:image]].mutableCopy; + curTweet.tweetImages = @[[TweetImage tweetImageWithAssetLocalIdentifier:nil andImage:image]].mutableCopy; } TweetSendViewController *vc = [TweetSendViewController new]; vc.curTweet = curTweet; @@ -91,6 +91,9 @@ - (void)viewDidLoad [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); } @@ -152,7 +155,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N [self showActionForPhoto]; }; cell.deleteTweetImageBlock = ^(TweetImage *toDelete){ - [weakSelf.curTweet deleteATweetImage:toDelete]; + [weakSelf.curTweet deleteTweetImage:toDelete]; [weakSelf.myTableView reloadData]; }; return cell; @@ -177,13 +180,13 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath - (void)showActionForPhoto{ @weakify(self); - [[UIActionSheet bk_actionSheetCustomWithTitle:nil buttonTitles:@[@"拍照", @"从相册选择"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + [[UIAlertController ea_actionSheetCustomWithTitle:nil buttonTitles:@[@"拍照", @"从相册选择"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { @strongify(self); - [self photoActionSheet:sheet DismissWithButtonIndex:index]; + [self photoActionSheetDismissWithButtonIndex:index]; }] showInView:self.view]; } -- (void)photoActionSheet:(UIActionSheet *)sheet DismissWithButtonIndex:(NSInteger)buttonIndex{ +- (void)photoActionSheetDismissWithButtonIndex:(NSInteger)buttonIndex{ if (buttonIndex == 0) { // 拍照 if (![Helper checkCameraAuthorizationStatus]) { @@ -203,24 +206,33 @@ - (void)photoActionSheet:(UIActionSheet *)sheet DismissWithButtonIndex:(NSIntege return; } QBImagePickerController *imagePickerController = [[QBImagePickerController alloc] init]; - [imagePickerController.selectedAssetURLs removeAllObjects]; - [imagePickerController.selectedAssetURLs addObjectsFromArray:self.curTweet.selectedAssetURLs]; - imagePickerController.filterType = QBImagePickerControllerFilterTypePhotos; + [imagePickerController.selectedAssets removeAllObjects]; + PHFetchResult *fetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:self.curTweet.selectedAssetLocalIdentifiers options:nil]; + [fetchResult enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + [imagePickerController.selectedAssets addObject:obj]; + }]; + imagePickerController.mediaType = QBImagePickerMediaTypeImage; imagePickerController.delegate = self; imagePickerController.allowsMultipleSelection = YES; - imagePickerController.maximumNumberOfSelection = 9; - UINavigationController *navigationController = [[BaseNavigationController alloc] initWithRootViewController:imagePickerController]; - [self presentViewController:navigationController animated:YES completion:NULL]; + imagePickerController.maximumNumberOfSelection = 6; + [self presentViewController:imagePickerController animated:YES completion:NULL]; + } } #pragma mark UIImagePickerControllerDelegate - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{ UIImage *pickerImage = [info objectForKey:UIImagePickerControllerOriginalImage]; - ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init]; - [assetsLibrary writeImageToSavedPhotosAlbum:[pickerImage CGImage] orientation:(ALAssetOrientation)pickerImage.imageOrientation completionBlock:^(NSURL *assetURL, NSError *error) { - [self.curTweet addASelectedAssetURL:assetURL]; - [self.myTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:1 inSection:0]] withRowAnimation:UITableViewRowAnimationFade]; + PHPhotoLibrary *photoLibrary = [PHPhotoLibrary sharedPhotoLibrary]; + __block NSString *localId; + [photoLibrary performChanges:^{ + PHAssetChangeRequest *assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:pickerImage]; + localId = assetChangeRequest.placeholderForCreatedAsset.localIdentifier; + } completionHandler:^(BOOL success, NSError * _Nullable error) { + if (success) { + [self.curTweet addSelectedAssetLocalIdentifier:localId]; + [self.myTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:1 inSection:0]] withRowAnimation:UITableViewRowAnimationFade]; + } }]; [picker dismissViewControllerAnimated:YES completion:^{}]; } @@ -230,14 +242,15 @@ - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{ } #pragma mark QBImagePickerControllerDelegate -- (void)qb_imagePickerController:(QBImagePickerController *)imagePickerController didSelectAssets:(NSArray *)assets{ - NSMutableArray *selectedAssetURLs = [NSMutableArray new]; - [imagePickerController.selectedAssetURLs enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { - [selectedAssetURLs addObject:obj]; + +- (void)qb_imagePickerController:(QBImagePickerController *)imagePickerController didFinishPickingAssets:(NSArray *)assets{ + NSMutableArray *selectedAssetLocalIdentifiers = [NSMutableArray new]; + [imagePickerController.selectedAssets enumerateObjectsUsingBlock:^(PHAsset *obj, NSUInteger idx, BOOL *stop) { + [selectedAssetLocalIdentifiers addObject:obj.localIdentifier]; }]; @weakify(self); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - self.curTweet.selectedAssetURLs = selectedAssetURLs; + self.curTweet.selectedAssetLocalIdentifiers = selectedAssetLocalIdentifiers; dispatch_async(dispatch_get_main_queue(), ^{ @strongify(self); [self.myTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:1 inSection:0]] withRowAnimation:UITableViewRowAnimationFade]; @@ -258,7 +271,7 @@ - (void)cancelBtnClicked:(id)sender{ [self dismissSelfWithCompletion:nil]; }else{ __weak typeof(self) weakSelf = self; - [[UIActionSheet bk_actionSheetCustomWithTitle:@"是否保存草稿" buttonTitles:@[@"保存"] destructiveTitle:@"不保存" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + [[UIAlertController ea_actionSheetCustomWithTitle:@"是否保存草稿" buttonTitles:@[@"保存"] destructiveTitle:@"不保存" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf.curTweet saveSendData]; }else if (index == 1){ @@ -283,15 +296,12 @@ - (void)dismissSelfWithCompletion:(void (^)(void))completion{ - (void)handleCallBack:(NSString *)callback status:(BOOL)handleStatus{ NSString *schemeStr = [NSString stringWithFormat:@"%@://coding.net?type=%@&handle_result=%@", callback, @"handle_result", handleStatus? @(1): @(0)]; if (handleStatus) {//弹出提示给用户选择 - UIAlertView *alertV = [UIAlertView bk_alertViewWithTitle:@"已发送" message:@"是否需要返回原来应用?"]; - [alertV bk_setCancelButtonWithTitle:@"返回原应用" handler:nil]; - [alertV bk_addButtonWithTitle:@"留在 Coding" handler:nil]; - alertV.bk_didDismissBlock = ^(UIAlertView *alertView, NSInteger buttonIndex){ - if (buttonIndex == 0) {// + [[UIAlertController ea_alertViewWithTitle:@"已发送" message:@"是否需要返回原来应用?" buttonTitles:@[@"留在 CODING"] destructiveTitle:nil cancelTitle:@"返回原应用" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 1) {// [[UIApplication sharedApplication] openURL:[NSURL URLWithString:schemeStr]]; } - }; - [alertV show]; + }] show]; + }else{//直接返回 [[UIApplication sharedApplication] openURL:[NSURL URLWithString:schemeStr]]; [self dismissSelfWithCompletion:nil]; @@ -309,6 +319,12 @@ - (BOOL)isEmptyTweet{ } - (void)sendTweet{ + for (TweetImage *tImg in _curTweet.tweetImages) { + if (tImg.downloadState == TweetImageDownloadStateIng) { + [NSObject showHudTipStr:@"iCloud 图片尚未下载完毕"]; + return; + } + } _curTweet.tweetContent = [_curTweet.tweetContent aliasedString]; if (_sendNextTweet) { _sendNextTweet(_curTweet); diff --git a/Coding_iOS/Controllers/UserInfoDetailViewController.m b/Coding_iOS/Controllers/UserInfoDetailViewController.m index 44f864af4..62fe1b7bb 100644 --- a/Coding_iOS/Controllers/UserInfoDetailViewController.m +++ b/Coding_iOS/Controllers/UserInfoDetailViewController.m @@ -12,6 +12,7 @@ #import "UserInfoDetailUserCell.h" #import "TitleValueCell.h" +#import "Coding_NetAPIManager.h" @interface UserInfoDetailViewController () @property (strong, nonatomic) UITableView *myTableView; @@ -38,10 +39,26 @@ - (void)viewDidLoad { [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); + [self refresh]; } +- (void)refresh{ + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_UserInfo_WithObj:_curUser andBlock:^(id data, NSError *error) { + if (data) { + weakSelf.curUser = data; + [weakSelf.myTableView reloadData]; + } + }]; +} + +#ifdef Target_Enterprise + #pragma mark TableM - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ @@ -96,7 +113,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N [cell setTitleStr:@"最后活动" valueStr:[_curUser.last_activity_at string_yyyy_MM_dd]]; break; default: - [cell setTitleStr:@"个性后缀" valueStr:_curUser.global_key]; + [cell setTitleStr:@"用户名" valueStr:_curUser.global_key]; break; } break; @@ -115,7 +132,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } break; case 1: - [cell setTitleStr:@"生日" valueStr:_curUser.birthday]; + [cell setTitleStr:@"生日" valueStr:_curUser.birthday ?: @"未填写"]; break; case 2: [cell setTitleStr:@"所在地" valueStr:_curUser.location]; @@ -168,10 +185,139 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath [tableView deselectRowAtIndexPath:indexPath animated:YES]; } -- (void)dealloc -{ - _myTableView.delegate = nil; - _myTableView.dataSource = nil; +#else + +#pragma mark TableM + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ + return 6; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + NSInteger row; + switch (section) { + case 0: + row = 1; + break; + case 1: + row = 3; + break; + case 2: + row = 4; + break; + case 3: + row = 4; + break; + default: + row = 1; + break; + } + return row; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + if (indexPath.section == 0) { + UserInfoDetailUserCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_UserInfoDetailUserCell forIndexPath:indexPath]; + [cell setName:_curUser.name icon:_curUser.avatar]; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; + return cell; + }else if (indexPath.section == 4 || indexPath.section == 5){ + UserInfoDetailTagCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_UserInfoDetailTagCell forIndexPath:indexPath]; + [cell setTitleStr:indexPath.section == 4? @"开发技能": @"个性标签"]; + [cell setTagStr:indexPath.section == 4? _curUser.skills_str: _curUser.tags_str]; + cell.accessoryType = UITableViewCellAccessoryNone; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; + return cell; + }else{ + TitleValueCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_TitleValue forIndexPath:indexPath]; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; + + switch (indexPath.section) { + case 1: + switch (indexPath.row) { + case 0: + [cell setTitleStr:@"加入时间" valueStr:[_curUser.created_at string_yyyy_MM_dd]]; + break; + case 1: + [cell setTitleStr:@"最后活动" valueStr:[_curUser.last_activity_at string_yyyy_MM_dd]]; + break; + default: + [cell setTitleStr:@"用户名" valueStr:_curUser.global_key]; + break; + } + break; + case 2: + switch (indexPath.row) { + case 0: + if (_curUser.sex.intValue == 0) { + // 男 + [cell setTitleStr:@"性别" valueStr:@"男"]; + }else if (_curUser.sex.intValue == 1){ + // 女 + [cell setTitleStr:@"性别" valueStr:@"女"]; + }else{ + // 未知 + [cell setTitleStr:@"性别" valueStr:@"未知"]; + } + break; + case 1: + [cell setTitleStr:@"生日" valueStr:_curUser.birthday]; + break; + case 2: + [cell setTitleStr:@"所在地" valueStr:_curUser.location]; + break; + default: + [cell setTitleStr:@"座右铭" valueStr:_curUser.slogan]; + break; + } + break; + default: + if (indexPath.row == 0) { + [cell setTitleStr:@"学历" valueStr:_curUser.degree_str]; + }else if (indexPath.row == 1){ + [cell setTitleStr:@"学校" valueStr:_curUser.school]; + }else if (indexPath.row == 2){ + [cell setTitleStr:@"公司" valueStr:_curUser.company]; + }else{ + [cell setTitleStr:@"工作" valueStr:_curUser.job_str]; + } + break; + } + return cell; + } +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ + CGFloat cellHeight; + if (indexPath.section == 0) { + cellHeight = [UserInfoDetailUserCell cellHeight]; + }else if (indexPath.section == 4 || indexPath.section == 5){ + cellHeight = [UserInfoDetailTagCell cellHeightWithObj:indexPath.section == 4? _curUser.skills_str: _curUser.tags_str]; + }else{ + cellHeight = 44; + } + return cellHeight; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ + return 20.0; } +- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ + return 0.5; +} + +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ + UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 1)]; + headerView.backgroundColor = kColorTableSectionBg; + [headerView setHeight:20.0]; + return headerView; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; +} + +#endif + @end diff --git a/Coding_iOS/Controllers/UserInfoViewController.h b/Coding_iOS/Controllers/UserInfoViewController.h index 0f11b613d..0b7e3512b 100644 --- a/Coding_iOS/Controllers/UserInfoViewController.h +++ b/Coding_iOS/Controllers/UserInfoViewController.h @@ -7,7 +7,9 @@ // #import "BaseViewController.h" -#import "user.h" +#import "User.h" + +#import "UserInfoDetailViewController.h" @interface UserInfoViewController : BaseViewController @property (strong, nonatomic) User *curUser; diff --git a/Coding_iOS/Controllers/UserInfoViewController.m b/Coding_iOS/Controllers/UserInfoViewController.m index 4c2453430..f5c2aeffb 100644 --- a/Coding_iOS/Controllers/UserInfoViewController.m +++ b/Coding_iOS/Controllers/UserInfoViewController.m @@ -16,7 +16,6 @@ #import "AddUserViewController.h" #import "SettingViewController.h" #import "SettingMineInfoViewController.h" -#import "UserInfoDetailViewController.h" #import "ProjectListViewController.h" #import "LocalFoldersViewController.h" @@ -28,18 +27,21 @@ #import "UserInfoTextCell.h" #import "UserInfoIconCell.h" #import "TitleDisclosureCell.h" +#import "EaseUserInfoCell.h" +#import "UserActiveGraphCell.h" #import "StartImagesManager.h" -#import "EaseUserHeaderView.h" #import #import "CSMyTopicVC.h" #import "PointRecordsViewController.h" + @interface UserInfoViewController () @property (strong, nonatomic) UITableView *myTableView; -@property (strong, nonatomic) EaseUserHeaderView *headerView; @property (nonatomic, strong) ODRefreshControl *refreshControl; +@property (nonatomic, strong) EaseUserInfoCell *userInfoCell; +@property (nonatomic, strong) ActivenessModel *activenessModel; @end @@ -57,28 +59,48 @@ - (void)viewDidLoad{ [tableView registerClass:[UserInfoTextCell class] forCellReuseIdentifier:kCellIdentifier_UserInfoTextCell]; [tableView registerClass:[UserInfoIconCell class] forCellReuseIdentifier:kCellIdentifier_UserInfoIconCell]; [tableView registerClass:[TitleDisclosureCell class] forCellReuseIdentifier:kCellIdentifier_TitleDisclosure]; + [tableView registerClass:[UserActiveGraphCell class] forCellReuseIdentifier:kCellIdentifier_UserActiveGraphCell]; [self.view addSubview:tableView]; [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); + + _userInfoCell = [[EaseUserInfoCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellIdentifier_EaseUserInfoCell]; __weak typeof(self) weakSelf = self; - _headerView = [EaseUserHeaderView userHeaderViewWithUser:_curUser image:[StartImagesManager shareManager].curImage.image]; - _headerView.userIconClicked = ^(){ - [weakSelf userIconClicked]; + _userInfoCell.userIconClicked = ^(){ + [weakSelf userIconClicked]; //用户头像点击 + }; + _userInfoCell.fansCountBtnClicked = ^(){ + [weakSelf fansCountBtnClicked]; //粉丝 }; - _headerView.fansCountBtnClicked = ^(){ - [weakSelf fansCountBtnClicked]; + _userInfoCell.followsCountBtnClicked = ^(){ + [weakSelf followsCountBtnClicked]; //关注 }; - _headerView.followsCountBtnClicked = ^(){ - [weakSelf followsCountBtnClicked]; + _userInfoCell.followBtnClicked = ^(){ + [weakSelf followBtnClicked]; //加关注 }; - _headerView.followBtnClicked = ^(){ - [weakSelf followBtnClicked]; + _userInfoCell.editButtonClicked = ^() { + [weakSelf goToSettingInfo]; + }; + _userInfoCell.messageBtnClicked = ^(){ + [weakSelf messageBtnClicked]; //发消息 + }; + + _userInfoCell.detailInfoBtnClicked = ^(){ + [weakSelf goToDetailInfo]; //详情 }; - [_myTableView addParallaxWithView:_headerView andHeight:CGRectGetHeight(_headerView.frame)]; - _myTableView.tableFooterView = [self footerV]; + + + [[Coding_NetAPIManager sharedManager] request_Users_activenessWithGlobalKey:_curUser.global_key andBlock:^(ActivenessModel *data, NSError *error) { + weakSelf.activenessModel = data; + [weakSelf.myTableView reloadData]; + }]; + _refreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; [_refreshControl addTarget:self action:@selector(refresh) forControlEvents:UIControlEventValueChanged]; @@ -95,7 +117,7 @@ - (void)refresh{ [weakSelf.refreshControl endRefreshing]; if (data) { weakSelf.curUser = data; - weakSelf.headerView.curUser = data; + weakSelf.userInfoCell.user = data; weakSelf.title = weakSelf.curUser.name; [weakSelf.myTableView reloadData]; } @@ -112,38 +134,23 @@ - (UIView *)footerV{ #pragma mark Table M - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ - return 2; + return 3; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ - return section == 0? 4: 3; + return section <= 1? 1: 3; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ if (indexPath.section == 0) { - if (indexPath.row < 3) { - UserInfoTextCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_UserInfoTextCell forIndexPath:indexPath]; - switch (indexPath.row) { - case 0: - [cell setTitle:@"所在地" value:_curUser.location]; - break; - case 1: - [cell setTitle:@"座右铭" value:_curUser.slogan]; - break; - default: - [cell setTitle:@"个性标签" value:_curUser.tags_str]; - break; - } - [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; - return cell; - }else{ - TitleDisclosureCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_TitleDisclosure forIndexPath:indexPath]; - cell.titleLabel.font = [UIFont systemFontOfSize:15]; - cell.backgroundColor = [UIColor whiteColor]; - [cell setTitleStr:@"详细信息"]; - [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; - return cell; - } + EaseUserInfoCell *cell = self.userInfoCell; + cell.user = _curUser; + return cell; + } else if (indexPath.section == 1) { + UserActiveGraphCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_UserActiveGraphCell forIndexPath:indexPath]; + cell.activenessModel = _activenessModel; + return cell; + }else{ UserInfoIconCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_UserInfoIconCell forIndexPath:indexPath]; if (indexPath.row == 0) { @@ -159,7 +166,11 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ - return 44.0; + if (indexPath.section == 0) { + return [tableView cellHeightForIndexPath:indexPath model:_curUser keyPath:@"user" cellClass:[EaseUserInfoCell class] contentViewWidth:kScreen_Width]; + + } + return indexPath.section == 1 ? [UserActiveGraphCell cellHeight] : 44; } - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ @@ -177,9 +188,7 @@ - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ [tableView deselectRowAtIndexPath:indexPath animated:YES]; - if (indexPath.section == 0 && indexPath.row == 3) { - [self goToDetailInfo]; - }else if (indexPath.section == 1){ + if (indexPath.section == 2){ if (indexPath.row == 0) { [self goToProjects]; }else if(indexPath.row == 1){ @@ -229,7 +238,7 @@ - (void)followBtnClicked{ [[Coding_NetAPIManager sharedManager] request_FollowedOrNot_WithObj:_curUser andBlock:^(id data, NSError *error) { if (data) { weakSelf.curUser.followed = [NSNumber numberWithBool:!_curUser.followed.boolValue]; - weakSelf.headerView.curUser = weakSelf.curUser; + weakSelf.userInfoCell.user = weakSelf.curUser; if (weakSelf.followChanged) { weakSelf.followChanged(weakSelf.curUser); } @@ -237,6 +246,11 @@ - (void)followBtnClicked{ }]; } +- (void)goToSettingInfo{ + SettingMineInfoViewController *vc = [[SettingMineInfoViewController alloc] init]; + [self.navigationController pushViewController:vc animated:YES]; +} + - (void)goToTweets{ UserOrProjectTweetsViewController *vc = [[UserOrProjectTweetsViewController alloc] init]; vc.curTweets = [Tweets tweetsWithUser:_curUser]; diff --git a/Coding_iOS/Controllers/UserOrProjectTweetsViewController.m b/Coding_iOS/Controllers/UserOrProjectTweetsViewController.m index 391d3c96b..a1175f7d0 100755 --- a/Coding_iOS/Controllers/UserOrProjectTweetsViewController.m +++ b/Coding_iOS/Controllers/UserOrProjectTweetsViewController.m @@ -17,7 +17,8 @@ #import "SVPullToRefresh.h" #import "WebViewController.h" #import "ProjectTweetSendViewController.h" -#import "EaseUserHeaderView.h" +#import "UserActiveGraphCell.h" + @interface UserOrProjectTweetsViewController () @property (nonatomic, strong, readwrite) UITableView *myTableView; @@ -53,7 +54,7 @@ - (void)viewDidLoad if (_curTweets.tweetType == TweetTypeUserSingle) { self.title = _curTweets.curUser.name; }else if (_curTweets.tweetType == TweetTypeProject){ - self.title = _curTweets.curPro.name ?: @"项目内冒泡"; + self.title = @"公告列表"; self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"addBtn_Nav"] style:UIBarButtonItemStylePlain target:self action:@selector(addBtnClicked)]; }else{ self.title = @"冒泡列表"; @@ -72,6 +73,9 @@ - (void)viewDidLoad [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _refreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; @@ -81,10 +85,15 @@ - (void)viewDidLoad __weak typeof(self) weakSelf = self; _myMsgInputView = [UIMessageInputView messageInputViewWithType:UIMessageInputViewContentTypeTweet]; _myMsgInputView.delegate = self; + _myMsgInputView.curProject = _curTweets.curPro; [_myTableView addInfiniteScrollingWithActionHandler:^{ [weakSelf refreshMore]; }]; +} + +- (void)viewWillAppear:(BOOL)animated{ + [super viewWillAppear:animated]; [self refresh]; } @@ -129,7 +138,7 @@ - (void)messageInputView:(UIMessageInputView *)inputView sendText:(NSString *)te - (void)messageInputView:(UIMessageInputView *)inputView heightToBottomChenged:(CGFloat)heightToBottom{ [UIView animateWithDuration:0.25 delay:0.0f options:UIViewAnimationOptionTransitionFlipFromBottom animations:^{ UIEdgeInsets contentInsets= UIEdgeInsetsMake(0.0, 0.0, heightToBottom, 0.0);; - CGFloat msgInputY = kScreen_Height - heightToBottom - 64; + CGFloat msgInputY = kScreen_Height - heightToBottom - (44 + kSafeArea_Top); self.myTableView.contentInset = contentInsets; self.myTableView.scrollIndicatorInsets = contentInsets; @@ -145,6 +154,13 @@ - (void)messageInputView:(UIMessageInputView *)inputView heightToBottomChenged:( #pragma mark M +- (EaseBlankPageType)blankType{ + EaseBlankPageType blankType = ([[Login curLoginUser] isSameToUser:self.curTweets.curUser]? EaseBlankPageTypeTweet: + _curTweets.tweetType == TweetTypeProject? EaseBlankPageTypeTweetProject: + EaseBlankPageTypeTweetOther); + return blankType; +} + - (void)deleteTweet:(Tweet *)curTweet outTweetsIndex:(NSInteger)outTweetsIndex{ ESWeakSelf; [[Coding_NetAPIManager sharedManager] request_Tweet_Delete_WithObj:curTweet andBlock:^(id data, NSError *error) { @@ -152,7 +168,8 @@ - (void)deleteTweet:(Tweet *)curTweet outTweetsIndex:(NSInteger)outTweetsIndex{ if (data) { [_self.curTweets.list removeObject:curTweet]; [_self.myTableView reloadData]; - [_self.view configBlankPage:([[Login curLoginUser] isSameToUser:_self.curTweets.curUser]? EaseBlankPageTypeTweet: EaseBlankPageTypeTweetOther) hasData:(_self.curTweets.list.count > 0) hasError:NO offsetY:[_self blankPageOffsetY] reloadButtonBlock:^(id sender) { + + [_self.view configBlankPage:[_self blankType] hasData:(_self.curTweets.list.count > 0) hasError:NO offsetY:[_self blankPageOffsetY] reloadButtonBlock:^(id sender) { ESStrongSelf; [_self sendRequest]; }]; @@ -190,34 +207,35 @@ - (void)refreshMore{ } - (void)sendRequest{ - if (_curTweets.list.count <= 0) { - [self.view beginLoading]; + if (self.curTweets.list.count <= 0) { + [self.myTableView beginLoading]; } if (_curTweets.tweetType == TweetTypeUserSingle && _curTweets.curUser.name.length <= 0) { [self refreshCurUser]; - return; - } - - __weak typeof(self) weakSelf = self; - [[Coding_NetAPIManager sharedManager] request_Tweets_WithObj:_curTweets andBlock:^(id data, NSError *error) { - [weakSelf.refreshControl endRefreshing]; - [weakSelf.view endLoading]; - [weakSelf.myTableView.infiniteScrollingView stopAnimating]; - if (data) { - [weakSelf.curTweets configWithTweets:data]; - [weakSelf.myTableView reloadData]; - weakSelf.myTableView.showsInfiniteScrolling = weakSelf.curTweets.canLoadMore; - } - [weakSelf.view configBlankPage:([[Login curLoginUser] isSameToUser:self.curTweets.curUser]? EaseBlankPageTypeTweet: EaseBlankPageTypeTweetOther) hasData:(weakSelf.curTweets.list.count > 0) hasError:(error != nil) offsetY:[weakSelf blankPageOffsetY] reloadButtonBlock:^(id sender) { - [weakSelf sendRequest]; + }else if (_curTweets.tweetType == TweetTypeProject && ![_curTweets.curPro.id isKindOfClass:[NSNumber class]]){ + [self refreshCurPro]; + }else{ + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_Tweets_WithObj:_curTweets andBlock:^(id data, NSError *error) { + [weakSelf.myTableView endLoading]; + [weakSelf.refreshControl endRefreshing]; + [weakSelf.myTableView.infiniteScrollingView stopAnimating]; + if (data) { + [weakSelf.curTweets configWithTweets:data]; + [weakSelf.myTableView reloadData]; + weakSelf.myTableView.showsInfiniteScrolling = weakSelf.curTweets.canLoadMore; + } + [weakSelf.view configBlankPage:[weakSelf blankType] hasData:(weakSelf.curTweets.list.count > 0) hasError:(error != nil) offsetY:[weakSelf blankPageOffsetY] reloadButtonBlock:^(id sender) { + [weakSelf sendRequest]; + }]; }]; - }]; + } } - (CGFloat)blankPageOffsetY{//MeDisplayViewController CGFloat offsetY = 0; if ([self isMemberOfClass:NSClassFromString(@"MeDisplayViewController")]) { - offsetY = [(EaseUserHeaderView *)[self valueForKey:@"eaV"] originalHeight] + 60; + offsetY = ((UITableViewCell *)[self valueForKey:@"userInfoCell"]).frame.size.height + [UserActiveGraphCell cellHeight] + 80; } return offsetY; } @@ -230,14 +248,29 @@ - (void)refreshCurUser{ weakSelf.title = weakSelf.curTweets.curUser.name; [weakSelf sendRequest]; }else{ - [weakSelf.view endLoading]; - [weakSelf.view configBlankPage:([[Login curLoginUser] isSameToUser:self.curTweets.curUser]? EaseBlankPageTypeTweet: EaseBlankPageTypeTweetOther) hasData:(weakSelf.curTweets.list.count > 0) hasError:YES offsetY:[weakSelf blankPageOffsetY] reloadButtonBlock:^(id sender) { + [weakSelf.myTableView endLoading]; + [weakSelf.view configBlankPage:[weakSelf blankType] hasData:(weakSelf.curTweets.list.count > 0) hasError:YES offsetY:[weakSelf blankPageOffsetY] reloadButtonBlock:^(id sender) { [weakSelf sendRequest]; }]; } }]; } +- (void)refreshCurPro{ + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_ProjectDetail_WithObj:_curTweets.curPro andBlock:^(id data, NSError *error) { + if (data) { + weakSelf.curTweets.curPro = data; + weakSelf.title = weakSelf.curTweets.curPro.name; + [weakSelf sendRequest]; + }else{ + [weakSelf.myTableView endLoading]; + [weakSelf.view configBlankPage:[weakSelf blankType] hasData:(weakSelf.curTweets.list.count > 0) hasError:YES offsetY:[weakSelf blankPageOffsetY] reloadButtonBlock:^(id sender) { + [weakSelf sendRequest]; + }]; + } + }]; +} #pragma mark TableM - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ @@ -266,7 +299,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N if ([Login isLoginUserGlobalKey:weakSelf.commentToUser.global_key]) { - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"删除此评论" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + UIAlertController *actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"删除此评论" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0 && weakSelf.commentIndex >= 0) { Comment *comment = [weakSelf.commentTweet.comment_list objectAtIndex:weakSelf.commentIndex]; [weakSelf deleteComment:comment ofTweet:weakSelf.commentTweet]; @@ -284,9 +317,15 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N [weakSelf.myTableView reloadData]; }; cell.userBtnClickedBlock = ^(User *curUser){ - UserInfoViewController *vc = [[UserInfoViewController alloc] init]; - vc.curUser = curUser; - [self.navigationController pushViewController:vc animated:YES]; + if (kTarget_Enterprise) { + UserInfoDetailViewController *vc = [UserInfoDetailViewController new]; + vc.curUser = curUser; + [self.navigationController pushViewController:vc animated:YES]; + }else{ + UserInfoViewController *vc = [[UserInfoViewController alloc] init]; + vc.curUser = curUser; + [self.navigationController pushViewController:vc animated:YES]; + } }; cell.moreLikersBtnClickedBlock = ^(Tweet *curTweet){ LikersViewController *vc = [[LikersViewController alloc] init]; @@ -299,7 +338,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } self.deleteTweet = curTweet; self.deleteTweetsIndex = outTweetsIndex; - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"删除此冒泡" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + UIAlertController *actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:curTweet.isProjectTweet? @"删除此公告": @"删除此冒泡" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf deleteTweet:weakSelf.deleteTweet outTweetsIndex:weakSelf.deleteTweetsIndex]; } @@ -325,6 +364,8 @@ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPa } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + Tweet *toTweet = [_curTweets.list objectAtIndex:indexPath.row]; [self goToDetailWithTweet:toTweet]; } @@ -333,11 +374,12 @@ - (void)goToDetailWithTweet:(Tweet *)curTweet{ curTweet.project = _curTweets.curPro; TweetDetailViewController *vc = [[TweetDetailViewController alloc] init]; vc.curTweet = curTweet; + vc.curProject = _curTweets.curPro; __weak typeof(self) weakSelf = self; vc.deleteTweetBlock = ^(Tweet *toDeleteTweet){ [weakSelf.curTweets.list removeObject:toDeleteTweet]; [weakSelf.myTableView reloadData]; - [weakSelf.view configBlankPage:([[Login curLoginUser] isSameToUser:self.curTweets.curUser]? EaseBlankPageTypeTweet: EaseBlankPageTypeTweetOther) hasData:(weakSelf.curTweets.list.count > 0) hasError:NO offsetY:[weakSelf blankPageOffsetY] reloadButtonBlock:^(id sender) { + [weakSelf.view configBlankPage:[weakSelf blankType] hasData:(weakSelf.curTweets.list.count > 0) hasError:NO offsetY:[weakSelf blankPageOffsetY] reloadButtonBlock:^(id sender) { [weakSelf sendRequest]; }]; }; diff --git a/Coding_iOS/Controllers/UsersViewController.m b/Coding_iOS/Controllers/UsersViewController.m index 0aeaeb65d..236ec59fe 100755 --- a/Coding_iOS/Controllers/UsersViewController.m +++ b/Coding_iOS/Controllers/UsersViewController.m @@ -59,9 +59,12 @@ - (void)viewDidLoad{ case UsersTypeFriends_Message: self.title = @"我的好友"; break; + case UsersType_CompanyMember: + self.title = @"企业成员"; + break; case UsersTypeFriends_At: case UsersTypeFriends_Transpond:{ - self.title = @"我的好友"; + self.title = kTarget_Enterprise? @"企业成员": @"我的好友"; self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"取消" style:UIBarButtonItemStylePlain target:self action:@selector(dismissSelf)]; } break; @@ -89,13 +92,16 @@ - (void)viewDidLoad{ [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _mySearchBar = ({ UISearchBar *searchBar = [[UISearchBar alloc] init]; searchBar.delegate = self; [searchBar sizeToFit]; - [searchBar setPlaceholder:@"昵称/个性后缀"]; + [searchBar setPlaceholder:@"昵称/用户名"]; searchBar; }); _myTableView.tableHeaderView = _mySearchBar; @@ -169,6 +175,9 @@ - (void)sendRequest{ [weakSelf.myTableView.infiniteScrollingView stopAnimating]; if (data) { [weakSelf.curUsers configWithObj:data]; + if (weakSelf.curUsers.type == UsersType_CompanyMember) {//发私信,移除自己 + [weakSelf.curUsers removeLoginUserFromList]; + } weakSelf.groupedDict = [weakSelf.curUsers dictGroupedByPinyin]; [weakSelf.myTableView reloadData]; @@ -327,6 +336,10 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath vc.type = AddUserTypeFollow; [self.navigationController pushViewController:vc animated:YES]; } + }else if (_curUsers.type == UsersType_CompanyMember){ + ConversationViewController *vc = [[ConversationViewController alloc] init]; + vc.myPriMsgs = [PrivateMessages priMsgsWithUser:user]; + [self.navigationController pushViewController:vc animated:YES]; }else if (_curUsers.type == UsersTypeFriends_At){ [self dismissViewControllerAnimated:YES completion:^{ if (weakSelf.selectUserBlock) { @@ -334,38 +347,33 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath } }]; }else if (_curUsers.type == UsersTypeFriends_Transpond){ - UIAlertView *alertView = [UIAlertView bk_alertViewWithTitle:@"确定发送给:" message:user.name]; - [alertView bk_setCancelButtonWithTitle:@"取消" handler:nil]; - [alertView bk_addButtonWithTitle:@"确定" handler:nil]; - [alertView bk_setDidDismissBlock:^(UIAlertView *alert, NSInteger index) { - switch (index) { - case 1: - { - [weakSelf dismissViewControllerAnimated:YES completion:^{ - if (weakSelf.transpondMessageBlock) { - PrivateMessage *nextMsg = [PrivateMessage privateMessageWithObj:weakSelf.curMessage andFriend:user]; - weakSelf.transpondMessageBlock(nextMsg); - } - }]; - } - break; - default: - break; + [[UIAlertController ea_alertViewWithTitle:@"确定发送给:" message:user.name buttonTitles:@[@"确定"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { + [weakSelf dismissViewControllerAnimated:YES completion:^{ + if (weakSelf.transpondMessageBlock) { + PrivateMessage *nextMsg = [PrivateMessage privateMessageWithObj:weakSelf.curMessage andFriend:user]; + weakSelf.transpondMessageBlock(nextMsg); + } + }]; } - }]; - [alertView show]; + }] show]; }else{ - UserInfoViewController *vc = [[UserInfoViewController alloc] init]; - vc.curUser = user; - vc.followChanged = ^(User *curUser){ - user.followed = curUser.followed; - [weakSelf.myTableView reloadData]; - }; - [self.navigationController pushViewController:vc animated:YES]; + if (kTarget_Enterprise) { + UserInfoDetailViewController *vc = [UserInfoDetailViewController new]; + vc.curUser = user; + [self.navigationController pushViewController:vc animated:YES]; + }else{ + UserInfoViewController *vc = [[UserInfoViewController alloc] init]; + vc.curUser = user; + vc.followChanged = ^(User *curUser){ + user.followed = curUser.followed; + [weakSelf.myTableView reloadData]; + }; + [self.navigationController pushViewController:vc animated:YES]; + } } } - #pragma mark UISearchBarDelegate - (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar{ [searchBar insertBGColor:kColorNavBG]; diff --git a/Coding_iOS/Controllers/ValueListViewController.h b/Coding_iOS/Controllers/ValueListViewController.h index e9ca06df7..b6ed05d70 100755 --- a/Coding_iOS/Controllers/ValueListViewController.h +++ b/Coding_iOS/Controllers/ValueListViewController.h @@ -12,7 +12,8 @@ typedef NS_ENUM(NSInteger, ValueListType) { ValueListTypeTaskStatus = 0, ValueListTypeTaskPriority, - ValueListTypeProjectMemberType + ValueListTypeProjectMemberType, + ValueListTypeTeamMemberType }; typedef void(^IndexSelectedBlock)(NSInteger index); diff --git a/Coding_iOS/Controllers/ValueListViewController.m b/Coding_iOS/Controllers/ValueListViewController.m index e4f34fe83..a01c41b77 100755 --- a/Coding_iOS/Controllers/ValueListViewController.m +++ b/Coding_iOS/Controllers/ValueListViewController.m @@ -8,6 +8,7 @@ #import "ValueListViewController.h" #import "ValueListCell.h" +#import "ProjectTypeExplanationViewController.h" @interface ValueListViewController () @property (strong, nonatomic) UITableView *myTableView; @@ -47,6 +48,9 @@ - (void)viewDidLoad [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); if (self.type == ValueListTypeProjectMemberType) { @@ -82,14 +86,11 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N row = self.dataList.count-1 -row; } switch (_type) { - case ValueListTypeTaskStatus: - case ValueListTypeProjectMemberType: - [cell setTitleStr:[_dataList objectAtIndex:row] imageStr:nil isSelected:(_selectedIndex == row)]; - break; case ValueListTypeTaskPriority: [cell setTitleStr:[_dataList objectAtIndex:row] imageStr:[NSString stringWithFormat:@"taskPriority%ld", (long)row] isSelected:(_selectedIndex == row)]; break; default: + [cell setTitleStr:[_dataList objectAtIndex:row] imageStr:nil isSelected:(_selectedIndex == row)]; break; } [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:10]; @@ -118,16 +119,27 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath } self.selectedIndex = value; - if (_type == ValueListTypeTaskPriority || _type == ValueListTypeTaskStatus) { +// if (_type == ValueListTypeTaskPriority || _type == ValueListTypeTaskStatus) { [self.navigationController popViewControllerAnimated:YES]; - if (_selectBlock) { - _selectBlock(self.selectedIndex); - } - }else{ - [self.myTableView reloadData]; - } +// 在 viewWillDisappear 有 _selectBlock 了已经 +// if (_selectBlock) { +// _selectBlock(self.selectedIndex); +// } +// }else{ +// [self.myTableView reloadData]; +// } } +#ifdef Target_Enterprise + +#pragma mark - Tip +- (void)showMemberTypeTip{ + ProjectTypeExplanationViewController *vc = [ProjectTypeExplanationViewController new]; + [self.navigationController pushViewController:vc animated:YES]; +} + +#else + #pragma mark - Tip - (void)showMemberTypeTip{ if (self.tipView) { @@ -195,4 +207,6 @@ - (void)dismissTipView{ }]; } +#endif + @end diff --git a/Coding_iOS/Controllers/WebViewController.m b/Coding_iOS/Controllers/WebViewController.m index 2249d09c0..800148517 100644 --- a/Coding_iOS/Controllers/WebViewController.m +++ b/Coding_iOS/Controllers/WebViewController.m @@ -76,9 +76,11 @@ - (void)viewDidLoad{ CGRect barFrame = CGRectMake(0, navigaitonBarBounds.size.height - progressBarHeight, navigaitonBarBounds.size.width, progressBarHeight); _progressView = [[NJKWebViewProgressView alloc] initWithFrame:barFrame]; _progressView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin; - _progressView.progressBarView.backgroundColor = [UIColor colorWithHexString:@"0x3abd79"]; - - [self.navigationItem setRightBarButtonItem:[[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"moreBtn_Nav"] style:UIBarButtonItemStylePlain target:self action:@selector(shareItemClicked)] animated:YES]; + _progressView.progressBarView.backgroundColor = kColorLightBlue; + + if (!kTarget_Enterprise) {//企业版不支持分享 + [self.navigationItem setRightBarButtonItem:[[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"moreBtn_Nav"] style:UIBarButtonItemStylePlain target:self action:@selector(shareItemClicked)] animated:YES]; + } } - (void)viewWillAppear:(BOOL)animated{ diff --git a/Coding_iOS/Controllers/WikiEditViewController.h b/Coding_iOS/Controllers/WikiEditViewController.h new file mode 100644 index 000000000..183f299b5 --- /dev/null +++ b/Coding_iOS/Controllers/WikiEditViewController.h @@ -0,0 +1,17 @@ +// +// WikiEditViewController.h +// Coding_Enterprise_iOS +// +// Created by Easeeeeeeeee on 2017/4/7. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "BaseViewController.h" +#import "EAWiki.h" +#import "Project.h" + +@interface WikiEditViewController : BaseViewController +@property (nonatomic, strong) Project *myProject; +@property (strong, nonatomic) EAWiki *curWiki; +- (void)saveWikiDraft; +@end diff --git a/Coding_iOS/Controllers/WikiEditViewController.m b/Coding_iOS/Controllers/WikiEditViewController.m new file mode 100644 index 000000000..d49ebb56f --- /dev/null +++ b/Coding_iOS/Controllers/WikiEditViewController.m @@ -0,0 +1,320 @@ +// +// WikiEditViewController.m +// Coding_Enterprise_iOS +// +// Created by Easeeeeeeeee on 2017/4/7. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "WikiEditViewController.h" +#import "Coding_NetAPIManager.h" +#import "WebContentManager.h" +#import "WikiHeaderView.h" +#import "EaseMarkdownTextView.h" +#import "UIViewController+BackButtonHandler.h" + + +@interface WikiEditViewController () +@property (strong, nonatomic) UISegmentedControl *segmentedControl; +@property (assign, nonatomic) NSInteger curIndex; + +@property (strong, nonatomic) UIWebView *preview; +@property (strong, nonatomic) UIActivityIndicatorView *activityIndicator; +@property (strong, nonatomic) WikiHeaderView *headerV; + +@property (strong, nonatomic) UIView *editView; +@property (strong, nonatomic) UITextField *inputTitleView; +@property (strong, nonatomic) EaseMarkdownTextView *inputContentView; +@property (strong, nonatomic) UIView *lineView; + +@end + +@implementation WikiEditViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + self.view.backgroundColor = kColorTableBG; + if (!_segmentedControl) { + _segmentedControl = ({ + UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:@[@"编辑", @"预览"]]; + [segmentedControl setWidth:80 forSegmentAtIndex:0]; + [segmentedControl setWidth:80 forSegmentAtIndex:1]; + [segmentedControl setTitleTextAttributes:@{ + NSFontAttributeName: [UIFont systemFontOfSize:16], + NSForegroundColorAttributeName: [UIColor whiteColor] + } + forState:UIControlStateSelected]; + [segmentedControl setTitleTextAttributes:@{ + NSFontAttributeName: [UIFont systemFontOfSize:16], + NSForegroundColorAttributeName: kColorNavTitle + } forState:UIControlStateNormal]; + [segmentedControl addTarget:self action:@selector(segmentedControlSelected:) forControlEvents:UIControlEventValueChanged]; + segmentedControl; + }); + + self.navigationItem.titleView = _segmentedControl; + } + + [self.navigationItem setRightBarButtonItem:[UIBarButtonItem itemWithBtnTitle:@"保存" target:self action:@selector(saveBtnClicked)] animated:YES]; + self.navigationItem.rightBarButtonItem.enabled = NO; + + [[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillChangeFrameNotification object:nil] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(NSNotification *aNotification) { + if (self.inputContentView) { + NSDictionary* userInfo = [aNotification userInfo]; + CGRect keyboardEndFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; + self.inputContentView.contentInset = UIEdgeInsetsMake(0, 0, CGRectGetHeight(keyboardEndFrame), 0); + self.inputContentView.scrollIndicatorInsets = self.inputContentView.contentInset; + } + }]; + + self.curIndex = 0; + if ([self.curWiki hasDraft]) { + BOOL versionChanged = [self.curWiki draftVersionChanged]; + __weak typeof(self) weakSelf = self; + [[UIAlertController ea_alertViewWithTitle:@"提示" message:versionChanged? @"有最新版本更新,您是否继续编辑上次保存的草稿?": @"是否启用上次保存的草稿?" buttonTitles:@[@"编辑草稿"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { + [weakSelf.curWiki readDraft]; + [weakSelf refreshUI]; + }else{ + [weakSelf.curWiki deleteDraft]; + } + }] show]; + } +} + +- (void)refreshUI{ + self.inputTitleView.text = self.curWiki.mdTitle; + self.inputContentView.text = self.curWiki.mdContent; + if (_curIndex == 1) { + [self loadPreview]; + } +} + +- (void)viewDidAppear:(BOOL)animated{ + [super viewDidAppear:animated]; + if (_curIndex == 0) { + [self loadEditView]; + } else { + [self loadPreview]; + } + //禁用屏幕左滑返回手势 + if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) { + self.navigationController.interactivePopGestureRecognizer.enabled = NO; + } +} + +- (void)viewDidDisappear:(BOOL)animated { + [super viewDidDisappear:animated]; + //开启屏幕左滑返回手势 + if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) { + self.navigationController.interactivePopGestureRecognizer.enabled = YES; + } +} + +- (BOOL)navigationShouldPopOnBackButton{ + self.curWiki.mdTitle = _inputTitleView.text; + self.curWiki.mdContent = _inputContentView.text; + if ([self.curWiki hasChanged]) { + __weak typeof(self) weakSelf = self; + [[UIAlertController ea_alertViewWithTitle:@"提示" message:@"是否需要保存草稿?" buttonTitles:@[@"保存"] destructiveTitle:nil cancelTitle:@"不保存" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { + [weakSelf.curWiki saveDraft]; + }else{ + [weakSelf.curWiki deleteDraft]; + } + [weakSelf.navigationController popViewControllerAnimated:YES]; + }] show]; + return NO; + }else{ + return YES; + } +} + +- (void)saveWikiDraft{ + self.curWiki.mdTitle = _inputTitleView.text; + self.curWiki.mdContent = _inputContentView.text; + if ([self.curWiki hasChanged]) { + [self.curWiki saveDraft]; + } +} + +#pragma mark UISegmentedControl +- (void)segmentedControlSelected:(id)sender{ + UISegmentedControl *segmentedControl = (UISegmentedControl *)sender; + self.curIndex = segmentedControl.selectedSegmentIndex; +} + +#pragma mark index_view +- (void)setCurIndex:(NSInteger)curIndex{ + _curIndex = curIndex; + if (_segmentedControl.selectedSegmentIndex != curIndex) { + [_segmentedControl setSelectedSegmentIndex:_curIndex]; + } + + if (_curIndex == 0) { + [self loadEditView]; + } else { + [self loadPreview]; + } +} + +#pragma mark PreView + +- (void)loadPreview{ + if (!_preview) { + _preview = [[UIWebView alloc] initWithFrame:self.view.bounds]; + _preview.delegate = self; + _preview.backgroundColor = [UIColor clearColor]; + _preview.opaque = NO; + _preview.scalesPageToFit = YES; + [self.view addSubview:_preview]; + //webview加载指示 + _activityIndicator = [[UIActivityIndicatorView alloc] + initWithActivityIndicatorStyle: + UIActivityIndicatorViewStyleGray]; + _activityIndicator.hidesWhenStopped = YES; + [_activityIndicator setCenter:CGPointMake(CGRectGetWidth(_preview.frame)/2, CGRectGetHeight(_preview.frame)/2)]; + [_preview addSubview:_activityIndicator]; + [_preview mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; + if (!_headerV) { + _headerV = [WikiHeaderView new]; + _headerV.isForEdit = YES; + [_preview.scrollView addSubview:_headerV]; + } + } + self.curWiki.mdTitle = _inputTitleView.text; + self.curWiki.mdContent = _inputContentView.text; + + _headerV.curWiki = _curWiki; + _preview.scrollView.contentInset = UIEdgeInsetsMake(_headerV.height, 0, 0, 0); + + _preview.hidden = NO; + _editView.hidden = YES; + [self.view endEditing:YES]; + [self previewLoadMDData]; +} + +- (void)previewLoadMDData{ + NSString *mdStr = self.curWiki.mdContent; + @weakify(self); + [[Coding_NetAPIManager sharedManager] request_MDHtmlStr_WithMDStr:mdStr inProject:self.myProject andBlock:^(id data, NSError *error) { + @strongify(self); + NSString *htmlStr = data? data : error.description; + NSString *contentStr = [WebContentManager wikiPatternedWithContent:htmlStr]; + [self.preview loadHTMLString:contentStr baseURL:nil]; + }]; +} +#pragma mark EditView + + +- (void)loadEditView{ + if (!_editView) { + //控件 + _editView = [[UIView alloc] initWithFrame:self.view.bounds]; + [self.view addSubview:_editView]; + + _inputTitleView = [UITextField new]; + _inputTitleView.textColor = kColor222; + _inputTitleView.font = [UIFont systemFontOfSize:18]; + [_editView addSubview:_inputTitleView]; + + _lineView = [UIView new]; + _lineView.backgroundColor = kColorDDD; + [_editView addSubview:_lineView]; + + _inputContentView = [[EaseMarkdownTextView alloc] initWithFrame:CGRectZero]; + _inputContentView.curProject = self.myProject; + _inputContentView.textColor = kColor222; + _inputContentView.placeholder = @"页面内容"; + _inputContentView.backgroundColor = [UIColor clearColor]; + _inputContentView.font = [UIFont systemFontOfSize:15]; + _inputContentView.textContainerInset = UIEdgeInsetsMake(10, kPaddingLeftWidth - 5, 8, kPaddingLeftWidth - 5); + [_editView addSubview:_inputContentView]; + + [self.view addSubview:_editView]; + // 布局 + [_editView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; + [_inputTitleView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(_editView.mas_top).offset(10.0); + make.height.mas_equalTo(30); + make.left.equalTo(_editView).offset(kPaddingLeftWidth); + make.right.equalTo(_editView).offset(-kPaddingLeftWidth); + }]; + [_lineView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(_inputTitleView.mas_bottom).offset(12.0); + make.left.equalTo(_editView).offset(kPaddingLeftWidth); + make.height.mas_equalTo(1.0); + make.right.equalTo(_editView); + }]; + [_inputContentView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(_lineView.mas_bottom).offset(5.0); + make.left.right.bottom.equalTo(_editView); + }]; + // 内容 + @weakify(self); + RAC(self.navigationItem.rightBarButtonItem, enabled) = [RACSignal combineLatest:@[self.inputTitleView.rac_textSignal, + self.inputContentView.rac_textSignal] + reduce:^id (NSString *title, NSString *content) { + @strongify(self); + title = self.inputTitleView.text; + content = self.inputContentView.text; + BOOL enabled = ([title stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]].length > 0 + && (![title isEqualToString:self.curWiki.mdTitle] || ![content isEqualToString:self.curWiki.mdContent])); + return @(enabled); + }]; + _inputTitleView.text = _curWiki.mdTitle; + _inputContentView.text = _curWiki.mdContent; + } + _editView.hidden = NO; + _preview.hidden = YES; +} + +#pragma mark - click +- (void)saveBtnClicked{ + self.curWiki.mdTitle = _inputTitleView.text; + self.curWiki.mdContent = _inputContentView.text; + + self.navigationItem.rightBarButtonItem.enabled = NO; + [NSObject showHUDQueryStr:@"正在保存..."]; + @weakify(self); + [[Coding_NetAPIManager sharedManager] request_ModifyWiki:_curWiki pro:_myProject andBlock:^(id data, NSError *error) { + @strongify(self); + self.navigationItem.rightBarButtonItem.enabled = YES; + [NSObject hideHUDQuery]; + if (data) { + [NSObject showHudTipStr:@"保存成功"]; + [self.navigationController popViewControllerAnimated:YES]; + } + }]; +} + +#pragma mark UIWebViewDelegate +- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ + DebugLog(@"strLink=[%@]",request.URL.absoluteString); + UIViewController *vc = [BaseViewController analyseVCFromLinkStr:request.URL.absoluteString]; + if (vc) { + [self.navigationController pushViewController:vc animated:YES]; + return NO; + } + return YES; +} +- (void)webViewDidStartLoad:(UIWebView *)webView{ + [_activityIndicator startAnimating]; +} +- (void)webViewDidFinishLoad:(UIWebView *)webView{ + [_activityIndicator stopAnimating]; +} +- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{ + if([error code] == NSURLErrorCancelled) + return; + else + DebugLog(@"%@", error.description); +} + + +@end diff --git a/Coding_iOS/Controllers/WikiHistoryListViewController.h b/Coding_iOS/Controllers/WikiHistoryListViewController.h new file mode 100644 index 000000000..7fef4a06a --- /dev/null +++ b/Coding_iOS/Controllers/WikiHistoryListViewController.h @@ -0,0 +1,17 @@ +// +// WikiHistoryListViewController.h +// Coding_Enterprise_iOS +// +// Created by Easeeeeeeeee on 2017/4/7. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "BaseViewController.h" +#import "EAWiki.h" +#import "Project.h" + +@interface WikiHistoryListViewController : BaseViewController +@property (nonatomic, strong) Project *myProject; +@property (strong, nonatomic) EAWiki *curWiki; + +@end diff --git a/Coding_iOS/Controllers/WikiHistoryListViewController.m b/Coding_iOS/Controllers/WikiHistoryListViewController.m new file mode 100644 index 000000000..469761de8 --- /dev/null +++ b/Coding_iOS/Controllers/WikiHistoryListViewController.m @@ -0,0 +1,116 @@ +// +// WikiHistoryListViewController.m +// Coding_Enterprise_iOS +// +// Created by Easeeeeeeeee on 2017/4/7. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "WikiHistoryListViewController.h" +#import "WikiHistoryCell.h" +#import "ODRefreshControl.h" +#import "Coding_NetAPIManager.h" +#import "WikiViewController.h" + +@interface WikiHistoryListViewController () +@property (strong, nonatomic) UITableView *myTableView; +@property (strong, nonatomic) ODRefreshControl *myRefreshControl; + +@property (strong, nonatomic) NSArray *historyList; +@end + +@implementation WikiHistoryListViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + self.title = @"历史版本"; + _myTableView = ({ + UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped]; + tableView.separatorStyle = UITableViewCellSeparatorStyleNone; +// tableView.backgroundColor = kColorTableBG; +// tableView.tableFooterView = [UIView new]; + tableView.delegate = self; + tableView.dataSource = self; + [tableView registerClass:[WikiHistoryCell class] forCellReuseIdentifier:kCellIdentifier_WikiHistoryCell]; + [self.view addSubview:tableView]; + [tableView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; + tableView; + }); + _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; + [_myRefreshControl addTarget:self action:@selector(refresh) forControlEvents:UIControlEventValueChanged]; + [self refresh]; +} + +- (void)refresh{ + if (_historyList.count <= 0) { + [self.view beginLoading]; + } + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_WikiHistoryWithWiki:_curWiki pro:_myProject andBlock:^(id data, NSError *error) { + [weakSelf.view endLoading]; + [weakSelf.myRefreshControl endRefreshing]; + if (data) { + weakSelf.historyList = data; + [weakSelf.myTableView reloadData]; + } + [weakSelf.view configBlankPage:EaseBlankPageTypeView hasData:(weakSelf.historyList.count > 0) hasError:(error != nil) reloadButtonBlock:^(id sender) { + [weakSelf refresh]; + }]; + }]; +} + + +#pragma mark Table Method + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ + return _historyList.count; +} + +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ + return [UIView new]; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ + return 15; +} + +- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{ + return [UIView new]; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ + return kLine_MinHeight; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + return 1; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + WikiHistoryCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_WikiHistoryCell forIndexPath:indexPath]; + cell.curWiki = _historyList[indexPath.section]; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:0]; + return cell; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ + return [WikiHistoryCell cellHeightWithObj:_historyList[indexPath.section]]; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + if (indexPath.section == _historyList.count - 1) { + [self.navigationController popViewControllerAnimated:YES]; + }else{ + EAWiki *wiki = _historyList[indexPath.section]; + WikiViewController *vc = [WikiViewController new]; + vc.myProject = _myProject; + [vc setWikiIid:_curWiki.iid version:wiki.version]; + [self.navigationController pushViewController:vc animated:YES]; + } +} + +@end diff --git a/Coding_iOS/Controllers/WikiViewController.h b/Coding_iOS/Controllers/WikiViewController.h new file mode 100644 index 000000000..7f2d7ec3a --- /dev/null +++ b/Coding_iOS/Controllers/WikiViewController.h @@ -0,0 +1,23 @@ +// +// WikiViewController.h +// Coding_Enterprise_iOS +// +// Created by Ease on 2017/4/5. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "BaseViewController.h" +#import "Project.h" +#import "EAWiki.h" + +@interface WikiViewController : BaseViewController +@property (nonatomic, strong) Project *myProject; +@property (strong, nonatomic, readonly) NSNumber *iid, *version; +- (void)setWikiIid:(NSNumber *)iid version:(NSNumber *)version; +@end + +@interface WikiFooterView : UIView +@property (strong, nonatomic) EAWiki *curWiki; +@property (readonly, nonatomic, strong) NSArray *menuBtnList; +@property (copy, nonatomic) void(^buttonClickedBlock)(NSInteger index); +@end diff --git a/Coding_iOS/Controllers/WikiViewController.m b/Coding_iOS/Controllers/WikiViewController.m new file mode 100644 index 000000000..43d6a3be9 --- /dev/null +++ b/Coding_iOS/Controllers/WikiViewController.m @@ -0,0 +1,529 @@ +// +// WikiViewController.m +// Coding_Enterprise_iOS +// +// Created by Ease on 2017/4/5. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "WikiViewController.h" +#import "Coding_NetAPIManager.h" +#import "WebContentManager.h" +#import "ODRefreshControl.h" +#import "WikiMenuListView.h" +#import "WikiHistoryListViewController.h" +#import "WikiEditViewController.h" +#import "WikiHeaderView.h" +#import "FunctionTipsManager.h" +#import "MartFunctionTipView.h" +#import "KxMenu.h" + +@interface WikiViewController () +@property (strong, nonatomic) UIWebView *webContentView; +@property (strong, nonatomic) UIActivityIndicatorView *activityIndicator; +@property (nonatomic, strong) ODRefreshControl *myRefreshControl; + +@property (strong, nonatomic, readwrite) NSNumber *iid, *version; +@property (strong, nonatomic) EAWiki *curWiki; +@property (strong, nonatomic) NSArray *wikiList; + +@property (strong, nonatomic) WikiHeaderView *headerV; +@property (strong, nonatomic) WikiFooterView *footerV; + +@property (strong, nonatomic) WikiMenuListView *menuListV; + +@property (assign, nonatomic) BOOL isShowingFunctionTip; +@end + +@implementation WikiViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + self.view.backgroundColor = kColorTableBG; + self.title = _myProject.name; + _version = _version ?: @(-1); + {//用webView显示内容 + _webContentView = [[UIWebView alloc] initWithFrame:self.view.bounds]; + _webContentView.delegate = self; + _webContentView.scrollView.delegate = self; + _webContentView.backgroundColor = [UIColor clearColor]; + _webContentView.opaque = NO; + _webContentView.scalesPageToFit = YES; + [self.view addSubview:_webContentView]; + //webview加载指示 + _activityIndicator = [[UIActivityIndicatorView alloc] + initWithActivityIndicatorStyle: + UIActivityIndicatorViewStyleGray]; + _activityIndicator.hidesWhenStopped = YES; + [_activityIndicator setCenter:CGPointMake(CGRectGetWidth(_webContentView.frame)/2, CGRectGetHeight(_webContentView.frame)/2)]; + [_webContentView addSubview:_activityIndicator]; + [_webContentView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; + } + _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:self.webContentView.scrollView]; + [_myRefreshControl addTarget:self action:@selector(refresh) forControlEvents:UIControlEventValueChanged]; + + [self addGesture]; + + [self.navigationItem setRightBarButtonItem:[[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"moreBtn_Nav"] style:UIBarButtonItemStylePlain target:self action:@selector(rightNavBtnClicked)] animated:NO]; +} + +- (void)setCurWiki:(EAWiki *)curWiki{ + _curWiki = curWiki; + if (_curWiki) { + _iid = _curWiki.iid ?: _iid; + }else{ + _iid = nil; + } + if (!_headerV) { + _headerV = [WikiHeaderView new]; + [_webContentView.scrollView addSubview:_headerV]; + } + if (!_footerV) { + __weak typeof(self) weakSelf = self; + _footerV = [WikiFooterView new]; + [self.view addSubview:_footerV]; + _footerV.buttonClickedBlock = ^(NSInteger index){ + [weakSelf handleFooterIndex:index]; + }; + _footerV.y = self.view.height - _footerV.height; + } + _headerV.curWiki = _footerV.curWiki = _curWiki; + _webContentView.scrollView.contentInset = UIEdgeInsetsMake(_headerV.height, 0, _footerV.height, 0); + +// //新功能提示 +// [self showMenuTip]; +} + +- (void)setWikiIid:(NSNumber *)iid version:(NSNumber *)version{ + _iid = iid; + _version = version; +} + +- (void)viewWillAppear:(BOOL)animated{ + [super viewWillAppear:animated]; + + [self refreshWikiList]; +} + +#pragma mark Gesture +- (void)addGesture{ + UISwipeGestureRecognizer *swipeG = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(showMenuListV)]; + swipeG.direction = UISwipeGestureRecognizerDirectionRight; + [self.view addGestureRecognizer:swipeG]; +} + +#pragma mark Tip + +//- (void)showMenuTip{ +// if (_footerV.menuBtnList.count < 3 || +// ![[FunctionTipsManager shareManager] needToTip:kFunctionTipStr_WikiMenu] || +// _isShowingFunctionTip) { +// return; +// } +// +// UIButton *originBtn = _footerV.menuBtnList[0]; +// CGRect fromFrame = [originBtn convertRect:originBtn.frame toView:self.view]; +// fromFrame.origin.y -= 3; +// +// _isShowingFunctionTip = YES; +// __weak typeof(self) weakSelf = self; +// [MartFunctionTipView showText:@"这里可查看页面目录" direction:AMPopTipDirectionUp bubbleOffset:35 inView:self.view fromFrame:fromFrame dismissHandler:^{ +// weakSelf.isShowingFunctionTip = NO; +// [[FunctionTipsManager shareManager] markTiped:kFunctionTipStr_WikiMenu]; +// [weakSelf showHistoryTip]; +// }]; +//} +// +//- (void)showHistoryTip{ +// if (_footerV.menuBtnList.count < 3 || +// ![[FunctionTipsManager shareManager] needToTip:kFunctionTipStr_WikiHistory] || +// _isShowingFunctionTip) { +// return; +// } +// [MobClick event:kUmeng_Event_Request_ActionOfLocal label:@"Wiki_点击历史版本"]; +// +// UIButton *originBtn = _footerV.menuBtnList[1]; +// CGRect fromFrame = [originBtn convertRect:originBtn.frame toView:self.view]; +// fromFrame.origin.y -= 3; +// +// _isShowingFunctionTip = YES; +// __weak typeof(self) weakSelf = self; +// [MartFunctionTipView showText:@"这里可查看历史版本" direction:AMPopTipDirectionUp bubbleOffset:-35 inView:self.view fromFrame:fromFrame dismissHandler:^{ +// weakSelf.isShowingFunctionTip = NO; +// [[FunctionTipsManager shareManager] markTiped:kFunctionTipStr_WikiHistory]; +// }]; +//} + +#pragma refresh Data + +- (void)refresh{ + if (!_wikiList) { + [self refreshWikiList]; + }else{ + [self refreshWikiDetail]; + } + if (![_myProject.id isKindOfClass:[NSNumber class]]) { + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_ProjectDetail_WithObj:_myProject andBlock:^(id data, NSError *error) { + if (data) { + weakSelf.myProject = data; + } + }]; + } +} + +- (void)refreshWikiList{ + if (!_curWiki) { + [self.view beginLoading]; + } + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_WikiListWithPro:_myProject andBlock:^(id data, NSError *error) { + if (data) { + weakSelf.wikiList = data; + } + if (weakSelf.wikiList.count > 0) { + if (!weakSelf.navigationItem.rightBarButtonItem) { + [weakSelf.navigationItem setRightBarButtonItem:[[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"moreBtn_Nav"] style:UIBarButtonItemStylePlain target:weakSelf action:@selector(rightNavBtnClicked)] animated:NO]; + } + weakSelf.iid = weakSelf.iid ?: [(EAWiki *)weakSelf.wikiList.firstObject iid]; + [weakSelf refreshWikiDetail]; + }else{ + [weakSelf.navigationItem setRightBarButtonItem:nil animated:NO]; + [weakSelf doSomethingWithError:error]; + } + }]; +} + +- (void)refreshWikiDetail{ + if (!_iid) { + [self refreshWikiList]; + }else{ + if (!_curWiki) { + [self.view beginLoading]; + } + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_WikiDetailWithPro:_myProject iid:_iid version:_version andBlock:^(id data, NSError *error) { + if (data) { + weakSelf.curWiki = data; + } + [weakSelf doSomethingWithError:error]; + }]; + } +} + +- (void)doSomethingWithError:(NSError *)error{ + [self.view endLoading]; + [self.myRefreshControl endRefreshing]; + + NSString *contentStr = [WebContentManager wikiPatternedWithContent:_curWiki.html]; +// [self.webContentView loadHTMLString:contentStr baseURL:nil]; + [self.webContentView loadHTMLString:contentStr baseURL:[NSURL URLWithString:[self p_baseHref]]]; + + + BOOL hasError = (error != nil && !_curWiki); + [self.view configBlankPage:EaseBlankPageTypeWiki hasData:(_curWiki != nil) hasError:hasError reloadButtonBlock:^(id sender) { + [self refresh]; + }]; + self.webContentView.hidden = hasError; +} + +- (NSString *)p_baseHref{//写在 wiki.html 文件里的,没有 baseHref 的话,锚点会异常 + return @"https://coding.net/"; +} + +#pragma mark Footer Action + +- (void)handleFooterIndex:(NSInteger)index{ + if (_curWiki.isHistoryVersion) {//恢复版本 + __weak typeof(self) weakSelf = self; + [[UIAlertController ea_actionSheetCustomWithTitle:@"确定要恢复到当前版本吗?" buttonTitles:@[@"确认恢复"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { + [weakSelf revertWiki]; + } + }] showInView:self.view]; + }else{ + if (index == 1) {//编辑 + WikiEditViewController *vc = [WikiEditViewController new]; + vc.curWiki = _curWiki; + vc.myProject = _myProject; + [self.navigationController pushViewController:vc animated:YES]; + }else if (index == 2){//查看历史版本 + WikiHistoryListViewController *vc = [WikiHistoryListViewController new]; + vc.curWiki = _curWiki; + vc.myProject = _myProject; + [self.navigationController pushViewController:vc animated:YES]; + }else{//目录 + [self showMenuListV]; + } + } +} + +- (void)showMenuListV{ + if (!_wikiList || !_curWiki) { + return; + } + if (!_menuListV) { + _menuListV = [WikiMenuListView new]; + __weak typeof(self) weakSelf = self; + _menuListV.selectedWikiBlock = ^(EAWiki *wiki){ + [MobClick event:kUmeng_Event_Request_ActionOfLocal label:@"Wiki_点击目录"]; + + weakSelf.curWiki = wiki; + [weakSelf refreshWikiDetail]; + }; + } + [_menuListV setWikiList:_wikiList selectedWiki:_curWiki]; + [_menuListV show]; +} + +- (void)revertWiki{ + __weak typeof(self) weakSelf = self; + [NSObject showHUDQueryStr:@"请稍等..."]; + [[Coding_NetAPIManager sharedManager] request_RevertWiki:_iid toVersion:_version pro:_myProject andBlock:^(id data, NSError *error) { + [NSObject hideHUDQuery]; + if (data) { + [NSObject showHudTipStr:@"设置成功"]; + + UINavigationController *nav = weakSelf.navigationController; + for (NSInteger index = nav.viewControllers.count - 2; index >= 0; index--) { + UIViewController *vc = nav.viewControllers[index]; + if ([vc isKindOfClass:[WikiViewController class]]) { + [nav popToViewController:vc animated:YES]; + break; + } + } + } + }]; +} + +#pragma mark UIScrollView + +- (void)scrollViewDidScroll:(UIScrollView *)scrollView{ + if (_isShowingFunctionTip) { + return; + } + if (scrollView.contentSize.height <= CGRectGetHeight(scrollView.bounds)-50) { + [self hideFooterV:NO]; + return; + }else if (scrollView.panGestureRecognizer.state == UIGestureRecognizerStateChanged){ + CGPoint velocity = [scrollView.panGestureRecognizer velocityInView:scrollView]; + [self hideFooterV:velocity.y < 0]; + } +} + +- (void)hideFooterV:(BOOL)hide{ + static BOOL isAnimating = NO; + CGFloat footerY = self.view.height - (hide? 0: _footerV.height); + if (fabs(_footerV.y - footerY) > .1 && !isAnimating) { + isAnimating = YES; + [UIView animateWithDuration:.3 animations:^{ + _footerV.y = footerY; + } completion:^(BOOL finished) { + isAnimating = NO; + }]; + } +} + +#pragma mark UIWebViewDelegate +- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ + DebugLog(@"strLink=[%@]",request.URL.absoluteString); +// #user-content-examples + NSString *urlStr = request.URL.absoluteString; + if ([urlStr isEqualToString:[self p_baseHref]] || + [urlStr hasPrefix:[[self p_baseHref] stringByAppendingString:@"#"]]) { + return YES; + }else{ + UIViewController *vc = [BaseViewController analyseVCFromLinkStr:request.URL.absoluteString]; + if (vc) { + [self.navigationController pushViewController:vc animated:YES]; + return NO; + } + return YES; + } +} +- (void)webViewDidStartLoad:(UIWebView *)webView{ + [_activityIndicator startAnimating]; +} +- (void)webViewDidFinishLoad:(UIWebView *)webView{ + [_activityIndicator stopAnimating]; +} +- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{ + if([error code] == NSURLErrorCancelled) + return; + else + DebugLog(@"%@", error.description); +} + +#pragma mark nav +- (void)rightNavBtnClicked{ + if ([KxMenu isShowingInView:self.view]) { + [KxMenu dismissMenu:YES]; + }else{ + [KxMenu setTitleFont:[UIFont systemFontOfSize:14]]; + [KxMenu setTintColor:[UIColor whiteColor]]; + [KxMenu setLineColor:kColorDDD]; + + NSMutableArray *menuItems = [@[ + [KxMenuItem menuItem:@"共享链接" image:[UIImage imageNamed:@"wiki_menu_icon_share"] target:self action:@selector(goToShareFileLink)], + [KxMenuItem menuItem:@"删除文件" image:[UIImage imageNamed:@"wiki_menu_icon_delete"] target:self action:@selector(showDeleteWikiTip)], + ] mutableCopy]; + [menuItems setValue:kColor222 forKey:@"foreColor"]; + CGRect senderFrame = CGRectMake(kScreen_Width - (kDevice_Is_iPhone6Plus? 30: 26), 5, 0, 0); + [KxMenu showMenuInView:self.view + fromRect:senderFrame + menuItems:menuItems]; + } +} + +- (void)goToShareFileLink{ + __weak typeof(self) weakSelf = self; + UIAlertController *actionSheet; + if (_curWiki.share) { + actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"该链接适用于所有人,无需登录" buttonTitles:@[@"拷贝链接"] destructiveTitle:@"关闭共享" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { + [weakSelf doCopyShareUrl]; + }else if (index == 1) { + [weakSelf doCloseShareUrl]; + } + }]; + }else{ + actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"当前未开启共享,请先创建公开链接" buttonTitles:@[@"开启共享并拷贝链接"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { + [weakSelf doOpenAndCopyShareUrl]; + } + }]; + } + [actionSheet showInView:self.view]; +} + +- (void)doCopyShareUrl{ + if (_curWiki.share) { + [[UIPasteboard generalPasteboard] setString:_curWiki.share.url]; + [NSObject showHudTipStr:@"链接已拷贝到粘贴板"]; + }else{ + [NSObject showHudTipStr:@"文件还未打开共享"]; + } +} + +- (void)doOpenAndCopyShareUrl{ + _curWiki.project_id = _myProject.id; + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_OpenShareOfWiki:_curWiki andBlock:^(id data, NSError *error) { + if (data) { + weakSelf.curWiki.share = [FileShare instanceWithUrl:data]; + [weakSelf doCopyShareUrl]; + } + }]; +} + +- (void)doCloseShareUrl{ + NSString *hashStr = [[_curWiki.share.url componentsSeparatedByString:@"/"] lastObject]; + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_CloseWikiShareHash:hashStr andBlock:^(id data, NSError *error) { + if (data) { + weakSelf.curWiki.share = nil; + [NSObject showHudTipStr:@"共享链接已关闭"]; + } + }]; +} + + +- (void)showDeleteWikiTip{ + if (_iid) { + __weak typeof(self) weakSelf = self; + [[UIAlertController ea_actionSheetCustomWithTitle:@"确定要删除 Wiki 文档吗?" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { + [weakSelf deleteWiki]; + } + }] showInView:self.view]; + } +} + +- (void)deleteWiki{ + __weak typeof(self) weakSelf = self; + [NSObject showHUDQueryStr:@"请稍等..."]; + [[Coding_NetAPIManager sharedManager] request_DeleteWikiWithPro:_myProject iid:_iid andBlock:^(id data, NSError *error) { + [NSObject hideHUDQuery]; + if (data) { + [NSObject showHudTipStr:@"删除成功"]; + weakSelf.curWiki = nil; + [weakSelf refreshWikiList]; + } + }]; +} + +@end + +#pragma mark WikiFooterView + +@interface WikiFooterView () +@property (strong, nonatomic) UIButton *revertBtn; +@property (readwrite, strong, nonatomic) NSMutableArray *menuBtnList; +@end + +@implementation WikiFooterView + +- (instancetype)init{ + self = [super init]; + if (self) { + self.frame = CGRectMake(0, 0, kScreen_Width, 49 + kSafeArea_Bottom); + self.backgroundColor = kColorNavBG; + [self addLineUp:YES andDown:NO]; + } + return self; +} + +- (void)setCurWiki:(EAWiki *)curWiki{ + _curWiki = curWiki; + self.hidden = (_curWiki == nil); + + BOOL isHistoryVersion = _curWiki.isHistoryVersion; + [_menuBtnList setValue:@(isHistoryVersion) forKey:@"hidden"]; + _revertBtn.hidden = !isHistoryVersion; + + __weak typeof(self) weakSelf = self; + if (isHistoryVersion && !_revertBtn) { + _revertBtn = [[UIButton alloc] initWithFrame:self.bounds]; + _revertBtn.height -= kSafeArea_Bottom; + [_revertBtn bk_addEventHandler:^(id sender) { + [weakSelf handleButtonClickedIndex:0]; + } forControlEvents:UIControlEventTouchUpInside]; + + + _revertBtn.titleLabel.font = [UIFont systemFontOfSize:15]; + [_revertBtn setTitleColor:kColorDark3 forState:UIControlStateNormal]; + [_revertBtn setTitle:@"恢复至该版本" forState:UIControlStateNormal]; + [_revertBtn setImage:[UIImage imageNamed:@"wiki_revert"] forState:UIControlStateNormal]; + + CGFloat padding = 16; + _revertBtn.titleEdgeInsets = UIEdgeInsetsMake(0, padding/ 2, 0, -padding/ 2); + _revertBtn.imageEdgeInsets = UIEdgeInsetsMake(0, -padding/ 2, 0, padding/ 2); + + [self addSubview:_revertBtn]; + }else if (!isHistoryVersion && !_menuBtnList){ + _menuBtnList = @[].mutableCopy; + NSInteger num = 3; + CGFloat width = self.width/ num; + CGFloat height = self.height - kSafeArea_Bottom; + for (NSInteger index = 0; index < num; index++) { + UIButton *menuBtn = [[UIButton alloc] initWithFrame:CGRectMake(index * width, 0, width, height)]; + [menuBtn bk_addEventHandler:^(id sender) { + [weakSelf handleButtonClickedIndex:index]; + } forControlEvents:UIControlEventTouchUpInside]; + [menuBtn setImage:[UIImage imageNamed:[NSString stringWithFormat:@"wiki_menu_%d", (int)index]] forState:UIControlStateNormal]; + [self addSubview:menuBtn]; + [_menuBtnList addObject:menuBtn]; + } + } +} + +- (void)handleButtonClickedIndex:(NSInteger)index{ + if (self.buttonClickedBlock) { + self.buttonClickedBlock(index); + } +} + +@end diff --git a/Coding_iOS/Ease_2FA/Controllers/OTPListViewController.m b/Coding_iOS/Ease_2FA/Controllers/OTPListViewController.m index a069009e4..800403f24 100644 --- a/Coding_iOS/Ease_2FA/Controllers/OTPListViewController.m +++ b/Coding_iOS/Ease_2FA/Controllers/OTPListViewController.m @@ -67,7 +67,7 @@ + (NSString *)otpCodeWithGK:(NSString *)global_key{ for (OTPAuthURL *authURL in authURLs) { NSString *cur_issure = authURL.issuer; NSString *cur_global_key = [[authURL.name componentsSeparatedByString:@"@"] firstObject]; - if ([cur_issure isEqualToString:@"Coding"] && + if ([cur_issure.uppercaseString isEqualToString:@"CODING"] && [cur_global_key isEqualToString:global_key]) { otpCode = authURL.otpCode; break; @@ -149,9 +149,9 @@ - (void)configUI{ if (!_tipLabel) { _tipLabel = [UILabel new]; _tipLabel.numberOfLines = 0; - _tipLabel.textAlignment = NSTextAlignmentCenter; + _tipLabel.textAlignment = NSTextAlignmentNatural; _tipLabel.textColor = kColor222; - _tipLabel.text = @"启用两步验证后,登录 Coding 账户或进行敏感操作时都将需要输入密码和本客户端生成的验证码。"; + _tipLabel.text = @"启用两步验证后,账户登录或进行敏感操作时,都将需要输入密码和本客户端生成的验证码。"; [self.view addSubview:_tipLabel]; } if (!_beginButton) { @@ -160,7 +160,7 @@ - (void)configUI{ [_beginButton mas_makeConstraints:^(MASConstraintMaker *make) { make.size.mas_equalTo(CGSizeMake(kScreen_Width-kPaddingLeftWidth*2, 45)); make.centerX.equalTo(self.view); - make.bottom.equalTo(self.view).offset(-20); + make.bottom.equalTo(self.view).offset(-20- kSafeArea_Bottom); }]; } CGSize tipImageSize = tipImage.size; @@ -215,13 +215,11 @@ - (void)dealWithScanResult:(NSString *)resultStr ofVC:(ZXScanCodeViewController }else{ tipStr = [NSString stringWithFormat:@"条码「%@」不是有效的身份验证令牌条码", resultStr]; } - UIAlertView *alertV = [UIAlertView bk_alertViewWithTitle:@"无效条码" message:tipStr]; - [alertV bk_addButtonWithTitle:@"重试" handler:^{ + [[UIAlertController ea_alertViewWithTitle:@"无效条码" message:tipStr buttonTitles:@[@"重试"] destructiveTitle:nil cancelTitle:nil andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (![vc isScaning]) { [vc startScan]; } - }]; - [alertV show]; + }] show]; } } @@ -235,12 +233,9 @@ - (void)addOneAuthURL:(OTPAuthURL *)authURL{ if ([authURL.otpCode isEqualToString:item.otpCode]) { kTipAlert(@"该二维码已被保存为账户名:\n%@", authURL.name); }else{ - UIAlertView *alertV = [UIAlertView bk_alertViewWithTitle:@"提示" message:[NSString stringWithFormat:@"账户名:%@ 已存在\n选择 '更新' 覆盖原账户。", authURL.name]]; - [alertV bk_setCancelButtonWithTitle:@"取消" handler:nil]; - [alertV bk_addButtonWithTitle:@"更新" handler:nil]; @weakify(self); - alertV.bk_didDismissBlock = ^(UIAlertView *alertView, NSInteger buttonIndex){ - if (buttonIndex == 1) { + [[UIAlertController ea_alertViewWithTitle:@"提示" message:[NSString stringWithFormat:@"账户名:%@ 已存在\n选择 '更新' 覆盖原账户。", authURL.name] buttonTitles:@[@"更新"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { @strongify(self); if ([authURL saveToKeychain]) { if ([self.authURLs indexOfObject:item] != NSNotFound) { @@ -251,10 +246,8 @@ - (void)addOneAuthURL:(OTPAuthURL *)authURL{ }else{ kTipAlert(@"保存过程中发生了异常,请重新扫描"); } - } - }; - [alertV show]; + }] show]; } break; } @@ -327,14 +320,13 @@ - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEd if (editingStyle == UITableViewCellEditingStyleDelete) { OTPAuthURL *authURL = self.authURLs[indexPath.section]; __weak typeof(self) weakSelf = self; - UIAlertView *alertV = [UIAlertView bk_alertViewWithTitle:@"删除此账户不会停用两步验证" message:@"\n您可能会因此无法登录自己的账户\n在删除该账户前,请先停用两步验证,或者确保您可以通过其它方法生成验证码。"]; - [alertV bk_setCancelButtonWithTitle:@"取消" handler:^{ - [weakSelf configUI]; - }]; - [alertV bk_addButtonWithTitle:@"确认删除" handler:^{ - [weakSelf deleteOneAuthURL:authURL]; - }]; - [alertV show]; + [[UIAlertController ea_alertViewWithTitle:@"删除此账户不会停用两步验证" message:@"\n您可能会因此无法登录自己的账户\n在删除该账户前,请先停用两步验证,或者确保您可以通过其它方法生成验证码。" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { + [weakSelf deleteOneAuthURL:authURL]; + }else{ + [weakSelf configUI]; + } + }] show]; } } diff --git a/Coding_iOS/Ease_2FA/Controllers/ZXScanCodeViewController.h b/Coding_iOS/Ease_2FA/Controllers/ZXScanCodeViewController.h index 864016c1c..af92aadc0 100644 --- a/Coding_iOS/Ease_2FA/Controllers/ZXScanCodeViewController.h +++ b/Coding_iOS/Ease_2FA/Controllers/ZXScanCodeViewController.h @@ -11,7 +11,9 @@ @interface ZXScanCodeViewController : BaseViewController @property (strong, nonatomic, readonly) AVCaptureVideoPreviewLayer *videoPreviewLayer; -- (BOOL)isScaning; + +@property (assign, nonatomic, readonly) BOOL isScaning; + - (void)startScan; - (void)stopScan; diff --git a/Coding_iOS/Ease_2FA/Controllers/ZXScanCodeViewController.m b/Coding_iOS/Ease_2FA/Controllers/ZXScanCodeViewController.m index 4292494ca..d1d5c4ba3 100644 --- a/Coding_iOS/Ease_2FA/Controllers/ZXScanCodeViewController.m +++ b/Coding_iOS/Ease_2FA/Controllers/ZXScanCodeViewController.m @@ -17,6 +17,9 @@ @interface ZXScanCodeViewController () - + + + + + - - - + + + + - + - - + + - - + + + + + + - + - - - - + + + - + - + - + + - + diff --git a/Coding_iOS/Launch Screen_E.xib b/Coding_iOS/Launch Screen_E.xib new file mode 100644 index 000000000..630ddc06f --- /dev/null +++ b/Coding_iOS/Launch Screen_E.xib @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Coding_iOS/Models/ActivenessModel.h b/Coding_iOS/Models/ActivenessModel.h new file mode 100644 index 000000000..c07e6266a --- /dev/null +++ b/Coding_iOS/Models/ActivenessModel.h @@ -0,0 +1,28 @@ +// +// ActivenessModel.h +// Coding_iOS +// +// Created by 张达棣 on 16/11/29. +// Copyright © 2016年 Coding. All rights reserved. +// + +#import +@class ActiveDuration, DailyActiveness; + +@interface ActivenessModel : NSObject +@property (nonatomic, strong) NSString *total_with_seal_top_line; +@property (nonatomic, strong) NSString *start_date; +@property (nonatomic, strong) ActiveDuration *longest_active_duration; +@property (nonatomic, strong) ActiveDuration *current_active_duration; +@property (nonatomic, strong) NSArray *dailyActiveness; +@end + + + +@interface ActiveDuration : NSObject +@property (nonatomic, strong) NSString *days, *start_date, *end_date; +@end + +@interface DailyActiveness : NSObject +@property (nonatomic, strong) NSString *date, *count; +@end diff --git a/Coding_iOS/Models/ActivenessModel.m b/Coding_iOS/Models/ActivenessModel.m new file mode 100644 index 000000000..ba582a6c5 --- /dev/null +++ b/Coding_iOS/Models/ActivenessModel.m @@ -0,0 +1,22 @@ +// +// ActivenessModel.m +// Coding_iOS +// +// Created by 张达棣 on 16/11/29. +// Copyright © 2016年 Coding. All rights reserved. +// + +#import "ActivenessModel.h" + +@implementation ActivenessModel + +@end + + +@implementation ActiveDuration + +@end + +@implementation DailyActiveness + +@end diff --git a/Coding_iOS/Models/CodeBranchOrTag.h b/Coding_iOS/Models/CodeBranchOrTag.h index a8d2df58a..0727804a0 100644 --- a/Coding_iOS/Models/CodeBranchOrTag.h +++ b/Coding_iOS/Models/CodeBranchOrTag.h @@ -8,7 +8,25 @@ #import +@class CodeBranchOrTagCommit, CodeBranchOrTagMetric; + @interface CodeBranchOrTag : NSObject @property (strong, nonatomic) NSString *name; @property (strong, nonatomic) NSNumber *is_default_branch, *is_protected; + +@property (strong, nonatomic) CodeBranchOrTagCommit *last_commit;//不一定有 +@property (strong, nonatomic) CodeBranchOrTagMetric *branch_metric;//这是需要另外请求的 +@end + + +@interface CodeBranchOrTagCommit : NSObject +@property (strong, nonatomic) NSString *commitId, *shortMessage; +@property (strong, nonatomic) NSDate *commitTime; +@end + +@interface CodeBranchOrTagMetric : NSObject + +@property (strong, nonatomic) NSString *base; +@property (strong, nonatomic) NSNumber *ahead, *behind; + @end diff --git a/Coding_iOS/Models/CodeBranchOrTag.m b/Coding_iOS/Models/CodeBranchOrTag.m index 52b841438..e47bdf680 100644 --- a/Coding_iOS/Models/CodeBranchOrTag.m +++ b/Coding_iOS/Models/CodeBranchOrTag.m @@ -10,4 +10,15 @@ @implementation CodeBranchOrTag + + +@end + + +@implementation CodeBranchOrTagCommit + +@end + +@implementation CodeBranchOrTagMetric + @end diff --git a/Coding_iOS/Models/CodeFile.h b/Coding_iOS/Models/CodeFile.h index 482dc77e3..13bd17a2b 100755 --- a/Coding_iOS/Models/CodeFile.h +++ b/Coding_iOS/Models/CodeFile.h @@ -16,11 +16,16 @@ @property (readwrite, nonatomic, strong) NSString *ref, *path; @property (readwrite, nonatomic, strong) CodeFile_RealFile *file; @property (strong, nonatomic) Commit *headCommit; -@property (strong, nonatomic) NSString *editData, *editMessage; +@property (strong, nonatomic) NSString *editData, *editMessage, *editName; + (CodeFile *)codeFileWithRef:(NSString *)ref andPath:(NSString *)path; -+ (CodeFile *)codeFileWithMDStr:(NSString *)md_html; ++ (CodeFile *)codeFileWithMDPreview:(NSString *)md_html; ++ (CodeFile *)codeFileToCommitWithRef:(NSString *)ref andPath:(NSString *)path name:(NSString *)name data:(NSString *)data message:(NSString *)message headCommit:(Commit *)headCommit; ++ (CodeFile *)codeFileWithLocalURL:(NSURL *)localURL; + - (NSDictionary *)toEditParams; +- (NSDictionary *)toDeleteParams; +- (NSDictionary *)toCreateParams; @end @@ -30,4 +35,4 @@ @property (readwrite, nonatomic, strong) Committer *lastCommitter; @property (nonatomic, assign) BOOL previewed; @property (nonatomic, assign) NSInteger size; -@end \ No newline at end of file +@end diff --git a/Coding_iOS/Models/CodeFile.m b/Coding_iOS/Models/CodeFile.m index 35b53f9b4..b2e5ddf10 100755 --- a/Coding_iOS/Models/CodeFile.m +++ b/Coding_iOS/Models/CodeFile.m @@ -16,7 +16,7 @@ + (CodeFile *)codeFileWithRef:(NSString *)ref andPath:(NSString *)path{ codeFile.path = path; return codeFile; } -+ (CodeFile *)codeFileWithMDStr:(NSString *)md_html{ ++ (CodeFile *)codeFileWithMDPreview:(NSString *)md_html{ CodeFile *codeFile = [self codeFileWithRef:@"" andPath:@"README"]; CodeFile_RealFile *file = [CodeFile_RealFile new]; @@ -27,6 +27,26 @@ + (CodeFile *)codeFileWithMDStr:(NSString *)md_html{ codeFile.file = file; return codeFile; } ++ (CodeFile *)codeFileToCommitWithRef:(NSString *)ref andPath:(NSString *)path name:(NSString *)name data:(NSString *)data message:(NSString *)message headCommit:(Commit *)headCommit{ + CodeFile *codeFile = [self codeFileWithRef:ref andPath:path]; + codeFile.editName = name; + codeFile.editData = data; + codeFile.editMessage = message; + codeFile.headCommit = headCommit; + return codeFile; +} + ++ (CodeFile *)codeFileWithLocalURL:(NSURL *)localURL{ + CodeFile *codeFile = [self new]; + CodeFile_RealFile *file = [CodeFile_RealFile new]; + file.mode = @"file"; + NSStringEncoding enc; + file.data = [NSString stringWithContentsOfURL:localURL usedEncoding:&enc error:nil]; + file.lang = localURL.ea_lang ?: @""; + codeFile.file = file; + return codeFile; +} + - (NSString *)path{ if (!_path) { _path = @""; @@ -45,6 +65,12 @@ - (NSString *)editData{ } return _editData; } +- (NSString *)editName{ + if (!_editName) { + _editName = _file.name.copy; + } + return _editName; +} - (NSString *)editMessage{ if (!_editMessage) { _editMessage = [NSString stringWithFormat:@"update %@", _path]; @@ -58,9 +84,29 @@ - (NSDictionary *)toEditParams{ params[@"lastCommitSha"] = self.headCommit.commitId; return params; } + +- (NSDictionary *)toDeleteParams{ + NSMutableDictionary *params = @{}.mutableCopy; + params[@"message"] = [NSString stringWithFormat:@"delete: %@", self.file.name]; + params[@"lastCommitSha"] = self.headCommit.commitId; + return params; +} + +- (NSDictionary *)toCreateParams{ + NSMutableDictionary *params = @{}.mutableCopy; + params[@"title"] = self.editName; + params[@"content"] = self.editData ?: @""; + params[@"message"] = self.editMessage; + params[@"lastCommitSha"] = self.headCommit.commitId ?: @""; + return params; +} @end @implementation CodeFile_RealFile -@end \ No newline at end of file +- (void)setPreview:(NSString *)preview{ + _preview = [preview stringByReplacingOccurrencesOfString:@"{{CodingUrl}}" withString:@""]; +} + +@end diff --git a/Coding_iOS/Models/CodeTree.h b/Coding_iOS/Models/CodeTree.h index 80bcb774b..1feb8b698 100755 --- a/Coding_iOS/Models/CodeTree.h +++ b/Coding_iOS/Models/CodeTree.h @@ -7,31 +7,24 @@ // #import +#import "Commit.h" -@class CodeTree_Committer, CodeTree_LastCommit, CodeTree_File, CodeTree_CommitInfo; +@class CodeTree_File, CodeTree_CommitInfo; @interface CodeTree : NSObject @property (readwrite, nonatomic, strong) NSMutableArray *files, *commitInfos; @property (nonatomic, assign) BOOL can_edit, isHead; -@property (readwrite, nonatomic, strong) CodeTree_LastCommit *lastCommit; +@property (readwrite, nonatomic, strong) Commit *lastCommit, *headCommit; @property (strong, nonatomic) NSDictionary *propertyArrayMap; @property (readwrite, nonatomic, strong) NSString *ref, *path; @property (assign, nonatomic) BOOL isLoading; +@property (strong, nonatomic) NSArray *treeList; + - (void)configWithCommitInfos:(NSArray *)infos; + (CodeTree *)codeTreeMaster; + (CodeTree *)codeTreeWithRef:(NSString *)ref andPath:(NSString *)path; @end -@interface CodeTree_LastCommit : NSObject -@property (readwrite, nonatomic, strong) NSString *commitId, *fullMessage, *shortMessage; -@property (strong, nonatomic) NSDate *commitTime; -@property (readwrite, nonatomic, strong) CodeTree_Committer *committer; -@end - -@interface CodeTree_Committer : NSObject -@property (readwrite, nonatomic, strong) NSString *avatar, *name, *link, *email; -@end - @interface CodeTree_File : NSObject @property (readwrite, nonatomic, strong) NSString *mode, *name, *path; @property (readwrite, nonatomic, strong) CodeTree_CommitInfo *info; @@ -41,5 +34,6 @@ @property (readwrite, nonatomic, strong) NSDate *lastCommitDate; @property (readwrite, nonatomic, strong) NSString *lastCommitId, *lastCommitMessage; @property (readwrite, nonatomic, strong) NSString *mode, *name, *path; -@property (readwrite, nonatomic, strong) CodeTree_Committer *lastCommitter; -@end \ No newline at end of file +@property (readwrite, nonatomic, strong) Committer *lastCommitter; +@property (readwrite, nonatomic, strong) NSString *submoduleLink, *submoduleUrl; +@end diff --git a/Coding_iOS/Models/CodeTree.m b/Coding_iOS/Models/CodeTree.m index 5f5bae5e6..d1d07edee 100755 --- a/Coding_iOS/Models/CodeTree.m +++ b/Coding_iOS/Models/CodeTree.m @@ -58,14 +58,6 @@ - (void)configWithCommitInfos:(NSArray *)infos{ } @end -@implementation CodeTree_LastCommit - -@end - -@implementation CodeTree_Committer - -@end - @implementation CodeTree_File - (NSString *)mode{ if (!_mode) { @@ -77,4 +69,4 @@ - (NSString *)mode{ @implementation CodeTree_CommitInfo -@end \ No newline at end of file +@end diff --git a/Coding_iOS/Models/CodingSkill.h b/Coding_iOS/Models/CodingSkill.h new file mode 100644 index 000000000..c8dc37bb3 --- /dev/null +++ b/Coding_iOS/Models/CodingSkill.h @@ -0,0 +1,18 @@ +// +// CodingSkill.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2017/9/18. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import + +@interface CodingSkill : NSObject +@property (strong, nonatomic) NSString *skillName; +@property (strong, nonatomic) NSNumber *skillId, *level; + +@property (strong, nonatomic, readonly) NSString *skill_str; + ++ (NSArray *)levelList; +@end diff --git a/Coding_iOS/Models/CodingSkill.m b/Coding_iOS/Models/CodingSkill.m new file mode 100644 index 000000000..3c29155ed --- /dev/null +++ b/Coding_iOS/Models/CodingSkill.m @@ -0,0 +1,22 @@ +// +// CodingSkill.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2017/9/18. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "CodingSkill.h" + +@implementation CodingSkill + +- (NSString *)skill_str{ + NSInteger level = MIN([CodingSkill levelList].count, MAX(0, _level.integerValue - 1)); + return [NSString stringWithFormat:@"%@·%@", _skillName, [CodingSkill levelList][level]]; +} + ++ (NSArray *)levelList{ + return @[@"入门", @"一般", @"熟练", @"精通", ]; +} + +@end diff --git a/Coding_iOS/Models/CodingTip.m b/Coding_iOS/Models/CodingTip.m index 89a9afcaf..715040d1b 100644 --- a/Coding_iOS/Models/CodingTip.m +++ b/Coding_iOS/Models/CodingTip.m @@ -64,7 +64,7 @@ - (void)adjust{ _target_type_ColorName = @"0x379FD3"; } _target_type_imageName = [NSString stringWithFormat:@"tipIcon_%@", _target_type]; - _content = _htmlMedia.contentDisplay; + _content = [_htmlMedia.contentDisplay stringByReplacingOccurrencesOfString:@"团队" withString:@"企业"]; } + (NSDictionary *)p_color_dict{ @@ -95,7 +95,7 @@ + (NSDictionary *)p_color_dict{ @"TweetComment" : @"0xFB8638", @"TweetLike" : @"0xFF5847", @"User" : @"0x496AB3", - @"UserFollow" : @"0x3BBD79", + @"UserFollow" : @"0x0060FF", @"ProjectTopicCommentVote": @"", }; }); diff --git a/Coding_iOS/Models/CodingTips.m b/Coding_iOS/Models/CodingTips.m index d4a40b681..25498830f 100755 --- a/Coding_iOS/Models/CodingTips.m +++ b/Coding_iOS/Models/CodingTips.m @@ -78,6 +78,9 @@ - (NSDictionary *)toTipsParams{ params = @{@"type" : @[@(4), @(6)], @"page" : _willLoadMore? [NSNumber numberWithInteger:_page.integerValue +1]: [NSNumber numberWithInteger:1], @"pageSize" : _pageSize}; + }else if (_type == 3){ + params = @{@"page" : _willLoadMore? [NSNumber numberWithInteger:_page.integerValue +1]: [NSNumber numberWithInteger:1], + @"pageSize" : _pageSize}; } return params; } @@ -93,6 +96,8 @@ - (NSDictionary *)toMarkReadParams{ }else if (_type == 2){ params = @{@"type" : @(4), @"all" : @(1)}; + }else if (_type == 3){ + params = @{@"all" : @(1)}; } return params; } diff --git a/Coding_iOS/Models/Commit.h b/Coding_iOS/Models/Commit.h index 1d34cba52..1d80693f9 100755 --- a/Coding_iOS/Models/Commit.h +++ b/Coding_iOS/Models/Commit.h @@ -20,4 +20,4 @@ @interface Committer : NSObject @property (readwrite, nonatomic, strong) NSString *avatar, *name, *link, *email; -@end \ No newline at end of file +@end diff --git a/Coding_iOS/Models/EABasePageModel.h b/Coding_iOS/Models/EABasePageModel.h new file mode 100644 index 000000000..ac2ed8cdd --- /dev/null +++ b/Coding_iOS/Models/EABasePageModel.h @@ -0,0 +1,20 @@ +// +// EABasePageModel.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/22. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import + +@interface EABasePageModel : NSObject +@property (readwrite, nonatomic, strong) NSNumber *page, *pageSize, *totalPage, *totalRow; +@property (assign, nonatomic) BOOL canLoadMore, willLoadMore, isLoading; + +@property (readwrite, nonatomic, strong) NSMutableArray *list;//需要指定数据类型的数据 +@property (readwrite, nonatomic, strong) NSDictionary *propertyArrayMap;//指定数据类型的字典 + +- (NSMutableDictionary *)toParams; +- (void)configWithObj:(EABasePageModel *)resultA; +@end diff --git a/Coding_iOS/Models/EABasePageModel.m b/Coding_iOS/Models/EABasePageModel.m new file mode 100644 index 000000000..d2bc818a2 --- /dev/null +++ b/Coding_iOS/Models/EABasePageModel.m @@ -0,0 +1,45 @@ +// +// EABasePageModel.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/22. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "EABasePageModel.h" + +@implementation EABasePageModel +- (instancetype)init +{ + self = [super init]; + if (self) { + _propertyArrayMap = @{ +// @"list": @"CodeBranchOrTag", + }; + _canLoadMore = YES; + _isLoading = _willLoadMore = NO; + _page = @1; + _pageSize = @20; + } + return self; +} + +- (NSMutableDictionary *)toParams{ + return @{@"page" : (_willLoadMore? @(_page.intValue +1): @1), + @"pageSize" : _pageSize}.mutableCopy; + +} + +- (void)configWithObj:(EABasePageModel *)resultA{ + self.page = resultA.page; + self.totalPage = resultA.totalPage; + self.totalRow = resultA.totalRow; + if (_willLoadMore) { + [self.list addObjectsFromArray:resultA.list]; + }else{ + self.list = [NSMutableArray arrayWithArray:resultA.list]; + } + self.canLoadMore = self.page.intValue < self.totalPage.intValue; +} + +@end diff --git a/Coding_iOS/Models/EABoardTaskList.h b/Coding_iOS/Models/EABoardTaskList.h new file mode 100644 index 000000000..75caf6fea --- /dev/null +++ b/Coding_iOS/Models/EABoardTaskList.h @@ -0,0 +1,33 @@ +// +// EABoardTaskList.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/4/27. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "EABasePageModel.h" +#import "Task.h" +#import "Project.h" + +typedef enum : NSUInteger { + EABoardTaskListCustom = 0, + EABoardTaskListDoing, + EABoardTaskListDone, + EABoardTaskListBlank +} EABoardTaskListType; + +@interface EABoardTaskList : EABasePageModel + +@property (strong, nonatomic) NSNumber *id, *board_id, *owner_id, *project_id; +@property (assign, nonatomic) EABoardTaskListType type; +@property (assign, nonatomic) NSInteger order; +@property (strong, nonatomic) NSString *title; + +@property (assign, nonatomic, readonly) BOOL canEdit, isBlankType; +@property (assign, nonatomic) Project *curPro;//辅助属性 + +- (NSString *)toTaskListPath; + ++ (instancetype)blankBoardTLWithProject:(Project *)project; +@end diff --git a/Coding_iOS/Models/EABoardTaskList.m b/Coding_iOS/Models/EABoardTaskList.m new file mode 100644 index 000000000..a78d572f6 --- /dev/null +++ b/Coding_iOS/Models/EABoardTaskList.m @@ -0,0 +1,42 @@ +// +// EABoardTaskList.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/4/27. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "EABoardTaskList.h" + +@implementation EABoardTaskList + +- (instancetype)init +{ + self = [super init]; + if (self) { + self.propertyArrayMap = @{@"list": @"Task"}; + } + return self; +} + +- (BOOL)canEdit{ + return _type == EABoardTaskListCustom; +} + +- (BOOL)isBlankType{ + return _type == EABoardTaskListBlank; +} + +- (NSString *)toTaskListPath{ + return [NSString stringWithFormat:@"api/user/%@/project/%@/tasks/board/%@/list/%@/tasks", _curPro.owner_user_name, _curPro.name, _board_id, _id]; +} + ++ (instancetype)blankBoardTLWithProject:(Project *)project{ + EABoardTaskList *blankItem = [self new]; + blankItem.id = @(-1); + blankItem.curPro = project; + blankItem.type = EABoardTaskListBlank; + return blankItem; +} + +@end diff --git a/Coding_iOS/Models/EACodeBranches.h b/Coding_iOS/Models/EACodeBranches.h new file mode 100644 index 000000000..76e366176 --- /dev/null +++ b/Coding_iOS/Models/EACodeBranches.h @@ -0,0 +1,26 @@ +// +// EACodeBranches.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/22. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "EABasePageModel.h" +#import "CodeBranchOrTag.h" +#import "Project.h" + +@interface EACodeBranches : EABasePageModel + +@property (strong, nonatomic) NSString *queryStr; +@property (strong, nonatomic) Project *curPro; + +@property (strong, nonatomic) CodeBranchOrTag *defaultBranch; + +- (NSString *)toPath; +- (NSDictionary *)toParams; + +//branch_metrics: +//https://coding.net/api/user/ease/project/CodingTest/git/branch_metrics?base=e5d4955b8201309874dcb64f7cbdf314014fa3bf&targets=e5d4955b8201309874dcb64f7cbdf314014fa3bf%2C719ff69d71d306641ceaa894a1eea6abb08d00ec%2Ca5739517e0490ce3cdf0902e6da866ebb6aab3b1%2C1802d88cb77846b257f92029eae4a22933bfffb6%2Ce5d6e7ba21db8e22d641fb47fc52c5f6632b5559%2Cbdcb860a7780c79fb365276d3b8836f8068178c4%2Cb85c2f817364a3662abce8012073a63af89c1e95%2C5f209a9743367af232e624742743aeabb0a85f10%2Cf03dd077b2a2c1a5474e45a4fb8f4acb343694e1%2Cf304e9aa98158da4adaba3bb9295cc3fdf468f02 + +@end diff --git a/Coding_iOS/Models/EACodeBranches.m b/Coding_iOS/Models/EACodeBranches.m new file mode 100644 index 000000000..967a0345e --- /dev/null +++ b/Coding_iOS/Models/EACodeBranches.m @@ -0,0 +1,44 @@ +// +// EACodeBranches.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/22. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "EACodeBranches.h" + +@implementation EACodeBranches + +- (instancetype)init +{ + self = [super init]; + if (self) { + self.propertyArrayMap = @{@"list": @"CodeBranchOrTag"}; + } + return self; +} + +- (CodeBranchOrTag *)defaultBranch{ + if (!_defaultBranch) { + for (CodeBranchOrTag *itemB in self.list) { + if (itemB.is_default_branch.boolValue) { + _defaultBranch = itemB; + break; + } + } + } + return _defaultBranch; +} + +//https://coding.net/api/user/ease/project/CodingTest/git/branches/filter?page=1&q= +- (NSString *)toPath{ + return [NSString stringWithFormat:@"api/user/%@/project/%@/git/branches/filter", _curPro.owner_user_name, _curPro.name]; +} +- (NSDictionary *)toParams{ + NSMutableDictionary *params = [super toParams]; + params[@"q"] = _queryStr; + return params; +} + +@end diff --git a/Coding_iOS/Models/EACodeRelease.h b/Coding_iOS/Models/EACodeRelease.h new file mode 100644 index 000000000..7bf1f481e --- /dev/null +++ b/Coding_iOS/Models/EACodeRelease.h @@ -0,0 +1,46 @@ +// +// EACodeRelease.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/22. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import +#import "User.h" +#import "Commit.h" +#import "ResourceReference.h" +#import "Project.h" + +@class EACodeReleaseAttachment; + +@interface EACodeRelease : NSObject + +@property (strong, nonatomic) NSNumber *id, *creator_id, *project_id, *iid, *pre, *draft; +@property (strong, nonatomic) NSString *tag_name, *commit_sha, *target_commitish, *title, *body, *markdownBody, *compare_tag_name; +@property (strong, nonatomic) NSDate *created_at; +@property (strong, nonatomic) User *author; +@property (strong, nonatomic) Commit *last_commit; +@property (strong, nonatomic) NSMutableArray *resource_references;//ResourceReferenceItem +@property (strong, nonatomic) NSMutableArray *attachments;//EACodeReleaseAttachment +@property (readwrite, nonatomic, strong) NSDictionary *propertyArrayMap;//指定数据类型的字典 + +@property (strong, nonatomic) Project *project;//需要自己填充的 +@property (assign, nonatomic) CGFloat contentHeight; + +@property (strong, nonatomic) NSString *editTitle, *editBody;//edit + +- (BOOL)hasChanged; + +- (NSString *)editPath; +- (NSDictionary *)editParams; + +@end + +@interface EACodeReleaseAttachment : NSObject + +@property (strong, nonatomic) NSNumber *id, *size; +@property (strong, nonatomic) NSString *name; + +@end + diff --git a/Coding_iOS/Models/EACodeRelease.m b/Coding_iOS/Models/EACodeRelease.m new file mode 100644 index 000000000..24547991a --- /dev/null +++ b/Coding_iOS/Models/EACodeRelease.m @@ -0,0 +1,71 @@ +// +// EACodeRelease.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/22. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "EACodeRelease.h" + +@implementation EACodeRelease +- (instancetype)init +{ + self = [super init]; + if (self) { + self.propertyArrayMap = @{@"resource_references": @"ResourceReferenceItem", + @"attachments": @"EACodeReleaseAttachment", + }; + _contentHeight = 1.0; + } + return self; +} + +- (NSString *)editTitle{ + if (!_editTitle) { + _editTitle = _title.copy; + } + return _editTitle; +} + +- (NSString *)editBody{ + if (!_editBody) { + _editBody = _body.copy; + } + return _editBody; +} + +- (BOOL)hasChanged{ + return ![_editTitle isEqualToString:_title] || ![_editBody isEqualToString:_body]; +} + +- (NSString *)editPath{ + return [NSString stringWithFormat:@"api/user/%@/project/%@/git/releases/update/%@", _project.owner_user_name, _project.name, _tag_name]; +} +- (NSDictionary *)editParams{ + NSMutableDictionary *params = @{}.mutableCopy; + params[@"title"] = _editTitle; + params[@"body"] = _editBody; + + params[@"tag_name"] = _tag_name; + params[@"commit_sha"] = _commit_sha; + params[@"target_commitish"] = _target_commitish; + params[@"draft"] = _draft; + params[@"pre"] = _pre; + + if (_resource_references.count > 0) { + params[@"resource_references"] = [_resource_references valueForKey:@"code"]; + } + for (EACodeReleaseAttachment *item in _attachments) { + params[[NSString stringWithFormat:@"attachments[%@]", item.id]] = item.name; + } + return params; +} + +@end + + +@implementation EACodeReleaseAttachment + +@end + diff --git a/Coding_iOS/Models/EACodeReleases.h b/Coding_iOS/Models/EACodeReleases.h new file mode 100644 index 000000000..2c2bc39df --- /dev/null +++ b/Coding_iOS/Models/EACodeReleases.h @@ -0,0 +1,18 @@ +// +// EACodeReleases.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/22. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "EABasePageModel.h" +#import "EACodeRelease.h" +#import "Project.h" + +@interface EACodeReleases : EABasePageModel +@property (strong, nonatomic) Project *curPro; + +- (NSString *)toPath; +- (NSDictionary *)toParams; +@end diff --git a/Coding_iOS/Models/EACodeReleases.m b/Coding_iOS/Models/EACodeReleases.m new file mode 100644 index 000000000..c28437219 --- /dev/null +++ b/Coding_iOS/Models/EACodeReleases.m @@ -0,0 +1,29 @@ +// +// EACodeReleases.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/22. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "EACodeReleases.h" + +@implementation EACodeReleases +- (instancetype)init +{ + self = [super init]; + if (self) { + self.propertyArrayMap = @{@"list": @"EACodeRelease"}; + } + return self; +} + +//https://coding.net/api/user/ease/project/CodingTest/git/releases?page=1&pageSize=10 +- (NSString *)toPath{ + return [NSString stringWithFormat:@"api/user/%@/project/%@/git/releases", _curPro.owner_user_name, _curPro.name]; +} +- (NSDictionary *)toParams{ + return [super toParams]; +} + +@end diff --git a/Coding_iOS/Models/EAMilestone.h b/Coding_iOS/Models/EAMilestone.h new file mode 100644 index 000000000..55c5f88ea --- /dev/null +++ b/Coding_iOS/Models/EAMilestone.h @@ -0,0 +1,17 @@ +// +// EAMilestone.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/5/14. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "EABasePageModel.h" + +@interface EAMilestone : EABasePageModel +@property (strong, nonatomic) NSNumber *id, *project_id, *status, *processing, *finished, *percentage, *remaining_days, *expire_days; +@property (strong, nonatomic) NSString *name, *description_mine, *start_date, *publish_date; +@end + +//"start_date": "2018-05-14", +//"publish_date": "2018-05-30", diff --git a/Coding_iOS/Models/EAMilestone.m b/Coding_iOS/Models/EAMilestone.m new file mode 100644 index 000000000..ddbcf695c --- /dev/null +++ b/Coding_iOS/Models/EAMilestone.m @@ -0,0 +1,13 @@ +// +// EAMilestone.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/5/14. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "EAMilestone.h" + +@implementation EAMilestone + +@end diff --git a/Coding_iOS/Models/EAWiki.h b/Coding_iOS/Models/EAWiki.h new file mode 100644 index 000000000..d7db6a20f --- /dev/null +++ b/Coding_iOS/Models/EAWiki.h @@ -0,0 +1,42 @@ +// +// EAWiki.h +// Coding_Enterprise_iOS +// +// Created by Ease on 2017/4/5. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import +#import "User.h" +#import "FileShare.h" + +@interface EAWiki : NSObject +@property (strong, nonatomic) User *creator, *editor; +@property (strong, nonatomic) NSNumber *id, *iid, *historyId, *currentUserRoleId, *historiesCount, *lastVersion, *currentVersion, *parentIid, *order, *version; +@property (strong, nonatomic) NSNumber *project_id;//需要从别的地方拿数据 +@property (strong, nonatomic) NSString *title, *content, *html, *msg, *path; +@property (strong, nonatomic) NSDate *createdAt, *updatedAt; +@property (strong, nonatomic) NSArray *children; +@property (strong, nonatomic, readonly) NSDictionary *propertyArrayMap; + +@property (readwrite, nonatomic, strong) FileShare *share; + +@property (readonly, strong, nonatomic) EAWiki *parentWiki; +@property (readonly, nonatomic, strong) NSArray *childrenDisplayList; + +@property (assign, nonatomic) BOOL isExpanded; +@property (readonly, assign, nonatomic) NSInteger lavel; +@property (readonly, assign, nonatomic) BOOL isHistoryVersion, hasChildren; + +@property (strong, nonatomic) NSString *mdTitle, *mdContent;//edit +@property (strong, nonatomic) NSNumber *draftVersion; + +- (BOOL)hasDraft; +- (BOOL)draftVersionChanged; +- (BOOL)hasChanged; +- (void)saveDraft; +- (void)readDraft; +- (void)deleteDraft; + +- (NSDictionary *)toShareParams; +@end diff --git a/Coding_iOS/Models/EAWiki.m b/Coding_iOS/Models/EAWiki.m new file mode 100644 index 000000000..6fef6df0a --- /dev/null +++ b/Coding_iOS/Models/EAWiki.m @@ -0,0 +1,146 @@ +// +// EAWiki.m +// Coding_Enterprise_iOS +// +// Created by Ease on 2017/4/5. +// Copyright © 2017年 Coding. All rights reserved. +// +#define kEAWiki_MaxLevel 3 + +#import "EAWiki.h" + +@interface EAWiki () +@property (readwrite, strong, nonatomic) EAWiki *parentWiki; +@property (readwrite, nonatomic, strong) NSArray *childrenDisplayList; +@end + +@implementation EAWiki + +- (instancetype)init{ + self = [super init]; + if (self) { + _isExpanded = YES; + _parentWiki = nil; + } + return self; +} + +- (NSDictionary *)propertyArrayMap{ + return @{@"children": @"EAWiki"}; +} + +- (void)setChildren:(NSArray *)children{ + _children = children; + for (EAWiki *wiki in _children) { + wiki.parentWiki = self; + } +} + +- (NSInteger)lavel{ + NSInteger lavel = 0; + EAWiki *tempWiki = self; + while (tempWiki.parentWiki) { + tempWiki = tempWiki.parentWiki; + lavel += 1; + } +// return lavel; + return MIN(lavel, kEAWiki_MaxLevel); +} + +- (BOOL)isHistoryVersion{ + return _currentVersion.integerValue < _lastVersion.integerValue; +} + +- (BOOL)hasChildren{ + return self.childrenDisplayList.count > 0; +} + +- (NSString *)mdTitle{ + if (!_mdTitle) { + _mdTitle = _title.copy; + } + return _mdTitle; +} + +- (NSString *)mdContent{ + if (!_mdContent) { + _mdContent = _content.copy; + } + return _mdContent; +} + +- (NSArray *)childrenDisplayList{ +// return _children; + if (self.lavel < kEAWiki_MaxLevel - 1) { + return _children; + }else + if (!_childrenDisplayList) { + if (self.lavel < kEAWiki_MaxLevel - 1) { + _childrenDisplayList = _children.copy; + }else if (self.lavel == kEAWiki_MaxLevel - 1){ + _childrenDisplayList = [self allChildren].copy; + }else{ + _childrenDisplayList = @[]; + } + } + return _childrenDisplayList; +} + +- (NSArray *)allChildren{ + NSMutableArray *list = _children? _children.mutableCopy: @[].mutableCopy; + for (EAWiki *wiki in _children) { + NSArray *childrenList = [wiki allChildren]; + NSUInteger loc = [list indexOfObject:wiki]; + if (childrenList.count > 0 && loc != NSNotFound) { + [list insertObjects:childrenList atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(loc + 1, childrenList.count)]]; + } + } + return list; +} + +- (BOOL)hasDraft{ + NSDictionary *data = [NSObject loadResponseWithPath:[self p_draftPath]]; + return data != nil; +} +- (BOOL)draftVersionChanged{ + NSDictionary *data = [NSObject loadResponseWithPath:[self p_draftPath]]; + NSNumber *draftVersion = data[@"draftVersion"]; + if (draftVersion.integerValue < _currentVersion.integerValue) { + return YES; + } + return NO; +} +- (BOOL)hasChanged{ + return ![_mdTitle isEqualToString:_title] || ![_mdContent isEqualToString:_content]; +} +- (void)saveDraft{ + [NSObject saveResponseData:[self p_draftData] toPath:[self p_draftPath]]; +} +- (void)readDraft{ + NSDictionary *data = [NSObject loadResponseWithPath:[self p_draftPath]]; + self.mdTitle = data[@"mdTitle"]; + self.mdContent = data[@"mdContent"]; + self.draftVersion = data[@"draftVersion"]; +} +- (void)deleteDraft{ + [NSObject deleteResponseCacheForPath:[self p_draftPath]]; +} +- (NSString *)p_draftPath{ + return [NSString stringWithFormat:@"wiki_%@", _id]; +} +- (NSDictionary *)p_draftData{ + return @{@"mdTitle": _mdTitle ?: @"", + @"mdContent": _mdContent ?: @"", + @"draftVersion": _currentVersion ?: @0}; +} + +- (NSDictionary *)toShareParams{ + return @{ + @"projectId": _project_id, + @"resourceId": _iid, + @"resourceType": @2, + @"accessType": @0 + }; +} + +@end diff --git a/Coding_iOS/Models/FileVersion.h b/Coding_iOS/Models/FileVersion.h index 7ad5ea0f2..05c0d6ad5 100644 --- a/Coding_iOS/Models/FileVersion.h +++ b/Coding_iOS/Models/FileVersion.h @@ -15,7 +15,7 @@ @property (strong, nonatomic) NSDate *created_at; @property (readwrite, nonatomic, strong) User *owner; -@property (strong, nonatomic, readonly) NSString *diskFileName; +@property (strong, nonatomic, readonly) NSString *diskFileName, *storage_key_for_disk; - (NSString *)downloadPath; @@ -25,5 +25,5 @@ //download - (DownloadState)downloadState; - (Coding_DownloadTask *)cDownloadTask; -- (NSURL *)hasBeenDownload; +- (NSURL *)diskFileUrl; @end diff --git a/Coding_iOS/Models/FileVersion.m b/Coding_iOS/Models/FileVersion.m index 61ac66f4c..87270f816 100644 --- a/Coding_iOS/Models/FileVersion.m +++ b/Coding_iOS/Models/FileVersion.m @@ -16,10 +16,22 @@ @interface FileVersion () @implementation FileVersion - (NSString *)diskFileName{ if (!_diskFileName) { - _diskFileName = [NSString stringWithFormat:@"%@|||%@|||%@|%@", _name, _project_id.stringValue, _storage_type, _storage_key]; + _diskFileName = [NSString stringWithFormat:@"%@|||%@|||%@|%@", _name, _project_id.stringValue, self.storage_type, self.storage_key_for_disk]; } return _diskFileName; } + +- (NSString *)storage_key_for_disk{ + NSArray *fileNameCom = [_name componentsSeparatedByString:@"."]; + NSMutableArray *storage_keyCom = [_storage_key componentsSeparatedByString:@"."].mutableCopy; + if (fileNameCom.count > 1 && storage_keyCom.count > 0 && ![fileNameCom.lastObject isEqualToString:storage_keyCom.lastObject]) {//_storage_key 后缀名与 fileNameCom 后缀名不同的情况 + [storage_keyCom addObject:fileNameCom.lastObject]; + return [storage_keyCom componentsJoinedByString:@"."]; + }else{ + return [_storage_key componentsSeparatedByString:@"/"].lastObject;//'group0/M00/00/01/fwAAAVsHsvqAOY8rABzvMF5h1Ck652.JPG'..诡异的前半截数据 + } +} + - (NSString *)downloadPath{ return [NSString stringWithFormat:@"%@api/project/%@/files/histories/%@/download", [NSObject baseURLStr], _project_id, _history_id]; } @@ -34,7 +46,7 @@ - (NSString *)toDeletePath{ //download - (DownloadState)downloadState{ DownloadState state = DownloadStateDefault; - if ([self hasBeenDownload]) { + if ([self diskFileUrl]) { state = DownloadStateDownloaded; }else{ Coding_DownloadTask *cDownloadTask = [self cDownloadTask]; @@ -53,7 +65,7 @@ - (DownloadState)downloadState{ - (Coding_DownloadTask *)cDownloadTask{ return [Coding_FileManager cDownloadTaskForKey:_storage_key]; } -- (NSURL *)hasBeenDownload{ - return [Coding_FileManager diskDownloadUrlForKey:_storage_key]; +- (NSURL *)diskFileUrl{ + return [Coding_FileManager diskDownloadUrlForKey:self.storage_key] ?: [Coding_FileManager diskDownloadUrlForKey:self.storage_key_for_disk]; } @end diff --git a/Coding_iOS/Models/Login.h b/Coding_iOS/Models/Login.h index c02b1177d..6ab81c7d4 100755 --- a/Coding_iOS/Models/Login.h +++ b/Coding_iOS/Models/Login.h @@ -8,10 +8,14 @@ #import #import "User.h" +#import "Team.h" +#import "Project.h" + @interface Login : NSObject //请求 -@property (readwrite, nonatomic, strong) NSString *email, *password, *j_captcha; +@property (readwrite, nonatomic, strong) NSString *email, *password, *j_captcha, *company, *ssoType; @property (readwrite, nonatomic, strong) NSNumber *remember_me; +@property (readwrite, nonatomic) BOOL ssoEnabled; - (NSString *)goToLoginTipWithCaptcha:(BOOL)needCaptcha; - (NSString *)toPath; @@ -19,12 +23,22 @@ + (BOOL) isLogin; + (void) doLogin:(NSDictionary *)loginData; ++ (void) doLoginCompany:(NSDictionary *)loginCompanyData; ++ (void) updateLoginIsAdministrator:(NSNumber *)isAdministrator; + (void) doLogout; + (void)setPreUserEmail:(NSString *)emailStr; + (NSString *)preUserEmail; + (User *)curLoginUser; ++ (Team *)curLoginCompany; + + (void)setXGAccountWithCurUser; + (User *)userWithGlobaykeyOrEmail:(NSString *)textStr; + (NSMutableDictionary *)readLoginDataList; -+(BOOL)isLoginUserGlobalKey:(NSString *)global_key; ++ (BOOL)isLoginUserGlobalKey:(NSString *)global_key; ++ (BOOL)canEditPro:(Project *)pro; + +// Git Clone 需要用 http 的方式校验 ++ (void)setPassword:(NSString *)password; ++ (NSString *)curPassword; + @end diff --git a/Coding_iOS/Models/Login.m b/Coding_iOS/Models/Login.m index e8fea5980..8d3c5d05f 100644 --- a/Coding_iOS/Models/Login.m +++ b/Coding_iOS/Models/Login.m @@ -9,13 +9,17 @@ #import "Login.h" #import "XGPush.h" #import "AppDelegate.h" +#import "Coding_NetAPIManager.h" #define kLoginStatus @"login_status" #define kLoginPreUserEmail @"pre_user_email" #define kLoginUserDict @"user_dict" #define kLoginDataListPath @"login_data_list_path.plist" +#define kLoginTeamKey @"login_team_key" +#define kLoginPasswordKey(_key_) [NSString stringWithFormat:@"password|%@", _key_] static User *curLoginUser; +static Team *curLoginTeam; @implementation Login - (instancetype)init @@ -25,6 +29,8 @@ - (instancetype)init self.remember_me = [NSNumber numberWithBool:YES]; self.email = @""; self.password = @""; + self.ssoType = @"default"; + self.ssoEnabled = NO; } return self; } @@ -33,18 +39,26 @@ - (NSString *)toPath{ return @"api/v2/account/login"; } - (NSDictionary *)toParams{ + NSString *password = [self.password sha1Str]; + if (self.ssoEnabled && [self.ssoType isEqualToString:@"ldap"]) { + password = self.password; + } NSMutableDictionary *params = @{@"account": self.email, - @"password" : [self.password sha1Str], + @"password" : password, @"remember_me" : self.remember_me? @"true" : @"false",}.mutableCopy; if (self.j_captcha.length > 0) { params[@"j_captcha"] = self.j_captcha; } + [Login p_setPassword:self.password forAccount:self.email.lowercaseString];//保存一下密码 return params; } - (NSString *)goToLoginTipWithCaptcha:(BOOL)needCaptcha{ + if (kTarget_Enterprise && _company.length <= 0) { + return @"请填写企业域名"; + } if (!_email || _email.length <= 0) { - return @"请填写「手机号码/电子邮箱/个性后缀」"; + return @"请填写「手机号码/电子邮箱/用户名」"; } if (!_password || _password.length <= 0) { return @"请填写密码"; @@ -84,11 +98,44 @@ + (void)doLogin:(NSDictionary *)loginData{ [Login setXGAccountWithCurUser]; [self saveLoginData:loginData]; + + if (kTarget_Enterprise) { + if (![self curLoginCompany]) { + [[Coding_NetAPIManager sharedManager] request_UpdateCompanyInfoBlock:^(id data, NSError *error) { + }]; + } + if (!curLoginUser.isAdministrator) { + [[Coding_NetAPIManager sharedManager] request_UpdateIsAdministratorBlock:^(id data, NSError *error) { + }]; + } + } }else{ [Login doLogout]; } } ++ (void) doLoginCompany:(NSDictionary *)loginCompanyData{ + if (loginCompanyData) { + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + [defaults setObject:loginCompanyData forKey:kLoginTeamKey]; + curLoginTeam = [NSObject objectOfClass:@"Team" fromJSON:loginCompanyData]; + [defaults synchronize]; + } +} + ++ (void) updateLoginIsAdministrator:(NSNumber *)isAdministrator{ + if (!isAdministrator) { + return; + } + if (!curLoginUser.isAdministrator || [curLoginUser.isAdministrator isEqualToNumber:isAdministrator]) { + curLoginUser.isAdministrator = isAdministrator; + + NSMutableDictionary *loginData = [[[NSUserDefaults standardUserDefaults] objectForKey:kLoginUserDict] mutableCopy]; + loginData[@"isAdministrator"] = isAdministrator; + [self doLogin:loginData]; + } +} + + (NSMutableDictionary *)readLoginDataList{ NSMutableDictionary *loginDataList = [NSMutableDictionary dictionaryWithContentsOfFile:[self loginDataListPath]]; if (!loginDataList) { @@ -186,10 +233,51 @@ + (User *)curLoginUser{ return curLoginUser; } ++ (Team *)curLoginCompany{ + if (!curLoginTeam) { + NSDictionary *loginCompanyData = [[NSUserDefaults standardUserDefaults] objectForKey:kLoginTeamKey]; + curLoginTeam = loginCompanyData? [NSObject objectOfClass:@"Team" fromJSON:loginCompanyData]: nil; + } + return [curLoginTeam.global_key.lowercaseString isEqualToString:[NSObject baseCompany].lowercaseString]? curLoginTeam: nil; +} + +(BOOL)isLoginUserGlobalKey:(NSString *)global_key{ if (global_key.length <= 0) { return NO; } return [[self curLoginUser].global_key isEqualToString:global_key]; } ++ (BOOL)canEditPro:(Project *)pro{ + if ([Login isLogin]) { + return (pro.current_user_role_id.integerValue >= 90 || + [self curLoginUser].isAdministrator.boolValue); + } + return NO; +} + +// Git Clone 需要用 http 的方式校验 ++ (void)setPassword:(NSString *)password{ + if ([self curLoginUser].global_key) { + [self p_setPassword:password forAccount:[self curLoginUser].global_key]; + } +} + ++ (void)p_setPassword:(NSString *)password forAccount:(NSString *)account{ + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + [defaults setObject:password forKey:kLoginPasswordKey(account)]; + [defaults synchronize]; +} + ++ (NSString *)curPassword{ + if ([self isLogin]) { + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + User *curU = [self curLoginUser]; + return ([defaults objectForKey:kLoginPasswordKey(curU.global_key)] ?: + [defaults objectForKey:kLoginPasswordKey(curU.email)] ?: + [defaults objectForKey:kLoginPasswordKey(curU.phone)]); + }else{ + return nil; + } +} + @end diff --git a/Coding_iOS/Models/MRPR.m b/Coding_iOS/Models/MRPR.m index 4df8906e0..8955eda92 100644 --- a/Coding_iOS/Models/MRPR.m +++ b/Coding_iOS/Models/MRPR.m @@ -33,6 +33,9 @@ - (void)setPath:(NSString *)path{ if (pathComponents.count == 8) { _des_owner_name = pathComponents[2]; _des_project_name = pathComponents[4]; + }else if (pathComponents.count == 6){ + _des_owner_name = [NSObject baseCompany]; + _des_project_name = pathComponents[2]; } } @@ -121,6 +124,8 @@ - (NSString *)p_prePath{ NSArray *pathComponents = [_path componentsSeparatedByString:@"/"]; if (pathComponents.count == 8) { prePath = [NSString stringWithFormat:@"api/user/%@/project/%@/git/%@/%@/", pathComponents[2], pathComponents[4], pathComponents[6], pathComponents[7]]; + }else if (pathComponents.count == 6){ + prePath = [NSString stringWithFormat:@"api/user/%@/project/%@/git/%@/%@/", [NSObject baseCompany], pathComponents[2], pathComponents[4], pathComponents[5]]; } NSLog(@"path === %@", prePath); return prePath; diff --git a/Coding_iOS/Models/MRPRPreInfo.h b/Coding_iOS/Models/MRPRPreInfo.h index 165024527..2f91569e8 100644 --- a/Coding_iOS/Models/MRPRPreInfo.h +++ b/Coding_iOS/Models/MRPRPreInfo.h @@ -15,7 +15,7 @@ @property (strong, nonatomic) MRPR *merge_request; @property (strong, nonatomic) MRPR *mrpr; @property (strong, nonatomic) NSNumber *can_edit_src_branch; -@property (strong, nonatomic) NSNumber *can_edit; +@property (strong, nonatomic) NSNumber *can_edit, *can_merge, *can_grant; @property (strong, nonatomic) NSNumber *author_can_edit; @end diff --git a/Coding_iOS/Models/MRPRS.h b/Coding_iOS/Models/MRPRS.h index 5fada5af9..d985802ef 100644 --- a/Coding_iOS/Models/MRPRS.h +++ b/Coding_iOS/Models/MRPRS.h @@ -10,17 +10,19 @@ #import "MRPR.h" typedef NS_ENUM(NSInteger, MRPRSType) { - MRPRSTypeMRAll = 0, - MRPRSTypeMRMine, - MRPRSTypeMRReview, - MRPRSTypeMROther, - MRPRSTypePR, + MRPRSTypeMRDefault = 0, + MRPRSTypeMRCanMerge, + MRPRSTypeMRCannotMerge, + MRPRSTypeMRRefused, + MRPRSTypeMRAccepted, + MRPRSTypePROpen, + MRPRSTypePRClosed, + MRPRSTypePRAll, }; @interface MRPRS : NSObject @property (strong, nonatomic) NSString *user_gk, *project_name; @property (nonatomic, assign, readonly) MRPRSType type; -@property (assign, nonatomic, readonly) BOOL statusIsOpen; @property (readwrite, nonatomic, strong) NSNumber *page, *pageSize, *totalPage, *totalRow; @property (readwrite, nonatomic, strong) NSMutableArray *list; @@ -31,6 +33,6 @@ typedef NS_ENUM(NSInteger, MRPRSType) { - (NSString *)toPath; - (void)configWithMRPRS:(MRPRS *)resultA; --(instancetype)initWithType:(MRPRSType)type statusIsOpen:(BOOL)statusIsOpen userGK:(NSString *)user_gk projectName:(NSString *)project_name; +-(instancetype)initWithType:(MRPRSType)type userGK:(NSString *)user_gk projectName:(NSString *)project_name; @end diff --git a/Coding_iOS/Models/MRPRS.m b/Coding_iOS/Models/MRPRS.m index 27fcac4c7..87dbbf466 100644 --- a/Coding_iOS/Models/MRPRS.m +++ b/Coding_iOS/Models/MRPRS.m @@ -23,11 +23,10 @@ - (instancetype)init return self; } --(instancetype)initWithType:(MRPRSType)type statusIsOpen:(BOOL)statusIsOpen userGK:(NSString *)user_gk projectName:(NSString *)project_name{ +-(instancetype)initWithType:(MRPRSType)type userGK:(NSString *)user_gk projectName:(NSString *)project_name{ self = [self init]; if (self) { _type = type; - _statusIsOpen = statusIsOpen; _user_gk = user_gk; _project_name = project_name; } @@ -37,40 +36,22 @@ -(instancetype)initWithType:(MRPRSType)type statusIsOpen:(BOOL)statusIsOpen user - (NSDictionary *)toParams{ NSMutableDictionary *params = @{@"page" : (_willLoadMore? [NSNumber numberWithInteger:_page.intValue +1] : [NSNumber numberWithInteger:1]), @"pageSize" : _pageSize}.mutableCopy; - if (_type != MRPRSTypePR || _type != MRPRSTypeMRAll) { - params[@"status"] = _statusIsOpen? @"open": @"closed"; - } + params[@"status"] = (_type == MRPRSTypeMRCanMerge? @"canmerge": + _type == MRPRSTypeMRCannotMerge? @"cannotmerge": + _type == MRPRSTypeMRRefused? @"refused": + _type == MRPRSTypeMRAccepted? @"accepted": + nil); return params; } - (NSString *)toPath{ NSString *typeStr; - switch (_type) { - case MRPRSTypeMRAll: - if (_statusIsOpen) { - typeStr = @"merges/open"; - }else{ - typeStr = @"merges/closed"; - } - break; - case MRPRSTypeMRMine: - typeStr = @"merges/list/mine"; - break; - case MRPRSTypeMRReview: - typeStr = @"merges/list/review"; - break; - case MRPRSTypeMROther: - typeStr = @"merges/list/other"; - break; - case MRPRSTypePR: - if (_statusIsOpen) { - typeStr = @"pulls/open"; - }else{ - typeStr = @"pulls/closed"; - } - break; - default: - typeStr = @""; - break; + if (_type < MRPRSTypePROpen) { + typeStr = @"merges/filter"; + }else{ + typeStr = (_type == MRPRSTypePROpen? @"pulls/open": + _type == MRPRSTypePRClosed? @"pulls/closed": + _type == MRPRSTypePRAll? @"pulls/all": + @""); } return [NSString stringWithFormat:@"api/user/%@/project/%@/git/%@", _user_gk, _project_name, typeStr]; } diff --git a/Coding_iOS/Models/PointRecords.h b/Coding_iOS/Models/PointRecords.h index 6384a35fc..f5b8d2503 100644 --- a/Coding_iOS/Models/PointRecords.h +++ b/Coding_iOS/Models/PointRecords.h @@ -15,6 +15,8 @@ @property (readwrite, nonatomic, strong) NSDictionary *propertyArrayMap; @property (readwrite, nonatomic, strong) NSMutableArray *list; +@property (strong, nonatomic) NSNumber *points_left; + - (NSString *)toPath; - (NSDictionary *)toParams; - (void)configWithObj:(PointRecords *)records; diff --git a/Coding_iOS/Models/PointRecords.m b/Coding_iOS/Models/PointRecords.m index 45244991c..8b5e76c89 100644 --- a/Coding_iOS/Models/PointRecords.m +++ b/Coding_iOS/Models/PointRecords.m @@ -22,6 +22,12 @@ - (instancetype)init } return self; } +- (NSNumber *)points_left{ + if (!_points_left && _list.count > 0) { + _points_left = [(PointRecord *)_list.firstObject points_left]; + } + return _points_left; +} - (NSString *)toPath{ return @"api/point/records"; } diff --git a/Coding_iOS/Models/Project.h b/Coding_iOS/Models/Project.h index b849e70b7..d2fafea75 100644 --- a/Coding_iOS/Models/Project.h +++ b/Coding_iOS/Models/Project.h @@ -7,6 +7,7 @@ // #import +#import //https://github.com/libgit2/objective-git @interface Project : NSObject @property (readwrite, nonatomic, strong) NSString *icon, *name, *owner_user_name, *backend_project_path, *full_name, *description_mine, *path, *parent_depot_path, *current_user_role,*project_path; @@ -16,6 +17,9 @@ @property (strong, nonatomic) User *owner; @property (strong, nonatomic) NSDate *created_at,*updated_at; +@property (strong, nonatomic) NSNumber *board_id;//目前一个项目,只有一个看板。。从看板列表接口得到 +@property (assign, nonatomic) BOOL hasEverHandledBoard; + + (Project *)project_All; + (Project *)project_FeedBack; @@ -29,6 +33,8 @@ - (NSString *)toDeletePath; +- (NSString *)toArchivePath; + - (NSString *)toMembersPath; - (NSDictionary *)toMembersParams; @@ -38,4 +44,15 @@ - (NSString *)localMembersPath; - (NSString *)toBranchOrTagPath:(NSString *)path; + +#pragma mark Git + +- (NSURL *)remoteURL; +- (NSURL *)localURL; +- (BOOL)isLocalRepoExist; +- (BOOL)deleteLocalRepo; +- (GTRepository *)localRepo; +- (void)gitCloneBlock:(void(^)(GTRepository *repo, NSError *error))handleBlock progressBlock:(void (^)(const git_transfer_progress *progress, BOOL *stop))progressBlock; +- (void)gitPullBlock:(void(^)(BOOL result, NSString *tipStr))handleBlock progressBlock:(void (^)(const git_transfer_progress *progress, BOOL *stop))progressBlock; + @end diff --git a/Coding_iOS/Models/Project.m b/Coding_iOS/Models/Project.m index 0706eaa75..d82e2da74 100644 --- a/Coding_iOS/Models/Project.m +++ b/Coding_iOS/Models/Project.m @@ -8,8 +8,25 @@ #import "Project.h" #import "Login.h" +#import "NProjectViewController.h" +#import "EALocalCodeListViewController.h" @implementation Project + +- (BOOL)hasEverHandledBoard{ + NSNumber *hasEverHandledBoard = [[NSUserDefaults standardUserDefaults] objectForKey:self.p_hasEverHandledBoardKey]; + return hasEverHandledBoard? hasEverHandledBoard.boolValue : NO; +} + +- (void)setHasEverHandledBoard:(BOOL)hasEverHandledBoard{ + [[NSUserDefaults standardUserDefaults] setObject:@(hasEverHandledBoard) forKey:self.p_hasEverHandledBoardKey]; + [[NSUserDefaults standardUserDefaults] synchronize]; +} + +- (NSString *)p_hasEverHandledBoardKey{ + return [NSString stringWithFormat:@"%@/%@/hasEverHandledBoardKey", self.owner_user_name, self.name]; +} + - (instancetype)init { self = [super init]; @@ -61,6 +78,9 @@ -(id)copyWithZone:(NSZone*)zone { return person; } +- (NSString *)owner_user_name{ + return _owner_user_name ?: [NSObject baseCompany]; +} - (void)setFull_name:(NSString *)full_name{ _full_name = full_name; @@ -89,7 +109,7 @@ + (Project *)project_FeedBack{ } -(NSString *)toProjectPath{ - return @"api/project"; + return kTarget_Enterprise? [NSString stringWithFormat:@"api/team/%@/project", [NSObject baseCompany]]: @"api/project"; } -(NSDictionary *)toCreateParams{ @@ -100,20 +120,34 @@ -(NSDictionary *)toCreateParams{ }else{ type = @"2"; } - - return @{@"name":self.name, - @"description":self.description_mine, - @"type":type, - @"gitEnabled":@"true", - @"gitReadmeEnabled": _gitReadmeEnabled.boolValue? @"true": @"false", - @"gitIgnore":@"no", - @"gitLicense":@"no", - // @"importFrom":@"no", - @"vcsType":@"git"}; + if (kTarget_Enterprise) { + return @{@"name":self.name, + @"description":self.description_mine, + @"type":type, + @"gitEnabled":@"true", + @"gitReadmeEnabled": _gitReadmeEnabled.boolValue? @"true": @"false", + @"gitIgnore":@"no", + @"gitLicense":@"no", + // @"importFrom":@"no", + @"vcsType":@"git", + @"teamGK": [NSObject baseCompany], + @"joinTeam": @"true", + }; + }else{ + return @{@"name":self.name, + @"description":self.description_mine, + @"type":type, + @"gitEnabled":@"true", + @"gitReadmeEnabled": _gitReadmeEnabled.boolValue? @"true": @"false", + @"gitIgnore":@"no", + @"gitLicense":@"no", + // @"importFrom":@"no", + @"vcsType":@"git"}; + } } -(NSString *)toUpdatePath{ - return [self toProjectPath]; + return @"api/project"; } -(NSDictionary *)toUpdateParams{ @@ -129,7 +163,19 @@ -(NSString *)toUpdateIconPath{ } -(NSString *)toDeletePath{ - return [NSString stringWithFormat:@"api/user/%@/project/%@",self.owner_user_name, self.name]; + if (kTarget_Enterprise) { + return [NSString stringWithFormat:@"api/team/%@/project/%@/delete", [Login curLoginCompany].global_key, _id]; + }else{ + return [NSString stringWithFormat:@"api/user/%@/project/%@",self.owner_user_name, self.name]; + } +} + +- (NSString *)toArchivePath{ + if (kTarget_Enterprise) { + return [NSString stringWithFormat:@"api/team/%@/project/%@/archive", [Login curLoginCompany].global_key, self.id]; + }else{ + return [NSString stringWithFormat:@"api/project/%@/archive", self.id]; + } } - (NSString *)toMembersPath{ @@ -167,4 +213,135 @@ - (NSString *)toBranchOrTagPath:(NSString *)path{ // return @"未填写"; // } //} + +- (NSURL *)remoteURL{ + NSURL *remoteURL; + if (kTarget_Enterprise) { + remoteURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@/%@.git", [NSObject e_URLStr], self.owner_user_name, self.name]]; + }else{ + remoteURL = [NSURL URLWithString:[NSString stringWithFormat:@"https://git.coding.net/%@/%@.git", self.owner_user_name, self.name]]; + } + return remoteURL; +} +- (NSURL *)localURL{ + NSFileManager* fileManager = [NSFileManager defaultManager]; + NSURL *appDocsDir = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask].lastObject; + NSURL *localURL = [NSURL URLWithString:[NSString stringWithFormat:@"repositories/%@/%@", self.owner_user_name, self.name] relativeToURL:appDocsDir]; + return localURL; +} +- (BOOL)isLocalRepoExist{ + NSFileManager* fileManager = [NSFileManager defaultManager]; + return [fileManager fileExistsAtPath:self.localURL.path]; +} +- (BOOL)deleteLocalRepo{ + NSFileManager* fileManager = [NSFileManager defaultManager]; + return [fileManager removeItemAtURL:self.localURL error:nil]; +} +- (GTRepository *)localRepo{ + NSError *error = nil; + GTRepository *repo = [GTRepository repositoryWithURL:self.localURL error:&error]; + return repo; +} +- (void)gitCloneBlock:(void(^)(GTRepository *repo, NSError *error))handleBlock progressBlock:(void (^)(const git_transfer_progress *progress, BOOL *stop))progressBlock{ + __weak typeof(self) weakSelf = self; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + NSError *error = nil; + GTCheckoutOptions *checkoutOptions = [GTCheckoutOptions checkoutOptionsWithStrategy:GTCheckoutStrategyForce]; + NSMutableDictionary *cloneOptions = @{GTRepositoryCloneOptionsCheckoutOptions: checkoutOptions}.mutableCopy; + if (weakSelf.is_public && !weakSelf.is_public.boolValue) {//私有项目 + cloneOptions[GTRepositoryCloneOptionsCredentialProvider] = [weakSelf.class p_credentialProvider]; + } + GTRepository *repo = [GTRepository cloneFromURL:weakSelf.remoteURL toWorkingDirectory:weakSelf.localURL options:cloneOptions error:&error transferProgressBlock:progressBlock]; + dispatch_async(dispatch_get_main_queue(), ^{ + if (handleBlock) { + handleBlock(repo, error); + } + }); + }); +} +- (void)gitPullBlock:(void(^)(BOOL result, NSString *tipStr))handleBlock progressBlock:(void (^)(const git_transfer_progress *progress, BOOL *stop))progressBlock{ + if (!self.isLocalRepoExist) { + handleBlock(NO, @"本地仓库未找到"); + }else{ + GTRepository *repo = [GTRepository repositoryWithURL:self.localURL error:nil]; + if (!repo) { + handleBlock(NO, @"本地仓库未找到"); + }else{ + GTConfiguration *configuration = [repo configurationWithError:nil]; + GTRemote *remote = configuration.remotes.firstObject; + if (!remote) { + handleBlock(NO, @"仓库信息不完整"); + }else{ + __weak typeof(self) weakSelf = self; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + NSError *error = nil; + NSArray *branchList = [repo localBranchesWithError:&error]; + if (branchList.count > 0) { + GTBranch *curBranch = branchList.firstObject; + NSMutableDictionary *options = @{GTRepositoryRemoteOptionsDownloadTags: @(GTRemoteDownloadTagsAuto)}.mutableCopy; + if (weakSelf.is_public && !weakSelf.is_public.boolValue) {//私有项目 + options[GTRepositoryRemoteOptionsCredentialProvider] = [weakSelf.class p_credentialProvider]; + } + NSError *error = nil; + BOOL result = [repo pullBranch:curBranch fromRemote:remote withOptions:options error:&error progress:progressBlock]; + dispatch_async(dispatch_get_main_queue(), ^{ + if (handleBlock) { + handleBlock(result, error.localizedDescription); + } + }); + }else{ + dispatch_async(dispatch_get_main_queue(), ^{ + if (handleBlock) { + handleBlock(NO, @"本地分支为空,请删除后,重新 clone 代码"); + } + }); + } + }); + } + } + } +} + ++ (GTCredentialProvider *)p_credentialProvider{ + __block NSInteger credTimes = 0; + GTCredentialProvider *provider = [GTCredentialProvider providerWithBlock:^GTCredential *(GTCredentialType type, NSString *URL, NSString *credUserName) { + GTCredential *cred = nil; + if (type & GTCredentialTypeUserPassPlaintext) { + if (credTimes < 10) {//用户名密码错了不知道提示,居然不知道停的。。 + NSString *userName = [Login curLoginUser].global_key ?: @""; + NSString *password = [Login curPassword] ?: @""; + cred = [GTCredential credentialWithUserName:userName password:password error:nil]; + }else{ + [self p_handleCredentialFailure]; + } + } + credTimes++; + return cred; + }]; + return provider; +} + ++ (void)p_handleCredentialFailure{ + UIAlertController *alertCtrl = [UIAlertController alertControllerWithTitle:@"身份验证失败!" message:@"HTTP/S 协议需要用户的密码" preferredStyle:UIAlertControllerStyleAlert]; + UIAlertAction *cancelA = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]; + UIAlertAction *confirmA = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) { + NSString *textStr = alertCtrl.textFields[0].text; + [Login setPassword:textStr]; + //下面这段,貌似没必要。。用户自己去再次点击也可以 + UIViewController *vc = [BaseViewController presentingVC]; + if ([vc isKindOfClass:[NProjectViewController class]]) { + [(NProjectViewController *)vc cloneRepo]; + }else if ([vc isKindOfClass:[EALocalCodeListViewController class]]){ + [(EALocalCodeListViewController *)vc pullRepo]; + } + }]; + [alertCtrl addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { + textField.placeholder = @"请输入密码"; + textField.secureTextEntry = YES; + }]; + [alertCtrl addAction:cancelA]; + [alertCtrl addAction:confirmA]; + [[BaseViewController presentingVC] presentViewController:alertCtrl animated:YES completion:nil]; +} + @end diff --git a/Coding_iOS/Models/ProjectActivities.h b/Coding_iOS/Models/ProjectActivities.h index 5467674a6..799d35f9f 100755 --- a/Coding_iOS/Models/ProjectActivities.h +++ b/Coding_iOS/Models/ProjectActivities.h @@ -15,6 +15,7 @@ typedef NS_ENUM(NSInteger, ProjectActivityType) ProjectActivityTypeAll = 0, ProjectActivityTypeTask, ProjectActivityTypeTopic, + ProjectActivityTypeWiki, ProjectActivityTypeFile, ProjectActivityTypeCode, ProjectActivityTypeOther diff --git a/Coding_iOS/Models/ProjectActivities.m b/Coding_iOS/Models/ProjectActivities.m index 923a15893..34fc0c454 100755 --- a/Coding_iOS/Models/ProjectActivities.m +++ b/Coding_iOS/Models/ProjectActivities.m @@ -45,6 +45,9 @@ + (ProjectActivities *)proActivitiesWithPro:(Project *)project type:(ProjectActi case ProjectActivityTypeTopic: proActs.type = @"topic"; break; + case ProjectActivityTypeWiki: + proActs.type = @"wiki"; + break; case ProjectActivityTypeFile: proActs.type = @"file"; break; @@ -147,4 +150,4 @@ - (void)refreshListGroupWithArray:(NSArray *)responseA isAdd:(BOOL)isAdd{ } } } -@end \ No newline at end of file +@end diff --git a/Coding_iOS/Models/ProjectActivity.h b/Coding_iOS/Models/ProjectActivity.h index e8e724679..2055c840e 100644 --- a/Coding_iOS/Models/ProjectActivity.h +++ b/Coding_iOS/Models/ProjectActivity.h @@ -14,13 +14,15 @@ #import "FileComment.h" #import "ProjectFile.h" #import "ProjectTag.h" +#import "EAMilestone.h" @class Task; @class ProjectTopic; @interface ProjectActivity : NSObject -@property (readwrite, nonatomic, strong) NSNumber *id; -@property (readwrite, nonatomic, strong) NSString *target_type, *action, *action_msg, *type, *ref, *ref_type, *ref_path, *pull_request_title, *merge_request_title, *comment_content, *merge_request_path, *pull_request_path, *version; +@property (readwrite, nonatomic, strong) NSNumber *id, *wiki_iid; +@property (readwrite, nonatomic, strong) NSString *target_type, *action, *action_msg, *type, *ref, *ref_type, *ref_path, *pull_request_title, *merge_request_title, *comment_content, *merge_request_path, *pull_request_path, *version, *wiki_title, *wiki_path, *old_name, *ref_name; +@property (strong, nonatomic) NSString *release_title, *release_tag_name, *release_path; @property (readwrite, nonatomic, strong) User *user, *target_user, *watcher; @property (readwrite, nonatomic, strong) NSDate *created_at; @property (readwrite, nonatomic, strong) Task *origin_task, *task; @@ -36,6 +38,10 @@ @property (strong, nonatomic) Commit *commit; @property (strong, nonatomic) FileComment *projectFileComment; @property (strong, nonatomic) ProjectFile *projectFile; +@property (strong, nonatomic) EAMilestone *milestone; + +@property (readwrite, strong, nonatomic) NSString *content; +@property (readwrite, nonatomic, strong) HtmlMedia *htmlMedia; @property (readonly, nonatomic, strong) NSMutableArray *actionMediaItems, *contentMediaItems; @property (readonly, nonatomic, strong) NSMutableString *actionStr, *contentStr; diff --git a/Coding_iOS/Models/ProjectActivity.m b/Coding_iOS/Models/ProjectActivity.m index 33817e403..6bc751ae3 100644 --- a/Coding_iOS/Models/ProjectActivity.m +++ b/Coding_iOS/Models/ProjectActivity.m @@ -32,6 +32,13 @@ - (void)setComment_content:(NSString *)comment_content{ } } +- (void)setContent:(NSString *)content{ + if (_content != content) { + _htmlMedia = [HtmlMedia htmlMediaWithString:content showType:MediaShowTypeNone]; + _content = _htmlMedia.contentDisplay; + } +} + - (NSString *)ref_type{ if ([_ref_type isEqualToString:@"tag"]) { return @"标签"; @@ -73,6 +80,9 @@ - (NSMutableString *)actionStr{ [self addActionUser:_user]; [_actionStr appendFormat:@"%@项目成员", _action_msg]; } + }else if ([_target_type isEqualToString:@"Release"]){ + [self addActionUser:_user]; + [_actionStr appendFormat:@"%@版本", _action_msg]; }else if ([_target_type isEqualToString:@"Task"]){ [self addActionUser:_user]; if ([_action isEqualToString:@"update_priority"]) { @@ -85,6 +95,16 @@ - (NSMutableString *)actionStr{ } }else if ([_action isEqualToString:@"update_description"]) { [_actionStr appendFormat:@"更新了任务「%@」的描述", _task.title]; + }else if ([_action isEqualToString:@"update_label"]) { + [_actionStr appendFormat:@"更新了任务「%@」的标签", _task.title]; + }else if ([_action isEqualToString:@"add_watcher"]){ + [_actionStr saveAppendString:_action_msg]; + [self addActionUser:_watcher]; + }else if ([_action isEqualToString:@"remove_watcher"]){ + [_actionStr saveAppendString:_action_msg]; + [self addActionUser:_watcher]; + }else if ([_action isEqualToString:@"add_milestone"] || [_action isEqualToString:@"remove_milestone"]){ + [_actionStr appendFormat:@"在任务「%@」中%@", _task.title, _action_msg]; }else{ [_actionStr saveAppendString:_action_msg]; if (_origin_task.owner) { @@ -105,43 +125,71 @@ - (NSMutableString *)actionStr{ [self addActionUser:_user]; [_actionStr appendFormat:@"将项目「%@」%@", _project.full_name, _action_msg]; [self addActionUser:_target_user]; + }else if ([_target_type isEqualToString:@"Project"] && [_action isEqualToString:@"transferToTeam"]){ + [self addActionUser:_user]; + [_actionStr appendFormat:@"转让了项目"]; }else{ [self addActionUser:_user]; - [_actionStr saveAppendString:_action_msg]; - if ([_target_type isEqualToString:@"ProjectTopic"]){ - [_actionStr appendString:@"讨论"]; - if ([_action isEqualToString:@"comment"]) { - [_actionStr appendFormat:@"「%@」", _project_topic.parent.title]; - } - }else if ([_target_type isEqualToString:@"ProjectFile"]){ - [_actionStr appendString:[_type isEqualToString:@"dir"]? @"文件夹": @"文件"]; - }else if ([_target_type isEqualToString:@"ProjectFileComment"]){ - [_actionStr appendFormat:@"文件「%@」的评论", _projectFile.title]; - }else if ([_target_type isEqualToString:@"Depot"]){ - if ([_action isEqualToString:@"push"]) { - [_actionStr appendFormat:@"项目 %@ 「%@」", self.ref_type, _ref]; - }else if ([_action isEqualToString:@"fork"]){ - [_actionStr appendFormat:@"项目「%@」到 「%@」", _source_depot.name, _depot.name]; - } + if ([_target_type isEqualToString:@"ProjectTweet"]){ + NSString *action_msg = ([_action isEqualToString:@"create"]? @"发布了": + [_action isEqualToString:@"update"]? @"更新了": + [_action isEqualToString:@"delete"]? @"删除了": + _action); + [_actionStr appendFormat:@"%@项目公告", action_msg]; }else{ - [_actionStr appendString:@"项目"]; - if ([_target_type isEqualToString:@"Project"]){ - }else if ([_target_type isEqualToString:@"QcTask"]){ - [_actionStr appendFormat:@"「%@」的质量分析任务", _project.full_name]; - }else if ([_target_type isEqualToString:@"ProjectStar"]){ - [_actionStr appendFormat:@"「%@」", _project.full_name]; - }else if ([_target_type isEqualToString:@"ProjectWatcher"]){ - [_actionStr appendFormat:@"「%@」", _project.full_name]; - }else if ([_target_type isEqualToString:@"PullRequestBean"]){ - [_actionStr appendFormat:@"「%@」中的 Pull Request", _depot.name]; - }else if ([_target_type isEqualToString:@"PullRequestComment"]){ - [_actionStr appendFormat:@"「%@」中的 Pull Request 「%@」", _depot.name, _pull_request_title]; - }else if ([_target_type isEqualToString:@"MergeRequestBean"]){ - [_actionStr appendFormat:@"「%@」中的 Merge Request", _depot.name]; - }else if ([_target_type isEqualToString:@"MergeRequestComment"]){ - [_actionStr appendFormat:@"「%@」中的 Merge Request 「%@」", _depot.name, _merge_request_title]; - }else if ([_target_type isEqualToString:@"CommitLineNote"]){ - [_actionStr appendFormat:@"「%@」的 %@「%@」", _project.full_name, _line_note.noteable_type, _line_note.noteable_title]; + [_actionStr saveAppendString:_action_msg]; + if ([_target_type isEqualToString:@"ProjectTopic"]){ + [_actionStr appendString:@"讨论"]; + if ([_action isEqualToString:@"comment"]) { + [_actionStr appendFormat:@"「%@」", _project_topic.parent.title]; + } + }else if ([_target_type isEqualToString:@"BranchMember"]){ + if ([@[@"add", @"remove"] containsObject:_action]) { + [_actionStr appendString:@"分支管理员"]; + }else{//deny_push/allow_push + [self addActionUser:self.target_user]; + [_actionStr appendString:@"直接 Push 保护分支"]; + } + }else if ([_target_type isEqualToString:@"ProtectedBranch"]){ +// enable_protected_branch/allow_force_push/disable_protected_branch + }else if ([_target_type isEqualToString:@"ProjectFile"]){ + if ([_action isEqualToString:@"rename"]) { + [_actionStr appendString:@"修改了文件名称"]; + }else{ + [_actionStr appendString:[_type isEqualToString:@"dir"]? @"文件夹": @"文件"]; + } + }else if ([_target_type isEqualToString:@"ProjectFileComment"]){ + [_actionStr appendFormat:@"文件「%@」的评论", _projectFile.title]; + }else if ([_target_type isEqualToString:@"Depot"]){ + if ([_action isEqualToString:@"push"]) { + [_actionStr appendFormat:@"项目 %@ 「%@」", self.ref_type, _ref]; + }else if ([_action isEqualToString:@"fork"]){ + [_actionStr appendFormat:@"项目「%@」到 「%@」", _source_depot.name, _depot.name]; + } + }else if ([_target_type isEqualToString:@"Wiki"]){ + [_actionStr appendString:@"wiki"]; + }else if ([_target_type isEqualToString:@"Milestone"]){ + + }else{ + [_actionStr appendString:@"项目"]; + if ([_target_type isEqualToString:@"Project"]){ + }else if ([_target_type isEqualToString:@"QcTask"]){ + [_actionStr appendFormat:@"「%@」的质量分析任务", _project.full_name]; + }else if ([_target_type isEqualToString:@"ProjectStar"]){ + [_actionStr appendFormat:@"「%@」", _project.full_name]; + }else if ([_target_type isEqualToString:@"ProjectWatcher"]){ + [_actionStr appendFormat:@"「%@」", _project.full_name]; + }else if ([_target_type isEqualToString:@"PullRequestBean"]){ + [_actionStr appendFormat:@"「%@」中的 Pull Request", _depot.name]; + }else if ([_target_type isEqualToString:@"PullRequestComment"]){ + [_actionStr appendFormat:@"「%@」中的 Pull Request 「%@」", _depot.name, _pull_request_title]; + }else if ([_target_type isEqualToString:@"MergeRequestBean"]){ + [_actionStr appendFormat:@"「%@」中的 Merge Request", _depot.name]; + }else if ([_target_type isEqualToString:@"MergeRequestComment"]){ + [_actionStr appendFormat:@"「%@」中的 Merge Request 「%@」", _depot.name, _merge_request_title]; + }else if ([_target_type isEqualToString:@"CommitLineNote"]){ + [_actionStr appendFormat:@"「%@」的 %@「%@」", _project.full_name, _line_note.noteable_type, _line_note.noteable_title]; + } } } } @@ -162,6 +210,14 @@ - (NSMutableString *)contentStr{ [_contentStr appendFormat:@"「%@」", [NSDate convertStr_yyyy_MM_ddToDisplay:_task.deadline]]; }else if ([_action isEqualToString:@"update_description"]) { [_contentStr saveAppendString:_task.description_mine]; + }else if ([_action isEqualToString:@"update_label"]) { + if (_labels.count > 0) { + [_contentStr appendFormat:@"%@", [[_labels valueForKey:@"name"] componentsJoinedByString:@","]]; + }else{ + [_contentStr appendFormat:@"移除了任务的所有标签"]; + } + }else if ([_action isEqualToString:@"add_milestone"] || [_action isEqualToString:@"remove_milestone"]){ + [_contentStr saveAppendString:_milestone.name]; }else{ [_contentStr saveAppendString:_task.title]; } @@ -176,7 +232,11 @@ - (NSMutableString *)contentStr{ [_contentStr saveAppendString:_project_topic.title]; } }else if ([_target_type isEqualToString:@"ProjectFile"]){ - [_contentStr saveAppendString:_file.name]; + if ([_action isEqualToString:@"rename"]) { + [_contentStr appendFormat:@"%@ -> %@", _old_name, _file.name]; + }else{ + [_contentStr saveAppendString:_file.name]; + } }else if ([_target_type isEqualToString:@"ProjectFileComment"]){ [_contentStr saveAppendString:_projectFileComment.content]; }else if ([_target_type isEqualToString:@"Depot"]){ @@ -213,6 +273,22 @@ - (NSMutableString *)contentStr{ [_contentStr saveAppendString:_comment_content]; }else if ([_target_type isEqualToString:@"CommitLineNote"]){ [_contentStr appendFormat:@"%@", _line_note.content]; + }else if ([_target_type isEqualToString:@"Wiki"]){ + [_contentStr appendFormat:@"%@", _wiki_title]; + }else if ([_target_type isEqualToString:@"ProjectTweet"]){ + [_contentStr saveAppendString:_content]; + }else if ([_target_type isEqualToString:@"BranchMember"]){ + if ([@[@"add", @"remove"] containsObject:_action]) { + [_contentStr saveAppendString:self.target_user.name]; + }else{//deny_push/allow_push + [_contentStr saveAppendString:self.ref_name]; + } + }else if ([_target_type isEqualToString:@"ProtectedBranch"]){ + [_contentStr saveAppendString:self.ref_name]; + }else if ([_target_type isEqualToString:@"Milestone"]){ + [_contentStr saveAppendString:_milestone.name]; + }else if ([_target_type isEqualToString:@"Release"]){ + [_contentStr saveAppendString:_release_title.length> 0 ? _release_title: _release_tag_name]; }else{ [_contentStr appendString:@"**未知**"]; } diff --git a/Coding_iOS/Models/ProjectFile.h b/Coding_iOS/Models/ProjectFile.h index da067d2ef..9390227a1 100755 --- a/Coding_iOS/Models/ProjectFile.h +++ b/Coding_iOS/Models/ProjectFile.h @@ -22,20 +22,25 @@ typedef NS_ENUM(NSInteger, DownloadState){ @interface ProjectFile : NSObject @property (readwrite, nonatomic, strong) NSDate *created_at, *updated_at; -@property (readwrite, nonatomic, strong) NSNumber *id,*file_id, *owner_id, *parent_id, *type, *current_user_role_id, *size, *project_id, *number; -@property (readwrite, nonatomic, strong) NSString *name, *fileType, *owner_preview, *preview, *storage_key, *storage_type, *title, *path; +@property (readwrite, nonatomic, strong) NSNumber *id, *file_id, *owner_id, *parent_id, *type, *current_user_role_id, *size, *project_id, *number, *count; +@property (readwrite, nonatomic, strong) NSString *name, *owner_name, *fileType, *owner_preview, *preview, *storage_key, *storage_type, *title, *path; @property (readwrite, nonatomic, strong) User *owner; @property (readwrite, nonatomic, strong) FileShare *share, *share_ea; -@property (strong, nonatomic, readonly) NSString *diskFileName; +@property (strong, nonatomic, readonly) NSString *diskFileName, *storage_key_for_disk; +@property (strong, nonatomic) NSString *next_name; +@property (strong, nonatomic) NSString *project_name, *project_owner_name; + (ProjectFile *)fileWithFileId:(NSNumber *)fileId andProjectId:(NSNumber *)project_id; ++ (instancetype)sharedFolderInProject:(NSString *)project_name ofUser:(NSString *)project_owner_name; - (instancetype)initWithFileId:(NSNumber *)fileId inProject:(NSString *)project_name ofUser:(NSString *)project_owner_name; +- (BOOL)isDefaultFolder; +- (BOOL)isSharedFolder; - (BOOL)isEmpty; - (DownloadState)downloadState; - (Coding_DownloadTask *)cDownloadTask; -- (NSURL *)hasBeenDownload; +- (NSURL *)diskFileUrl; - (NSString *)downloadPath; @@ -51,4 +56,7 @@ typedef NS_ENUM(NSInteger, DownloadState){ - (NSString *)toHistoryListPath; - (NSDictionary *)toShareParams; + +- (NSString *)toFolderFilesPath; +- (NSDictionary *)toFolderFilesParams; @end diff --git a/Coding_iOS/Models/ProjectFile.m b/Coding_iOS/Models/ProjectFile.m index 10c2333e6..8ab4a00df 100755 --- a/Coding_iOS/Models/ProjectFile.m +++ b/Coding_iOS/Models/ProjectFile.m @@ -10,7 +10,6 @@ #import "Coding_FileManager.h" @interface ProjectFile () -@property (strong, nonatomic) NSString *project_name, *project_owner_name; @property (strong, nonatomic, readwrite) NSString *diskFileName; @end @@ -37,7 +36,7 @@ -(id)copyWithZone:(NSZone*)zone { file.type = [_type copy]; file.parent_id = [_parent_id copy]; file.owner_id = [_owner_id copy]; - file.file_id = [_file_id copy]; + file.file_id = [self.file_id copy]; file.created_at = [_created_at copy]; file.updated_at = [_updated_at copy]; file.id=[_id copy]; @@ -52,10 +51,16 @@ +(ProjectFile *)fileWithFileId:(NSNumber *)fileId andProjectId:(NSNumber *)proje return file; } ++ (instancetype)sharedFolderInProject:(NSString *)project_name ofUser:(NSString *)project_owner_name{ + ProjectFile *file = [[self alloc] initWithFileId:@(-1) inProject:project_name ofUser:project_owner_name]; + file.type = @0;//文件夹类型 + return file; +} + - (instancetype)initWithFileId:(NSNumber *)fileId inProject:(NSString *)project_name ofUser:(NSString *)project_owner_name{ self = [super init]; if (self) { - _file_id = fileId; + self.file_id = fileId; _project_id = nil; _project_name = project_name; _project_owner_name = project_owner_name; @@ -72,13 +77,29 @@ - (void)setOwner_preview:(NSString *)owner_preview{ } } +- (NSNumber *)file_id{ + return _file_id ?: _id; +} + +- (void)setCount:(NSNumber *)count{ + _count = @(MAX(0, count.integerValue)); +} + +- (BOOL)isDefaultFolder{ + return _file_id && _file_id.integerValue == 0; +} + +- (BOOL)isSharedFolder{ + return _file_id && _file_id.integerValue == -1; +} + - (BOOL)isEmpty{ return !(self.storage_key && self.storage_key.length > 0); } - (DownloadState)downloadState{ DownloadState state = DownloadStateDefault; - if ([self hasBeenDownload]) { + if ([self diskFileUrl]) { state = DownloadStateDownloaded; }else{ Coding_DownloadTask *cDownloadTask = [self cDownloadTask]; @@ -95,33 +116,50 @@ - (DownloadState)downloadState{ return state; } +- (NSString *)owner_name{ + return _owner_name ?: _owner.name; +} + - (NSString *)downloadPath{ - NSString *path = [NSString stringWithFormat:@"%@api/project/%@/files/%@/download", [NSObject baseURLStr], _project_id.stringValue, _file_id.stringValue]; + NSString *path = [NSString stringWithFormat:@"%@api/project/%@/files/%@/download", [NSObject baseURLStr], _project_id.stringValue, self.file_id.stringValue]; return path; } - (NSString *)diskFileName{ if (!_diskFileName) { - _diskFileName = [NSString stringWithFormat:@"%@|||%@|||%@|%@", _name, _project_id.stringValue, _storage_type, _storage_key]; + _diskFileName = [NSString stringWithFormat:@"%@|||%@|||%@|%@", _name, _project_id.stringValue, _storage_type, self.storage_key_for_disk]; } return _diskFileName; } +- (NSString *)storage_key_for_disk{ + NSArray *fileNameCom = [_name componentsSeparatedByString:@"."]; + NSMutableArray *storage_keyCom = [_storage_key componentsSeparatedByString:@"."].mutableCopy; + if (fileNameCom.count > 1 && storage_keyCom.count > 0 && ![fileNameCom.lastObject isEqualToString:storage_keyCom.lastObject]) {//_storage_key 后缀名与 fileNameCom 后缀名不同的情况 + [storage_keyCom addObject:fileNameCom.lastObject]; + return [storage_keyCom componentsJoinedByString:@"."]; + }else if (_storage_key.length > 0){ + return [_storage_key componentsSeparatedByString:@"/"].lastObject;//'group0/M00/00/01/fwAAAVsHsvqAOY8rABzvMF5h1Ck652.JPG'..诡异的前半截数据 + }else{// 说是以后,可能迁移到腾讯云,_storage_key 字段可能不保 + return [NSString stringWithFormat:@"%@_%@.%@", _project_id, _file_id, fileNameCom.lastObject]; + } +} + - (Coding_DownloadTask *)cDownloadTask{ return [Coding_FileManager cDownloadTaskForKey:_storage_key]; } -- (NSURL *)hasBeenDownload{ - return [Coding_FileManager diskDownloadUrlForKey:_storage_key]; +- (NSURL *)diskFileUrl{ + return [Coding_FileManager diskDownloadUrlForKey:self.storage_key] ?: [Coding_FileManager diskDownloadUrlForKey:self.storage_key_for_disk]; } - (NSString *)toDeletePath{ return [NSString stringWithFormat:@"api/project/%@/file/delete", _project_id.stringValue]; } - (NSDictionary *)toDeleteParams{ - return @{@"fileIds" : @[_file_id.stringValue]}; + return @{@"fileIds" : @[self.file_id.stringValue]}; } - (NSDictionary *)toMoveToParams{ - return @{@"fileId" : @[_file_id.stringValue]}; + return @{@"fileId" : @[self.file_id.stringValue]}; } - (NSString *)toDetailPath{ @@ -135,20 +173,36 @@ - (NSString *)toDetailPath{ } - (NSString *)toActivityListPath{ - return [NSString stringWithFormat:@"api/project/%@/file/%@/activities", _project_id.stringValue, _file_id.stringValue]; + return [NSString stringWithFormat:@"api/project/%@/file/%@/activities", _project_id.stringValue, self.file_id.stringValue]; } - (NSString *)toHistoryListPath{ - return [NSString stringWithFormat:@"api/project/%@/files/%@/histories", _project_id.stringValue, _file_id.stringValue]; + return [NSString stringWithFormat:@"api/project/%@/files/%@/histories", _project_id.stringValue, self.file_id.stringValue]; } - (NSDictionary *)toShareParams{ return @{ @"projectId": _project_id, - @"resourceId": _file_id, + @"resourceId": self.file_id, @"resourceType": @0, @"accessType": @0 }; } + + + +- (NSString *)toFolderFilesPath{ + if (self.isSharedFolder) { + return [NSString stringWithFormat:@"api/user/%@/project/%@/folder/shared_files", _project_owner_name, _project_name]; + }else{ + return [NSString stringWithFormat:@"api/user/%@/project/%@/folder/%@/all", _project_owner_name, _project_name, self.file_id]; + } +} +- (NSDictionary *)toFolderFilesParams{ + return @{@"height": @"90", + @"width": @"90", + @"page" : @"1", + @"pageSize": @"500"}; +} @end diff --git a/Coding_iOS/Models/ProjectFiles.h b/Coding_iOS/Models/ProjectFiles.h index 296a8520d..711f7df63 100755 --- a/Coding_iOS/Models/ProjectFiles.h +++ b/Coding_iOS/Models/ProjectFiles.h @@ -16,4 +16,6 @@ @property (strong, nonatomic) NSDictionary *propertyArrayMap; @property (assign, nonatomic) BOOL isLoading; +@property (readonly, nonatomic, strong) NSMutableArray *fileList, *folderList; +- (void)addSharedFolder; @end diff --git a/Coding_iOS/Models/ProjectFiles.m b/Coding_iOS/Models/ProjectFiles.m index 14d5c0da6..470f45640 100755 --- a/Coding_iOS/Models/ProjectFiles.m +++ b/Coding_iOS/Models/ProjectFiles.m @@ -20,4 +20,19 @@ - (instancetype)init } return self; } + +- (void)setList:(NSMutableArray *)list{ + _list = list.mutableCopy; + _folderList = [list filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"type == 0"]]].mutableCopy ?: @[].mutableCopy; + _fileList = [list filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"type != 0"]]].mutableCopy ?: @[].mutableCopy; + +} + +- (void)addSharedFolder{ + ProjectFile *tempF = _list.firstObject; + ProjectFile *sharedF = [ProjectFile sharedFolderInProject:tempF.project_name ofUser:tempF.project_owner_name]; + [_list insertObject:sharedF atIndex:0]; + [_folderList insertObject:sharedF atIndex:0]; +} + @end diff --git a/Coding_iOS/Models/ProjectFolder.m b/Coding_iOS/Models/ProjectFolder.m index d53cafa4d..dfa89836b 100755 --- a/Coding_iOS/Models/ProjectFolder.m +++ b/Coding_iOS/Models/ProjectFolder.m @@ -88,7 +88,7 @@ - (NSDictionary *)toFilesParams{ return @{@"height": @"90", @"width": @"90", @"page" : @"1", - @"pageSize": @"9999"}; + @"pageSize": @(999999999)}; } - (NSString *)toRenamePath{ return [NSString stringWithFormat:@"api/project/%@/dir/%@/name/%@", _project_id.stringValue, _file_id.stringValue, _next_name]; diff --git a/Coding_iOS/Models/ProjectFolders.m b/Coding_iOS/Models/ProjectFolders.m index ab3096f3e..46ca99cb1 100755 --- a/Coding_iOS/Models/ProjectFolders.m +++ b/Coding_iOS/Models/ProjectFolders.m @@ -56,7 +56,7 @@ - (NSString *)toFoldersPathWithObj:(NSNumber *)project_id{ } - (NSDictionary *)toFoldersParams{ return @{@"page": @"1", - @"pageSize": @"9999"}; + @"pageSize": @(999999999)}; } - (NSString *)toFoldersCountPathWithObj:(NSNumber *)project_id{ diff --git a/Coding_iOS/Models/ProjectLineNote.h b/Coding_iOS/Models/ProjectLineNote.h index b17757dfc..598622024 100644 --- a/Coding_iOS/Models/ProjectLineNote.h +++ b/Coding_iOS/Models/ProjectLineNote.h @@ -8,6 +8,9 @@ #import #import "User.h" +#import "ProjectTag.h" + +@class ProjectLineNoteComment; @interface ProjectLineNote : NSObject @property (strong, nonatomic) User *author; @@ -26,4 +29,15 @@ @property (readwrite, strong, nonatomic) NSNumber *position; @property (strong, nonatomic) NSDate *created_at; @property (readwrite, nonatomic, strong) HtmlMedia *htmlMedia; + +@property (strong, nonatomic) ProjectLineNoteComment *comment; + +@end + + +@interface ProjectLineNoteComment : NSObject + +@property (strong, nonatomic) User *reviewer, *watcher; +@property (strong, nonatomic) ProjectTag *label; + @end diff --git a/Coding_iOS/Models/ProjectLineNote.m b/Coding_iOS/Models/ProjectLineNote.m index d803fcd8f..2acc519d6 100644 --- a/Coding_iOS/Models/ProjectLineNote.m +++ b/Coding_iOS/Models/ProjectLineNote.m @@ -17,3 +17,18 @@ - (void)setContent:(NSString *)content{ } @end + + +@implementation ProjectLineNoteComment + +- (void)setLabel:(NSString *)label{ + if ([label isKindOfClass:[NSString class]] && label.length > 0) { + NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:[label dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:nil]; + _label = [NSObject objectOfClass:@"ProjectTag" fromJSON:jsonDict]; + + }else{ + _label = nil; + } +} + +@end diff --git a/Coding_iOS/Models/ProjectRole.h b/Coding_iOS/Models/ProjectRole.h new file mode 100644 index 000000000..b9bcf7657 --- /dev/null +++ b/Coding_iOS/Models/ProjectRole.h @@ -0,0 +1,16 @@ +// +// ProjectRole.h +// Coding_Enterprise_iOS +// +// Created by Easeeeeeeeee on 2017/6/6. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import +#import "Project.h" + +@interface ProjectRole : NSObject +@property (strong, nonatomic) NSString *alias; +@property (strong, nonatomic) NSNumber *id, *project_id, *user_id, *type; +@property (strong, nonatomic) Project *project; +@end diff --git a/Coding_iOS/Models/ProjectRole.m b/Coding_iOS/Models/ProjectRole.m new file mode 100644 index 000000000..3f577d2fa --- /dev/null +++ b/Coding_iOS/Models/ProjectRole.m @@ -0,0 +1,13 @@ +// +// ProjectRole.m +// Coding_Enterprise_iOS +// +// Created by Easeeeeeeeee on 2017/6/6. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "ProjectRole.h" + +@implementation ProjectRole + +@end diff --git a/Coding_iOS/Models/Projects.h b/Coding_iOS/Models/Projects.h index 199fe53a6..c9ab9dc40 100755 --- a/Coding_iOS/Models/Projects.h +++ b/Coding_iOS/Models/Projects.h @@ -27,6 +27,8 @@ typedef NS_ENUM(NSInteger, ProjectsType) { ProjectsTypeAll = 0, ProjectsTypeCreated, + ProjectsTypeCreatedPrivate, + ProjectsTypeCreatedPublic, ProjectsTypeJoined, ProjectsTypeWatched, ProjectsTypeStared, diff --git a/Coding_iOS/Models/Projects.m b/Coding_iOS/Models/Projects.m index 4e9c53248..3eb35892d 100755 --- a/Coding_iOS/Models/Projects.m +++ b/Coding_iOS/Models/Projects.m @@ -30,7 +30,7 @@ + (Projects *)projectsWithType:(ProjectsType)type andUser:(User *)user{ pros.curUser = user; pros.page = [NSNumber numberWithInteger:1]; - pros.pageSize = [NSNumber numberWithInteger:9999]; + pros.pageSize = @(999999999); return pros; } @@ -45,6 +45,8 @@ - (NSString *)typeStr{ typeStr = @"joined"; break; case ProjectsTypeCreated: + case ProjectsTypeCreatedPrivate: + case ProjectsTypeCreatedPublic: typeStr = @"created"; break; case ProjectsTypeTaProject: @@ -102,6 +104,8 @@ - (void)configWithProjects:(Projects *)responsePros{ NSArray *projectList = responsePros.list; if (self.type == ProjectsTypeToChoose) { projectList = [projectList filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"is_public == %d", NO]]; + }else if (self.type == ProjectsTypeCreatedPrivate || self.type == ProjectsTypeCreatedPublic){ + projectList = [projectList filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"is_public == %d", (self.type == ProjectsTypeCreatedPublic)]]; } if (!projectList) { return; diff --git a/Coding_iOS/Models/ResourceReference.h b/Coding_iOS/Models/ResourceReference.h index 198da4f29..3dfb79c3f 100644 --- a/Coding_iOS/Models/ResourceReference.h +++ b/Coding_iOS/Models/ResourceReference.h @@ -9,7 +9,7 @@ #import @interface ResourceReference : NSObject -@property (strong, nonatomic) NSMutableArray *Task, *MergeRequestBean, *ProjectTopic, *ProjectFile, *itemList; +@property (strong, nonatomic) NSMutableArray *Task, *MergeRequestBean, *ProjectTopic, *ProjectFile, *Release, *Wiki, *itemList; @property (readwrite, nonatomic, strong) NSDictionary *propertyArrayMap; @end @@ -17,4 +17,4 @@ @interface ResourceReferenceItem : NSObject @property (strong, nonatomic) NSString *target_type, *title, *link; @property (strong, nonatomic) NSNumber *code, *target_id; -@end \ No newline at end of file +@end diff --git a/Coding_iOS/Models/ResourceReference.m b/Coding_iOS/Models/ResourceReference.m index fcc5c633d..e96c1251c 100644 --- a/Coding_iOS/Models/ResourceReference.m +++ b/Coding_iOS/Models/ResourceReference.m @@ -17,6 +17,8 @@ - (instancetype)init @"MergeRequestBean": @"ResourceReferenceItem", @"ProjectTopic": @"ResourceReferenceItem", @"ProjectFile": @"ResourceReferenceItem", + @"Release": @"ResourceReferenceItem", + @"Wiki": @"ResourceReferenceItem", }; } @@ -29,6 +31,8 @@ - (NSMutableArray *)itemList{ [_itemList addObjectsFromArray:_ProjectTopic]; [_itemList addObjectsFromArray:_ProjectFile]; [_itemList addObjectsFromArray:_MergeRequestBean]; + [_itemList addObjectsFromArray:_Release]; + [_itemList addObjectsFromArray:_Wiki]; } return _itemList; } @@ -36,4 +40,4 @@ - (NSMutableArray *)itemList{ @implementation ResourceReferenceItem -@end \ No newline at end of file +@end diff --git a/Coding_iOS/Models/Shop.m b/Coding_iOS/Models/Shop.m index 4e541d44a..052863516 100644 --- a/Coding_iOS/Models/Shop.m +++ b/Coding_iOS/Models/Shop.m @@ -72,7 +72,7 @@ - (void)configWithGiftGoods:(NSArray *)responseA{ if (responseA && [responseA count] > 0) { [responseA enumerateObjectsUsingBlock:^(ShopGoods *obj, NSUInteger idx, BOOL * _Nonnull stop) { - if (_points_left.doubleValue >= obj.points_cost.doubleValue) { + if (obj.available_points.doubleValue >= obj.points_cost.doubleValue) { obj.exchangeable = YES; } }]; @@ -97,7 +97,7 @@ - (void)configWithGiftGoods:(NSArray *)responseA{ - (NSArray *)getExchangeGiftData { - NSMutableArray *mutaleArray = [NSMutableArray arrayWithCapacity:10]; + NSMutableArray *mutaleArray = [NSMutableArray new]; [_shopGoodsArray enumerateObjectsUsingBlock:^(ShopGoods *obj, NSUInteger idx, BOOL * _Nonnull stop) { if (obj.exchangeable) { [mutaleArray addObject:obj]; diff --git a/Coding_iOS/Models/ShopGoods.h b/Coding_iOS/Models/ShopGoods.h index 8f7abb44b..4665d4493 100644 --- a/Coding_iOS/Models/ShopGoods.h +++ b/Coding_iOS/Models/ShopGoods.h @@ -11,16 +11,21 @@ @interface ShopGoods : BaseModel @property (strong, nonatomic) NSNumber *id; -@property (strong, nonatomic) NSNumber *points_cost; +@property (strong, nonatomic) NSNumber *points_cost, *count, *available_points, *price; @property (strong, nonatomic) NSString *image ,*name ,*giftId; @property (assign, nonatomic) BOOL exchangeable; //能否兑换的 @property (strong, nonatomic) NSString *description_mine; @property (strong, nonatomic) NSArray *options; @property (strong, nonatomic) NSDictionary *propertyArrayMap; +@property (assign, nonatomic) BOOL usePoint; + +@property (assign, nonatomic, readonly) BOOL hasAvailablePoints, needToPay; +@property (assign, nonatomic, readonly) NSString *curPrice, *curPointWillUse; + @end @interface ShopGoodsOption : BaseModel @property (strong, nonatomic) NSNumber *id, *gift_id, *status, *size; @property (strong, nonatomic) NSString *name; -@end \ No newline at end of file +@end diff --git a/Coding_iOS/Models/ShopGoods.m b/Coding_iOS/Models/ShopGoods.m index 9d80f8562..9a07bc802 100644 --- a/Coding_iOS/Models/ShopGoods.m +++ b/Coding_iOS/Models/ShopGoods.m @@ -15,11 +15,29 @@ - (instancetype)init if (self) { _propertyArrayMap = [NSDictionary dictionaryWithObjectsAndKeys: @"ShopGoodsOption", @"options", nil]; + _usePoint = YES; } return self; } + +- (BOOL)hasAvailablePoints{ + return (_available_points && _available_points.floatValue > 0); +} + +- (BOOL)needToPay{ + return self.curPrice.floatValue > 0; +} + +- (NSString *)curPrice{ + return [NSString stringWithFormat:@"%.2f", !_usePoint? _points_cost.floatValue * 50: MAX(0, _points_cost.floatValue - _available_points.floatValue) * 50]; +} + +- (NSString *)curPointWillUse{ + return [NSString stringWithFormat:@"%.2f", !_usePoint? 0: MIN(_points_cost.floatValue, _available_points.floatValue)]; +} + @end @implementation ShopGoodsOption -@end \ No newline at end of file +@end diff --git a/Coding_iOS/Models/ShopOrder.h b/Coding_iOS/Models/ShopOrder.h index 8004d9533..2b2d4b654 100644 --- a/Coding_iOS/Models/ShopOrder.h +++ b/Coding_iOS/Models/ShopOrder.h @@ -14,7 +14,7 @@ @property (strong, nonatomic) NSNumber *userId; @property (strong, nonatomic) NSNumber *giftId; @property (strong, nonatomic) NSNumber *pointsCost; -@property (strong, nonatomic) NSNumber *status; +@property (strong, nonatomic) NSNumber *status;//3 待付款, 0 未发货, 1 已发货, 2 已完成 @property (strong, nonatomic) NSNumber *createdAt; @property (strong, nonatomic) NSString *receiverName; @property (strong, nonatomic) NSString *receiverAddress; @@ -25,4 +25,5 @@ @property (strong, nonatomic) NSString *giftImage; @property (strong, nonatomic) NSString *remark; @property (strong, nonatomic) NSString *optionName; +@property (strong, nonatomic) NSNumber *paymentAmount, *pointDiscount; @end diff --git a/Coding_iOS/Models/ShopOrderModel.h b/Coding_iOS/Models/ShopOrderModel.h index a6f59c427..4d7c90d8a 100644 --- a/Coding_iOS/Models/ShopOrderModel.h +++ b/Coding_iOS/Models/ShopOrderModel.h @@ -12,6 +12,7 @@ typedef NS_ENUM(NSInteger, ShopOrderType) { ShopOrderAll = 0, + ShopOrderUnPay, ShopOrderUnSend, ShopOrderSend, }; diff --git a/Coding_iOS/Models/ShopOrderModel.m b/Coding_iOS/Models/ShopOrderModel.m index c31da4deb..62f681192 100644 --- a/Coding_iOS/Models/ShopOrderModel.m +++ b/Coding_iOS/Models/ShopOrderModel.m @@ -40,7 +40,7 @@ - (void)configOrderWithReson:(NSArray *)responseA if (responseA && [responseA count] > 0) { self.canLoadMore = (responseA.count >= _pageSize.intValue); - if (_page.intValue == 1) { + if (!_willLoadMore) { _dateSource = [NSMutableArray arrayWithArray:responseA]; }else { @@ -57,6 +57,19 @@ - (NSArray *)getDataSourceByOrderType case ShopOrderAll: return _dateSource; break; + case ShopOrderUnPay: + { + NSMutableArray *array = [NSMutableArray arrayWithCapacity:10]; + [_dateSource enumerateObjectsUsingBlock:^(ShopOrder *obj, NSUInteger idx, BOOL * _Nonnull stop) { + if (obj.status.intValue == 3) { + if (obj) { + [array addObject:obj]; + } + } + }]; + return array; + break; + } case ShopOrderSend: { NSMutableArray *array = [NSMutableArray arrayWithCapacity:10]; diff --git a/Coding_iOS/Models/Task.h b/Coding_iOS/Models/Task.h index 343f677d0..709ee8def 100755 --- a/Coding_iOS/Models/Task.h +++ b/Coding_iOS/Models/Task.h @@ -13,9 +13,11 @@ #import "TaskComment.h" #import "ProjectTag.h" #import "ResourceReference.h" +#import "EABoardTaskList.h" @class Project; @class Task_Description; +@class EABoardTaskList; typedef NS_ENUM(NSInteger, TaskHandleType) { TaskHandleTypeEdit = 0, @@ -37,8 +39,10 @@ typedef NS_ENUM(NSInteger, TaskHandleType) { @property (readwrite, nonatomic, strong) NSString *nextCommentStr; @property (strong, nonatomic) Task_Description *task_description; @property (strong, nonatomic) ResourceReference *resourceReference; +@property (strong, nonatomic) EABoardTaskList *task_board_list; + (Task *)taskWithProject:(Project *)project andUser:(User *)user; ++ (Task *)taskWithBoardTaskList:(EABoardTaskList *)boardTL andUser:(User *)user; + (Task *)taskWithBackend_project_path:(NSString *)backend_project_path andId:(NSString *)taskId; + (Task *)taskWithTask:(Task *)task; - (BOOL)isSameToTask:(Task *)task; diff --git a/Coding_iOS/Models/Task.m b/Coding_iOS/Models/Task.m index 72fad52a3..9c575c060 100755 --- a/Coding_iOS/Models/Task.m +++ b/Coding_iOS/Models/Task.m @@ -66,6 +66,11 @@ + (Task *)taskWithProject:(Project *)project andUser:(User *)user{ curTask.task_description = [Task_Description defaultDescription]; return curTask; } ++ (Task *)taskWithBoardTaskList:(EABoardTaskList *)boardTL andUser:(User *)user{ + Task *curTask = [self taskWithProject:boardTL.curPro andUser:user]; + curTask.task_board_list = boardTL; + return curTask; +} + (Task *)taskWithTask:(Task *)task{ Task *curTask = [[Task alloc] init]; [curTask copyDataFrom:task]; @@ -84,6 +89,7 @@ - (BOOL)isSameToTask:(Task *)task{ } return ([self.content isEqualToString:task.content] && [self.owner.global_key isEqualToString:task.owner.global_key] + && ((!self.task_board_list && !task.task_board_list) || (task.task_board_list.id && [self.task_board_list.id isEqualToNumber:task.task_board_list.id])) && self.priority.intValue == task.priority.intValue && self.status.intValue == task.status.intValue && ((!self.deadline && !task.deadline) || [self.deadline isEqualToString:task.deadline]) @@ -121,6 +127,7 @@ - (void)copyDataFrom:(Task *)task{ self.needRefreshDetail = task.needRefreshDetail; self.deadline = task.deadline; self.number = task.number; + self.task_board_list = task.task_board_list; self.has_description = task.has_description; self.task_description = task.task_description; @@ -169,6 +176,7 @@ -(NSDictionary *)toUpdateParamsWithOld:(Task *)oldTask{ }else if (oldTask.deadline && !self.deadline){ [params setObject:@"" forKey:@"deadline"]; } + params[@"task_board_list"] = _task_board_list.id ?: @""; return params; } @@ -197,6 +205,9 @@ - (NSDictionary *)toAddTaskParams{ if (self.watchers.count > 0) { params[@"watchers"] = [self.watchers valueForKey:@"id"]; } + if (_task_board_list) { + params[@"task_board_list"] = _task_board_list.id; + } return params; } //删除任务 diff --git a/Coding_iOS/Models/Tasks.h b/Coding_iOS/Models/Tasks.h index 8030bbb34..69ceb10c3 100755 --- a/Coding_iOS/Models/Tasks.h +++ b/Coding_iOS/Models/Tasks.h @@ -20,6 +20,14 @@ typedef NS_ENUM(NSInteger, TaskEntranceType){ TaskEntranceTypeMine, }; +typedef NS_ENUM(NSInteger, TaskRoleType) +{ + TaskRoleTypeOwner = 0, //执行者 + TaskRoleTypeWatcher, //关注者 + TaskRoleTypeCreator, //创建者 + TaskRoleTypeAll, //所有任务 +}; + @interface Tasks : NSObject @property (readwrite, nonatomic, strong) NSNumber *page, *pageSize, *totalPage, *totalRow; diff --git a/Coding_iOS/Models/Team.h b/Coding_iOS/Models/Team.h index 5d54e9fca..fd5395cdf 100644 --- a/Coding_iOS/Models/Team.h +++ b/Coding_iOS/Models/Team.h @@ -5,13 +5,32 @@ // Created by Ease on 2016/9/9. // Copyright © 2016年 Coding. All rights reserved. // +#define kEANeedTipRemainDays 5 #import #import "User.h" +@class TeamInfo; + @interface Team : NSObject @property (strong, nonatomic) NSNumber *id, *member_count, *project_count, *current_user_role_id; +@property (strong, nonatomic) NSNumber *locked;//是否被锁定(停用) @property (strong, nonatomic) NSString *name, *introduction, *avatar, *path, *global_key; @property (strong, nonatomic) NSDate *created_at, *updated_at; @property (strong, nonatomic) User *owner; -@end \ No newline at end of file +@property (strong, nonatomic) TeamInfo *info;//需要另行请求的参数 request_InfoOfTeam +@property (assign, nonatomic) BOOL hasDismissWebTip; ++ (instancetype)teamWithGK:(NSString *)global_key; +- (NSString *)toUpdateInfoPath; +- (NSDictionary *)toUpdateInfoParams; +@end + +@interface TeamInfo : NSObject +@property (strong, nonatomic) NSNumber *balance, *remain_days, *trial, *payed; +@property (strong, nonatomic) NSDate *billing_date, *created_at, *estimate_date, *suspended_at; +@property (strong, nonatomic) NSNumber *locked;//是否被锁定(停用) +- (BOOL)isToped_up; +- (NSInteger)stopped_days; +- (NSInteger)beyond_days; +- (NSInteger)trial_left_days; +@end diff --git a/Coding_iOS/Models/Team.m b/Coding_iOS/Models/Team.m index fa0ec62b9..0797387f0 100644 --- a/Coding_iOS/Models/Team.m +++ b/Coding_iOS/Models/Team.m @@ -5,9 +5,47 @@ // Created by Ease on 2016/9/9. // Copyright © 2016年 Coding. All rights reserved. // +#define kEAMaxTrialDays 15 #import "Team.h" @implementation Team ++ (instancetype)teamWithGK:(NSString *)global_key{ + Team *team = [Team new]; + team.global_key = global_key; + return team; +} +- (NSString *)toUpdateInfoPath{ + return [NSString stringWithFormat:@"api/team/%@/update", _global_key]; +} +- (NSDictionary *)toUpdateInfoParams{ + return @{@"global_key": _global_key, + @"name": _name, + @"introduction": _introduction ?: @"", + }; +} + +@end + +@implementation TeamInfo +- (BOOL)isToped_up{//是否充过值 + return _payed? _payed.boolValue: _balance.integerValue > 0; +} + +- (NSInteger)stopped_days{//停用天数 + if (_suspended_at) { + return MAX(0, [_suspended_at daysAgo]); + }else{ + return MAX(0, [_estimate_date daysAgo] - ([self isToped_up]? 5: 0)); + } +} + +- (NSInteger)beyond_days{//超期天数 + return MAX(0, [_estimate_date daysAgo]); +} + +- (NSInteger)trial_left_days{//试用期剩余天数 + return MAX(0, kEAMaxTrialDays - MAX(0, [_created_at daysAgo])); +} @end diff --git a/Coding_iOS/Models/TeamMember.h b/Coding_iOS/Models/TeamMember.h index 5442f93f3..18f015490 100644 --- a/Coding_iOS/Models/TeamMember.h +++ b/Coding_iOS/Models/TeamMember.h @@ -10,13 +10,13 @@ #import "User.h" @interface TeamMember : NSObject -@property (readwrite, nonatomic, strong) NSNumber *id, *team_id, *user_id, *role;//role:80是member,100是creater +@property (readwrite, nonatomic, strong) NSNumber *id, *team_id, *user_id, *role;//role:80是member,90是admin,100是creater @property (readwrite, nonatomic, strong) User *user; @property (readwrite, nonatomic, strong) NSDate *created_at, *updated_at; @property (strong, nonatomic) NSString *alias, *default2faMethod; //edit @property (strong, nonatomic) NSString *editAlias; -@property (strong, nonatomic) NSNumber *editType; +@property (strong, nonatomic) NSNumber *editRole; -@end \ No newline at end of file +@end diff --git a/Coding_iOS/Models/TeamMember.m b/Coding_iOS/Models/TeamMember.m index 81ebd1e4c..774af3cc1 100644 --- a/Coding_iOS/Models/TeamMember.m +++ b/Coding_iOS/Models/TeamMember.m @@ -10,4 +10,17 @@ @implementation TeamMember +- (NSString *)editAlias{ + if (!_editAlias) { + _editAlias = _alias ?: @""; + } + return _editAlias; +} +- (NSNumber *)editRole{ + if (!_editRole) { + _editRole = _role; + } + return _editRole; +} + @end diff --git a/Coding_iOS/Models/TeamPurchaseBilling.h b/Coding_iOS/Models/TeamPurchaseBilling.h new file mode 100644 index 000000000..c9c6e008e --- /dev/null +++ b/Coding_iOS/Models/TeamPurchaseBilling.h @@ -0,0 +1,20 @@ +// +// TeamPurchaseBilling.h +// Coding_Enterprise_iOS +// +// Created by Ease on 2017/3/7. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import +#import "TeamPurchaseBillingDetail.h" + +@interface TeamPurchaseBilling : NSObject +@property (strong, nonatomic) NSNumber *id, *price, *balance; +@property (strong, nonatomic) NSDate *created_at, *billing_date; +@property (strong, nonatomic) NSArray *details; +@property (strong, nonatomic, readonly) NSArray *details_display; +@property (strong, nonatomic, readonly) NSDictionary *propertyArrayMap; + +@property (assign, nonatomic) BOOL isExpanded;//UI 页面是都展开了 +@end diff --git a/Coding_iOS/Models/TeamPurchaseBilling.m b/Coding_iOS/Models/TeamPurchaseBilling.m new file mode 100644 index 000000000..ea4dbb705 --- /dev/null +++ b/Coding_iOS/Models/TeamPurchaseBilling.m @@ -0,0 +1,30 @@ +// +// TeamPurchaseBilling.m +// Coding_Enterprise_iOS +// +// Created by Ease on 2017/3/7. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "TeamPurchaseBilling.h" + +@implementation TeamPurchaseBilling + +- (NSDictionary *)propertyArrayMap{ + return @{@"details": @"TeamPurchaseBillingDetail"}; +} + +- (void)setDetails:(NSArray *)details{ + _details = details; + NSSet *daySet = [NSSet setWithArray:[_details valueForKey:@"days"]]; + NSArray *dayArray = [daySet sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:nil ascending:NO selector:@selector(compare:)]]]; + NSMutableArray *details_display = @[].mutableCopy; + for (NSNumber *day in dayArray) { + NSArray *list = [_details filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"days = %@", day]]; +// NSString *displayStr = [NSString stringWithFormat:@"%lu 人,已使用 %@ 天", (unsigned long)list.count, day]; + NSString *displayStr = [NSString stringWithFormat:@"%lu 人", (unsigned long)list.count]; + [details_display addObject:displayStr]; + } + _details_display = details_display; +} +@end diff --git a/Coding_iOS/Models/TeamPurchaseBillingDetail.h b/Coding_iOS/Models/TeamPurchaseBillingDetail.h new file mode 100644 index 000000000..c604ef254 --- /dev/null +++ b/Coding_iOS/Models/TeamPurchaseBillingDetail.h @@ -0,0 +1,15 @@ +// +// TeamPurchaseBillingDetail.h +// Coding_Enterprise_iOS +// +// Created by Ease on 2017/3/7. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import + +@interface TeamPurchaseBillingDetail : NSObject +@property (strong, nonatomic) NSString *user_name, *user_gk; +@property (strong, nonatomic) NSNumber *days; +@property (strong, nonatomic) NSDate *start_date, *end_date; +@end diff --git a/Coding_iOS/Models/TeamPurchaseBillingDetail.m b/Coding_iOS/Models/TeamPurchaseBillingDetail.m new file mode 100644 index 000000000..5f016f4e1 --- /dev/null +++ b/Coding_iOS/Models/TeamPurchaseBillingDetail.m @@ -0,0 +1,13 @@ +// +// TeamPurchaseBillingDetail.m +// Coding_Enterprise_iOS +// +// Created by Ease on 2017/3/7. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "TeamPurchaseBillingDetail.h" + +@implementation TeamPurchaseBillingDetail + +@end diff --git a/Coding_iOS/Models/TeamPurchaseOrder.h b/Coding_iOS/Models/TeamPurchaseOrder.h new file mode 100644 index 000000000..4028f8c78 --- /dev/null +++ b/Coding_iOS/Models/TeamPurchaseOrder.h @@ -0,0 +1,15 @@ +// +// TeamPurchaseOrder.h +// Coding_Enterprise_iOS +// +// Created by Ease on 2017/3/7. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import + +@interface TeamPurchaseOrder : NSObject +@property (strong, nonatomic) NSNumber *price; +@property (strong, nonatomic) NSString *number, *status, *action, *creator_name, *creator_gk; +@property (strong, nonatomic) NSDate *created_at; +@end diff --git a/Coding_iOS/Models/TeamPurchaseOrder.m b/Coding_iOS/Models/TeamPurchaseOrder.m new file mode 100644 index 000000000..6061948c0 --- /dev/null +++ b/Coding_iOS/Models/TeamPurchaseOrder.m @@ -0,0 +1,13 @@ +// +// TeamPurchaseOrder.m +// Coding_Enterprise_iOS +// +// Created by Ease on 2017/3/7. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "TeamPurchaseOrder.h" + +@implementation TeamPurchaseOrder + +@end diff --git a/Coding_iOS/Models/Tweet.h b/Coding_iOS/Models/Tweet.h index 1d49187a1..966a62b4e 100644 --- a/Coding_iOS/Models/Tweet.h +++ b/Coding_iOS/Models/Tweet.h @@ -16,7 +16,7 @@ @class TweetImage; @interface Tweet : NSObject -@property (readwrite, nonatomic, strong) NSString *content, *device, *location, *coord, *address; +@property (readwrite, nonatomic, strong) NSString *content, *device, *location, *coord, *address, *raw; @property (readwrite, nonatomic, strong) NSNumber *liked, *rewarded, *activity_id, *id, *comments, *likes, *rewards; @property (readwrite, nonatomic, strong) NSDate *created_at, *sort_time; @property (readwrite, nonatomic, strong) User *owner; @@ -27,7 +27,7 @@ @property (nonatomic,strong) TweetSendLocationResponse *locationData; @property (readwrite, nonatomic, strong) NSMutableArray *tweetImages;//对 selectedAssetURLs 操作即可,最好不要直接赋值。。应用跳转带的图片会直接对 tweetImages赋值 -@property (readwrite, nonatomic, strong) NSMutableArray *selectedAssetURLs; +@property (readwrite, nonatomic, strong) NSMutableArray *selectedAssetLocalIdentifiers; @property (readwrite, nonatomic, strong) NSString *tweetContent; @property (readwrite, nonatomic, strong) NSString *nextCommentStr; @property (strong, nonatomic) NSString *callback; @@ -39,9 +39,9 @@ - (BOOL)isProjectTweet; -- (void)addASelectedAssetURL:(NSURL *)assetURL; -- (void)deleteASelectedAssetURL:(NSURL *)assetURL; -- (void)deleteATweetImage:(TweetImage *)tweetImage; +- (void)addSelectedAssetLocalIdentifier:(NSString *)localIdentifier; +- (void)deleteSelectedAssetLocalIdentifier:(NSString *)localIdentifier; +- (void)deleteTweetImage:(TweetImage *)tweetImage; - (NSInteger)numOfComments; - (BOOL)hasMoreComments; @@ -95,11 +95,20 @@ typedef NS_ENUM(NSInteger, TweetImageUploadState) TweetImageUploadStateFail }; +typedef NS_ENUM(NSInteger, TweetImageDownloadState) +{ + TweetImageDownloadStateInit = 0, + TweetImageDownloadStateIng, + TweetImageDownloadStateSuccess, + TweetImageDownloadStateFail +}; + @interface TweetImage : NSObject @property (readwrite, nonatomic, strong) UIImage *image, *thumbnailImage; -@property (strong, nonatomic) NSURL *assetURL; +@property (strong, nonatomic) NSString *assetLocalIdentifier; @property (assign, nonatomic) TweetImageUploadState uploadState; +@property (assign, nonatomic) TweetImageDownloadState downloadState; @property (readwrite, nonatomic, strong) NSString *imageStr; -+ (instancetype)tweetImageWithAssetURL:(NSURL *)assetURL; -+ (instancetype)tweetImageWithAssetURL:(NSURL *)assetURL andImage:(UIImage *)image; ++ (instancetype)tweetImageWithAssetLocalIdentifier:(NSString *)localIdentifier; ++ (instancetype)tweetImageWithAssetLocalIdentifier:(NSString *)localIdentifier andImage:(UIImage *)image; @end diff --git a/Coding_iOS/Models/Tweet.m b/Coding_iOS/Models/Tweet.m index 132d4536e..fa2000435 100644 --- a/Coding_iOS/Models/Tweet.m +++ b/Coding_iOS/Models/Tweet.m @@ -8,6 +8,7 @@ #import "Tweet.h" #import "Login.h" +#import "YLGIFImage.h" static Tweet *_tweetForSend = nil; @@ -196,12 +197,14 @@ - (void)saveSendData{ NSMutableDictionary *tweetImagesDict = [NSMutableDictionary new]; for (int i = 0; i < [self.tweetImages count]; i++) { TweetImage *tImg = [self.tweetImages objectAtIndex:i]; - if (tImg.image) { - NSString *imgNameStr = [NSString stringWithFormat:@"%@_%d.jpg", dataPath, i]; - if (tImg.assetURL.absoluteString) { - [tweetImagesDict setObject:tImg.assetURL.absoluteString forKey:imgNameStr]; - } - [NSObject saveImage:tImg.image imageName:imgNameStr inFolder:dataPath]; + NSString *imgNameStr = [NSString stringWithFormat:@"%@_%d.jpg", dataPath, i]; + if (tImg.assetLocalIdentifier) { + [tweetImagesDict setObject:tImg.assetLocalIdentifier forKey:imgNameStr]; + } + if (tImg.downloadState == TweetImageDownloadStateSuccess) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + [NSObject saveImage:tImg.image imageName:imgNameStr inFolder:dataPath]; + }); } } [NSObject saveResponseData:@{@"content" : _tweetContent? _tweetContent: @"", @@ -221,15 +224,17 @@ - (void)loadSendData{ self.locationData = [NSObject objectOfClass:@"TweetSendLocationResponse" fromJSON:[contentDict objectForKey:@"locationData"]]; } _tweetImages = [NSMutableArray new]; - _selectedAssetURLs = [NSMutableArray new]; + _selectedAssetLocalIdentifiers = [NSMutableArray new]; [tweetImagesDict enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *obj, BOOL *stop) { - NSURL *assetURL = [NSURL URLWithString:obj]; NSData *imageData = [NSObject loadImageDataWithName:key inFolder:dataPath]; + TweetImage *tImg; if (imageData) { - TweetImage *tImg = [TweetImage tweetImageWithAssetURL:assetURL andImage:[UIImage imageWithData:imageData]]; - [self.tweetImages addObject:tImg]; - [self.selectedAssetURLs addObject:assetURL]; + tImg = [TweetImage tweetImageWithAssetLocalIdentifier:obj andImage:[YLGIFImage imageWithData:imageData]]; + }else{ + tImg = [TweetImage tweetImageWithAssetLocalIdentifier:obj]; } + [self.tweetImages addObject:tImg]; + [self.selectedAssetLocalIdentifiers addObject:obj]; }]; } @@ -308,122 +313,107 @@ - (NSString *)toShareLinkStr{ if (_project) { shareLinkStr = [NSString stringWithFormat:@"%@u/%@/p/%@?pp=%@", [NSObject baseURLStr], _project.owner_user_name, _project.name, _id.stringValue]; }else{ - shareLinkStr = [NSString stringWithFormat:@"%@u/%@/pp/%@", kBaseUrlStr_Phone, _owner.global_key, _id]; + shareLinkStr = [NSString stringWithFormat:@"%@u/%@/pp/%@", [NSObject baseURLStr], _owner.global_key, _id]; } return shareLinkStr; } -#pragma mark ALAsset -- (void)setSelectedAssetURLs:(NSMutableArray *)selectedAssetURLs{ +#pragma mark PHAsset +- (void)setSelectedAssetLocalIdentifiers:(NSMutableArray *)selectedAssetLocalIdentifiers{ NSMutableArray *needToAdd = [NSMutableArray new]; NSMutableArray *needToDelete = [NSMutableArray new]; - [self.selectedAssetURLs enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { - if (![selectedAssetURLs containsObject:obj]) { + [self.selectedAssetLocalIdentifiers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + if (![selectedAssetLocalIdentifiers containsObject:obj]) { [needToDelete addObject:obj]; } }]; [needToDelete enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { - [self deleteASelectedAssetURL:obj]; + [self deleteSelectedAssetLocalIdentifier:obj]; }]; - [selectedAssetURLs enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { - if (![self.selectedAssetURLs containsObject:obj]) { + [selectedAssetLocalIdentifiers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + if (![self.selectedAssetLocalIdentifiers containsObject:obj]) { [needToAdd addObject:obj]; } }]; [needToAdd enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { - [self addASelectedAssetURL:obj]; + [self addSelectedAssetLocalIdentifier:obj]; }]; } - (BOOL)isProjectTweet{ return self.project_id != nil || _project != nil; } -- (void)addASelectedAssetURL:(NSURL *)assetURL{ - if (!_selectedAssetURLs) { - _selectedAssetURLs = [NSMutableArray new]; + +- (void)addSelectedAssetLocalIdentifier:(NSString *)localIdentifier{ + if (!_selectedAssetLocalIdentifiers) { + _selectedAssetLocalIdentifiers = [NSMutableArray new]; } if (!_tweetImages) { _tweetImages = [NSMutableArray new]; } - [_selectedAssetURLs addObject:assetURL]; - + [_selectedAssetLocalIdentifiers addObject:localIdentifier]; + NSMutableArray *tweetImages = [self mutableArrayValueForKey:@"tweetImages"];//为了kvo - TweetImage *tweetImg = [TweetImage tweetImageWithAssetURL:assetURL]; + TweetImage *tweetImg = [TweetImage tweetImageWithAssetLocalIdentifier:localIdentifier]; [tweetImages addObject:tweetImg]; } -- (void)deleteASelectedAssetURL:(NSURL *)assetURL{ - [self.selectedAssetURLs removeObject:assetURL]; +- (void)deleteSelectedAssetLocalIdentifier:(NSString *)localIdentifier{ + [self.selectedAssetLocalIdentifiers removeObject:localIdentifier]; NSMutableArray *tweetImages = [self mutableArrayValueForKey:@"tweetImages"];//为了kvo [tweetImages enumerateObjectsUsingBlock:^(TweetImage *obj, NSUInteger idx, BOOL *stop) { - if (obj.assetURL == assetURL) { + if (obj.assetLocalIdentifier == localIdentifier) { [tweetImages removeObject:obj]; *stop = YES; } }]; } - -- (void)deleteATweetImage:(TweetImage *)tweetImage{ +- (void)deleteTweetImage:(TweetImage *)tweetImage{ NSMutableArray *tweetImages = [self mutableArrayValueForKey:@"tweetImages"];//为了kvo [tweetImages removeObject:tweetImage]; - if (tweetImage.assetURL) { - [self.selectedAssetURLs removeObject:tweetImage.assetURL]; + if (tweetImage.assetLocalIdentifier) { + [self.selectedAssetLocalIdentifiers removeObject:tweetImage.assetLocalIdentifier]; } } @end @implementation TweetImage -+ (instancetype)tweetImageWithAssetURL:(NSURL *)assetURL{ + ++ (instancetype)tweetImageWithAssetLocalIdentifier:(NSString *)localIdentifier{ + if (!localIdentifier) { + return nil; + } + PHAsset *asset = [PHAsset assetWithLocalIdentifier:localIdentifier]; + if (!asset) { + return nil; + } TweetImage *tweetImg = [[TweetImage alloc] init]; tweetImg.uploadState = TweetImageUploadStateInit; - tweetImg.assetURL = assetURL; - - void (^selectAsset)(ALAsset *) = ^(ALAsset *asset){ - if (asset) { - UIImage *highQualityImage = [UIImage fullScreenImageALAsset:asset]; - UIImage *thumbnailImage = [UIImage imageWithCGImage:[asset thumbnail]]; - dispatch_async(dispatch_get_main_queue(), ^{ - tweetImg.image = highQualityImage; - tweetImg.thumbnailImage = thumbnailImage; - }); - } - }; - - ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init]; - @weakify(assetsLibrary); - [assetsLibrary assetForURL:assetURL resultBlock:^(ALAsset *asset) { - if (asset) { - selectAsset(asset); - }else{ - @strongify(assetsLibrary); - [assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupPhotoStream usingBlock:^(ALAssetsGroup *group, BOOL *stop) { - [group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stopG) { - if([result.defaultRepresentation.url isEqual:assetURL]) { - selectAsset(result); - *stop = YES; - *stopG = YES; - } - }]; - } failureBlock:^(NSError *error) { - [NSObject showHudTipStr:@"读取图片失败"]; - }]; - } - }failureBlock:^(NSError *error) { - [NSObject showHudTipStr:@"读取图片失败"]; + tweetImg.assetLocalIdentifier = localIdentifier; + tweetImg.thumbnailImage = asset.loadThumbnailImage; + tweetImg.downloadState = TweetImageDownloadStateIng; + [asset loadImageWithProgressHandler:nil resultHandler:^(UIImage *result, NSDictionary *info) { + DebugLog(@"\n----------\nresultHandler: %@", info); + tweetImg.image = result; + tweetImg.downloadState = result? TweetImageDownloadStateSuccess: TweetImageDownloadStateFail; }]; return tweetImg; - } -+ (instancetype)tweetImageWithAssetURL:(NSURL *)assetURL andImage:(UIImage *)image{ ++ (instancetype)tweetImageWithAssetLocalIdentifier:(NSString *)localIdentifier andImage:(UIImage *)image{ TweetImage *tweetImg = [[TweetImage alloc] init]; tweetImg.uploadState = TweetImageUploadStateInit; - tweetImg.assetURL = assetURL; + tweetImg.downloadState = TweetImageUploadStateSuccess; + tweetImg.assetLocalIdentifier = localIdentifier; tweetImg.image = image; tweetImg.thumbnailImage = [image scaledToSize:CGSizeMake(kScaleFrom_iPhone5_Desgin(70), kScaleFrom_iPhone5_Desgin(70)) highQuality:YES]; return tweetImg; } +- (UIImage *)image{ + return _image ?: _thumbnailImage; +} + @end diff --git a/Coding_iOS/Models/Tweets.m b/Coding_iOS/Models/Tweets.m index 8cf4a712f..2e7bfc8b9 100755 --- a/Coding_iOS/Models/Tweets.m +++ b/Coding_iOS/Models/Tweets.m @@ -90,6 +90,9 @@ - (NSDictionary *)toParams{ } - (void)configWithTweets:(NSArray *)responseA{ + if (self.curPro) { + [responseA setValue:self.curPro forKey:@"project"]; + } if (responseA && [responseA count] > 0) { self.canLoadMore = (_tweetType != TweetTypePublicHot); Tweet *lastTweet = [responseA lastObject]; diff --git a/Coding_iOS/Models/User.h b/Coding_iOS/Models/User.h index 48b713ced..33a8997bb 100755 --- a/Coding_iOS/Models/User.h +++ b/Coding_iOS/Models/User.h @@ -9,14 +9,29 @@ #import @interface User : NSObject -@property (readwrite, nonatomic, strong) NSString *avatar, *name, *global_key, *path, *slogan, *company, *tags_str, *tags, *location, *job_str, *job, *email, *birthday, *pinyinName; -@property (readwrite, nonatomic, strong) NSString *curPassword, *resetPassword, *resetPasswordConfirm, *phone, *introduction, *phone_country_code, *country; -@property (readwrite, nonatomic, strong) NSNumber *id, *sex, *follow, *followed, *fans_count, *follows_count, *tweets_count, *status, *points_left, *email_validation, *is_phone_validated; -@property (readwrite, nonatomic, strong) NSDate *created_at, *last_logined_at, *last_activity_at, *updated_at; +@property (strong, nonatomic) NSDictionary *propertyArrayMap; + +//vip 1-4:普通、银牌、金牌、钻石 + +@property (readwrite, nonatomic, strong) NSString *avatar, *name, *global_key, *path, *slogan, *company, *tags_str, *tags, *location, *job_str, *email, *birthday, *pinyinName; +@property (readwrite, nonatomic, strong) NSString *curPassword, *resetPassword, *resetPasswordConfirm, *phone, *introduction, *phone_country_code, *country, *school; + +@property (readwrite, nonatomic, strong) NSNumber *id, *sex, *follow, *followed, *fans_count, *follows_count, *tweets_count, *status, *points_left, *email_validation, *is_phone_validated, *vip, *degree, *job; +@property (readwrite, nonatomic, strong) NSDate *created_at, *last_logined_at, *last_activity_at, *updated_at, *vip_expired_at; + +@property (strong, nonatomic) NSNumber *isAdministrator; + +@property (strong, nonatomic) NSArray *skills; + +@property (strong, nonatomic, readonly) NSString *skills_str, *degree_str, *vipName; + +@property (assign, nonatomic, readonly) BOOL isUserInfoCompleted, canUpgradeByCompleteUserInfo, willExpired, hasNoEamilAndPhone; + (User *)userWithGlobalKey:(NSString *)global_key; ++ (NSArray *)degreeList; + - (BOOL)isSameToUser:(User *)user; - (NSString *)toUserInfoPath; @@ -35,4 +50,5 @@ - (NSString *)localFriendsPath; - (NSString *)changePasswordTips; + @end diff --git a/Coding_iOS/Models/User.m b/Coding_iOS/Models/User.m index 31d225942..3ad829be9 100755 --- a/Coding_iOS/Models/User.m +++ b/Coding_iOS/Models/User.m @@ -7,9 +7,20 @@ // #import "User.h" +#import "CodingSkill.h" + @implementation User +- (instancetype)init +{ + self = [super init]; + if (self) { + _propertyArrayMap = [NSDictionary dictionaryWithObjectsAndKeys: + @"CodingSkill", @"skills", nil]; + } + return self; +} -(id)copyWithZone:(NSZone*)zone { User *user = [[[self class] allocWithZone:zone] init]; @@ -46,6 +57,7 @@ -(id)copyWithZone:(NSZone*)zone { user.created_at = [_created_at copy]; user.updated_at = [_updated_at copy]; user.email_validation = [_email_validation copy]; + user.school = [_school copy]; return user; } @@ -119,6 +131,25 @@ - (NSString *)tags_str{ return @"未添加"; } } +- (NSString *)skills_str{ + if (_skills.count > 0) { + return [[_skills valueForKey:@"skill_str"] componentsJoinedByString:@","]; + }else{ + return @"未填写"; + } +} +- (NSString *)school{ + return _school.length > 0? _school: @"未填写"; +} +- (NSString *)degree_str{ + NSArray *degreeList = [User degreeList]; + NSInteger degreeIndex = _degree.integerValue - 1; + if (degreeIndex >= 0 && degreeIndex < degreeList.count) { + return degreeList[degreeIndex]; + }else{ + return @"未填写"; + } +} - (NSString *)slogan{ if (_slogan && _slogan.length > 0) { return _slogan; @@ -141,26 +172,45 @@ - (NSString *)pinyinName{ return _pinyinName; } +- (NSString *)vipName{ + NSDictionary *vipDict = @{@1: @"普通会员", + @2: @"银牌会员", + @3: @"黄金会员", + @4: @"钻石会员", + }; + return vipDict[_vip]; +} + - (NSString *)toUpdateInfoPath{ return @"api/user/updateInfo"; } - (NSDictionary *)toUpdateInfoParams{ - return @{@"id" : _id, - @"email" : _email? _email: @"", - @"global_key" : _global_key? _global_key: @"", -// 暂时没用到 -// @"introduction" : _introduction, -// @"phone" : _phone, -// /static/fruit_avatar/Fruit-20.png - @"lavatar" : _avatar? _avatar: [NSString stringWithFormat:@"/static/fruit_avatar/Fruit-%d.png", (rand()%20)+1], - @"name" : _name? _name: @"", - @"sex" : _sex? _sex: [NSNumber numberWithInteger:2], - @"birthday" : _birthday? _birthday: @"", - @"location" : _location? _location: @"", - @"slogan" : _slogan? _slogan: @"", - @"company" : _company? _company: @"", - @"job" : _job? _job: [NSNumber numberWithInteger:0], - @"tags" : _tags? _tags: @""}; + NSMutableDictionary *params = @{@"id" : _id, + @"email" : _email? _email: @"", + @"global_key" : _global_key? _global_key: @"", + // 暂时没用到 + // @"introduction" : _introduction, + // @"phone" : _phone, + // /static/fruit_avatar/Fruit-20.png + @"lavatar" : _avatar? _avatar: [NSString stringWithFormat:@"/static/fruit_avatar/Fruit-%d.png", (rand()%20)+1], + @"name" : _name? _name: @"", + @"sex" : _sex? _sex: [NSNumber numberWithInteger:2], + @"birthday" : _birthday? _birthday: @"", + @"location" : _location? _location: @"", + @"slogan" : _slogan? _slogan: @"", + @"company" : _company? _company: @"", + @"job" : _job? _job: [NSNumber numberWithInteger:0], + @"tags" : _tags? _tags: @"", + }.mutableCopy; + if (!kTarget_Enterprise) { + params[@"school"] = _school ?: @""; + params[@"degree"] = _degree ?: @""; + for (int index = 0; index < _skills.count; index++) { + CodingSkill *curSkill = _skills[index]; + params[[NSString stringWithFormat:@"skills[%d]", index]] = [NSString stringWithFormat:@"%@:%@", curSkill.skillId, curSkill.level]; + } + } + return params; } - (NSString *)toDeleteConversationPath{ return [NSString stringWithFormat:@"api/message/conversations/%@", self.id.stringValue]; @@ -169,6 +219,27 @@ - (NSString *)localFriendsPath{ return @"FriendsPath"; } +- (BOOL)isUserInfoCompleted{ + if (!_sex || _birthday.length <= 0 || _location.length <= 0 || !_job || !_degree || _school.length <= 0 || !_is_phone_validated.boolValue || !_email_validation.boolValue || _skills.count <= 0) { + return NO; + } + return YES; +} + +- (BOOL)canUpgradeByCompleteUserInfo{ + return NO;// +// return (!self.isUserInfoCompleted && self.vip.integerValue < 2); +} + +- (BOOL)willExpired{ + NSTimeInterval timeInterval = [self.vip_expired_at timeIntervalSinceDate:[NSDate date]]; + return (self.vip.integerValue >= 3 && (timeInterval < 3 * 24 * 60 * 60)); +} + +- (BOOL)hasNoEamilAndPhone{ + return self.email.length <= 0 && self.phone.length <= 0; +} + - (NSString *)changePasswordTips{ NSString *tipStr = nil; if (!self.curPassword || self.curPassword.length <= 0){ @@ -186,4 +257,8 @@ - (NSString *)changePasswordTips{ } return tipStr; } + ++ (NSArray *)degreeList{ + return @[@"高中及以下", @"大专", @"本科", @"硕士及以上"]; +} @end diff --git a/Coding_iOS/Models/UserServiceInfo.h b/Coding_iOS/Models/UserServiceInfo.h index 8475e3a79..8d70264f6 100644 --- a/Coding_iOS/Models/UserServiceInfo.h +++ b/Coding_iOS/Models/UserServiceInfo.h @@ -9,5 +9,8 @@ #import @interface UserServiceInfo : NSObject -@property (strong, nonatomic) NSNumber *balance, *point_left, *private, *public, *team, *total_memory, *used_memory; +@property (strong, nonatomic) NSNumber *balance, *point_left, *private, *public, *team; +//, *total_memory, *used_memory; + +@property (strong, nonatomic) NSString *private_project_quota, *public_project_quota; @end diff --git a/Coding_iOS/Models/UserServiceInfo.m b/Coding_iOS/Models/UserServiceInfo.m index 4a6422393..9cc83c3e8 100644 --- a/Coding_iOS/Models/UserServiceInfo.m +++ b/Coding_iOS/Models/UserServiceInfo.m @@ -10,4 +10,12 @@ @implementation UserServiceInfo +- (void)setPublic_project_quota:(NSString *)public_project_quota{ + _public_project_quota = [public_project_quota isKindOfClass:[NSNumber class]]? ((NSNumber *)public_project_quota).stringValue: public_project_quota; +} + +- (void)setPrivate_project_quota:(NSString *)private_project_quota{ + _private_project_quota = [private_project_quota isKindOfClass:[NSNumber class]]? ((NSNumber *)private_project_quota).stringValue: private_project_quota; +} + @end diff --git a/Coding_iOS/Models/Users.h b/Coding_iOS/Models/Users.h index a12238949..3905278e8 100755 --- a/Coding_iOS/Models/Users.h +++ b/Coding_iOS/Models/Users.h @@ -12,6 +12,7 @@ typedef NS_ENUM(NSInteger, UsersType) { UsersTypeFollowers = 0, UsersTypeFriends_Attentive, + UsersType_CompanyMember, UsersTypeFriends_Message, UsersTypeFriends_At, UsersTypeFriends_Transpond, @@ -36,6 +37,7 @@ typedef NS_ENUM(NSInteger, UsersType) { - (NSString *)toPath; - (NSDictionary *)toParams; - (void)configWithObj:(Users *)resultA; +- (void)removeLoginUserFromList; - (NSDictionary *)dictGroupedByPinyin; diff --git a/Coding_iOS/Models/Users.m b/Coding_iOS/Models/Users.m index 8881bd9c1..433464f26 100755 --- a/Coding_iOS/Models/Users.m +++ b/Coding_iOS/Models/Users.m @@ -7,6 +7,7 @@ // #import "Users.h" +#import "Login.h" @implementation Users - (instancetype)init @@ -18,7 +19,7 @@ - (instancetype)init _canLoadMore = YES; _isLoading = _willLoadMore = NO; _page = [NSNumber numberWithInteger:1]; - _pageSize = [NSNumber numberWithInteger:9999]; + _pageSize = @(999999999); } return self; } @@ -52,6 +53,10 @@ - (NSString *)toPath{ path = [NSString stringWithFormat:@"api/user/%@/project/%@/stargazers", _project_owner_name, _project_name]; }else if (_type == UsersTypeProjectWatch){ path = [NSString stringWithFormat:@"api/user/%@/project/%@/watchers", _project_owner_name, _project_name]; + }else if (_type == UsersType_CompanyMember){ + path = [NSString stringWithFormat:@"api/team/%@/members", [NSObject baseCompany]]; + }else if (_type == UsersTypeFriends_Transpond && kTarget_Enterprise){ + path = [NSString stringWithFormat:@"api/team/%@/members", [NSObject baseCompany]]; } return path; } @@ -79,6 +84,19 @@ - (void)configWithObj:(Users *)resultA{ } } +- (void)removeLoginUserFromList{ + __block User *loginUser = nil; + [self.list enumerateObjectsUsingBlock:^(User * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + if ([obj.global_key isEqualToString:[Login curLoginUser].global_key] || + [obj.id isEqualToNumber:[Login curLoginUser].id]) { + loginUser = obj; + } + }]; + if (loginUser) { + [self.list removeObject:loginUser]; + } +} + - (NSDictionary *)dictGroupedByPinyin{ if (self.list.count <= 0) { return @{@"#" : [NSMutableArray array]}; diff --git a/Coding_iOS/Resources/.DS_Store b/Coding_iOS/Resources/.DS_Store index 4d8726d8e..a23aa8157 100644 Binary files a/Coding_iOS/Resources/.DS_Store and b/Coding_iOS/Resources/.DS_Store differ diff --git a/Coding_iOS/Resources/code_lang.plist b/Coding_iOS/Resources/code_lang.plist new file mode 100644 index 000000000..6675c5112 --- /dev/null +++ b/Coding_iOS/Resources/code_lang.plist @@ -0,0 +1,4337 @@ + + + + + 1 + + troff + + 1in + + troff + + 1m + + troff + + 1x + + troff + + 2 + + troff + + 3 + + troff + + 3in + + troff + + 3m + + troff + + 3qt + + troff + + 3x + + troff + + 4 + + troff + + 4th + + forth + + 5 + + troff + + 6 + + troff + + 6pl + + perl + + 6pm + + perl + + 7 + + troff + + 8 + + troff + + 8xk + + text + + 8xk.txt + + text + + 8xp + + text + + 8xp.txt + + text + + 9 + + troff + + E + + text + + JSON-tmLanguage + + json + + ML + + mllike + + _coffee + + coffee + + _js + + javascript + + _ls + + livescript + + a51 + + assembly_x86 + + abap + + abap + + abnf + + text + + ada + + ada + + adb + + ada + + adml + + xml + + admx + + xml + + ado + + text + + adoc + + asciidoc + + adp + + tcl + + ads + + ada + + afm + + text + + agc + + assembly_x86 + + agda + + text + + ahk + + autohotkey + + ahkl + + autohotkey + + aj + + text + + al + + perl + + als + + text + + ampl + + text + + angelscript + + clike + + anim + + yaml + + ant + + xml + + apacheconf + + apache_conf + + apib + + markdown + + apl + + apl + + app.src + + erlang + + applescript + + applescript + + arc + + text + + arpa + + text + + as + + actionscript + clike + + asax + + htmlembedded + + asc + + asciiarmor + asciidoc + c_cpp + + asciidoc + + asciidoc + + ascx + + htmlembedded + + asd + + lisp + + ash + + c_cpp + + ashx + + htmlembedded + + asm + + assembly_x86 + + asmx + + htmlembedded + + asn + + asn.1 + + asn1 + + asn.1 + + asp + + htmlembedded + + aspx + + htmlembedded + + asset + + yaml + + au3 + + autohotkey + + aug + + text + + auk + + text + + aux + + tex + + avsc + + json + + aw + + php + + awk + + text + + axd + + htmlembedded + + axi + + text + + axi.erb + + text + + axml + + xml + + axs + + text + + axs.erb + + text + + b + + brainfuck + text + + bal + + text + + bas + + vb + + bash + + sh + + bat + + batchfile + + bats + + sh + + bb + + text + + bbx + + tex + + bdy + + sql + + befunge + + text + + bf + + brainfuck + text + + bib + + tex + + bison + + text + + blade + + text + + blade.php + + text + + bmx + + text + + bones + + javascript + + boo + + text + + boot + + clojure + + brd + + xml + text + + bro + + text + + brs + + text + + bsl + + text + + bsv + + verilog + + builder + + ruby + + builds + + xml + + bzl + + python + + c + + c_cpp + + c++ + + c_cpp + + c++-objdump + + assembly_x86 + + c++objdump + + assembly_x86 + + c-objdump + + assembly_x86 + + cake + + coffee + csharp + + capnp + + text + + cats + + c_cpp + + cbl + + cobol + + cbx + + tex + + cc + + c_cpp + + ccp + + cobol + + ccproj + + xml + + ccxml + + xml + + cdf + + mathematica + + ceylon + + text + + cfc + + coldfusion + + cfg + + ini + + cfm + + coldfusion + + cfml + + coldfusion + + cgi + + python + perl + sh + + cginc + + text + + ch + + text + + chem + + troff + + chpl + + text + + chs + + haskell + + cirru + + cirru + + cjsx + + coffee + + ck + + java + + cl + + lisp + text + c_cpp + + cl2 + + clojure + + click + + text + + clixml + + xml + + clj + + clojure + + cljc + + clojure + + cljs + + clojure + + cljs.hl + + clojure + + cljscm + + clojure + + cljx + + clojure + + clp + + text + + cls + + tex + vb + java + text + + clw + + text + + cmake + + cmake + + cmake.in + + cmake + + cmd + + batchfile + + cob + + cobol + + cobol + + cobol + + coffee + + coffee + + com + + text + + command + + sh + + conll + + text + + conllu + + text + + coq + + text + + cp + + pascal + c_cpp + + cpp + + c_cpp + + cpp-objdump + + assembly_x86 + + cppobjdump + + assembly_x86 + + cproject + + xml + + cps + + pascal + + cpy + + cobol + + cql + + sql + + cr + + ruby + + creole + + text + + cs + + smalltalk + csharp + + cscfg + + xml + + csd + + csound_document + + csdef + + xml + + csh + + sh + + cshtml + + csharp + + csl + + xml + + cson + + coffee + + csproj + + xml + + css + + css + + csv + + text + + csx + + csharp + + ct + + xml + + ctp + + php + + cu + + c_cpp + + cuh + + c_cpp + + cw + + text + + cwl + + yaml + + cxx + + c_cpp + + cxx-objdump + + assembly_x86 + + cy + + javascript + + d + + d + c_cpp + makefile + + d-objdump + + assembly_x86 + + dae + + xml + + darcspatch + + text + + dart + + dart + + dats + + ocaml + + db2 + + sql + + dcl + + text + + ddl + + sql + + decls + + text + + depproj + + xml + + desktop + + text + + desktop.in + + text + + dfm + + pascal + + di + + d + + diff + + diff + + dita + + xml + + ditamap + + xml + + ditaval + + xml + + djs + + text + + dll.config + + xml + + dlm + + idl + + dm + + c_cpp + + do + + text + + dockerfile + + dockerfile + + doh + + text + + dot + + text + + dotsettings + + xml + + dpatch + + text + + dpr + + pascal + + druby + + ruby + + dtx + + tex + + duby + + ruby + + dwl + + text + + dyalog + + apl + + dyl + + dylan + + dylan + + dylan + + e + + eiffel + + eam.fs + + text + + eb + + python + + ebnf + + ebnf + + ebuild + + sh + + ec + + text + + ecl + + prolog + ecl + + eclass + + sh + + eclxml + + ecl + + ecr + + htmlmixed + + edc + + json + + edn + + clojure + + eex + + htmlmixed + + eh + + text + + ejs + + ejs + + el + + lisp + + eliom + + ocaml + + eliomi + + ocaml + + elm + + elm + + em + + coffee + + emacs + + lisp + + emacs.desktop + + lisp + + emberscript + + coffee + + epj + + json + + eps + + text + + eq + + csharp + + erb + + htmlembedded + + erb.deface + + htmlembedded + + erl + + erlang + + es + + javascript + erlang + + es6 + + javascript + + escript + + erlang + + ex + + elixir + + exs + + elixir + + eye + + ruby + + f + + forth + fortran + text + + f03 + + fortran + + f08 + + fortran + + f77 + + fortran + + f90 + + fortran + + f95 + + fortran + + factor + + factor + + fan + + text + + fancypack + + text + + fcgi + + python + perl + php + sh + lua + ruby + + fea + + text + + feature + + text + + filters + + xml + + fish + + text + + flex + + text + + flux + + text + + fnc + + sql + + for + + forth + fortran + text + + forth + + forth + + fp + + glsl + + fpp + + fortran + + fr + + haskell + forth + text + + frag + + glsl + javascript + + frg + + glsl + + frm + + vb + + frt + + forth + + frx + + vb + + fs + + glsl + mllike + forth + text + + fsh + + glsl + + fshader + + glsl + + fsi + + mllike + + fsproj + + xml + + fsx + + mllike + + fth + + forth + + ftl + + ftl + + fun + + mllike + + fx + + text + + fxh + + text + + fxml + + xml + + fy + + text + + g + + text + gcode + + g4 + + text + + gap + + text + + gawk + + text + + gbl + + text + + gbo + + text + + gbp + + text + + gbr + + text + + gbs + + text + + gco + + gcode + + gcode + + gcode + + gd + + text + + gdb + + text + + gdbinit + + text + + gemspec + + ruby + + geo + + glsl + + geojson + + json + + geom + + glsl + + gf + + haskell + + gi + + text + + gko + + text + + glade + + xml + + glf + + tcl + + glsl + + glsl + + glslv + + glsl + + gltf + + json + + gml + + xml + text + c_cpp + + gms + + text + + gn + + python + + gni + + python + + gnu + + text + + gnuplot + + text + + go + + golang + + god + + ruby + + golo + + text + + gp + + text + + gpb + + text + + gpt + + text + + gql + + text + + grace + + text + + gradle + + text + + graphql + + text + + groovy + + groovy + + grt + + groovy + + grxml + + xml + + gs + + text + javascript + + gshader + + glsl + + gsp + + jsp + + gst + + text + + gsx + + text + + gtl + + text + + gto + + text + + gtp + + text + + gtpl + + groovy + + gts + + text + + gv + + text + + gvy + + groovy + + gyp + + python + + gypi + + python + + h + + c_cpp + objectivec + + h++ + + c_cpp + + haml + + haml + + haml.deface + + haml + + handlebars + + handlebars + + hats + + ocaml + + hb + + text + + hbs + + handlebars + + hcl + + ruby + + hh + + php + c_cpp + + hic + + clojure + + hlean + + text + + hlsl + + text + + hlsli + + text + + hpp + + c_cpp + + hqf + + text + + hrl + + erlang + + hs + + haskell + + hsc + + haskell + + htm + + html + + html + + html + + html.hl + + html + + http + + http + + hx + + haxe + + hxsl + + haxe + + hxx + + c_cpp + + hy + + text + + i7x + + text + + iced + + coffee + + icl + + text + + idc + + c_cpp + + idr + + text + + ihlp + + text + + ijs + + text + + ik + + text + + ily + + text + + iml + + xml + + inc + + assembly_x86 + php + pascal + text + html + c_cpp + sql + + ini + + ini + + inl + + c_cpp + + ino + + c_cpp + + ins + + tex + + intr + + dylan + + io + + io + + iol + + text + + ipf + + text + + ipp + + c_cpp + + ipynb + + json + + irclog + + mirc + + iss + + text + + ivy + + xml + + j + + java + text + + jade + + jade + + jake + + javascript + + java + + java + + jbuilder + + ruby + + jelly + + xml + + jflex + + text + + jinja + + django + + jinja2 + + django + + jison + + text + + jisonlex + + text + + jl + + julia + + jq + + jsoniq + + js + + javascript + + jsb + + javascript + + jscad + + javascript + + jsfl + + javascript + + jsm + + javascript + + json + + json + + json5 + + javascript + + jsonl + + json + + jsonld + + javascript + + jsp + + jsp + + jsproj + + xml + + jss + + javascript + + jsx + + javascript + + kicad_mod + + lisp + + kicad_pcb + + lisp + + kicad_wks + + lisp + + kid + + xml + + kit + + html + + kml + + xml + + kojo + + scala + + krl + + text + + ksh + + sh + + kt + + clike + + ktm + + clike + + kts + + clike + + l + + lisp + troff + text + + lagda + + text + + las + + text + + lasso + + text + + lasso8 + + text + + lasso9 + + text + + latte + + smarty + + launch + + xml + + lbx + + tex + + ld + + text + + ldml + + text + + lds + + text + + lean + + text + + less + + less + + lex + + text + + lfe + + lisp + + lgt + + text + + lhs + + haskell-literate + + lid + + dylan + + lidr + + text + + liquid + + liquid + + lisp + + lisp + + litcoffee + + text + + ll + + text + + lmi + + python + + logtalk + + text + + lol + + text + + lookml + + yaml + + lpr + + pascal + + ls + + livescript + text + + lsl + + lsl + + lslp + + lsl + + lsp + + lisp + + ltx + + tex + + lua + + lua + + lvproj + + xml + + ly + + text + + m + + objectivec + mumps + forth + prolog + matlab + mathematica + text + + m4 + + text + + ma + + mathematica + + mak + + makefile + + make + + makefile + + mako + + text + + man + + troff + + mao + + text + + markdown + + markdown + + marko + + htmlmixed + + mask + + mask + + mat + + yaml + + mata + + text + + matah + + text + + mathematica + + mathematica + + matlab + + matlab + + mawk + + text + + maxhelp + + json + + maxpat + + json + + maxproj + + json + + mcr + + text + + md + + lisp + markdown + + mdown + + markdown + + mdpolicy + + xml + + mdwn + + markdown + + me + + troff + + mediawiki + + text + + meta + + yaml + + metal + + c_cpp + + minid + + text + + mir + + ruby + + mirah + + ruby + + mjml + + xml + + mjs + + javascript + + mk + + makefile + + mkd + + markdown + + mkdn + + markdown + + mkdown + + markdown + + mkfile + + makefile + + mkii + + tex + + mkiv + + tex + + mkvi + + tex + + ml + + ocaml + + ml4 + + ocaml + + mli + + ocaml + + mll + + ocaml + + mly + + ocaml + + mm + + xml + objectivec + + mmk + + text + + mms + + text + + mo + + modelica + + mod + + xml + text + + model.lkml + + yaml + + monkey + + text + + monkey2 + + text + + moo + + prolog + text + + moon + + text + + mq4 + + c_cpp + + mq5 + + c_cpp + + mqh + + c_cpp + + ms + + assembly_x86 + troff + text + + mspec + + ruby + + mss + + text + + mt + + mathematica + + mtl + + text + + mtml + + html + + mu + + text + + muf + + forth + + mumps + + mumps + + mustache + + django + + mxml + + xml + + mxt + + json + + mysql + + sql + + myt + + text + + n + + troff + text + + nasm + + assembly_x86 + + natvis + + xml + + nawk + + text + + nb + + mathematica + text + + nbp + + mathematica + + nc + + text + + ncl + + text + + ndproj + + xml + + ne + + text + + nearley + + text + + nf + + groovy + + nginxconf + + nginx + + ni + + text + + nim + + text + + nimrod + + text + + ninja + + text + + nit + + text + + nix + + nix + + njk + + django + + njs + + javascript + + nl + + lisp + text + + nlogo + + lisp + + no + + text + + nproj + + xml + + nqp + + perl + + nr + + troff + + nse + + lua + + nsh + + nsis + + nsi + + nsis + + nu + + scheme + + numpy + + python + + numpyw + + python + + numsc + + python + + nuspec + + xml + + nut + + c_cpp + + ny + + lisp + + obj + + text + + objdump + + assembly_x86 + + odd + + xml + + ol + + text + + omgrofl + + text + + ooc + + text + + opa + + text + + opal + + text + + opencl + + c_cpp + + orc + + csound_orchestra + + org + + text + + os + + text + + osm + + xml + + owl + + xml + + ox + + text + + oxh + + text + + oxo + + text + + oxygene + + text + + oz + + oz + + p + + text + + p4 + + text + + p6 + + perl + + p6l + + perl + + p6m + + perl + + p8 + + lua + + pac + + javascript + + pan + + text + + parrot + + text + + pas + + pascal + + pascal + + pascal + + pasm + + text + + pat + + json + + patch + + diff + + pb + + text + + pbi + + text + + pbt + + text + + pck + + sql + + pcss + + text + + pd + + text + + pd_lua + + lua + + pde + + text + + pep + + text + + perl + + perl + + pfa + + text + + ph + + perl + + php + + php + + php3 + + php + + php4 + + php + + php5 + + php + + phps + + php + + phpt + + php + + phtml + + php + + pic + + troff + + pig + + text + + pike + + text + + pir + + text + + pkb + + sql + + pkgproj + + xml + + pkl + + text + + pks + + sql + + pl + + perl + prolog + + pl6 + + perl + + plb + + sql + + plist + + xml + + plot + + text + + pls + + sql + + plsql + + sql + + plt + + text + + pluginspec + + xml + ruby + + plx + + perl + + pm + + perl + c_cpp + + pm6 + + perl + + pmod + + text + + po + + text + + pod + + perl + + podsl + + lisp + + podspec + + ruby + + pogo + + text + + pony + + text + + pot + + text + + pov + + text + + pp + + pascal + puppet + + pprx + + text + + prc + + sql + + prefab + + yaml + + prefs + + ini + + prg + + text + + pri + + text + + pro + + idl + ini + prolog + text + + proj + + xml + + prolog + + prolog + + properties + + ini + + props + + xml + + proto + + protobuf + + prw + + text + + ps + + text + + ps1 + + powershell + + ps1xml + + xml + + psc + + text + + psc1 + + xml + + psd1 + + powershell + + psgi + + perl + + psm1 + + powershell + + pt + + xml + + pub + + asciiarmor + + pug + + jade + + purs + + haskell + + pwn + + text + + pxd + + python + + pxi + + python + + py + + python + + py3 + + python + + pyde + + python + + pyi + + python + + pyp + + python + + pyt + + python + + pytb + + text + + pyw + + python + + pyx + + python + + qbs + + text + + qml + + text + + r + + r + text + + r2 + + text + + r3 + + text + + rabl + + ruby + + rake + + ruby + + raml + + yaml + + raw + + text + + rb + + ruby + + rbbas + + text + + rbfrm + + text + + rbmnu + + text + + rbres + + text + + rbtbar + + text + + rbuild + + ruby + + rbuistate + + text + + rbw + + ruby + + rbx + + ruby + + rbxs + + lua + + rd + + r + + rdf + + xml + + rdoc + + rdoc + + re + + rust + c_cpp + + reb + + text + + rebol + + text + + red + + text + + reds + + text + + reek + + yaml + + regex + + text + + regexp + + text + + rei + + rust + + rest + + rst + + rest.txt + + rst + + resx + + xml + + rex + + text + + rexx + + text + + rg + + clojure + + rhtml + + rhtml + + ring + + text + + rkt + + lisp + + rktd + + lisp + + rktl + + lisp + + rl + + text + + rmd + + markdown + + rnh + + text + + rno + + troff + text + + robot + + text + + roff + + troff + + ron + + markdown + + rpy + + python + + rq + + sparql + + rs + + rust + text + + rs.in + + rust + + rsc + + text + + rsh + + text + + rss + + xml + + rst + + rst + + rst.txt + + rst + + rsx + + r + + ru + + ruby + + ruby + + ruby + + rviz + + yaml + + s + + assembly_x86 + + sage + + python + + sagews + + python + + sas + + sas + + sass + + sass + + sats + + ocaml + + sbt + + scala + + sc + + text + scala + + scad + + scad + + scala + + scala + + scaml + + text + + scd + + text + + sce + + text + + sch + + xml + text + scheme + + sci + + text + + scm + + scheme + + sco + + csound_score + + scpt + + applescript + + scrbl + + lisp + + scss + + scss + + scxml + + xml + + self + + text + + sexp + + lisp + + sfd + + yaml + + sfproj + + xml + + sh + + sh + + sh-session + + sh + + sh.in + + sh + + shader + + glsl + text + + shen + + text + + shproj + + xml + + sig + + mllike + + sj + + text + + sjs + + javascript + + sl + + text + + sld + + scheme + + slim + + slim + + sls + + yaml + scheme + + sma + + text + + smali + + text + + sml + + mllike + + smt + + text + + smt2 + + text + + soy + + soy_template + + sp + + text + + sparql + + sparql + + spc + + sql + + spec + + python + rpm + ruby + + spin + + text + + sps + + scheme + + sqf + + text + + sql + + sql + pgsql + + sra + + text + + srdf + + xml + + srt + + lisp + text + + sru + + text + + srw + + text + + ss + + scheme + + ssjs + + javascript + + sss + + text + + st + + smalltalk + html + + stTheme + + xml + + stan + + text + + sthlp + + text + + ston + + text + + storyboard + + xml + + sty + + tex + + styl + + stylus + + sublime-build + + javascript + + sublime-commands + + javascript + + sublime-completions + + javascript + + sublime-keymap + + javascript + + sublime-macro + + javascript + + sublime-menu + + javascript + + sublime-mousemap + + javascript + + sublime-project + + javascript + + sublime-settings + + javascript + + sublime-snippet + + xml + + sublime-syntax + + yaml + + sublime-theme + + javascript + + sublime-workspace + + javascript + + sublime_metrics + + javascript + + sublime_session + + javascript + + sv + + verilog + + svg + + xml + + svh + + verilog + + swift + + swift + + syntax + + yaml + + t + + perl + lua + text + + tab + + sql + + tac + + python + + targets + + xml + + tcc + + c_cpp + + tcl + + tcl + + tcsh + + sh + + tea + + text + + tesc + + glsl + + tese + + glsl + + tex + + tex + + textile + + textile + + tf + + ruby + + tfstate + + json + + tfstate.backup + + json + + tfvars + + ruby + + thor + + ruby + + thrift + + text + + thy + + text + + tl + + text + + tla + + text + + tm + + tcl + + tmCommand + + xml + + tmLanguage + + xml + + tmPreferences + + xml + + tmSnippet + + xml + + tmTheme + + xml + + tmac + + troff + + tml + + xml + + tmux + + sh + + toc + + tex + text + + toml + + toml + + tool + + sh + + topojson + + json + + tpb + + sql + + tpl + + smarty + + tpp + + c_cpp + + tps + + sql + + trg + + sql + + ts + + typescript + xml + + tst + + text + + tsx + + typescript + xml + + ttl + + turtle + + tu + + text + + twig + + twig + + txl + + text + + txt + + text + + uc + + java + + udf + + sql + + udo + + csound_orchestra + + ui + + xml + + unity + + yaml + + uno + + csharp + + upc + + c_cpp + + ur + + text + + urdf + + xml + + urs + + text + + ux + + xml + + v + + verilog + text + + vala + + vala + + vapi + + vala + + vark + + text + + vb + + vb + + vba + + vb + + vbhtml + + vb + + vbproj + + xml + + vbs + + vb + + vcl + + text + + vcxproj + + xml + + veo + + verilog + + vert + + glsl + + vh + + verilog + + vhd + + vhdl + + vhdl + + vhdl + + vhf + + vhdl + + vhi + + vhdl + + vho + + vhdl + + vhost + + nginx + apache_conf + + vhs + + vhdl + + vht + + vhdl + + vhw + + vhdl + + view.lkml + + yaml + + vim + + text + + viw + + sql + + volt + + d + + vrx + + glsl + + vsh + + glsl + + vshader + + glsl + + vsixmanifest + + xml + + vssettings + + xml + + vstemplate + + xml + + vue + + html + + vw + + sql + + vxml + + xml + + w + + text + + wast + + lisp + + wat + + lisp + + watchr + + ruby + + wdl + + text + + webapp + + json + + webidl + + webidl + + webmanifest + + json + + weechatlog + + mirc + + wiki + + text + + wisp + + clojure + + wixproj + + xml + + wl + + mathematica + + wlt + + mathematica + + wlua + + lua + + workbook + + markdown + + wsdl + + xml + + wsf + + xml + + wsgi + + python + + wxi + + xml + + wxl + + xml + + wxs + + xml + + x + + text + c_cpp + + x10 + + text + + x3d + + xml + + xacro + + xml + + xaml + + xml + + xc + + c_cpp + + xht + + html + + xhtml + + html + + xi + + text + + xib + + xml + + xlf + + xml + + xliff + + xml + + xm + + text + + xmi + + xml + + xml + + xml + + xml.dist + + xml + + xojo_code + + text + + xojo_menu + + text + + xojo_report + + text + + xojo_script + + text + + xojo_toolbar + + text + + xojo_window + + text + + xpl + + xml + + xpm + + c_cpp + + xproc + + xml + + xproj + + xml + + xpy + + python + + xq + + xquery + + xql + + xquery + + xqm + + xquery + + xquery + + xquery + + xqy + + xquery + + xrl + + erlang + + xs + + c_cpp + + xsd + + xml + + xsjs + + javascript + + xsjslib + + javascript + + xsl + + xml + + xslt + + xml + + xsp-config + + xml + + xsp.metadata + + xml + + xspec + + xml + + xtend + + text + + xul + + xml + + y + + text + + yacc + + text + + yaml + + yaml + + yaml-tmlanguage + + yaml + + yang + + text + + yap + + prolog + + yar + + text + + yara + + text + + yml + + yaml + + yml.mysql + + yaml + + yrl + + erlang + + yy + + text + + zcml + + xml + + zep + + php + + zimpl + + text + + zmpl + + text + + zone + + text + + zpl + + text + + zsh + + sh + + lock + + objectivec + + resolved + + objectivec + + entitlements + + objectivec + + example + + objectivec + + + diff --git a/Coding_iOS/Resources/diff-ios.html b/Coding_iOS/Resources/diff-ios.html index 067199a9e..850a46608 100644 --- a/Coding_iOS/Resources/diff-ios.html +++ b/Coding_iOS/Resources/diff-ios.html @@ -188,7 +188,7 @@ } .webview-detail a{ - color: #3bbd79; + color: #2D59A2; text-decoration: none; } diff --git a/Coding_iOS/Resources/modules/bubble.html b/Coding_iOS/Resources/modules/bubble.html new file mode 100644 index 000000000..71bb09b8a --- /dev/null +++ b/Coding_iOS/Resources/modules/bubble.html @@ -0,0 +1,1688 @@ + + + + + + + + + + 冒泡详情 + + + + + + + +
${webview_content}
+ + + + + + + diff --git a/Coding_iOS/Resources/modules/code.html b/Coding_iOS/Resources/modules/code.html new file mode 100644 index 000000000..3b8a2433b --- /dev/null +++ b/Coding_iOS/Resources/modules/code.html @@ -0,0 +1,1222 @@ + + + + + + + + + + 代码预览 + + + + + + +
+ + + + + + \ No newline at end of file diff --git a/Coding_iOS/Resources/modules/markdown.html b/Coding_iOS/Resources/modules/markdown.html new file mode 100644 index 000000000..31cd00b66 --- /dev/null +++ b/Coding_iOS/Resources/modules/markdown.html @@ -0,0 +1,1622 @@ + + + + + + + + + + Markdown 预览 + + + + + + +
${webview_content}
+ + + + + + + diff --git a/Coding_iOS/Resources/modules/topic-ios.html b/Coding_iOS/Resources/modules/topic-ios.html new file mode 100644 index 000000000..597fe9173 --- /dev/null +++ b/Coding_iOS/Resources/modules/topic-ios.html @@ -0,0 +1,1677 @@ + + + + + + + + + + 讨论详情 + + + + + + + +
${webview_content}
+ + + + + + + diff --git a/Coding_iOS/Resources/modules/wiki.html b/Coding_iOS/Resources/modules/wiki.html new file mode 100644 index 000000000..5bce538e8 --- /dev/null +++ b/Coding_iOS/Resources/modules/wiki.html @@ -0,0 +1,16112 @@ + + + + + + + + + Wiki + + + +
${webview_content}
+ + + + + + \ No newline at end of file diff --git a/Coding_iOS/Resources/service_terms.html b/Coding_iOS/Resources/service_terms.html index ca7982e4a..8c9d48264 100644 --- a/Coding_iOS/Resources/service_terms.html +++ b/Coding_iOS/Resources/service_terms.html @@ -310,29 +310,29 @@

服务条款

-

欢迎使用 Coding —— 云端软件开发平台,包括代码托管,运行空间,质量控制,项目管理等等。Coding 由深圳市扣钉网络科技有限公司(以下简称“扣钉网络”)开发运营。本服务条款是您与扣钉网络之间的协议,并在必要的时候进行修订,且无需另行通知。修订后的条款一旦在网页上公布即有效代替原来的服务条款。

+

欢迎使用 CODING —— 云端软件开发平台,包括代码托管,运行空间,质量控制,项目管理等等。CODING 由深圳市扣钉网络科技有限公司(以下简称“扣钉网络”)开发运营。本服务条款是您与扣钉网络之间的协议,并在必要的时候进行修订,且无需另行通知。修订后的条款一旦在网页上公布即有效代替原来的服务条款。

1、本网站的使用

-

如果您有意愿使用 Coding的某些付费服务,这将表示您同意支付其中的所有费用。在您提交使用付费产品的申请后,扣钉网络将提供经我们认可的第三方在线服务机构的支付方式,并要求您支付相关费用。成功支付后,表明您已经获得使用付费服务的权利并且已经达成此项交易,除非因扣钉网络的原因导致服务无法正常提供,否则我们将不退还您已经支付的服务费。

+

如果您有意愿使用 CODING 的某些付费服务,这将表示您同意支付其中的所有费用。在您提交使用付费产品的申请后,扣钉网络将提供经我们认可的第三方在线服务机构的支付方式,并要求您支付相关费用。成功支付后,表明您已经获得使用付费服务的权利并且已经达成此项交易,除非因扣钉网络的原因导致服务无法正常提供,否则我们将不退还您已经支付的服务费。

此外,由于您违反了《隐私策略》或者《服务条款》的相关规定而导致账户不可用,扣钉网络将不会退还付费产品的服务费。

以下行为是我们坚决反对和禁止的:

-

(1) 使用Coding的通信功能发送垃圾信息、频繁骚扰其他用户和造成用户反感的行为;
- (2) 对网站服务器进行恶意攻击, 或者采取恶意手段使用 Coding,造成服务器异常;
- (3) 使用 Coding 从事非法活动或者为非法活动提供帮助。

+

(1) 使用 CODING 的通信功能发送垃圾信息、频繁骚扰其他用户和造成用户反感的行为;
+ (2) 对网站服务器进行恶意攻击, 或者采取恶意手段使用 CODING,造成服务器异常;
+ (3) 使用 CODING 从事非法活动或者为非法活动提供帮助。

-

如果您采取了上述行为,我们有权终止/暂停您使用 Coding 的权利,并将视该行为引起后果的严重性追究责任,并保留通过法律途径追偿合理损失的权利。

+

如果您采取了上述行为,我们有权终止/暂停您使用 CODING 的权利,并将视该行为引起后果的严重性追究责任,并保留通过法律途径追偿合理损失的权利。

2、知识产权声明

本网站,包括(但不仅限于) 文字,内容,软件,录像,音乐,声音,图形,照片,图表,美术设计,图片,名称,标识,商标和/或服务标志(包括已注册和未注册的),以及其他资料(以下简称网站内容)都受到版权法,商标法和一切知识产权公约的保护。未经扣钉网络、用户或相关权利人书面许可, 任何人不得以任何形式进行使用或创造相关衍生作品。本网站内容包括扣钉网络所有或控制下的内容和第三方所有或控制下,并授权扣钉网络使用的内容。所有代码,文章,讨论等一切构成本网站的元素都可能是受版权保护的作品。您同意遵守所有适用本网站的版权保护法律法规,以及所有本网站包含的补充性的版权说明或限制。本网站的内容均由相应的机构/个人上传、维护。对于本站内容的任何使用请遵守内容所附带的授权协议。如不清楚相应的授权协议请询问上传该内容的机构/个人。

-

任何在 Coding 上注册的账号上传的内容的版权均归上传者所有,上传者承担所有被上传内容的版权责任。扣钉网络有权在其拥有的网站上,展示上传者上传到本网站公共区域的内容。

+

任何在 CODING 上注册的账号上传的内容的版权均归上传者所有,上传者承担所有被上传内容的版权责任。扣钉网络有权在其拥有的网站上,展示上传者上传到本网站公共区域的内容。

3、个人信息的保护

diff --git a/Coding_iOS/Resources/webview b/Coding_iOS/Resources/webview deleted file mode 160000 index 0ea5a9216..000000000 --- a/Coding_iOS/Resources/webview +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0ea5a92168f1170f11a86bceb9aeddfd9be27bfa diff --git a/Coding_iOS/Util/Common/EaseGitButton.m b/Coding_iOS/Util/Common/EaseGitButton.m index 7d1129e9a..da450a3a3 100644 --- a/Coding_iOS/Util/Common/EaseGitButton.m +++ b/Coding_iOS/Util/Common/EaseGitButton.m @@ -26,7 +26,7 @@ - (instancetype)initWithFrame:(CGRect)frame if(self){ self.layer.masksToBounds = YES; self.layer.cornerRadius = 2.0; - self.layer.borderWidth = 0.5; + self.layer.borderWidth = 1.0; CGFloat splitX = floor(CGRectGetWidth(frame) *11/18); CGFloat frameHeight = CGRectGetHeight(frame); @@ -37,8 +37,8 @@ - (instancetype)initWithFrame:(CGRect)frame fontSize = 14; } - _lineView = [[UIView alloc] initWithFrame:CGRectMake(splitX, 0, 1, frameHeight)]; - _lineView.backgroundColor = kColorTableSectionBg; + _lineView = [[UIView alloc] initWithFrame:CGRectMake(splitX, (frameHeight - 12)/ 2, 1, 12)]; + _lineView.backgroundColor = kColorDarkA; [self addSubview:_lineView]; _leftButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, splitX, frameHeight)]; @@ -101,17 +101,17 @@ + (instancetype)gitButtonWithFrame:(CGRect)frame + (EaseGitButton *)gitButtonWithFrame:(CGRect)frame type:(EaseGitButtonType)type{ EaseGitButton *button; - UIColor *normalBGColor = kColorDDD; switch (type) { case EaseGitButtonTypeStar: - button = [EaseGitButton gitButtonWithFrame:frame normalTitle:@" 收藏" checkedTitle:@" 已收藏" normalIcon:@"git_icon_star_old" checkedIcon:@"git_icon_stared" normalBGColor:normalBGColor checkedBGColor:kColorBrandGreen normalBorderColor:nil checkedBorderColor:nil userNum:0 checked:NO]; + + button = [EaseGitButton gitButtonWithFrame:frame normalTitle:@" 收藏" checkedTitle:@" 已收藏" normalIcon:@"git_icon_star" checkedIcon:@"git_icon_stared" normalBGColor:kColorWhite checkedBGColor:kColorDark4 normalBorderColor:kColorD8DDE4 checkedBorderColor:nil userNum:0 checked:NO]; break; case EaseGitButtonTypeWatch: - button = [EaseGitButton gitButtonWithFrame:frame normalTitle:@" 关注" checkedTitle:@" 已关注" normalIcon:@"git_icon_watch_old" checkedIcon:@"git_icon_watched" normalBGColor:normalBGColor checkedBGColor:[UIColor colorWithHexString:@"0x4E90BF"] normalBorderColor:nil checkedBorderColor:nil userNum:0 checked:NO]; + button = [EaseGitButton gitButtonWithFrame:frame normalTitle:@" 关注" checkedTitle:@" 已关注" normalIcon:@"git_icon_watch" checkedIcon:@"git_icon_watched" normalBGColor:kColorWhite checkedBGColor:[UIColor colorWithHexString:@"0x4F95E8"] normalBorderColor:kColorD8DDE4 checkedBorderColor:nil userNum:0 checked:NO]; break; case EaseGitButtonTypeFork: default: - button = [EaseGitButton gitButtonWithFrame:frame normalTitle:@" Fork" checkedTitle:@" Fork" normalIcon:@"git_icon_fork_old" checkedIcon:nil normalBGColor:normalBGColor checkedBGColor:normalBGColor normalBorderColor:nil checkedBorderColor:nil userNum:0 checked:NO]; + button = [EaseGitButton gitButtonWithFrame:frame normalTitle:@" Fork" checkedTitle:@" Fork" normalIcon:@"git_icon_fork" checkedIcon:nil normalBGColor:kColorD8DDE4 checkedBGColor:kColorD8DDE4 normalBorderColor:nil checkedBorderColor:nil userNum:0 checked:NO]; break; } button.type = type; @@ -133,9 +133,9 @@ - (void)updateContent{ self.layer.borderColor = _normalBorderColor.CGColor; } - UIColor *titleColor = [UIColor colorWithHexString:!_checked? @"0x222222": @"0xffffff"]; + UIColor *titleColor = [UIColor colorWithHexString:!_checked? @"0x425063": @"0xffffff"]; if (self.type == EaseGitButtonTypeFork) { - titleColor = kColor222; + titleColor = kColorDark4; } [_leftButton setTitleColor:titleColor forState:UIControlStateNormal]; [_rightButton setTitleColor:titleColor forState:UIControlStateNormal]; diff --git a/Coding_iOS/Util/Common/EaseGitButtonsView.h b/Coding_iOS/Util/Common/EaseGitButtonsView.h index 2ac0c199e..f2e9f2c54 100644 --- a/Coding_iOS/Util/Common/EaseGitButtonsView.h +++ b/Coding_iOS/Util/Common/EaseGitButtonsView.h @@ -6,7 +6,7 @@ // Copyright (c) 2015年 Coding. All rights reserved. // -#define EaseGitButtonsView_Height 49.0 +#define EaseGitButtonsView_Height (56.0 + kSafeArea_Bottom) #import "EaseGitButton.h" #import diff --git a/Coding_iOS/Util/Common/EaseGitButtonsView.m b/Coding_iOS/Util/Common/EaseGitButtonsView.m index 232581333..9b42dae75 100644 --- a/Coding_iOS/Util/Common/EaseGitButtonsView.m +++ b/Coding_iOS/Util/Common/EaseGitButtonsView.m @@ -21,7 +21,7 @@ - (instancetype)init self = [super init]; if (self) { [self addLineUp:YES andDown:NO]; - self.backgroundColor = kColorTableSectionBg; + self.backgroundColor = kColorWhite; } return self; } @@ -36,7 +36,7 @@ - (void)setCurProject:(Project *)curProject{ _gitButtons = [[NSMutableArray alloc] initWithCapacity:gitBtnNum]; for (int i = 0; i < gitBtnNum; i++) { - EaseGitButton *gitBtn = [EaseGitButton gitButtonWithFrame:CGRectMake(kPaddingLeftWidth + i *(btnWidth +whiteSpace),(EaseGitButtonsView_Height - 30)/2, btnWidth, 30) type:i]; + EaseGitButton *gitBtn = [EaseGitButton gitButtonWithFrame:CGRectMake(kPaddingLeftWidth + i *(btnWidth +whiteSpace),(EaseGitButtonsView_Height - kSafeArea_Bottom - 36)/2, btnWidth, 36) type:i]; __weak typeof(gitBtn) weakGitBtn = gitBtn; gitBtn.buttonClickedBlock = ^(EaseGitButton *button, EaseGitButtonPosition position){ if (position == EaseGitButtonPositionLeft) { diff --git a/Coding_iOS/Util/Common/EaseToolBar.m b/Coding_iOS/Util/Common/EaseToolBar.m index 759bc85fd..b26ed5770 100755 --- a/Coding_iOS/Util/Common/EaseToolBar.m +++ b/Coding_iOS/Util/Common/EaseToolBar.m @@ -6,7 +6,7 @@ // Copyright (c) 2014年 Coding. All rights reserved. // -#define kEaseToolBar_Height 49.0 +#define kEaseToolBar_Height (49.0 + kSafeArea_Bottom) #define kEaseToolBar_SplitLineViewTag 100 #import "EaseToolBar.h" @@ -30,7 +30,7 @@ - (instancetype)initWithItems:(NSArray *)buttonItems{ self = [super init]; if (self) { self.frame = CGRectMake(0, 0, kScreen_Width, kEaseToolBar_Height); - self.backgroundColor = kColorTableSectionBg; + self.backgroundColor = kColorWhite; self.buttonItems = buttonItems; } return self; @@ -42,11 +42,11 @@ - (void)setButtonItems:(NSArray *)buttonItems{ } _buttonItems = buttonItems; } - [self addLineUp:YES andDown:NO andColor:[UIColor lightGrayColor]]; + [self addLineUp:YES andDown:NO andColor:kColorD8DDE4]; if (_buttonItems.count > 0) { NSInteger num = _buttonItems.count; CGFloat itemWidth = CGRectGetWidth(self.frame)/num; - CGFloat itemHeight = CGRectGetHeight(self.frame); + CGFloat itemHeight = CGRectGetHeight(self.frame) - kSafeArea_Bottom; for (int i = 0; i < num; i++) { UIControl *item = _buttonItems[i]; @@ -54,9 +54,9 @@ - (void)setButtonItems:(NSArray *)buttonItems{ [item addTarget:self action:@selector(itemButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:item]; if (i < num-1) {//item之间的分隔线 - UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake((i+1)*itemWidth, (itemHeight - 25.0)/2, 0.5, 25)]; + UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake((i+1)*itemWidth, 0, 0.5, itemHeight)]; lineView.tag = kEaseToolBar_SplitLineViewTag; - lineView.backgroundColor = [UIColor colorWithHexString:@"0xd1d1d1"]; + lineView.backgroundColor = [UIColor colorWithHexString:@"0xD8DDE4"]; [self addSubview:lineView]; } } @@ -86,6 +86,9 @@ + (instancetype)easeToolBarItemWithTitle:(NSString *)title image:(NSString *)ima - (instancetype)initWithTitle:(NSString *)title image:(NSString *)imageName disableImage:(NSString *)disableImageName{ self = [super init]; if (self) { + if ((imageName || disableImageName) && ![title hasPrefix:@" "]) { + title = [NSString stringWithFormat:@" %@", title]; + } self.title = title; self.imageName = imageName; self.disableImageName = disableImageName; @@ -93,8 +96,8 @@ - (instancetype)initWithTitle:(NSString *)title image:(NSString *)imageName disa [self setIconImage:[UIImage imageNamed:_imageName]]; [self setButtonText:_title]; - [self setAttributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:15], - NSForegroundColorAttributeName:[UIColor colorWithHexString:@"0x888888"]} forUIControlState:UIControlStateNormal]; + [self setAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15], + NSForegroundColorAttributeName:[UIColor colorWithHexString:@"0x323A45"]} forUIControlState:UIControlStateNormal]; [self setIconPosition:IconPositionLeft]; [self setTextAlignment:NSTextAlignmentCenter]; [self setControlState:UIControlStateNormal]; @@ -105,8 +108,8 @@ - (instancetype)initWithTitle:(NSString *)title image:(NSString *)imageName disa - (void)setEnabled:(BOOL)enabled{ [super setEnabled:enabled]; NSString *imageName = enabled? _imageName:(_disableImageName? _disableImageName: _imageName); - NSDictionary *attributes = @{NSFontAttributeName:[UIFont boldSystemFontOfSize:15], - NSForegroundColorAttributeName:enabled? [UIColor colorWithHexString:@"0x888888"] : [UIColor colorWithHexString:@"0xc2c2c2"]}; + NSDictionary *attributes = @{NSFontAttributeName:[UIFont systemFontOfSize:15], + NSForegroundColorAttributeName:enabled? [UIColor colorWithHexString:@"0x323A45"] : [UIColor colorWithHexString:@"0xA9B3BE"]}; [self setIconImage:[UIImage imageNamed:imageName]]; [self setAttributes:attributes forUIControlState:UIControlStateNormal]; } diff --git a/Coding_iOS/Util/Common/Helper.m b/Coding_iOS/Util/Common/Helper.m index da56ac871..c64203d69 100644 --- a/Coding_iOS/Util/Common/Helper.m +++ b/Coding_iOS/Util/Common/Helper.m @@ -13,13 +13,11 @@ @implementation Helper + (BOOL)checkPhotoLibraryAuthorizationStatus { - if ([ALAssetsLibrary respondsToSelector:@selector(authorizationStatus)]) { - ALAuthorizationStatus authStatus = [ALAssetsLibrary authorizationStatus]; - if (ALAuthorizationStatusDenied == authStatus || - ALAuthorizationStatusRestricted == authStatus) { - [self showSettingAlertStr:@"请在iPhone的“设置->隐私->照片”中打开本应用的访问权限"]; - return NO; - } + PHAuthorizationStatus authStatus = PHPhotoLibrary.authorizationStatus; + if (authStatus == PHAuthorizationStatusRestricted || + authStatus == PHAuthorizationStatusDenied) { + [self showSettingAlertStr:@"请在iPhone的“设置->隐私->照片”中打开本应用的访问权限"]; + return NO; } return YES; } @@ -46,19 +44,15 @@ + (BOOL)checkCameraAuthorizationStatus + (void)showSettingAlertStr:(NSString *)tipStr{ //iOS8+系统下可跳转到‘设置’页面,否则只弹出提示窗即可 if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_7_1) { - UIAlertView *alertView = [UIAlertView bk_alertViewWithTitle:@"提示" message:tipStr]; - [alertView bk_setCancelButtonWithTitle:@"取消" handler:nil]; - [alertView bk_addButtonWithTitle:@"设置" handler:nil]; - [alertView bk_setDidDismissBlock:^(UIAlertView *alert, NSInteger index) { - if (index == 1) { + [[UIAlertController ea_alertViewWithTitle:@"提示" message:tipStr buttonTitles:@[@"设置"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { UIApplication *app = [UIApplication sharedApplication]; NSURL *settingsURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; if ([app canOpenURL:settingsURL]) { [app openURL:settingsURL]; } } - }]; - [alertView show]; + }] show]; }else{ kTipAlert(@"%@", tipStr); } diff --git a/Coding_iOS/Util/Common/UIBadgeView.m b/Coding_iOS/Util/Common/UIBadgeView.m index 4549e094c..581d2592c 100755 --- a/Coding_iOS/Util/Common/UIBadgeView.m +++ b/Coding_iOS/Util/Common/UIBadgeView.m @@ -85,7 +85,7 @@ - (id)init { - (void)commonInitialization { // Setup defaults [self setBackgroundColor:[UIColor clearColor]]; - _badgeBackgroundColor = [UIColor colorWithHexString:@"0xf75388"]; + _badgeBackgroundColor = [UIColor colorWithHexString:@"0xFF0000"]; _badgeTextColor = [UIColor whiteColor]; if (kDevice_Is_iPhone6 || kDevice_Is_iPhone6Plus) { _badgeTextFont = [UIFont boldSystemFontOfSize:12]; diff --git a/Coding_iOS/Util/Common/UITapImageView.h b/Coding_iOS/Util/Common/UITapImageView.h index 064f66b93..6a330a4b4 100755 --- a/Coding_iOS/Util/Common/UITapImageView.h +++ b/Coding_iOS/Util/Common/UITapImageView.h @@ -8,7 +8,9 @@ #import -@interface UITapImageView : UIImageView +#import "YLImageView.h" + +@interface UITapImageView : YLImageView - (void)addTapBlock:(void(^)(id obj))tapAction; -(void)setImageWithUrl:(NSURL *)imgUrl placeholderImage:(UIImage *)placeholderImage tapBlock:(void(^)(id obj))tapAction; diff --git a/Coding_iOS/Util/EADeviceToServerLog/EADeviceToServerLog.h b/Coding_iOS/Util/EADeviceToServerLog/EADeviceToServerLog.h new file mode 100644 index 000000000..4caeff494 --- /dev/null +++ b/Coding_iOS/Util/EADeviceToServerLog/EADeviceToServerLog.h @@ -0,0 +1,14 @@ +// +// EADeviceToServerLog.h +// CodingMart +// +// Created by Ease on 2016/11/28. +// Copyright © 2016年 net.coding. All rights reserved. +// + +#import + +@interface EADeviceToServerLog : NSObject ++ (instancetype)shareManager; +- (void)tryToStart; +@end diff --git a/Coding_iOS/Util/EADeviceToServerLog/EADeviceToServerLog.m b/Coding_iOS/Util/EADeviceToServerLog/EADeviceToServerLog.m new file mode 100644 index 000000000..ef4df3961 --- /dev/null +++ b/Coding_iOS/Util/EADeviceToServerLog/EADeviceToServerLog.m @@ -0,0 +1,405 @@ +// +// EADeviceToServerLog.m +// CodingMart +// +// Created by Ease on 2016/11/28. +// Copyright © 2016年 net.coding. All rights reserved. +// + +//MinIntervalDutation 单位(秒) +#define kEALogKey_PostServerPath @"https://tracker.coding.net/v1" +#define kEALogKey_MinIntervalDutation (60 * 30) +#define kEALogKey_LogFileName @"deviceLog" +#define kEALogKey_LastTimeLogDate @"ealastTimeLogDate" +#define kEALogKey_StartTime @"startTime" +#define kEALogKey_FinishTime @"finishTime" +#define kEALogKey_LogInfo @"log" + +#import +#import +#import +#import //https://github.com/libgit2/objective-git +#import "EADeviceToServerLog.h" +#import "EANetTraceRoute.h" +#import "LDNetGetAddress.h" +#import "Login.h" +#import "AFNetworkReachabilityManager.h" +#import "NSData+gzip.h" + +@interface EADeviceToServerLog () +@property (strong, nonatomic) NSMutableDictionary *logDict; +@property (strong, nonatomic) NSArray *hostStrList, *portList; +@property (assign, nonatomic) BOOL isRunning; +@end + +@implementation EADeviceToServerLog + ++ (instancetype)shareManager{ + static EADeviceToServerLog *shared_manager = nil; + static dispatch_once_t pred; + dispatch_once(&pred, ^{ + shared_manager = [[self alloc] init]; + }); + return shared_manager; +} + +- (instancetype)init +{ + self = [super init]; + if (self) { + _hostStrList = @[@"coding.net", + @"git.coding.net", + @"mart.coding.net"]; + _portList = @[@(80), + @(443)]; + } + return self; +} + +- (void)p_resetLog{ + if (!_logDict) { + _logDict = @{}.mutableCopy; + }else{ + [_logDict removeAllObjects]; + } + _logDict[kEALogKey_StartTime] = [self p_curTime]; +// 添加 App 信息 + _logDict[@"userAgent"] = [NSString userAgentStr]; + _logDict[@"globalKey"] = [Login curLoginUser].global_key; +} + +- (void)p_addLog:(NSDictionary *)dict{ + for (NSString *key in dict) { + _logDict[key] = dict[key]; + } +} + +- (NSNumber *)p_curTime{ + return @((long)(1000 *[[NSDate date] timeIntervalSince1970])); +} + +- (NSString*)p_dictionaryToJson:(NSDictionary *)dict{ + NSError *parseError = nil; + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:&parseError]; + return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; +} + +- (void)p_updateLogDate{ + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + [defaults setObject:[NSDate date] forKey:kEALogKey_LastTimeLogDate]; + [defaults synchronize]; +} + +- (NSDate *)p_lastTimeLogDate{ + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + return [defaults objectForKey:kEALogKey_LastTimeLogDate]; +} + +- (BOOL)p_canStartLog{ + if (_isRunning) { + return NO; + } + NSDate *lastTimeLogDate = [self p_lastTimeLogDate]; + if (!lastTimeLogDate) { + return YES; + }else{ + return [[NSDate date] timeIntervalSinceDate:lastTimeLogDate] > kEALogKey_MinIntervalDutation; + } +} + +- (void)tryToStart{ + return ; //停了。要开的话,以后再说 + +// if ([self p_canStartLog]) { +// [self startLog]; +// }else{ +// [self tryToPostToServer]; +// } +} + +- (void)tryToPostToServer{ + if (![AFNetworkReachabilityManager sharedManager].isReachableViaWiFi) { + return; + } + if (_isRunning) { + return; + } + _isRunning = YES; + NSString *logStr = [self p_readLog]; + if (logStr.length > 0) { + NSURL *url = [NSURL URLWithString:kEALogKey_PostServerPath]; + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; + request.HTTPMethod = @"POST"; + request.HTTPBody = [self p_gzipStr:logStr]; + [request setValue:@"text/plain" forHTTPHeaderField:@"Content-Type"]; + [request setValue:@"gzip" forHTTPHeaderField:@"Content-Encoding"]; + __weak typeof(self) weakSelf = self; + NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + [weakSelf handlePostToServerSuccess:!error]; + }]; + [task resume]; + }else{ + _isRunning = NO; + } +} + +- (NSData *)p_gzipStr:(NSString *)string{ + NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding]; + data = [NSData gzipData:data]; + return data; +} + +- (void)handlePostToServerSuccess:(BOOL)isSuccess{ + _isRunning = NO; + if (isSuccess) { + NSString *logFilePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject stringByAppendingFormat:@"/%@", kEALogKey_LogFileName]; + NSFileManager *fileManager = [NSFileManager defaultManager]; + if ([fileManager fileExistsAtPath:logFilePath]) { + [fileManager removeItemAtPath:logFilePath error:nil]; + } + } +} + +- (void)startLog{ + if (_isRunning) { + return; + } + _isRunning = YES; + [self p_resetLog]; + __weak typeof(self) weakSelf = self; + [self getLocalIPBlock:^(NSDictionary *dictLocalIP) { + if (!dictLocalIP) {//第一步获取 ip 不能完成的话,默认原因为连不上外网,取消截下来的监控步骤 + [weakSelf handleCancel]; + }else{ + [weakSelf p_addLog:dictLocalIP]; + [weakSelf getHostIPsBlock:^(NSDictionary *dictHostIPs) { + [weakSelf p_addLog:dictHostIPs]; + [weakSelf getHostPortsBlock:^(NSDictionary *dictHostPorts) { + [weakSelf p_addLog:dictHostPorts]; + [weakSelf getHostMtrsBlock:^(NSDictionary *dictHostMtrs) { + [weakSelf p_addLog:dictHostMtrs]; + [weakSelf getGitsBlock:^(NSDictionary *dictGits) { + [weakSelf p_addLog:dictGits]; + [weakSelf handleFinish]; + }]; + }]; + }]; + }]; + } + }]; +} + +- (void)handleFinish{ + _isRunning = NO; + _logDict[kEALogKey_FinishTime] = [self p_curTime]; + _logDict[@"logDuration"] = [NSString stringWithFormat:@"%ldms", ([_logDict[kEALogKey_FinishTime] longValue] - [_logDict[kEALogKey_StartTime] longValue])] ; + //写文件 + [self p_writeLog]; + [self p_resetLog]; + [self tryToPostToServer]; +} + + +- (void)handleCancel{ + _isRunning = NO; + [self p_resetLog]; +} + +- (void)p_writeLog{ + if (!_logDict) { + return; + } + NSData *logData = [NSJSONSerialization dataWithJSONObject:_logDict options:NSJSONWritingPrettyPrinted error:nil]; + NSString *logStr = [[NSString alloc] initWithData:logData encoding:NSUTF8StringEncoding]; + if (logStr.length <= 0) { + return; + } + NSString *logFilePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject stringByAppendingFormat:@"/%@", kEALogKey_LogFileName]; + NSFileManager *fileManager = [NSFileManager defaultManager]; + if ([fileManager fileExistsAtPath:logFilePath]) { + logStr = [NSString stringWithFormat:@"\n--------------------------------------------------\n%@", logStr]; + NSFileHandle *fileHandle = [NSFileHandle fileHandleForUpdatingAtPath:logFilePath]; + [fileHandle seekToEndOfFile]; + [fileHandle writeData:[logStr dataUsingEncoding:NSUTF8StringEncoding]]; + [fileHandle closeFile]; + }else{ + [logStr writeToFile:logFilePath atomically:YES encoding:NSUTF8StringEncoding error:nil]; + } + [self p_updateLogDate]; +} + +- (NSString *)p_readLog{ + NSString *logFilePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject stringByAppendingFormat:@"/%@", kEALogKey_LogFileName]; + NSFileManager *fileManager = [NSFileManager defaultManager]; + if ([fileManager fileExistsAtPath:logFilePath]) { + NSString *logStr = [[NSString alloc] initWithContentsOfFile:logFilePath encoding:NSUTF8StringEncoding error:nil]; + return logStr; + }else{ + return nil; + } +} + +- (void)getLocalIPBlock:(void(^)(NSDictionary *dictLocalIP))block{ + NSURL *url = [NSURL URLWithString:@"http://ip.cn"]; + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; + request.HTTPMethod = @"GET"; + [request setValue:@"curl/7.41.0" forHTTPHeaderField:@"User-Agent"]; + NSMutableDictionary *dictLocalIP = @{kEALogKey_StartTime: [self p_curTime]}.mutableCopy; + __weak typeof(self) weakSelf = self; + NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + NSString *dataStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + dictLocalIP[@"log"] = dataStr; + dictLocalIP[@"dns"] = [LDNetGetAddress outPutDNSServers]; + dictLocalIP[kEALogKey_FinishTime] = [weakSelf p_curTime]; + if (error) { + block(nil);//需要中断监控 + }else{ + block(@{@"localIp": dictLocalIP}); + } + }]; + [task resume]; +} + +- (void)getHostIPsBlock:(void(^)(NSDictionary *dictHostIPs))block{ + static NSMutableArray *dictHostIPList; + if (dictHostIPList.count == _hostStrList.count){ + block(@{@"hostIp": dictHostIPList}); + dictHostIPList = nil; + }else{ + if (!dictHostIPList) { + dictHostIPList = @[].mutableCopy; + } + __weak typeof(self) weakSelf = self; + [self getHost:_hostStrList[dictHostIPList.count] ipBlock:^(NSDictionary *dictHostIP) { + [dictHostIPList addObject:dictHostIP]; + [weakSelf getHostIPsBlock:block]; + }]; + } +} + +- (void)getHost:(NSString *)hostStr ipBlock:(void(^)(NSDictionary *dictHostIP))block{ + NSMutableDictionary *dictHostIP = @{kEALogKey_StartTime: [self p_curTime]}.mutableCopy; + dictHostIP[@"host"] = hostStr; + dictHostIP[@"ip"] = [self p_getIPWithHostName:hostStr]; + dictHostIP[kEALogKey_FinishTime] = [self p_curTime]; + block(dictHostIP); +} + +- (NSString *)p_getIPWithHostName:(NSString *)hostName{ + struct hostent *hs; + struct sockaddr_in server; + if ((hs = gethostbyname([hostName UTF8String])) != NULL) { + server.sin_addr = *((struct in_addr*)hs->h_addr_list[0]); + return [NSString stringWithUTF8String:inet_ntoa(server.sin_addr)]; + } + return nil; +} + +- (void)getHostPortsBlock:(void(^)(NSDictionary *dictHostPorts))block{ + static NSMutableArray *dictHostPortList; + if (dictHostPortList.count == _hostStrList.count * _portList.count){ + block(@{@"portScan": dictHostPortList}); + dictHostPortList = nil; + }else{ + if (!dictHostPortList) { + dictHostPortList = @[].mutableCopy; + } + __weak typeof(self) weakSelf = self; + [self getHost:_hostStrList[dictHostPortList.count / _portList.count] port:_portList[dictHostPortList.count % _portList.count] block:^(NSDictionary *dictHostPort) { + [dictHostPortList addObject:dictHostPort]; + [weakSelf getHostPortsBlock:block]; + }]; + } +} + +- (void)getHost:(NSString *)hostStr port:(NSNumber *)port block:(void(^)(NSDictionary *dictHostPort))block{ + NSMutableDictionary *dictHostPort = @{kEALogKey_StartTime: [self p_curTime]}.mutableCopy; + dictHostPort[@"host"] = hostStr; + dictHostPort[@"port"] = port; + NSString *errorStr = nil; + dictHostPort[@"result"] = @([self p_canLinkToHost:hostStr port:port errorStr:&errorStr]); + dictHostPort[kEALogKey_FinishTime] = [self p_curTime]; + block(dictHostPort); +} + +- (BOOL)p_canLinkToHost:(NSString *)hostStr port:(NSNumber *)port errorStr:(NSString **)errorStr{ + int socketFileDescriptor = socket(AF_INET, SOCK_STREAM, 0); + struct hostent *hs; + if (socketFileDescriptor == -1) { + *errorStr = @"创建 socket 失败"; + return NO; + }else if ((hs = gethostbyname([hostStr UTF8String])) == NULL){ + *errorStr = @"IP 地址解析失败"; + return NO; + }else{ + struct sockaddr_in socketParameters; + socketParameters.sin_family = AF_INET; + socketParameters.sin_addr = *((struct in_addr*)hs->h_addr_list[0]); + socketParameters.sin_port = htons(port.intValue); + int ret = connect(socketFileDescriptor, (struct sockaddr *) &socketParameters, sizeof(socketParameters)); + close(socketFileDescriptor); + if (ret == -1) { + *errorStr = @"socket 连接失败"; + return NO; + }else{//链接成功 + return YES; + } + } +} + +- (void)getHostMtrsBlock:(void(^)(NSDictionary *dictHostMtrs))block{ + NSString *dnsStr = [self.logDict[@"localIp"][@"dns"] firstObject]; + if (dnsStr.length > 0 && [dnsStr componentsSeparatedByString:@"."].count != 4) {//不是 ipv4 的暂时不处理 + block(nil); + return; + } + static NSMutableArray *dictHostMtrList; + if (!dictHostMtrList) { + dictHostMtrList = @[].mutableCopy; + } + if (dictHostMtrList.count == _hostStrList.count){ + block(@{@"mtr": dictHostMtrList}); + dictHostMtrList = nil; + }else{ + __weak typeof(self) weakSelf = self; + [self getHost:_hostStrList[dictHostMtrList.count] mtrBlock:^(NSDictionary *dictHostMtr) { + [dictHostMtrList addObject:dictHostMtr]; + [weakSelf getHostMtrsBlock:block]; + }]; + } +} + +- (void)getHost:(NSString *)hostStr mtrBlock:(void(^)(NSDictionary *dictHostMtr))block{ + NSMutableDictionary *dictHostMtr = @{kEALogKey_StartTime: [self p_curTime]}.mutableCopy; + dictHostMtr[@"host"] = hostStr; + [EANetTraceRoute getTraceRouteOfHost:hostStr block:^(NSArray *traceRouteList) { + dictHostMtr[@"pings"] = traceRouteList; + dictHostMtr[kEALogKey_FinishTime] = [self p_curTime]; + block(dictHostMtr); + }]; +} + +- (void)getGitsBlock:(void(^)(NSDictionary *dictGits))block{ + NSURL *repoURL = [NSURL URLWithString:@"https://git.coding.net/coding/test-point.git"]; + + NSFileManager* fileManager = [NSFileManager defaultManager]; + NSURL *appDocsDir = [fileManager URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask].lastObject; + NSURL *localURL = [NSURL URLWithString:repoURL.lastPathComponent relativeToURL:appDocsDir]; + if ([fileManager fileExistsAtPath:localURL.path isDirectory:nil]) {//已经存在的话,就先删掉 + [fileManager removeItemAtURL:localURL error:nil]; + } + + NSMutableDictionary *dictGits = @{kEALogKey_StartTime: [self p_curTime]}.mutableCopy; + dictGits[@"url"] = repoURL.absoluteString; + NSError* error = nil; + GTRepository *repo = [GTRepository cloneFromURL:repoURL toWorkingDirectory:localURL options:@{GTRepositoryCloneOptionsPerformCheckout: @NO} error:&error transferProgressBlock:^(const git_transfer_progress *progress, BOOL *stop) { + DebugLog(@"received_objects_count: %d", progress->received_objects); + }]; + + dictGits[kEALogKey_FinishTime] = [self p_curTime]; + dictGits[@"result"] = repo? @YES: @NO; + dictGits[kEALogKey_LogInfo] = error.description ?: @""; + block(@{@"git": dictGits}); +} + +@end diff --git a/Coding_iOS/Util/EADeviceToServerLog/EANetTraceRoute.h b/Coding_iOS/Util/EADeviceToServerLog/EANetTraceRoute.h new file mode 100644 index 000000000..5e53d4346 --- /dev/null +++ b/Coding_iOS/Util/EADeviceToServerLog/EANetTraceRoute.h @@ -0,0 +1,16 @@ +// +// EANetTraceRoute.h +// CodingMart +// +// Created by Ease on 2016/11/29. +// Copyright © 2016年 net.coding. All rights reserved. +// + +//libresolv.9.tbd +//CoreTelephony.framework + +#import + +@interface EANetTraceRoute : NSObject ++ (void)getTraceRouteOfHost:(NSString *)hostStr block:(void(^)(NSArray *traceRouteList))block; +@end diff --git a/Coding_iOS/Util/EADeviceToServerLog/EANetTraceRoute.m b/Coding_iOS/Util/EADeviceToServerLog/EANetTraceRoute.m new file mode 100644 index 000000000..6b74f9e84 --- /dev/null +++ b/Coding_iOS/Util/EADeviceToServerLog/EANetTraceRoute.m @@ -0,0 +1,67 @@ +// +// EANetTraceRoute.m +// CodingMart +// +// Created by Ease on 2016/11/29. +// Copyright © 2016年 net.coding. All rights reserved. +// + +#import "EANetTraceRoute.h" +#import "LDNetTraceRoute.h" + +@interface EANetTraceRoute () +@property (strong, nonatomic) LDNetTraceRoute *ldNTR; +@property (strong, nonatomic) NSString *hostStr; +@property (strong, nonatomic) NSMutableArray *traceRouteList; +@property (copy, nonatomic) void(^finishBlock)(NSArray *traceRouteList); + +@end + +@implementation EANetTraceRoute + ++ (instancetype)shareManager{ + static EANetTraceRoute *shared_manager = nil; + static dispatch_once_t pred; + dispatch_once(&pred, ^{ + shared_manager = [[self alloc] init]; + }); + return shared_manager; +} + ++ (void)getTraceRouteOfHost:(NSString *)hostStr block:(void(^)(NSArray *traceRouteList))block{ + EANetTraceRoute *eaNTR = [self shareManager]; + if ([eaNTR.ldNTR isRunning]) {//中断上一个 + [eaNTR.ldNTR stopTrace]; + [eaNTR traceRouteDidEnd]; + } + eaNTR.finishBlock = block; + [eaNTR doTraceRouteOfHost:hostStr]; +} + +- (void)doTraceRouteOfHost:(NSString *)hostStr{ + if (hostStr.length > 0) { + _hostStr = hostStr; + _traceRouteList = @[].mutableCopy; + if (!_ldNTR) { + _ldNTR = [[LDNetTraceRoute alloc] initWithMaxTTL:TRACEROUTE_MAX_TTL timeout:TRACEROUTE_TIMEOUT maxAttempts:5 port:TRACEROUTE_PORT]; + _ldNTR.delegate = self; + } + [NSThread detachNewThreadSelector:@selector(doTraceRoute:) + toTarget:_ldNTR + withObject:hostStr]; + }else{ + [self traceRouteDidEnd]; + } +} + +#pragma LDNetTraceRouteDelegate +- (void)appendRouteLog:(NSString *)routeLog{ + [_traceRouteList addObject:routeLog]; +} + +- (void)traceRouteDidEnd{ + if (_finishBlock) { + _finishBlock(_traceRouteList); + } +} +@end diff --git a/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetConnect.h b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetConnect.h new file mode 100644 index 000000000..72cd0523d --- /dev/null +++ b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetConnect.h @@ -0,0 +1,41 @@ +// +// LDNetConnect.h +// LDNetDiagnoServiceDemo +// +// Created by ZhangHaiyang on 15-8-5. +// Copyright (c) 2015年 庞辉. All rights reserved. +// + +#import + +/* + * @protocal LDNetConnectDelegate监测connect命令的的输出到日志变量; + * + */ +@protocol LDNetConnectDelegate +- (void)appendSocketLog:(NSString *)socketLog; +- (void)connectDidEnd:(BOOL)success; +@end + + +/* + * @class LDNetConnect ping监控 + * 主要是通过建立socket连接的过程,监控目标主机是否连通 + * 连续执行五次,因为每次的速度不一致,可以观察其平均速度来判断网络情况 + */ +@interface LDNetConnect : NSObject { +} + +@property (nonatomic, weak) id delegate; + +/** + * 通过hostaddress和port 进行connect诊断 + */ +- (void)runWithHostAddress:(NSString *)hostAddress port:(int)port; + +/** + * 停止connect + */ +- (void)stopConnect; + +@end diff --git a/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetConnect.m b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetConnect.m new file mode 100644 index 000000000..3307e24b6 --- /dev/null +++ b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetConnect.m @@ -0,0 +1,182 @@ +// +// LDNetConnect.m +// LDNetDiagnoServiceDemo +// +// Created by ZhangHaiyang on 15-8-5. +// Copyright (c) 2015年 庞辉. All rights reserved. +// + +#import +#import +#import +#import + +#import "LDNetConnect.h" +#import "LDNetTimer.h" + +#define MAXCOUNT_CONNECT 4 + +@interface LDNetConnect () { + BOOL _isExistSuccess; //监测是否有connect成功 + int _connectCount; //当前执行次数 + + int tcpPort; //执行端口 + NSString *_hostAddress; //目标域名的IP地址 + BOOL _isIPV6; + NSString *_resultLog; + NSInteger _sumTime; + CFSocketRef _socket; +} + +@property (nonatomic, assign) long _startTime; //每次执行的开始时间 + +@end + +@implementation LDNetConnect +@synthesize _startTime; + +/** + * 停止connect + */ +- (void)stopConnect +{ + _connectCount = MAXCOUNT_CONNECT + 1; +} + +/** + * 通过hostaddress和port 进行connect诊断 + */ +- (void)runWithHostAddress:(NSString *)hostAddress port:(int)port +{ + _hostAddress = hostAddress; + _isIPV6 = [_hostAddress rangeOfString:@":"].location == NSNotFound?NO:YES; + tcpPort = port; + _isExistSuccess = FALSE; + _connectCount = 0; + _sumTime = 0; + _resultLog = @""; + if (self.delegate && [self.delegate respondsToSelector:@selector(appendSocketLog:)]) { + [self.delegate + appendSocketLog:[NSString stringWithFormat:@"connect to host %@ ...", _hostAddress]]; + } + _startTime = [LDNetTimer getMicroSeconds]; + [self connect]; + do { + [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; + } while (_connectCount < MAXCOUNT_CONNECT); +} + +/** + * 建立socket对hostaddress进行连接 + */ +- (void)connect +{ + NSData *addrData = nil; + + //设置地址 + if (!_isIPV6) { + struct sockaddr_in nativeAddr4; + memset(&nativeAddr4, 0, sizeof(nativeAddr4)); + nativeAddr4.sin_len = sizeof(nativeAddr4); + nativeAddr4.sin_family = AF_INET; + nativeAddr4.sin_port = htons(tcpPort); + inet_pton(AF_INET, _hostAddress.UTF8String, &nativeAddr4.sin_addr.s_addr); + addrData = [NSData dataWithBytes:&nativeAddr4 length:sizeof(nativeAddr4)]; + } else { + struct sockaddr_in6 nativeAddr6; + memset(&nativeAddr6, 0, sizeof(nativeAddr6)); + nativeAddr6.sin6_len = sizeof(nativeAddr6); + nativeAddr6.sin6_family = AF_INET6; + nativeAddr6.sin6_port = htons(tcpPort); + inet_pton(AF_INET6, _hostAddress.UTF8String, &nativeAddr6.sin6_addr); + addrData = [NSData dataWithBytes:&nativeAddr6 length:sizeof(nativeAddr6)]; + } + + if (addrData != nil) { + [self connectWithAddress:addrData]; + } +} + +-(void)connectWithAddress:(NSData *)addr{ + struct sockaddr *pSockAddr = (struct sockaddr *)[addr bytes]; + int addressFamily = pSockAddr->sa_family; + + //创建套接字 + CFSocketContext CTX = {0, (__bridge_retained void *)(self), NULL, NULL, NULL}; + _socket = CFSocketCreate(kCFAllocatorDefault, addressFamily, SOCK_STREAM, IPPROTO_TCP, + kCFSocketConnectCallBack, TCPServerConnectCallBack, &CTX); + + //执行连接 + CFSocketConnectToAddress(_socket, (__bridge CFDataRef)addr, 3); + CFRunLoopRef cfrl = CFRunLoopGetCurrent(); // 获取当前运行循环 + CFRunLoopSourceRef source = + CFSocketCreateRunLoopSource(kCFAllocatorDefault, _socket, _connectCount); //定义循环对象 + CFRunLoopAddSource(cfrl, source, kCFRunLoopDefaultMode); //将循环对象加入当前循环中 + CFRelease(source); +} + + +/** + * connect回调函数 + */ +static void TCPServerConnectCallBack(CFSocketRef socket, CFSocketCallBackType type, + CFDataRef address, const void *data, void *info) +{ + if (data != NULL) { + printf("connect"); + LDNetConnect *con = (__bridge_transfer LDNetConnect *)info; + [con readStream:FALSE]; + } else { + + LDNetConnect *con = (__bridge_transfer LDNetConnect *)info; + [con readStream:TRUE]; + } +} + +/** + * 返回之后的一系列操作 + */ +- (void)readStream:(BOOL)success +{ + // NSString *errorLog = @""; + if (success) { + _isExistSuccess = TRUE; + NSInteger interval = [LDNetTimer computeDurationSince:_startTime] / 1000; + _sumTime += interval; + NSLog(@"connect success %ld", (long)interval); + _resultLog = [_resultLog + stringByAppendingString:[NSString stringWithFormat:@"%d's time=%ldms, ", + _connectCount + 1, (long)interval]]; + } else { + _sumTime = 99999; + _resultLog = + [_resultLog stringByAppendingString:[NSString stringWithFormat:@"%d's time=TimeOut, ", + _connectCount + 1]]; + } + if (_connectCount == MAXCOUNT_CONNECT - 1) { + if (_sumTime >= 99999) { + _resultLog = [_resultLog substringToIndex:[_resultLog length] - 1]; + } else { + _resultLog = [_resultLog + stringByAppendingString:[NSString stringWithFormat:@"average=%ldms", + (long)(_sumTime / 4)]]; + } + if (self.delegate && [self.delegate respondsToSelector:@selector(appendSocketLog:)]) { + [self.delegate appendSocketLog:_resultLog]; + } + } + + CFRelease(_socket); + _connectCount++; + if (_connectCount < MAXCOUNT_CONNECT) { + _startTime = [LDNetTimer getMicroSeconds]; + [self connect]; + + } else { + if (self.delegate && [self.delegate respondsToSelector:@selector(connectDidEnd:)]) { + [self.delegate connectDidEnd:_isExistSuccess]; + } + } +} + +@end diff --git a/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetDiagnoService.h b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetDiagnoService.h new file mode 100644 index 000000000..02447c9c6 --- /dev/null +++ b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetDiagnoService.h @@ -0,0 +1,81 @@ +// +// LDNetDiagnoService.h +// LDNetDiagnoServieDemo +// +// Created by 庞辉 on 14-10-29. +// Copyright (c) 2014年 庞辉. All rights reserved. +// + +#import + +/** + * @protocol 监控网络诊断的过程信息 + * + */ +@protocol LDNetDiagnoServiceDelegate +/** + * 告诉调用者诊断开始 + */ +- (void)netDiagnosisDidStarted; + + +/** + * 逐步返回监控信息, + * 如果需要实时显示诊断数据,实现此接口方法 + */ +- (void)netDiagnosisStepInfo:(NSString *)stepInfo; + + +/** + * 因为监控过程是一个异步过程,当监控结束后告诉调用者; + * 在监控结束的时候,对监控字符串进行处理 + */ +- (void)netDiagnosisDidEnd:(NSString *)allLogInfo; + +@end + + +/** + * @class 网络诊断服务 + * 通过对指定域名进行ping诊断和traceRoute诊断收集诊断日志 + */ +@interface LDNetDiagnoService : NSObject { +} +@property (nonatomic, weak, readwrite) + id delegate; //向调用者输出诊断信息接口 +@property (nonatomic, retain) NSString *dormain; //接口域名 + +/** + * 初始化网络诊断服务 + * theAppCode,theUID, theDormain为必填项 + */ +- (id)initWithAppCode:(NSString *)theAppCode + appName:(NSString *)theAppName + appVersion:(NSString *)theAppVersion + userID:(NSString *)theUID + deviceID:(NSString *)theDeviceID + dormain:(NSString *)theDormain + carrierName:(NSString *)theCarrierName + ISOCountryCode:(NSString *)theISOCountryCode + MobileCountryCode:(NSString *)theMobileCountryCode + MobileNetCode:(NSString *)theMobileNetCode; + + +/** + * 开始诊断网络 + */ +- (void)startNetDiagnosis; + + +/** + * 停止诊断网络 + */ +- (void)stopNetDialogsis; + + +/** + * 打印整体loginInfo; + */ +- (void)printLogInfo; + +@end diff --git a/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetDiagnoService.m b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetDiagnoService.m new file mode 100644 index 000000000..7dc8fb446 --- /dev/null +++ b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetDiagnoService.m @@ -0,0 +1,439 @@ +// +// LDNetDiagnoService.m +// LDNetDiagnoServieDemo +// +// Created by 庞辉 on 14-10-29. +// Copyright (c) 2014年 庞辉. All rights reserved. +// +#import +#import +#import +#import "LDNetDiagnoService.h" +#import "LDNetPing.h" +#import "LDNetTraceRoute.h" +#import "LDNetGetAddress.h" +#import "LDNetTimer.h" +#import "LDNetConnect.h" + +static NSString *const kPingOpenServerIP = @""; +static NSString *const kCheckOutIPURL = @""; + +@interface LDNetDiagnoService () { + NSString *_appCode; //客户端标记 + NSString *_appName; + NSString *_appVersion; + NSString *_UID; //用户ID + NSString *_deviceID; //客户端机器ID,如果不传入会默认取API提供的机器ID + NSString *_carrierName; + NSString *_ISOCountryCode; + NSString *_MobileCountryCode; + NSString *_MobileNetCode; + + NETWORK_TYPE _curNetType; + NSString *_localIp; + NSString *_gatewayIp; + NSArray *_dnsServers; + NSArray *_hostAddress; + + NSMutableString *_logInfo; //记录网络诊断log日志 + BOOL _isRunning; + BOOL _connectSuccess; //记录连接是否成功 + LDNetPing *_netPinger; + LDNetTraceRoute *_traceRouter; + LDNetConnect *_netConnect; +} + +@end + +@implementation LDNetDiagnoService +#pragma mark - public method +/** + * 初始化网络诊断服务 + */ +- (id)initWithAppCode:(NSString *)theAppCode + appName:(NSString *)theAppName + appVersion:(NSString *)theAppVersion + userID:(NSString *)theUID + deviceID:(NSString *)theDeviceID + dormain:(NSString *)theDormain + carrierName:(NSString *)theCarrierName + ISOCountryCode:(NSString *)theISOCountryCode + MobileCountryCode:(NSString *)theMobileCountryCode + MobileNetCode:(NSString *)theMobileNetCode +{ + self = [super init]; + if (self) { + _appCode = theAppCode; + _appName = theAppName; + _appVersion = theAppVersion; + _UID = theUID; + _deviceID = theDeviceID; + _dormain = theDormain; + _carrierName = theCarrierName; + _ISOCountryCode = theISOCountryCode; + _MobileCountryCode = theMobileCountryCode; + _MobileNetCode = theMobileNetCode; + + _logInfo = [[NSMutableString alloc] initWithCapacity:20]; + _isRunning = NO; + } + + return self; +} + + +/** + * 开始诊断网络 + */ +- (void)startNetDiagnosis +{ + if (!_dormain || [_dormain isEqualToString:@""]) return; + + _isRunning = YES; + [_logInfo setString:@""]; + [self recordStepInfo:@"开始诊断..."]; + [self recordCurrentAppVersion]; + [self recordLocalNetEnvironment]; + + //未联网不进行任何检测 + if (_curNetType == 0) { + _isRunning = NO; + [self recordStepInfo:@"\n当前主机未联网,请检查网络!"]; + [self recordStepInfo:@"\n网络诊断结束\n"]; + if (self.delegate && [self.delegate respondsToSelector:@selector(netDiagnosisDidEnd:)]) { + [self.delegate netDiagnosisDidEnd:_logInfo]; + } + return; + } + + if (_isRunning) { +// [self recordOutIPInfo]; + } + + if (_isRunning) { + // connect诊断,同步过程, 如果TCP无法连接,检查本地网络环境 + _connectSuccess = NO; + [self recordStepInfo:@"\n开始TCP连接测试..."]; + if ([_hostAddress count] > 0) { + _netConnect = [[LDNetConnect alloc] init]; + _netConnect.delegate = self; + for (int i = 0; i < [_hostAddress count]; i++) { + [_netConnect runWithHostAddress:[_hostAddress objectAtIndex:i] port:80]; + } + } else { + [self recordStepInfo:@"DNS解析失败,主机地址不可达"]; + } + if (_isRunning) { + [self pingDialogsis:!_connectSuccess]; + } + } + + + if (_isRunning) { + //开始诊断traceRoute + [self recordStepInfo:@"\n开始traceroute..."]; + _traceRouter = [[LDNetTraceRoute alloc] initWithMaxTTL:TRACEROUTE_MAX_TTL + timeout:TRACEROUTE_TIMEOUT + maxAttempts:TRACEROUTE_ATTEMPTS + port:TRACEROUTE_PORT]; + _traceRouter.delegate = self; + if (_traceRouter) { + [NSThread detachNewThreadSelector:@selector(doTraceRoute:) + toTarget:_traceRouter + withObject:_dormain]; + } + } +} + + +/** + * 停止诊断网络, 清空诊断状态 + */ +- (void)stopNetDialogsis +{ + if (_isRunning) { + if (_netConnect != nil) { + [_netConnect stopConnect]; + _netConnect = nil; + } + + if (_netPinger != nil) { + [_netPinger stopPing]; + _netPinger = nil; + } + + if (_traceRouter != nil) { + [_traceRouter stopTrace]; + _traceRouter = nil; + } + + _isRunning = NO; + } +} + + +/** + * 打印整体loginInfo; + */ +- (void)printLogInfo +{ + NSLog(@"\n%@\n", _logInfo); +} + + +#pragma mark - +#pragma mark - private method + +/*! + * @brief 获取App相关信息 + */ +- (void)recordCurrentAppVersion +{ + //输出应用版本信息和用户ID + [self recordStepInfo:[NSString stringWithFormat:@"应用code: %@", _appCode]]; + NSDictionary *dicBundle = [[NSBundle mainBundle] infoDictionary]; + + if (!_appName || [_appName isEqualToString:@""]) { + _appName = [dicBundle objectForKey:@"CFBundleDisplayName"]; + } + [self recordStepInfo:[NSString stringWithFormat:@"应用名称: %@", _appName]]; + + if (!_appVersion || [_appVersion isEqualToString:@""]) { + _appVersion = [dicBundle objectForKey:@"CFBundleShortVersionString"]; + } + [self recordStepInfo:[NSString stringWithFormat:@"应用版本: %@", _appVersion]]; + [self recordStepInfo:[NSString stringWithFormat:@"用户id: %@", _UID]]; + + //输出机器信息 + UIDevice *device = [UIDevice currentDevice]; + [self recordStepInfo:[NSString stringWithFormat:@"机器类型: %@", [device systemName]]]; + [self recordStepInfo:[NSString stringWithFormat:@"系统版本: %@", [device systemVersion]]]; + if (!_deviceID || [_deviceID isEqualToString:@""]) { + _deviceID = [self uniqueAppInstanceIdentifier]; + } + [self recordStepInfo:[NSString stringWithFormat:@"机器ID: %@", _deviceID]]; + + + //运营商信息 + if (!_carrierName || [_carrierName isEqualToString:@""]) { + CTTelephonyNetworkInfo *netInfo = [[CTTelephonyNetworkInfo alloc] init]; + CTCarrier *carrier = [netInfo subscriberCellularProvider]; + if (carrier != NULL) { + _carrierName = [carrier carrierName]; + _ISOCountryCode = [carrier isoCountryCode]; + _MobileCountryCode = [carrier mobileCountryCode]; + _MobileNetCode = [carrier mobileNetworkCode]; + } else { + _carrierName = @""; + _ISOCountryCode = @""; + _MobileCountryCode = @""; + _MobileNetCode = @""; + } + } + + [self recordStepInfo:[NSString stringWithFormat:@"运营商: %@", _carrierName]]; + [self recordStepInfo:[NSString stringWithFormat:@"ISOCountryCode: %@", _ISOCountryCode]]; + [self recordStepInfo:[NSString stringWithFormat:@"MobileCountryCode: %@", _MobileCountryCode]]; + [self recordStepInfo:[NSString stringWithFormat:@"MobileNetworkCode: %@", _MobileNetCode]]; +} + + +/*! + * @brief 获取本地网络环境信息 + */ +- (void)recordLocalNetEnvironment +{ + [self recordStepInfo:[NSString stringWithFormat:@"\n\n诊断域名 %@...\n", _dormain]]; + //判断是否联网以及获取网络类型 + NSArray *typeArr = [NSArray arrayWithObjects:@"2G", @"3G", @"4G", @"5G", @"wifi", nil]; + _curNetType = [LDNetGetAddress getNetworkTypeFromStatusBar]; + if (_curNetType == 0) { + [self recordStepInfo:[NSString stringWithFormat:@"当前是否联网: 未联网"]]; + } else { + [self recordStepInfo:[NSString stringWithFormat:@"当前是否联网: 已联网"]]; + if (_curNetType > 0 && _curNetType < 6) { + [self + recordStepInfo:[NSString stringWithFormat:@"当前联网类型: %@", + [typeArr objectAtIndex:_curNetType - 1]]]; + } + } + + //本地ip信息 + _localIp = [LDNetGetAddress deviceIPAdress]; + [self recordStepInfo:[NSString stringWithFormat:@"当前本机IP: %@", _localIp]]; + + if (_curNetType == NETWORK_TYPE_WIFI) { + _gatewayIp = [LDNetGetAddress getGatewayIPAddress]; + [self recordStepInfo:[NSString stringWithFormat:@"本地网关: %@", _gatewayIp]]; + } else { + _gatewayIp = @""; + } + + + _dnsServers = [NSArray arrayWithArray:[LDNetGetAddress outPutDNSServers]]; + [self recordStepInfo:[NSString stringWithFormat:@"本地DNS: %@", + [_dnsServers componentsJoinedByString:@", "]]]; + + [self recordStepInfo:[NSString stringWithFormat:@"远端域名: %@", _dormain]]; + + // host地址IP列表 + long time_start = [LDNetTimer getMicroSeconds]; + _hostAddress = [NSArray arrayWithArray:[LDNetGetAddress getDNSsWithDormain:_dormain]]; + long time_duration = [LDNetTimer computeDurationSince:time_start] / 1000; + if ([_hostAddress count] == 0) { + [self recordStepInfo:[NSString stringWithFormat:@"DNS解析结果: 解析失败"]]; + } else { + [self + recordStepInfo:[NSString stringWithFormat:@"DNS解析结果: %@ (%ldms)", + [_hostAddress componentsJoinedByString:@", "], + time_duration]]; + } +} + +/** + * 使用接口获取用户的出口IP和DNS信息 + */ +- (void)recordOutIPInfo +{ + [self recordStepInfo:@"\n开始获取运营商信息..."]; + // 初始化请求, 这里是变长的, 方便扩展 + NSMutableURLRequest *request = + [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:kCheckOutIPURL] + cachePolicy:NSURLRequestUseProtocolCachePolicy + timeoutInterval:10]; + + // 发送同步请求, data就是返回的数据 + NSError *error = nil; + NSData *data = + [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error]; + if (error != nil) { + NSLog(@"error = %@", error); + [self recordStepInfo:@"\n获取超时"]; + return; + } + NSString *response = [[NSString alloc] initWithData:data encoding:0x80000632]; + NSLog(@"response: %@", response); + [self recordStepInfo:response]; +} + + +/** + * 构建ping列表并进行ping诊断 + */ +- (void)pingDialogsis:(BOOL)pingLocal +{ + //诊断ping信息, 同步过程 + NSMutableArray *pingAdd = [[NSMutableArray alloc] init]; + NSMutableArray *pingInfo = [[NSMutableArray alloc] init]; + if (pingLocal) { + [pingAdd addObject:@"127.0.0.1"]; + [pingInfo addObject:@"本机"]; + [pingAdd addObject:_localIp]; + [pingInfo addObject:@"本机IP"]; + if (_gatewayIp && ![_gatewayIp isEqualToString:@""]) { + [pingAdd addObject:_gatewayIp]; + [pingInfo addObject:@"本地网关"]; + } + if ([_dnsServers count] > 0) { + [pingAdd addObject:[_dnsServers objectAtIndex:0]]; + [pingInfo addObject:@"DNS服务器"]; + } + } + + //不管服务器解析DNS是否可达,均需要ping指定ip地址 + if([_localIp rangeOfString:@":"].location == NSNotFound){ + [pingAdd addObject:kPingOpenServerIP]; + [pingInfo addObject:@"开放服务器"]; + } + + [self recordStepInfo:@"\n开始ping..."]; + _netPinger = [[LDNetPing alloc] init]; + _netPinger.delegate = self; + for (int i = 0; i < [pingAdd count]; i++) { + [self recordStepInfo:[NSString stringWithFormat:@"ping: %@ %@ ...", + [pingInfo objectAtIndex:i], + [pingAdd objectAtIndex:i]]]; + if ([[pingAdd objectAtIndex:i] isEqualToString:kPingOpenServerIP]) { + [_netPinger runWithHostName:[pingAdd objectAtIndex:i] normalPing:YES]; + } else { + [_netPinger runWithHostName:[pingAdd objectAtIndex:i] normalPing:YES]; + } + } +} + + +#pragma mark - +#pragma mark - netPingDelegate + +- (void)appendPingLog:(NSString *)pingLog +{ + [self recordStepInfo:pingLog]; +} + +- (void)netPingDidEnd +{ + // net +} + +#pragma mark - traceRouteDelegate +- (void)appendRouteLog:(NSString *)routeLog +{ + [self recordStepInfo:routeLog]; +} + +- (void)traceRouteDidEnd +{ + _isRunning = NO; + [self recordStepInfo:@"\n网络诊断结束\n"]; + if (self.delegate && [self.delegate respondsToSelector:@selector(netDiagnosisDidEnd:)]) { + [self.delegate netDiagnosisDidEnd:_logInfo]; + } +} + +#pragma mark - connectDelegate +- (void)appendSocketLog:(NSString *)socketLog +{ + [self recordStepInfo:socketLog]; +} + +- (void)connectDidEnd:(BOOL)success +{ + if (success) { + _connectSuccess = YES; + } +} + + +#pragma mark - common method +/** + * 如果调用者实现了stepInfo接口,输出信息 + */ +- (void)recordStepInfo:(NSString *)stepInfo +{ + if (stepInfo == nil) stepInfo = @""; + [_logInfo appendString:stepInfo]; + [_logInfo appendString:@"\n"]; + + if (self.delegate && [self.delegate respondsToSelector:@selector(netDiagnosisStepInfo:)]) { + [self.delegate netDiagnosisStepInfo:[NSString stringWithFormat:@"%@\n", stepInfo]]; + } +} + + +/** + * 获取deviceID + */ +- (NSString *)uniqueAppInstanceIdentifier +{ + NSString *app_uuid = @""; + CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault); + CFStringRef uuidString = CFUUIDCreateString(kCFAllocatorDefault, uuidRef); + app_uuid = [NSString stringWithString:(__bridge NSString *)uuidString]; + CFRelease(uuidString); + CFRelease(uuidRef); + return app_uuid; +} + + +@end diff --git a/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetGetAddress.h b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetGetAddress.h new file mode 100644 index 000000000..c359a4772 --- /dev/null +++ b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetGetAddress.h @@ -0,0 +1,58 @@ +// +// LDNetGetAddress.h +// LDNetDiagnoServiceDemo +// +// Created by ZhangHaiyang on 15-8-5. +// Copyright (c) 2015年 庞辉. All rights reserved. +// + +#import +#import + +@interface LDNetGetAddress : NSObject + +//网络类型 +typedef enum { + NETWORK_TYPE_NONE = 0, + NETWORK_TYPE_2G = 1, + NETWORK_TYPE_3G = 2, + NETWORK_TYPE_4G = 3, + NETWORK_TYPE_5G = 4, // 5G目前为猜测结果 + NETWORK_TYPE_WIFI = 5, +} NETWORK_TYPE; + +/*! + * 获取当前设备ip地址 + */ ++ (NSString *)deviceIPAdress; + + +/*! + * 获取当前设备网关地址 + */ ++ (NSString *)getGatewayIPAddress; + + +/*! + * 通过域名获取服务器DNS地址 + */ ++ (NSArray *)getDNSsWithDormain:(NSString *)hostName; + + +/*! + * 获取本地网络的DNS地址 + */ ++ (NSArray *)outPutDNSServers; + + +/*! + * 获取当前网络类型 + */ ++ (NETWORK_TYPE)getNetworkTypeFromStatusBar; + +/** + * 格式化IPV6地址 + */ ++(NSString *)formatIPV6Address:(struct in6_addr)ipv6Addr; + +@end diff --git a/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetGetAddress.m b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetGetAddress.m new file mode 100644 index 000000000..2f9e2422f --- /dev/null +++ b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetGetAddress.m @@ -0,0 +1,378 @@ +// +// LDNetGetAddress.m +// LDNetDiagnoServiceDemo +// +// Created by ZhangHaiyang on 15-8-5. +// Copyright (c) 2015年 庞辉. All rights reserved. +// + +#import "LDNetGetAddress.h" +#include +#include +#include +#include + +#include +#include + +#import +#import + +#if TARGET_IPHONE_SIMULATOR +#include "net_route.h" +#else +#include "Route.h" +#endif /*the very same from google-code*/ + +#define ROUNDUP(a) ((a) > 0 ? (1 + (((a)-1) | (sizeof(long) - 1))) : sizeof(long)) + +@implementation LDNetGetAddress + + +/*! + * 获取当前设备ip地址 + */ ++ (NSString *)deviceIPAdress +{ + NSString *address = @""; + struct ifaddrs *interfaces = NULL; + struct ifaddrs *temp_addr = NULL; + int success = 0; + + success = getifaddrs(&interfaces); + + if (success == 0) { // 0 表示获取成功 + + temp_addr = interfaces; + while (temp_addr != NULL) { + NSLog(@"ifa_name===%@",[NSString stringWithUTF8String:temp_addr->ifa_name]); + // Check if interface is en0 which is the wifi connection on the iPhone + if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"] || [[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"pdp_ip0"]) + { + //如果是IPV4地址,直接转化 + if (temp_addr->ifa_addr->sa_family == AF_INET){ + // Get NSString from C String + address = [self formatIPV4Address:((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr]; + } + + //如果是IPV6地址 + else if (temp_addr->ifa_addr->sa_family == AF_INET6){ + address = [self formatIPV6Address:((struct sockaddr_in6 *)temp_addr->ifa_addr)->sin6_addr]; + if (address && ![address isEqualToString:@""] && ![address.uppercaseString hasPrefix:@"FE80"]) break; + } + } + + temp_addr = temp_addr->ifa_next; + } + } + + freeifaddrs(interfaces); + + //以FE80开始的地址是单播地址 + if (address && ![address isEqualToString:@""] && ![address.uppercaseString hasPrefix:@"FE80"]) { + return address; + } else { + return @"127.0.0.1"; + } +} + +/*! + * 获取当前设备网关地址 + */ ++ (NSString *)getGatewayIPAddress{ + NSString *address = nil; + + NSString *gatewayIPV4 = [self getGatewayIPV4Address]; + NSString *gatewayIPV6 = [self getGatewayIPV6Address]; + + if (gatewayIPV6 != nil) { + address = gatewayIPV6; + } else { + address = gatewayIPV4; + } + + return address; +} + + ++ (NSString *)getGatewayIPV4Address +{ + + NSString *address = nil; + + /* net.route.0.inet.flags.gateway */ + int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_FLAGS, RTF_GATEWAY}; + + size_t l; + char *buf, *p; + struct rt_msghdr *rt; + struct sockaddr *sa; + struct sockaddr *sa_tab[RTAX_MAX]; + int i; + + if (sysctl(mib, sizeof(mib) / sizeof(int), 0, &l, 0, 0) < 0) { + address = @"192.168.0.1"; + } + + if (l > 0) { + buf = malloc(l); + if (sysctl(mib, sizeof(mib) / sizeof(int), buf, &l, 0, 0) < 0) { + address = @"192.168.0.1"; + } + + for (p = buf; p < buf + l; p += rt->rtm_msglen) { + rt = (struct rt_msghdr *)p; + sa = (struct sockaddr *)(rt + 1); + for (i = 0; i < RTAX_MAX; i++) { + if (rt->rtm_addrs & (1 << i)) { + sa_tab[i] = sa; + sa = (struct sockaddr *)((char *)sa + ROUNDUP(sa->sa_len)); + } else { + sa_tab[i] = NULL; + } + } + + if (((rt->rtm_addrs & (RTA_DST | RTA_GATEWAY)) == (RTA_DST | RTA_GATEWAY)) && + sa_tab[RTAX_DST]->sa_family == AF_INET && + sa_tab[RTAX_GATEWAY]->sa_family == AF_INET) { + unsigned char octet[4] = {0, 0, 0, 0}; + int i; + for (i = 0; i < 4; i++) { + octet[i] = (((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr >> + (i * 8)) & + 0xFF; + } + if (((struct sockaddr_in *)sa_tab[RTAX_DST])->sin_addr.s_addr == 0) { + in_addr_t addr = + ((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr; + address = [self formatIPV4Address:*((struct in_addr *)&addr)]; + NSLog(@"IPV4address%@", address); + break; + } + } + } + free(buf); + } + + return address; +} + ++ (NSString *)getGatewayIPV6Address +{ + + NSString *address = nil; + + /* net.route.0.inet.flags.gateway */ + int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET6, NET_RT_FLAGS, RTF_GATEWAY}; + + size_t l; + char *buf, *p; + struct rt_msghdr *rt; + struct sockaddr_in6 *sa; + struct sockaddr_in6 *sa_tab[RTAX_MAX]; + int i; + + if (sysctl(mib, sizeof(mib) / sizeof(int), 0, &l, 0, 0) < 0) { + address = @"192.168.0.1"; + } + + if (l > 0) { + buf = malloc(l); + if (sysctl(mib, sizeof(mib) / sizeof(int), buf, &l, 0, 0) < 0) { + address = @"192.168.0.1"; + } + + for (p = buf; p < buf + l; p += rt->rtm_msglen) { + rt = (struct rt_msghdr *)p; + sa = (struct sockaddr_in6 *)(rt + 1); + for (i = 0; i < RTAX_MAX; i++) { + if (rt->rtm_addrs & (1 << i)) { + sa_tab[i] = sa; + sa = (struct sockaddr_in6 *)((char *)sa + sa->sin6_len); + } else { + sa_tab[i] = NULL; + } + } + + if( ((rt->rtm_addrs & (RTA_DST|RTA_GATEWAY)) == (RTA_DST|RTA_GATEWAY)) + && sa_tab[RTAX_DST]->sin6_family == AF_INET6 + && sa_tab[RTAX_GATEWAY]->sin6_family == AF_INET6) + { + address = [self formatIPV6Address:((struct sockaddr_in6 *)(sa_tab[RTAX_GATEWAY]))->sin6_addr]; + NSLog(@"IPV6address%@", address); + break; + } + } + free(buf); + } + + return address; +} + + +/*! + * 通过hostname获取ip列表 DNS解析地址 + */ ++ (NSArray *)getDNSsWithDormain:(NSString *)hostName{ + NSMutableArray *result = [[NSMutableArray alloc] init]; + NSArray *IPV4DNSs = [self getIPV4DNSWithHostName:hostName]; + if (IPV4DNSs && IPV4DNSs.count > 0) { + [result addObjectsFromArray:IPV4DNSs]; + } + + //由于在IPV6环境下不能用IPV4的地址进行连接监测 + //所以只返回IPV6的服务器DNS地址 + NSArray *IPV6DNSs = [self getIPV6DNSWithHostName:hostName]; + if (IPV6DNSs && IPV6DNSs.count > 0) { + [result removeAllObjects]; + [result addObjectsFromArray:IPV6DNSs]; + } + + return [NSArray arrayWithArray:result]; +} + + ++ (NSArray *)getIPV4DNSWithHostName:(NSString *)hostName +{ + const char *hostN = [hostName UTF8String]; + struct hostent *phot; + + @try { + phot = gethostbyname(hostN); + } @catch (NSException *exception) { + return nil; + } + + NSMutableArray *result = [[NSMutableArray alloc] init]; + int j = 0; + while (phot && phot->h_addr_list && phot->h_addr_list[j]) { + struct in_addr ip_addr; + memcpy(&ip_addr, phot->h_addr_list[j], 4); + char ip[20] = {0}; + inet_ntop(AF_INET, &ip_addr, ip, sizeof(ip)); + + NSString *strIPAddress = [NSString stringWithUTF8String:ip]; + [result addObject:strIPAddress]; + j++; + } + + return [NSArray arrayWithArray:result]; +} + + ++ (NSArray *)getIPV6DNSWithHostName:(NSString *)hostName +{ + const char *hostN = [hostName UTF8String]; + struct hostent *phot; + + @try { + /** + * 只有在IPV6的网络下才会有返回值 + */ + phot = gethostbyname2(hostN, AF_INET6); + } @catch (NSException *exception) { + return nil; + } + + NSMutableArray *result = [[NSMutableArray alloc] init]; + int j = 0; + while (phot && phot->h_addr_list && phot->h_addr_list[j]) { + struct in6_addr ip6_addr; + memcpy(&ip6_addr, phot->h_addr_list[j], sizeof(struct in6_addr)); + NSString *strIPAddress = [self formatIPV6Address: ip6_addr]; + [result addObject:strIPAddress]; + j++; + } + + return [NSArray arrayWithArray:result]; +} + + +/*! + * 获取当前网络DNS服务器地址 + */ ++(NSArray *)outPutDNSServers{ + res_state res = malloc(sizeof(struct __res_state)); + int result = res_ninit(res); + + NSMutableArray *servers = [[NSMutableArray alloc] init]; + if (result == 0) { + union res_9_sockaddr_union *addr_union = malloc(res->nscount * sizeof(union res_9_sockaddr_union)); + res_getservers(res, addr_union, res->nscount); + + for (int i = 0; i < res->nscount; i++) { + if (addr_union[i].sin.sin_family == AF_INET) { + char ip[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &(addr_union[i].sin.sin_addr), ip, INET_ADDRSTRLEN); + NSString *dnsIP = [NSString stringWithUTF8String:ip]; + [servers addObject:dnsIP]; + NSLog(@"IPv4 DNS IP: %@", dnsIP); + } else if (addr_union[i].sin6.sin6_family == AF_INET6) { + char ip[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET6, &(addr_union[i].sin6.sin6_addr), ip, INET6_ADDRSTRLEN); + NSString *dnsIP = [NSString stringWithUTF8String:ip]; + [servers addObject:dnsIP]; + NSLog(@"IPv6 DNS IP: %@", dnsIP); + } else { + NSLog(@"Undefined family."); + } + } + } + res_nclose(res); + free(res); + + return [NSArray arrayWithArray:servers]; +} + + +/*! + * 获取当前网络类型 + * 通过statusBar的网络subview获取具体类型 + */ ++ (NETWORK_TYPE)getNetworkTypeFromStatusBar +{ + NSArray *subviews = [[[[UIApplication sharedApplication] valueForKey:@"statusBar"] + valueForKey:@"foregroundView"] subviews]; + NSNumber *dataNetworkItemView = nil; + for (id subview in subviews) { + if ([subview isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]]) { + dataNetworkItemView = subview; + break; + } + } + NETWORK_TYPE nettype = NETWORK_TYPE_NONE; + NSNumber *num = [dataNetworkItemView valueForKey:@"dataNetworkType"]; + nettype = [num intValue]; + return nettype; +} + + ++(NSString *)formatIPV6Address:(struct in6_addr)ipv6Addr{ + NSString *address = nil; + + char dstStr[INET6_ADDRSTRLEN]; + char srcStr[INET6_ADDRSTRLEN]; + memcpy(srcStr, &ipv6Addr, sizeof(struct in6_addr)); + if(inet_ntop(AF_INET6, srcStr, dstStr, INET6_ADDRSTRLEN) != NULL){ + address = [NSString stringWithUTF8String:dstStr]; + } + + return address; +} + + ++(NSString *)formatIPV4Address:(struct in_addr)ipv4Addr{ + NSString *address = nil; + + char dstStr[INET_ADDRSTRLEN]; + char srcStr[INET_ADDRSTRLEN]; + memcpy(srcStr, &ipv4Addr, sizeof(struct in_addr)); + if(inet_ntop(AF_INET, srcStr, dstStr, INET_ADDRSTRLEN) != NULL){ + address = [NSString stringWithUTF8String:dstStr]; + } + + return address; +} + + +@end diff --git a/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetPing.h b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetPing.h new file mode 100644 index 000000000..076ad1c01 --- /dev/null +++ b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetPing.h @@ -0,0 +1,44 @@ +// +// LDNetPing.h +// LDNetCheckServiceDemo +// +// Created by 庞辉 on 14-10-29. +// Copyright (c) 2014年 庞辉. All rights reserved. +// + +#import +#import "LDSimplePing.h" + + +/* + * @protocal LDNetPingDelegate监测Ping命令的的输出到日志变量; + * + */ +@protocol LDNetPingDelegate +- (void)appendPingLog:(NSString *)pingLog; +- (void)netPingDidEnd; +@end + + +/* + * @class LDNetPing ping监控 + * 主要是通过模拟shell命令ping的过程,监控目标主机是否连通 + * 连续执行五次,因为每次的速度不一致,可以观察其平均速度来判断网络情况 + */ +@protocol LDSimplePingDelegate; +@interface LDNetPing : NSObject { +} + +@property (nonatomic, weak, readwrite) id delegate; + +/** + * 通过hostname 进行ping诊断 + */ +- (void)runWithHostName:(NSString *)hostName normalPing:(BOOL)normalPing; + +/** + * 停止当前ping动作 + */ +- (void)stopPing; + +@end diff --git a/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetPing.m b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetPing.m new file mode 100644 index 000000000..5d6e22d57 --- /dev/null +++ b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetPing.m @@ -0,0 +1,325 @@ +// +// LDNetPing.m +// LDNetCheckServiceDemo +// +// Created by 庞辉 on 14-10-29. +// Copyright (c) 2014年 庞辉. All rights reserved. +// +#include +#include + +#import "LDNetPing.h" +#import "LDNetTimer.h" + +#define MAXCOUNT_PING 4 + +@interface LDNetPing () { + BOOL _isStartSuccess; //监测第一次ping是否成功 + int _sendCount; //当前执行次数 + long _startTime; //每次执行的开始时间 + NSString *_hostAddress; //目标域名的IP地址 + BOOL _isLargePing; + NSTimer *timer; +} + +@property (nonatomic, strong, readwrite) LDSimplePing *pinger; + +@end + + +@implementation LDNetPing +@synthesize pinger = _pinger; + + +- (void)dealloc +{ + [self->_pinger stop]; +} + + +/** + * 停止当前ping动作 + */ +- (void)stopPing +{ + [self->_pinger stop]; + self.pinger = nil; + _sendCount = MAXCOUNT_PING + 1; +} + + +/* + * 调用pinger解析指定域名 + * @param hostName 指定域名 + */ +- (void)runWithHostName:(NSString *)hostName normalPing:(BOOL)normalPing{ + assert(self.pinger == nil); + self.pinger = [[LDSimplePing alloc] initWithHostName:hostName]; + assert(self.pinger != nil); + + _isLargePing = !normalPing; + self.pinger.delegate = self; + [self.pinger start]; + + //在当前线程一直执行 + _sendCount = 1; + do { + [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; + } while (self.pinger != nil || _sendCount <= MAXCOUNT_PING); +} + + +/* + * 发送Ping数据,pinger会组装一个ICMP控制报文的数据发送过去 + * + */ +- (void)sendPing +{ + if (timer) { + [timer invalidate]; + } + if (_sendCount > MAXCOUNT_PING) { + _sendCount++; + self.pinger = nil; + if (self.delegate && [self.delegate respondsToSelector:@selector(netPingDidEnd)]) { + [self.delegate netPingDidEnd]; + } + } + + else { + assert(self.pinger != nil); + _sendCount++; + _startTime = [LDNetTimer getMicroSeconds]; + if (_isLargePing) { + NSString *testStr = @""; + for (int i=0; i<408; i++) { + testStr = [testStr stringByAppendingString:@"abcdefghi "]; + } + testStr = [testStr stringByAppendingString:@"abcdefgh"]; + NSData *data = [testStr dataUsingEncoding:NSASCIIStringEncoding]; + [self.pinger sendPingWithData:data]; + } else { + [self.pinger sendPingWithData:nil]; + } + timer = [NSTimer scheduledTimerWithTimeInterval:3.0 + target:self + selector:@selector(pingTimeout:) + userInfo:[NSNumber numberWithInt:_sendCount] + repeats:NO]; + } +} + +- (void)pingTimeout:(NSTimer *)index +{ + if ([[index userInfo] intValue] == _sendCount && _sendCount <= MAXCOUNT_PING + 1 && + _sendCount > 1) { + NSString *timeoutLog = + [NSString stringWithFormat:@"ping: cannot resolve %@: TimeOut", _hostAddress]; + if (self.delegate && [self.delegate respondsToSelector:@selector(appendPingLog:)]) { + [self.delegate appendPingLog:timeoutLog]; + } + [self sendPing]; + } +} + + +#pragma mark - Pingdelegate +/* + * PingDelegate: 套接口开启之后发送ping数据,并开启一个timer(1s间隔发送数据) + * + */ +- (void)simplePing:(LDSimplePing *)pinger didStartWithAddress:(NSData *)address +{ +#pragma unused(pinger) + assert(pinger == self.pinger); + assert(address != nil); + _hostAddress = [self DisplayAddressForAddress:address]; + NSLog(@"pinging %@", _hostAddress); + + // Send the first ping straight away. + _isStartSuccess = YES; + [self sendPing]; +} + +/* + * PingDelegate: ping命令发生错误之后,立即停止timer和线程 + * + */ +- (void)simplePing:(LDSimplePing *)pinger didFailWithError:(NSError *)error +{ +#pragma unused(pinger) + assert(pinger == self.pinger); +#pragma unused(error) + NSString *failCreateLog = [NSString stringWithFormat:@"#%u try create failed: %@", _sendCount, + [self shortErrorFromError:error]]; + if (self.delegate && [self.delegate respondsToSelector:@selector(appendPingLog:)]) { + [self.delegate appendPingLog:failCreateLog]; + } + + //如果不是创建套接字失败,都是发送数据过程中的错误,可以继续try发送数据 + if (_isStartSuccess) { + [self sendPing]; + } else { + [self stopPing]; + } +} + +/* + * PingDelegate: 发送ping数据成功 + * + */ +- (void)simplePing:(LDSimplePing *)pinger didSendPacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber; +{ +#pragma unused(pinger) + assert(pinger == self.pinger); +#pragma unused(packet) + NSLog(@"#%u sent success",sequenceNumber); +} + + +/* + * PingDelegate: 发送ping数据失败 + */ +- (void)simplePing:(LDSimplePing *)pinger didFailToSendPacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber error:(NSError *)error +{ +#pragma unused(pinger) + assert(pinger == self.pinger); +#pragma unused(packet) +#pragma unused(error) + NSString *sendFailLog = + [NSString stringWithFormat:@"#%u send failed: %@",sequenceNumber, + [self shortErrorFromError:error]]; + //记录 + if (self.delegate && [self.delegate respondsToSelector:@selector(appendPingLog:)]) { + [self.delegate appendPingLog:sendFailLog]; + } + + [self sendPing]; +} + + +/* + * PingDelegate: 成功接收到PingResponse数据 + */ +- (void)simplePing:(LDSimplePing *)pinger didReceivePingResponsePacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber +{ +#pragma unused(pinger) + assert(pinger == self.pinger); +#pragma unused(packet) + //由于IPV6在IPheader中不返回TTL数据,所以这里不返回TTL,改为返回Type + //http://blog.sina.com.cn/s/blog_6a1837e901012ds8.html + NSString *icmpReplyType = [NSString stringWithFormat:@"%@", [LDSimplePing icmpInPacket:packet]->type == 129 ? @"ICMPv6TypeEchoReply" : @"ICMPv4TypeEchoReply"]; + NSString *successLog = [NSString + stringWithFormat:@"%lu bytes from %@ icmp_seq=#%u type=%@ time=%ldms", + (unsigned long)[packet length], _hostAddress, + sequenceNumber, + icmpReplyType, + [LDNetTimer computeDurationSince:_startTime] / 1000]; + //记录ping成功的数据 + if (self.delegate && [self.delegate respondsToSelector:@selector(appendPingLog:)]) { + [self.delegate appendPingLog:successLog]; + } + + [self sendPing]; +} + + +/* + * PingDelegate: 接收到错误的pingResponse数据 + */ +- (void)simplePing:(LDSimplePing *)pinger didReceiveUnexpectedPacket:(NSData *)packet +{ + const ICMPHeader *icmpPtr; + if (self.pinger && pinger == self.pinger) { + icmpPtr = [LDSimplePing icmpInPacket:packet]; + NSString *errorLog = @""; + if (icmpPtr != NULL) { + errorLog = [NSString + stringWithFormat:@"#%u unexpected ICMP type=%u, code=%u, identifier=%u", + (unsigned int)OSSwapBigToHostInt16(icmpPtr->sequenceNumber), + (unsigned int)icmpPtr->type, (unsigned int)icmpPtr->code, + (unsigned int)OSSwapBigToHostInt16(icmpPtr->identifier)]; + } else { + errorLog = [NSString stringWithFormat:@"#%u try unexpected packet size=%zu", _sendCount, + (size_t)[packet length]]; + } + //记录 + if (self.delegate && [self.delegate respondsToSelector:@selector(appendPingLog:)]) { + [self.delegate appendPingLog:errorLog]; + } + } + + //当检测到错误数据的时候,再次发送 + [self sendPing]; +} + +/** + * 将ping接收的数据转换成ip地址 + * @param address 接受的ping数据 + */ +-(NSString *)DisplayAddressForAddress:(NSData *)address +{ + int err; + NSString *result; + char hostStr[NI_MAXHOST]; + + result = nil; + + if (address != nil) { + err = getnameinfo([address bytes], (socklen_t)[address length], hostStr, sizeof(hostStr), + NULL, 0, NI_NUMERICHOST); + if (err == 0) { + result = [NSString stringWithCString:hostStr encoding:NSASCIIStringEncoding]; + assert(result != nil); + } + } + + return result; +} + +/* + * 解析错误数据并翻译 + */ +- (NSString *)shortErrorFromError:(NSError *)error +{ + NSString *result; + NSNumber *failureNum; + int failure; + const char *failureStr; + + assert(error != nil); + + result = nil; + + // Handle DNS errors as a special case. + + if ([[error domain] isEqual:(NSString *)kCFErrorDomainCFNetwork] && + ([error code] == kCFHostErrorUnknown)) { + failureNum = [[error userInfo] objectForKey:(id)kCFGetAddrInfoFailureKey]; + if ([failureNum isKindOfClass:[NSNumber class]]) { + failure = [failureNum intValue]; + if (failure != 0) { + failureStr = gai_strerror(failure); + if (failureStr != NULL) { + result = [NSString stringWithUTF8String:failureStr]; + assert(result != nil); + } + } + } + } + + // Otherwise try various properties of the error object. + + if (result == nil) { + result = [error localizedFailureReason]; + } + if (result == nil) { + result = [error localizedDescription]; + } + if (result == nil) { + result = [error description]; + } + assert(result != nil); + return result; +} +@end diff --git a/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetTimer.h b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetTimer.h new file mode 100644 index 000000000..438d1d3fe --- /dev/null +++ b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetTimer.h @@ -0,0 +1,25 @@ +// +// LDNetTimer.h +// LDNetDiagnoServieDemo +// +// Created by 庞辉 on 14-10-29. +// Copyright (c) 2014年 庞辉. All rights reserved. +// + +#import + +@interface LDNetTimer : NSObject { +} + + +/** + * Retourne un timestamp en microsecondes. + */ ++ (long)getMicroSeconds; + + +/** + * Calcule une durée en millisecondes par rapport au timestamp passé en paramètre. + */ ++ (long)computeDurationSince:(long)uTime; +@end diff --git a/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetTimer.m b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetTimer.m new file mode 100644 index 000000000..4e5c62657 --- /dev/null +++ b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetTimer.m @@ -0,0 +1,36 @@ +// +// LDNetTimer.m +// LDNetDiagnoServieDemo +// +// Created by 庞辉 on 14-10-29. +// Copyright (c) 2014年 庞辉. All rights reserved. +// +#include +#import "LDNetTimer.h" + +@implementation LDNetTimer + +/** + * Retourne un timestamp en microsecondes. + */ ++ (long)getMicroSeconds +{ + struct timeval time; + gettimeofday(&time, NULL); + return time.tv_usec; +} + +/** + * Calcule une durée en millisecondes par rapport au timestamp passé en paramètre. + */ ++ (long)computeDurationSince:(long)uTime +{ + long now = [LDNetTimer getMicroSeconds]; + if (now < uTime) { + return 1000000 - uTime + now; + } + return now - uTime; +} + + +@end diff --git a/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetTraceRoute.h b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetTraceRoute.h new file mode 100644 index 000000000..a9abdf9ba --- /dev/null +++ b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetTraceRoute.h @@ -0,0 +1,61 @@ +// +// TraceRoute.h +// LDNetCheckServiceDemo +// +// Created by 庞辉 on 14-10-29. +// Copyright (c) 2014年 庞辉. All rights reserved. +// + +#import + +static const int TRACEROUTE_PORT = 30001; +static const int TRACEROUTE_MAX_TTL = 30; +static const int TRACEROUTE_ATTEMPTS = 3; +static const int TRACEROUTE_TIMEOUT = 5000000; + +/* + * @protocal LDNetTraceRouteDelegate监测TraceRoute命令的的输出到日志变量; + * + */ +@protocol LDNetTraceRouteDelegate +- (void)appendRouteLog:(NSString *)routeLog; +- (void)traceRouteDidEnd; +@end + + +/* + * @class LDNetTraceRoute TraceRoute网络监控 + * 主要是通过模拟shell命令traceRoute的过程,监控网络站点间的跳转 + * 默认执行20转,每转进行三次发送测速 + */ +@interface LDNetTraceRoute : NSObject { + int udpPort; //执行端口 + int maxTTL; //执行转数 + int readTimeout; //每次发送时间的timeout + int maxAttempts; //每转的发送次数 + NSString *running; + bool isrunning; +} + +@property (nonatomic, weak) id delegate; + +/** + * 初始化 + */ +- (LDNetTraceRoute *)initWithMaxTTL:(int)ttl + timeout:(int)timeout + maxAttempts:(int)attempts + port:(int)port; + +/** + * 监控tranceroute 路径 + */ +- (Boolean)doTraceRoute:(NSString *)host; + +/** + * 停止traceroute + */ +- (void)stopTrace; +- (bool)isRunning; + +@end diff --git a/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetTraceRoute.m b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetTraceRoute.m new file mode 100644 index 000000000..fc352f933 --- /dev/null +++ b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDNetTraceRoute.m @@ -0,0 +1,252 @@ +// +// TraceRoute.m +// LDNetCheckServiceDemo +// +// Created by 庞辉 on 14-10-29. +// Copyright (c) 2014年 庞辉. All rights reserved. +// + +#include +#include +#include + +#import "LDNetTraceRoute.h" +#import "LDNetTimer.h" +#import "LDNetGetAddress.h" + +@implementation LDNetTraceRoute + +/** + * 初始化 + */ +- (LDNetTraceRoute *)initWithMaxTTL:(int)ttl + timeout:(int)timeout + maxAttempts:(int)attempts + port:(int)port +{ + self = [super init]; + if (self) { + maxTTL = ttl; + udpPort = port; + readTimeout = timeout; + maxAttempts = attempts; + } + + return self; +} + + +/** + * 监控tranceroute 路径 + */ +- (Boolean)doTraceRoute:(NSString *)host +{ + //从name server获取server主机的地址 + NSArray *serverDNSs = [LDNetGetAddress getDNSsWithDormain:host]; + if (!serverDNSs || serverDNSs.count <= 0) { + if (_delegate != nil) { + [_delegate appendRouteLog:@"TraceRoute>>> Could not get host address"]; + [_delegate traceRouteDidEnd]; + } + return false; + } + + NSString *ipAddr0 = [serverDNSs objectAtIndex:0]; + //设置server主机的套接口地址 + NSData *addrData = nil; + BOOL isIPV6 = NO; + if ([ipAddr0 rangeOfString:@":"].location == NSNotFound) { + isIPV6 = NO; + struct sockaddr_in nativeAddr4; + memset(&nativeAddr4, 0, sizeof(nativeAddr4)); + nativeAddr4.sin_len = sizeof(nativeAddr4); + nativeAddr4.sin_family = AF_INET; + nativeAddr4.sin_port = htons(udpPort); + inet_pton(AF_INET, ipAddr0.UTF8String, &nativeAddr4.sin_addr.s_addr); + addrData = [NSData dataWithBytes:&nativeAddr4 length:sizeof(nativeAddr4)]; + } else { + isIPV6 = YES; + struct sockaddr_in6 nativeAddr6; + memset(&nativeAddr6, 0, sizeof(nativeAddr6)); + nativeAddr6.sin6_len = sizeof(nativeAddr6); + nativeAddr6.sin6_family = AF_INET6; + nativeAddr6.sin6_port = htons(udpPort); + inet_pton(AF_INET6, ipAddr0.UTF8String, &nativeAddr6.sin6_addr); + addrData = [NSData dataWithBytes:&nativeAddr6 length:sizeof(nativeAddr6)]; + } + + struct sockaddr *destination; + destination = (struct sockaddr *)[addrData bytes]; + + //初始化套接口 + struct sockaddr fromAddr; + int recv_sock; + int send_sock; + Boolean error = false; + + isrunning = true; + //创建一个支持ICMP协议的UDP网络套接口(用于接收) + + if ((recv_sock = socket(destination->sa_family, SOCK_DGRAM, isIPV6?IPPROTO_ICMPV6:IPPROTO_ICMP)) < 0) { + if (_delegate != nil) { + [_delegate appendRouteLog:@"TraceRoute>>> Could not create recv socket"]; + [_delegate traceRouteDidEnd]; + } + return false; + } + + //创建一个UDP套接口(用于发送) + if ((send_sock = socket(destination->sa_family, SOCK_DGRAM, 0)) < 0) { + if (_delegate != nil) { + [_delegate appendRouteLog:@"TraceRoute>>> Could not create xmit socket"]; + [_delegate traceRouteDidEnd]; + } + return false; + } + + + char *cmsg = "GET / HTTP/1.1\r\n\r\n"; + socklen_t n = sizeof(fromAddr); + char buf[100]; + + int ttl = 1; // index sur le TTL en cours de traitement. + int timeoutTTL = 0; + bool icmp = false; // Positionné à true lorsqu'on reçoit la trame ICMP en retour. + long startTime; // Timestamp lors de l'émission du GET HTTP + long delta; // Durée de l'aller-retour jusqu'au hop. + + // On progresse jusqu'à un nombre de TTLs max. + while (ttl <= maxTTL) { + memset(&fromAddr, 0, sizeof(fromAddr)); + + //设置不发送 `SIGPIPE` 信号 + int value = 1; + setsockopt(send_sock, SOL_SOCKET, SO_NOSIGPIPE, &value, sizeof(value)); + + //设置sender 套接字的ttl + if ((isIPV6? setsockopt(send_sock,IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl)):setsockopt(send_sock, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl))) < 0) { + error = true; + if (_delegate != nil) { + [_delegate appendRouteLog:@"TraceRoute>>> setsockopt failled"]; + } + } + + + //每一步连续发送maxAttenpts报文 + icmp = false; + NSMutableString *traceTTLLog = [[NSMutableString alloc] initWithCapacity:20]; + [traceTTLLog appendFormat:@"%d\t", ttl]; + NSString *hostAddress = @"***"; + for (int try = 0; try < maxAttempts; try ++) { + startTime = [LDNetTimer getMicroSeconds]; + //发送成功返回值等于发送消息的长度 + ssize_t sentLen = sendto(send_sock, cmsg, sizeof(cmsg), 0, (struct sockaddr *)destination, isIPV6?sizeof(struct sockaddr_in6):sizeof(struct sockaddr_in)); + if (sentLen != sizeof(cmsg)) { + NSLog(@"Error sending to server: %d %d", errno, (int)sentLen); + error = true; + [traceTTLLog appendFormat:@"?\t"]; + } + + long res = 0; + //从(已连接)套接口上接收数据,并捕获数据发送源的地址。 + if (-1 == fcntl(recv_sock, F_SETFL, O_NONBLOCK)) { + printf("fcntl socket error!\n"); + return -1; + } + /* set recvfrom from server timeout */ + struct timeval tv; + fd_set readfds; + tv.tv_sec = 1; + tv.tv_usec = 0; //设置了1s的延迟 + FD_ZERO(&readfds); + FD_SET(recv_sock, &readfds); + select(recv_sock + 1, &readfds, NULL, NULL, &tv); + if (FD_ISSET(recv_sock, &readfds) > 0) { + timeoutTTL = 0; + if ((res = recvfrom(recv_sock, buf, 100, 0, (struct sockaddr *)&fromAddr, &n)) < + 0) { + error = true; + [traceTTLLog appendFormat:@"?\t"]; + } else { + icmp = true; + delta = [LDNetTimer computeDurationSince:startTime]; + + //将“二进制整数” -> “点分十进制,获取hostAddress和hostName + if (fromAddr.sa_family == AF_INET) { + char display[INET_ADDRSTRLEN] = {0}; + inet_ntop(AF_INET, &((struct sockaddr_in *)&fromAddr)->sin_addr.s_addr, display, sizeof(display)); + hostAddress = [NSString stringWithFormat:@"%s", display]; + } + + else if (fromAddr.sa_family == AF_INET6) { + char ip[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET6, &((struct sockaddr_in6 *)&fromAddr)->sin6_addr, ip, INET6_ADDRSTRLEN); + hostAddress = [NSString stringWithUTF8String:ip]; + } + + if (try == 0) { + [traceTTLLog appendFormat:@"%@\t", hostAddress]; + } + [traceTTLLog appendFormat:@"%0.2fms\t", (float)delta / 1000]; + } + } else { + timeoutTTL++; + break; + } + + // On teste si l'utilisateur a demandé l'arrêt du traceroute + @synchronized(running) + { + if (!isrunning) { + ttl = maxTTL; + // On force le statut d'icmp pour ne pas générer un Hop en sortie de boucle; + icmp = true; + break; + } + } + } + + //输出报文,如果三次都无法监控接收到报文,跳转结束 + if (icmp) { + [self.delegate appendRouteLog:traceTTLLog]; + } else { + //如果连续三次接收不到icmp回显报文 + if (timeoutTTL >= 4) { + break; + } else { + [self.delegate appendRouteLog:[NSString stringWithFormat:@"%d\t???", ttl]]; + } + } + + if ([hostAddress isEqualToString:ipAddr0]) { + break; + } + ttl++; + } + + isrunning = false; + // On averti le delegate que le traceroute est terminé. + [_delegate traceRouteDidEnd]; + return error; +} + +/** + * 停止traceroute + */ +- (void)stopTrace +{ + @synchronized(running) + { + isrunning = false; + } +} + + +/** + * 检测traceroute是否在运行 + */ +- (bool)isRunning +{ + return isrunning; +} +@end diff --git a/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDSimplePing.h b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDSimplePing.h new file mode 100644 index 000000000..42fd24717 --- /dev/null +++ b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDSimplePing.h @@ -0,0 +1,269 @@ +/* + Copyright (C) 2016 Apple Inc. All Rights Reserved. + See LICENSE.txt for this sample’s licensing information + + Abstract: + An object wrapper around the low-level BSD Sockets ping function. + */ + +#import + +#if TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR +#import +#else +#import +#endif + +#include + +NS_ASSUME_NONNULL_BEGIN +// The SimplePing class is a very simple class that lets you send and receive pings. + +@protocol LDSimplePingDelegate; + +/*! Controls the IP address version used by SimplePing instances. + */ + +typedef NS_ENUM(NSInteger, SimplePingAddressStyle) { + SimplePingAddressStyleAny, ///< Use the first IPv4 or IPv6 address found; the default. + SimplePingAddressStyleICMPv4, ///< Use the first IPv4 address found. + SimplePingAddressStyleICMPv6 ///< Use the first IPv6 address found. +}; + + +@interface LDSimplePing : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +/*! Initialise the object to ping the specified host. + * \param hostName The DNS name of the host to ping; an IPv4 or IPv6 address in string form will + * work here. + * \returns The initialised object. + */ +- (instancetype)initWithHostName:(NSString *)hostName NS_DESIGNATED_INITIALIZER; + +/*! A copy of the value passed to `-initWithHostName:`. + */ +@property (nonatomic, copy, readonly) NSString *hostName; + +/*! The delegate for this object. + * \details Delegate callbacks are schedule in the default run loop mode of the run loop of the + * thread that calls `-start`. + */ + +@property (nonatomic, weak, readwrite, nullable) id delegate; + +/*! Controls the IP address version used by the object. + * \details You should set this value before starting the object. + */ + +@property (nonatomic, assign, readwrite) SimplePingAddressStyle addressStyle; + +/*! The address being pinged. + * \details The contents of the NSData is a (struct sockaddr) of some form. The + * value is nil while the object is stopped and remains nil on start until + * `-simplePing:didStartWithAddress:` is called. + */ + +@property (nonatomic, copy, readonly, nullable) NSData * hostAddress; + +/*! The address family for `hostAddress`, or `AF_UNSPEC` if that's nil. + */ + +@property (nonatomic, assign, readonly) sa_family_t hostAddressFamily; + +/*! The identifier used by pings by this object. + * \details When you create an instance of this object it generates a random identifier + * that it uses to identify its own pings. + */ + +@property (nonatomic, assign, readonly) uint16_t identifier; + +/*! The next sequence number to be used by this object. + * \details This value starts at zero and increments each time you send a ping (safely + * wrapping back to zero if necessary). The sequence number is included in the ping, + * allowing you to match up requests and responses, and thus calculate ping times and + * so on. + */ + +@property (nonatomic, assign, readonly) uint16_t nextSequenceNumber; + +/*! Starts the object. + * \details You should set up the delegate and any ping parameters before calling this. + * + * If things go well you'll soon get the `-simplePing:didStartWithAddress:` delegate + * callback, at which point you can start sending pings (via `-sendPingWithData:`) and + * will start receiving ICMP packets (either ping responses, via the + * `-simplePing:didReceivePingResponsePacket:sequenceNumber:` delegate callback, or + * unsolicited ICMP packets, via the `-simplePing:didReceiveUnexpectedPacket:` delegate + * callback). + * + * If the object fails to start, typically because `hostName` doesn't resolve, you'll get + * the `-simplePing:didFailWithError:` delegate callback. + * + * It is not correct to start an already started object. + */ + +- (void)start; + +/*! Sends a ping packet containing the specified data. + * \details Sends an actual ping. + * + * The object must be started when you call this method and, on starting the object, you must + * wait for the `-simplePing:didStartWithAddress:` delegate callback before calling it. + * \param data Some data to include in the ping packet, after the ICMP header, or nil if you + * want the packet to include a standard 56 byte payload (resulting in a standard 64 byte + * ping). + */ + +- (void)sendPingWithData:(nullable NSData *)data; + +/*! Stops the object. + * \details You should call this when you're done pinging. + * + * It's safe to call this on an object that's stopped. + */ + +- (void)stop; + +#pragma mark - tofix support IPV6 ++ (const struct ICMPHeader *)icmpInPacket:(NSData *)packet; + +@end + + + +@protocol LDSimplePingDelegate + +@optional + + +/*! A SimplePing delegate callback, called once the object has started up. + * \details This is called shortly after you start the object to tell you that the + * object has successfully started. On receiving this callback, you can call + * `-sendPingWithData:` to send pings. + * + * If the object didn't start, `-simplePing:didFailWithError:` is called instead. + * \param pinger The object issuing the callback. + * \param address The address that's being pinged; at the time this delegate callback + * is made, this will have the same value as the `hostAddress` property. + */ + +- (void)simplePing:(LDSimplePing *)pinger didStartWithAddress:(NSData *)address; + + +/*! A SimplePing delegate callback, called if the object fails to start up. + * \details This is called shortly after you start the object to tell you that the + * object has failed to start. The most likely cause of failure is a problem + * resolving `hostName`. + * + * By the time this callback is called, the object has stopped (that is, you don't + * need to call `-stop` yourself). + * \param pinger The object issuing the callback. + * \param error Describes the failure. + */ +- (void)simplePing:(LDSimplePing *)pinger didFailWithError:(NSError *)error; + + +/*! A SimplePing delegate callback, called when the object has successfully sent a ping packet. + * \details Each call to `-sendPingWithData:` will result in either a + * `-simplePing:didSendPacket:sequenceNumber:` delegate callback or a + * `-simplePing:didFailToSendPacket:sequenceNumber:error:` delegate callback (unless you + * stop the object before you get the callback). These callbacks are currently delivered + * synchronously from within `-sendPingWithData:`, but this synchronous behaviour is not + * considered API. + * \param pinger The object issuing the callback. + * \param packet The packet that was sent; this includes the ICMP header (`ICMPHeader`) and the + * data you passed to `-sendPingWithData:` but does not include any IP-level headers. + * \param sequenceNumber The ICMP sequence number of that packet. + */ + +- (void)simplePing:(LDSimplePing *)pinger didSendPacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber; + +/*! A SimplePing delegate callback, called when the object fails to send a ping packet. + * \details Each call to `-sendPingWithData:` will result in either a + * `-simplePing:didSendPacket:sequenceNumber:` delegate callback or a + * `-simplePing:didFailToSendPacket:sequenceNumber:error:` delegate callback (unless you + * stop the object before you get the callback). These callbacks are currently delivered + * synchronously from within `-sendPingWithData:`, but this synchronous behaviour is not + * considered API. + * \param pinger The object issuing the callback. + * \param packet The packet that was not sent; see `-simplePing:didSendPacket:sequenceNumber:` + * for details. + * \param sequenceNumber The ICMP sequence number of that packet. + * \param error Describes the failure. + */ +- (void)simplePing:(LDSimplePing *)pinger didFailToSendPacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber error:(NSError *)error; + + +/*! A SimplePing delegate callback, called when the object receives a ping response. + * \details If the object receives an ping response that matches a ping request that it + * sent, it informs the delegate via this callback. Matching is primarily done based on + * the ICMP identifier, although other criteria are used as well. + * \param pinger The object issuing the callback. + * \param packet The packet received; this includes the ICMP header (`ICMPHeader`) and any data that + * follows that in the ICMP message but does not include any IP-level headers. + * \param sequenceNumber The ICMP sequence number of that packet. + */ +- (void)simplePing:(LDSimplePing *)pinger didReceivePingResponsePacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber; + +/*! A SimplePing delegate callback, called when the object receives an unmatched ICMP message. + * \details If the object receives an ICMP message that does not match a ping request that it + * sent, it informs the delegate via this callback. The nature of ICMP handling in a + * BSD kernel makes this a common event because, when an ICMP message arrives, it is + * delivered to all ICMP sockets. + * + * IMPORTANT: This callback is especially common when using IPv6 because IPv6 uses ICMP + * for important network management functions. For example, IPv6 routers periodically + * send out Router Advertisement (RA) packets via Neighbor Discovery Protocol (NDP), which + * is implemented on top of ICMP. + * + * For more on matching, see the discussion associated with + * `-simplePing:didReceivePingResponsePacket:sequenceNumber:`. + * \param pinger The object issuing the callback. + * \param packet The packet received; this includes the ICMP header (`ICMPHeader`) and any data that + * follows that in the ICMP message but does not include any IP-level headers. + */ +- (void)simplePing:(LDSimplePing *)pinger didReceiveUnexpectedPacket:(NSData *)packet; + +@end + + +#pragma mark * ICMP On-The-Wire Format + +/*! Describes the on-the-wire header format for an ICMP ping. + * \details This defines the header structure of ping packets on the wire. Both IPv4 and + * IPv6 use the same basic structure. + * + * This is declared in the header because clients of SimplePing might want to use + * it parse received ping packets. + */ + +struct ICMPHeader { + uint8_t type; + uint8_t code; + uint16_t checksum; + uint16_t identifier; + uint16_t sequenceNumber; + // data... +}; +typedef struct ICMPHeader ICMPHeader; + +__Check_Compile_Time(sizeof(ICMPHeader) == 8); +__Check_Compile_Time(offsetof(ICMPHeader, type) == 0); +__Check_Compile_Time(offsetof(ICMPHeader, code) == 1); +__Check_Compile_Time(offsetof(ICMPHeader, checksum) == 2); +__Check_Compile_Time(offsetof(ICMPHeader, identifier) == 4); +__Check_Compile_Time(offsetof(ICMPHeader, sequenceNumber) == 6); + +enum { + ICMPv4TypeEchoRequest = 8, ///< The ICMP `type` for a ping request; in this case `code` is always 0. + ICMPv4TypeEchoReply = 0 ///< The ICMP `type` for a ping response; in this case `code` is always 0. +}; + +enum { + ICMPv6TypeEchoRequest = 128, ///< The ICMP `type` for a ping request; in this case `code` is always 0. + ICMPv6TypeEchoReply = 129 ///< The ICMP `type` for a ping response; in this case `code` is always 0. +}; + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDSimplePing.m b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDSimplePing.m new file mode 100644 index 000000000..cfbbeb17c --- /dev/null +++ b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/LDSimplePing.m @@ -0,0 +1,810 @@ +/* + Copyright (C) 2016 Apple Inc. All Rights Reserved. + See LICENSE.txt for this sample’s licensing information + + Abstract: + An object wrapper around the low-level BSD Sockets ping function. + */ + +#import "LDSimplePing.h" + +#include +#include +#include + +#pragma mark * IPv4 and ICMPv4 On-The-Wire Format + +/*! Describes the on-the-wire header format for an IPv4 packet. + * \details This defines the header structure of IPv4 packets on the wire. We need + * this in order to skip this header in the IPv4 case, where the kernel passes + * it to us for no obvious reason. + */ + +struct IPv4Header { + uint8_t versionAndHeaderLength; + uint8_t differentiatedServices; + uint16_t totalLength; + uint16_t identification; + uint16_t flagsAndFragmentOffset; + uint8_t timeToLive; + uint8_t protocol; + uint16_t headerChecksum; + uint8_t sourceAddress[4]; + uint8_t destinationAddress[4]; + // options... + // data... +}; +typedef struct IPv4Header IPv4Header; + +__Check_Compile_Time(sizeof(IPv4Header) == 20); +__Check_Compile_Time(offsetof(IPv4Header, versionAndHeaderLength) == 0); +__Check_Compile_Time(offsetof(IPv4Header, differentiatedServices) == 1); +__Check_Compile_Time(offsetof(IPv4Header, totalLength) == 2); +__Check_Compile_Time(offsetof(IPv4Header, identification) == 4); +__Check_Compile_Time(offsetof(IPv4Header, flagsAndFragmentOffset) == 6); +__Check_Compile_Time(offsetof(IPv4Header, timeToLive) == 8); +__Check_Compile_Time(offsetof(IPv4Header, protocol) == 9); +__Check_Compile_Time(offsetof(IPv4Header, headerChecksum) == 10); +__Check_Compile_Time(offsetof(IPv4Header, sourceAddress) == 12); +__Check_Compile_Time(offsetof(IPv4Header, destinationAddress) == 16); + + +/*! Calculates an IP checksum. + * \details This is the standard BSD checksum code, modified to use modern types. + * \param buffer A pointer to the data to checksum. + * \param bufferLen The length of that data. + * \returns The checksum value, in network byte order. + */ + +static uint16_t in_cksum(const void *buffer, size_t bufferLen) { + // + size_t bytesLeft; + int32_t sum; + const uint16_t * cursor; + union { + uint16_t us; + uint8_t uc[2]; + } last; + uint16_t answer; + + bytesLeft = bufferLen; + sum = 0; + cursor = buffer; + + /* + * Our algorithm is simple, using a 32 bit accumulator (sum), we add + * sequential 16 bit words to it, and at the end, fold back all the + * carry bits from the top 16 bits into the lower 16 bits. + */ + while (bytesLeft > 1) { + sum += *cursor; + cursor += 1; + bytesLeft -= 2; + } + + /* mop up an odd byte, if necessary */ + if (bytesLeft == 1) { + last.uc[0] = * (const uint8_t *) cursor; + last.uc[1] = 0; + sum += last.us; + } + + /* add back carry outs from top 16 bits to low 16 bits */ + sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ + sum += (sum >> 16); /* add carry */ + answer = (uint16_t) ~sum; /* truncate to 16 bits */ + + return answer; +} + +#pragma mark * SimplePing + +@interface LDSimplePing () + +// read/write versions of public properties + +@property (nonatomic, copy, readwrite, nullable) NSData *hostAddress; +@property (nonatomic, assign, readwrite) uint16_t nextSequenceNumber; + +// private properties + +/*! True if nextSequenceNumber has wrapped from 65535 to 0. + */ + +@property (nonatomic, assign, readwrite) BOOL nextSequenceNumberHasWrapped; + +/*! A host object for name-to-address resolution. + */ + +@property (nonatomic, strong, readwrite, nullable) CFHostRef host __attribute__ ((NSObject)); + +/*! A socket object for ICMP send and receive. + */ + +@property (nonatomic, strong, readwrite, nullable) CFSocketRef socket __attribute__ ((NSObject)); + +@end + + +@implementation LDSimplePing + +- (instancetype)initWithHostName:(NSString *)hostName { + NSParameterAssert(hostName != nil); + self = [super init]; + if (self != nil) { + self->_hostName = [hostName copy]; + self->_identifier = (uint16_t) arc4random(); + } + return self; +} + +- (void)dealloc { + [self stop]; + // Double check that -stop took care of _host and _socket. + assert(self->_host == NULL); + assert(self->_socket == NULL); +} + +- (sa_family_t)hostAddressFamily { + sa_family_t result; + + result = AF_UNSPEC; + if ( (self.hostAddress != nil) && (self.hostAddress.length >= sizeof(struct sockaddr)) ) { + result = ((const struct sockaddr *) self.hostAddress.bytes)->sa_family; + } + return result; +} + +/*! Shuts down the pinger object and tell the delegate about the error. + * \param error Describes the failure. + */ + +- (void)didFailWithError:(NSError *)error { + id strongDelegate; + + assert(error != nil); + + // We retain ourselves temporarily because it's common for the delegate method + // to release its last reference to us, which causes -dealloc to be called here. + // If we then reference self on the return path, things go badly. I don't think + // that happens currently, but I've got into the habit of doing this as a + // defensive measure. + + CFAutorelease( CFBridgingRetain( self )); + + [self stop]; + strongDelegate = self.delegate; + if ( (strongDelegate != nil) && [strongDelegate respondsToSelector:@selector(simplePing:didFailWithError:)] ) { + [strongDelegate simplePing:self didFailWithError:error]; + } +} + +/*! Shuts down the pinger object and tell the delegate about the error. + * \details This converts the CFStreamError to an NSError and then call through to + * -didFailWithError: to do the real work. + * \param streamError Describes the failure. + */ + +- (void)didFailWithHostStreamError:(CFStreamError)streamError { + NSDictionary * userInfo; + NSError * error; + + if (streamError.domain == kCFStreamErrorDomainNetDB) { + userInfo = @{(id) kCFGetAddrInfoFailureKey: @(streamError.error)}; + } else { + userInfo = nil; + } + error = [NSError errorWithDomain:(NSString *) kCFErrorDomainCFNetwork code:kCFHostErrorUnknown userInfo:userInfo]; + + [self didFailWithError:error]; +} + +/*! Builds a ping packet from the supplied parameters. + * \param type The packet type, which is different for IPv4 and IPv6. + * \param payload Data to place after the ICMP header. + * \param requiresChecksum Determines whether a checksum is calculated (IPv4) or not (IPv6). + * \returns A ping packet suitable to be passed to the kernel. + */ + +- (NSData *)pingPacketWithType:(uint8_t)type payload:(NSData *)payload requiresChecksum:(BOOL)requiresChecksum { + NSMutableData * packet; + ICMPHeader * icmpPtr; + + packet = [NSMutableData dataWithLength:sizeof(*icmpPtr) + payload.length]; + assert(packet != nil); + + icmpPtr = packet.mutableBytes; + icmpPtr->type = type; + icmpPtr->code = 0; + icmpPtr->checksum = 0; + icmpPtr->identifier = OSSwapHostToBigInt16(self.identifier); + icmpPtr->sequenceNumber = OSSwapHostToBigInt16(self.nextSequenceNumber); + memcpy(&icmpPtr[1], [payload bytes], [payload length]); + + if (requiresChecksum) { + // The IP checksum routine returns a 16-bit number that's already in correct byte order + // (due to wacky 1's complement maths), so we just put it into the packet as a 16-bit unit. + + icmpPtr->checksum = in_cksum(packet.bytes, packet.length); + } + + return packet; +} + +/** + * 通过ping的套接口发送数据 + */ +- (void)sendPingWithData:(NSData *)data { + int err; + NSData * payload; + NSData * packet; + ssize_t bytesSent; + id strongDelegate; + + // data may be nil + NSParameterAssert(self.hostAddress != nil); // gotta wait for -simplePing:didStartWithAddress: + + // Construct the ping packet. + + payload = data; + if (payload == nil) { + payload = [[NSString stringWithFormat:@"%28zd bottles of beer on the wall", (ssize_t) 99 - (size_t) (self.nextSequenceNumber % 100) ] dataUsingEncoding:NSASCIIStringEncoding]; + assert(payload != nil); + + // Our dummy payload is sized so that the resulting ICMP packet, including the ICMPHeader, is + // 64-bytes, which makes it easier to recognise our packets on the wire. + + assert([payload length] == 56); + } + + switch (self.hostAddressFamily) { + case AF_INET: { + packet = [self pingPacketWithType:ICMPv4TypeEchoRequest payload:payload requiresChecksum:YES]; + } break; + case AF_INET6: { + packet = [self pingPacketWithType:ICMPv6TypeEchoRequest payload:payload requiresChecksum:NO]; + } break; + default: { + assert(NO); + } break; + } + assert(packet != nil); + + // Send the packet. + + if (self.socket == NULL) { + bytesSent = -1; + err = EBADF; + } else { + bytesSent = sendto( + CFSocketGetNative(self.socket), + packet.bytes, + packet.length, + 0, + self.hostAddress.bytes, + (socklen_t) self.hostAddress.length + ); + err = 0; + if (bytesSent < 0) { + err = errno; + } + } + + // Handle the results of the send. + + strongDelegate = self.delegate; + if ( (bytesSent > 0) && (((NSUInteger) bytesSent) == packet.length) ) { + + // Complete success. Tell the client. + + if ( (strongDelegate != nil) && [strongDelegate respondsToSelector:@selector(simplePing:didSendPacket:sequenceNumber:)] ) { + [strongDelegate simplePing:self didSendPacket:packet sequenceNumber:self.nextSequenceNumber]; + } + } else { + NSError * error; + + // Some sort of failure. Tell the client. + + if (err == 0) { + err = ENOBUFS; // This is not a hugely descriptor error, alas. + } + error = [NSError errorWithDomain:NSPOSIXErrorDomain code:err userInfo:nil]; + if ( (strongDelegate != nil) && [strongDelegate respondsToSelector:@selector(simplePing:didFailToSendPacket:sequenceNumber:error:)] ) { + [strongDelegate simplePing:self didFailToSendPacket:packet sequenceNumber:self.nextSequenceNumber error:error]; + } + } + + self.nextSequenceNumber += 1; + if (self.nextSequenceNumber == 0) { + self.nextSequenceNumberHasWrapped = YES; + } +} + + +/*! Calculates the offset of the ICMP header within an IPv4 packet. + * \details In the IPv4 case the kernel returns us a buffer that includes the + * IPv4 header. We're not interested in that, so we have to skip over it. + * This code does a rough check of the IPv4 header and, if it looks OK, + * returns the offset of the ICMP header. + * \param packet The IPv4 packet, as returned to us by the kernel. + * \returns The offset of the ICMP header, or NSNotFound. + */ + ++ (NSUInteger)icmpHeaderOffsetInIPv4Packet:(NSData *)packet { + // Returns the offset of the ICMPv4Header within an IP packet. + NSUInteger result; + const struct IPv4Header * ipPtr; + size_t ipHeaderLength; + + result = NSNotFound; + if (packet.length >= (sizeof(IPv4Header) + sizeof(ICMPHeader))) { + ipPtr = (const IPv4Header *) packet.bytes; + if ( ((ipPtr->versionAndHeaderLength & 0xF0) == 0x40) && // IPv4 + ( ipPtr->protocol == IPPROTO_ICMP ) ) { + ipHeaderLength = (ipPtr->versionAndHeaderLength & 0x0F) * sizeof(uint32_t); + if (packet.length >= (ipHeaderLength + sizeof(ICMPHeader))) { + result = ipHeaderLength; + } + } + } + return result; +} + +/*! Checks whether the specified sequence number is one we sent. + * \param sequenceNumber The incoming sequence number. + * \returns YES if the sequence number looks like one we sent. + */ + +- (BOOL)validateSequenceNumber:(uint16_t)sequenceNumber { + if (self.nextSequenceNumberHasWrapped) { + // If the sequence numbers have wrapped that we can't reliably check + // whether this is a sequence number we sent. Rather, we check to see + // whether the sequence number is within the last 120 sequence numbers + // we sent. Note that the uint16_t subtraction here does the right + // thing regardless of the wrapping. + // + // Why 120? Well, if we send one ping per second, 120 is 2 minutes, which + // is the standard "max time a packet can bounce around the Internet" value. + return ((uint16_t) (self.nextSequenceNumber - sequenceNumber)) < (uint16_t) 120; + } else { + return sequenceNumber < self.nextSequenceNumber; + } +} + +/*! Checks whether an incoming IPv4 packet looks like a ping response. + * \details This routine modifies this `packet` data! It does this for two reasons: + * + * * It needs to zero out the `checksum` field of the ICMPHeader in order to do + * its checksum calculation. + * + * * It removes the IPv4 header from the front of the packet. + * \param packet The IPv4 packet, as returned to us by the kernel. + * \param sequenceNumberPtr A pointer to a place to start the ICMP sequence number. + * \returns YES if the packet looks like a reasonable IPv4 ping response. + */ + +- (BOOL)validatePing4ResponsePacket:(NSMutableData *)packet sequenceNumber:(uint16_t *)sequenceNumberPtr { + BOOL result; + NSUInteger icmpHeaderOffset; + ICMPHeader * icmpPtr; + uint16_t receivedChecksum; + uint16_t calculatedChecksum; + + result = NO; + + icmpHeaderOffset = [[self class] icmpHeaderOffsetInIPv4Packet:packet]; + if (icmpHeaderOffset != NSNotFound) { + icmpPtr = (struct ICMPHeader *) (((uint8_t *) packet.mutableBytes) + icmpHeaderOffset); + + receivedChecksum = icmpPtr->checksum; + icmpPtr->checksum = 0; + calculatedChecksum = in_cksum(icmpPtr, packet.length - icmpHeaderOffset); + icmpPtr->checksum = receivedChecksum; + + if (receivedChecksum == calculatedChecksum) { + if ( (icmpPtr->type == ICMPv4TypeEchoReply) && (icmpPtr->code == 0) ) { + if ( OSSwapBigToHostInt16(icmpPtr->identifier) == self.identifier ) { + uint16_t sequenceNumber; + + sequenceNumber = OSSwapBigToHostInt16(icmpPtr->sequenceNumber); + if ([self validateSequenceNumber:sequenceNumber]) { + + // Remove the IPv4 header off the front of the data we received, leaving us with + // just the ICMP header and the ping payload. + [packet replaceBytesInRange:NSMakeRange(0, icmpHeaderOffset) withBytes:NULL length:0]; + + *sequenceNumberPtr = sequenceNumber; + result = YES; + } + } + } + } + } + + return result; +} + +/*! Checks whether an incoming IPv6 packet looks like a ping response. + * \param packet The IPv6 packet, as returned to us by the kernel; note that this routine + * could modify this data but does not need to in the IPv6 case. + * \param sequenceNumberPtr A pointer to a place to start the ICMP sequence number. + * \returns YES if the packet looks like a reasonable IPv4 ping response. + */ + +- (BOOL)validatePing6ResponsePacket:(NSMutableData *)packet sequenceNumber:(uint16_t *)sequenceNumberPtr { + BOOL result; + const ICMPHeader * icmpPtr; + + result = NO; + + if (packet.length >= sizeof(*icmpPtr)) { + icmpPtr = packet.bytes; + + // In the IPv6 case we don't check the checksum because that's hard (we need to + // cook up an IPv6 pseudo header and we don't have the ingredients) and unnecessary + // (the kernel has already done this check). + + if ( (icmpPtr->type == ICMPv6TypeEchoReply) && (icmpPtr->code == 0) ) { + if ( OSSwapBigToHostInt16(icmpPtr->identifier) == self.identifier ) { + uint16_t sequenceNumber; + + sequenceNumber = OSSwapBigToHostInt16(icmpPtr->sequenceNumber); + if ([self validateSequenceNumber:sequenceNumber]) { + *sequenceNumberPtr = sequenceNumber; + result = YES; + } + } + } + } + return result; +} + +/*! Checks whether an incoming packet looks like a ping response. + * \param packet The packet, as returned to us by the kernel; note that may end up modifying + * this data. + * \param sequenceNumberPtr A pointer to a place to start the ICMP sequence number. + * \returns YES if the packet looks like a reasonable IPv4 ping response. + */ + +- (BOOL)validatePingResponsePacket:(NSMutableData *)packet sequenceNumber:(uint16_t *)sequenceNumberPtr { + BOOL result; + + switch (self.hostAddressFamily) { + case AF_INET: { + result = [self validatePing4ResponsePacket:packet sequenceNumber:sequenceNumberPtr]; + } break; + case AF_INET6: { + result = [self validatePing6ResponsePacket:packet sequenceNumber:sequenceNumberPtr]; + } break; + default: { + assert(NO); + result = NO; + } break; + } + return result; +} + +/*! Reads data from the ICMP socket. + * \details Called by the socket handling code (SocketReadCallback) to process an ICMP + * message waiting on the socket. + */ + +- (void)readData { + int err; + struct sockaddr_storage addr; + socklen_t addrLen; + ssize_t bytesRead; + void * buffer; + enum { kBufferSize = 65535 }; + + // 65535 is the maximum IP packet size, which seems like a reasonable bound + // here (plus it's what uses). + + buffer = malloc(kBufferSize); + assert(buffer != NULL); + + // Actually read the data. We use recvfrom(), and thus get back the source address, + // but we don't actually do anything with it. It would be trivial to pass it to + // the delegate but we don't need it in this example. + + addrLen = sizeof(addr); + bytesRead = recvfrom(CFSocketGetNative(self.socket), buffer, kBufferSize, 0, (struct sockaddr *) &addr, &addrLen); + err = 0; + if (bytesRead < 0) { + err = errno; + } + + // Process the data we read. + + if (bytesRead > 0) { + NSMutableData * packet; + id strongDelegate; + uint16_t sequenceNumber; + + packet = [NSMutableData dataWithBytes:buffer length:(NSUInteger) bytesRead]; + assert(packet != nil); + + // We got some data, pass it up to our client. + + strongDelegate = self.delegate; + if ( [self validatePingResponsePacket:packet sequenceNumber:&sequenceNumber] ) { + if ( (strongDelegate != nil) && [strongDelegate respondsToSelector:@selector(simplePing:didReceivePingResponsePacket:sequenceNumber:)] ) { + [strongDelegate simplePing:self didReceivePingResponsePacket:packet sequenceNumber:sequenceNumber]; + } + } else { + if ( (strongDelegate != nil) && [strongDelegate respondsToSelector:@selector(simplePing:didReceiveUnexpectedPacket:)] ) { + [strongDelegate simplePing:self didReceiveUnexpectedPacket:packet]; + } + } + } else { + + // We failed to read the data, so shut everything down. + + if (err == 0) { + err = EPIPE; + } + [self didFailWithError:[NSError errorWithDomain:NSPOSIXErrorDomain code:err userInfo:nil]]; + } + + free(buffer); + + // Note that we don't loop back trying to read more data. Rather, we just + // let CFSocket call us again. +} + +/*! The callback for our CFSocket object. + * \details This simply routes the call to our `-readData` method. + * \param s See the documentation for CFSocketCallBack. + * \param type See the documentation for CFSocketCallBack. + * \param address See the documentation for CFSocketCallBack. + * \param data See the documentation for CFSocketCallBack. + * \param info See the documentation for CFSocketCallBack; this is actually a pointer to the + * 'owning' object. + */ + +static void SocketReadCallback(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info) { + // This C routine is called by CFSocket when there's data waiting on our + // ICMP socket. It just redirects the call to Objective-C code. + LDSimplePing * obj; + + obj = (__bridge LDSimplePing *) info; + assert([obj isKindOfClass:[LDSimplePing class]]); + +#pragma unused(s) + assert(s == obj.socket); +#pragma unused(type) + assert(type == kCFSocketReadCallBack); +#pragma unused(address) + assert(address == nil); +#pragma unused(data) + assert(data == nil); + + [obj readData]; +} + +/*! Starts the send and receive infrastructure. + * \details This is called once we've successfully resolved `hostName` in to + * `hostAddress`. It's responsible for setting up the socket for sending and + * receiving pings. + */ + +- (void)startWithHostAddress { + int err; + int fd; + + assert(self.hostAddress != nil); + + // Open the socket. + + fd = -1; + err = 0; + switch (self.hostAddressFamily) { + case AF_INET: { + fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP); + if (fd < 0) { + err = errno; + } + } break; + case AF_INET6: { + fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_ICMPV6); + if (fd < 0) { + err = errno; + } + } break; + default: { + err = EPROTONOSUPPORT; + } break; + } + + if (err != 0) { + [self didFailWithError:[NSError errorWithDomain:NSPOSIXErrorDomain code:err userInfo:nil]]; + } else { + CFSocketContext context = {0, (__bridge void *)(self), NULL, NULL, NULL}; + CFRunLoopSourceRef rls; + id strongDelegate; + + // Wrap it in a CFSocket and schedule it on the runloop. + + self.socket = (CFSocketRef) CFAutorelease( CFSocketCreateWithNative(NULL, fd, kCFSocketReadCallBack, SocketReadCallback, &context) ); + assert(self.socket != NULL); + + // The socket will now take care of cleaning up our file descriptor. + + assert( CFSocketGetSocketFlags(self.socket) & kCFSocketCloseOnInvalidate ); + fd = -1; + + rls = CFSocketCreateRunLoopSource(NULL, self.socket, 0); + assert(rls != NULL); + + CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode); + + CFRelease(rls); + + strongDelegate = self.delegate; + if ( (strongDelegate != nil) && [strongDelegate respondsToSelector:@selector(simplePing:didStartWithAddress:)] ) { + [strongDelegate simplePing:self didStartWithAddress:self.hostAddress]; + } + } + assert(fd == -1); +} + +/*! Processes the results of our name-to-address resolution. + * \details Called by our CFHost resolution callback (HostResolveCallback) when host + * resolution is complete. We just latch the first appropriate address and kick + * off the send and receive infrastructure. + */ + +- (void)hostResolutionDone { + Boolean resolved; + NSArray * addresses; + + // Find the first appropriate address. + + addresses = (__bridge NSArray *) CFHostGetAddressing(self.host, &resolved); + if ( resolved && (addresses != nil) ) { + resolved = false; + for (NSData * address in addresses) { + const struct sockaddr * addrPtr; + + addrPtr = (const struct sockaddr *) address.bytes; + if ( address.length >= sizeof(struct sockaddr) ) { + switch (addrPtr->sa_family) { + case AF_INET: { + if (self.addressStyle != SimplePingAddressStyleICMPv6) { + self.hostAddress = address; + resolved = true; + } + } break; + case AF_INET6: { + if (self.addressStyle != SimplePingAddressStyleICMPv4) { + self.hostAddress = address; + resolved = true; + } + } break; + } + } + if (resolved) { + break; + } + } + } + + // We're done resolving, so shut that down. + + [self stopHostResolution]; + + // If all is OK, start the send and receive infrastructure, otherwise stop. + + if (resolved) { + [self startWithHostAddress]; + } else { + [self didFailWithError:[NSError errorWithDomain:(NSString *)kCFErrorDomainCFNetwork code:kCFHostErrorHostNotFound userInfo:nil]]; + } +} + +/*! The callback for our CFHost object. + * \details This simply routes the call to our `-hostResolutionDone` or + * `-didFailWithHostStreamError:` methods. + * \param theHost See the documentation for CFHostClientCallBack. + * \param typeInfo See the documentation for CFHostClientCallBack. + * \param error See the documentation for CFHostClientCallBack. + * \param info See the documentation for CFHostClientCallBack; this is actually a pointer to + * the 'owning' object. + */ + +static void HostResolveCallback(CFHostRef theHost, CFHostInfoType typeInfo, const CFStreamError *error, void *info) { + // This C routine is called by CFHost when the host resolution is complete. + // It just redirects the call to the appropriate Objective-C method. + LDSimplePing * obj; + + obj = (__bridge LDSimplePing *) info; + assert([obj isKindOfClass:[LDSimplePing class]]); + +#pragma unused(theHost) + assert(theHost == obj.host); +#pragma unused(typeInfo) + assert(typeInfo == kCFHostAddresses); + + if ( (error != NULL) && (error->domain != 0) ) { + [obj didFailWithHostStreamError:*error]; + } else { + [obj hostResolutionDone]; + } +} + +/** + * 开启ping命令 + * 如果用户直接提供了一个ip地址,就可以直接开始执行ping命令 + * 否则需要创建socket获取host + */ + +- (void)start { + Boolean success; + CFHostClientContext context = {0, (__bridge void *)(self), NULL, NULL, NULL}; + CFStreamError streamError; + + assert(self.host == NULL); + assert(self.hostAddress == nil); + + self.host = (CFHostRef) CFAutorelease( CFHostCreateWithName(NULL, (__bridge CFStringRef) self.hostName) ); + assert(self.host != NULL); + + CFHostSetClient(self.host, HostResolveCallback, &context); + + CFHostScheduleWithRunLoop(self.host, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + + success = CFHostStartInfoResolution(self.host, kCFHostAddresses, &streamError); + if ( ! success ) { + [self didFailWithHostStreamError:streamError]; + } +} + +/*! Stops the name-to-address resolution infrastructure. + */ + +- (void)stopHostResolution { + // Shut down the CFHost. + if (self.host != NULL) { + CFHostSetClient(self.host, NULL, NULL); + CFHostUnscheduleFromRunLoop(self.host, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + self.host = NULL; + } +} + +/*! Stops the send and receive infrastructure. + */ + +- (void)stopSocket { + if (self.socket != NULL) { + CFSocketInvalidate(self.socket); + self.socket = NULL; + } +} + +- (void)stop { + [self stopHostResolution]; + [self stopSocket]; + + // Junk the host address on stop. If the client calls -start again, we'll + // re-resolve the host name. + + self.hostAddress = NULL; +} + + +/** + * IPV4的返回包直接将IPV4的头去掉了 + */ ++(const struct ICMPHeader *)icmpInPacket:(NSData *)packet +{ + const struct ICMPHeader *result; + result = nil; + + if (packet.length >= sizeof(*result)) { + result = packet.bytes; + } + + return result; +} + +@end diff --git a/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/Route.h b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/Route.h new file mode 100644 index 000000000..6ae553b38 --- /dev/null +++ b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/Route.h @@ -0,0 +1,484 @@ +/* + * Copyright (c) 2000-2008 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * Copyright (c) 1980, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)route.h 8.3 (Berkeley) 4/19/94 + * $FreeBSD: src/sys/net/route.h,v 1.36.2.1 2000/08/16 06:14:23 jayanth Exp $ + */ + +#ifndef _NET_ROUTE_H_ +#define _NET_ROUTE_H_ +#include +#include +#include +#include + +/* + * Kernel resident routing tables. + * + * The routing tables are initialized when interface addresses + * are set by making entries for all directly connected interfaces. + */ + +/* + * A route consists of a destination address and a reference + * to a routing entry. These are often held by protocols + * in their control blocks, e.g. inpcb. + */ +#ifdef PRIVATE +struct rtentry; +struct route { + /* + * N.B: struct route must begin with ro_rt and ro_flags + * because the code does some casts of a 'struct route_in6 *' + * to a 'struct route *'. + */ + struct rtentry *ro_rt; + uint32_t ro_flags; /* route flags (see below) */ + struct sockaddr ro_dst; +}; + +#define ROF_SRCIF_SELECTED 0x1 /* source interface was selected */ + +#else +struct route; +#endif /* PRIVATE */ + +/* + * These numbers are used by reliable protocols for determining + * retransmission behavior and are included in the routing structure. + */ +struct rt_metrics { + u_int32_t rmx_locks; /* Kernel must leave these values alone */ + u_int32_t rmx_mtu; /* MTU for this path */ + u_int32_t rmx_hopcount; /* max hops expected */ + int32_t rmx_expire; /* lifetime for route, e.g. redirect */ + u_int32_t rmx_recvpipe; /* inbound delay-bandwidth product */ + u_int32_t rmx_sendpipe; /* outbound delay-bandwidth product */ + u_int32_t rmx_ssthresh; /* outbound gateway buffer limit */ + u_int32_t rmx_rtt; /* estimated round trip time */ + u_int32_t rmx_rttvar; /* estimated rtt variance */ + u_int32_t rmx_pksent; /* packets sent using this route */ + u_int32_t rmx_filler[4]; /* will be used for T/TCP later */ +}; + +/* + * rmx_rtt and rmx_rttvar are stored as microseconds; + */ +#define RTM_RTTUNIT 1000000 /* units for rtt, rttvar, as units per sec */ + +/* + * We distinguish between routes to hosts and routes to networks, + * preferring the former if available. For each route we infer + * the interface to use from the gateway address supplied when + * the route was entered. Routes that forward packets through + * gateways are marked so that the output routines know to address the + * gateway rather than the ultimate destination. + */ +#ifdef KERNEL_PRIVATE +#include +#ifndef RNF_NORMAL +#include +#endif +/* + * Kernel routing entry structure (private). + */ +struct rtentry { + struct radix_node rt_nodes[2]; /* tree glue, and other values */ +#define rt_key(r) ((struct sockaddr *)((r)->rt_nodes->rn_key)) +#define rt_mask(r) ((struct sockaddr *)((r)->rt_nodes->rn_mask)) + struct sockaddr *rt_gateway; /* value */ + int32_t rt_refcnt; /* # held references */ + uint32_t rt_flags; /* up/down?, host/net */ + struct ifnet *rt_ifp; /* the answer: interface to use */ + struct ifaddr *rt_ifa; /* the answer: interface addr to use */ + struct sockaddr *rt_genmask; /* for generation of cloned routes */ + void *rt_llinfo; /* pointer to link level info cache */ + void (*rt_llinfo_free)(void *); /* link level info free function */ + struct rt_metrics rt_rmx; /* metrics used by rx'ing protocols */ + struct rtentry *rt_gwroute; /* implied entry for gatewayed routes */ + struct rtentry *rt_parent; /* cloning parent of this route */ + uint32_t generation_id; /* route generation id */ + /* + * See bsd/net/route.c for synchronization notes. + */ + decl_lck_mtx_data(, rt_lock); /* lock for routing entry */ +}; +#endif /* KERNEL_PRIVATE */ + +#ifdef KERNEL_PRIVATE +#define rt_use rt_rmx.rmx_pksent +#endif /* KERNEL_PRIVATE */ + +#define RTF_UP 0x1 /* route usable */ +#define RTF_GATEWAY 0x2 /* destination is a gateway */ +#define RTF_HOST 0x4 /* host entry (net otherwise) */ +#define RTF_REJECT 0x8 /* host or net unreachable */ +#define RTF_DYNAMIC 0x10 /* created dynamically (by redirect) */ +#define RTF_MODIFIED 0x20 /* modified dynamically (by redirect) */ +#define RTF_DONE 0x40 /* message confirmed */ +#define RTF_DELCLONE 0x80 /* delete cloned route */ +#define RTF_CLONING 0x100 /* generate new routes on use */ +#define RTF_XRESOLVE 0x200 /* external daemon resolves name */ +#define RTF_LLINFO 0x400 /* generated by link layer (e.g. ARP) */ +#define RTF_STATIC 0x800 /* manually added */ +#define RTF_BLACKHOLE 0x1000 /* just discard pkts (during updates) */ +#define RTF_PROTO2 0x4000 /* protocol specific routing flag */ +#define RTF_PROTO1 0x8000 /* protocol specific routing flag */ + +#define RTF_PRCLONING 0x10000 /* protocol requires cloning */ +#define RTF_WASCLONED 0x20000 /* route generated through cloning */ +#define RTF_PROTO3 0x40000 /* protocol specific routing flag */ +/* 0x80000 unused */ +#define RTF_PINNED 0x100000 /* future use */ +#define RTF_LOCAL 0x200000 /* route represents a local address */ +#define RTF_BROADCAST 0x400000 /* route represents a bcast address */ +#define RTF_MULTICAST 0x800000 /* route represents a mcast address */ +#define RTF_IFSCOPE 0x1000000 /* has valid interface scope */ +#define RTF_CONDEMNED 0x2000000 /* defunct; no longer modifiable */ + /* 0x4000000 and up unassigned */ + +/* + * Routing statistics. + */ +struct rtstat { + short rts_badredirect; /* bogus redirect calls */ + short rts_dynamic; /* routes created by redirects */ + short rts_newgateway; /* routes modified by redirects */ + short rts_unreach; /* lookups which failed */ + short rts_wildcard; /* lookups satisfied by a wildcard */ +}; + +/* + * Structures for routing messages. + */ +struct rt_msghdr { + u_short rtm_msglen; /* to skip over non-understood messages */ + u_char rtm_version; /* future binary compatibility */ + u_char rtm_type; /* message type */ + u_short rtm_index; /* index for associated ifp */ + int rtm_flags; /* flags, incl. kern & message, e.g. DONE */ + int rtm_addrs; /* bitmask identifying sockaddrs in msg */ + pid_t rtm_pid; /* identify sender */ + int rtm_seq; /* for sender to identify action */ + int rtm_errno; /* why failed */ + int rtm_use; /* from rtentry */ + u_int32_t rtm_inits; /* which metrics we are initializing */ + struct rt_metrics rtm_rmx; /* metrics themselves */ +}; + +struct rt_msghdr2 { + u_short rtm_msglen; /* to skip over non-understood messages */ + u_char rtm_version; /* future binary compatibility */ + u_char rtm_type; /* message type */ + u_short rtm_index; /* index for associated ifp */ + int rtm_flags; /* flags, incl. kern & message, e.g. DONE */ + int rtm_addrs; /* bitmask identifying sockaddrs in msg */ + int32_t rtm_refcnt; /* reference count */ + int rtm_parentflags; /* flags of the parent route */ + int rtm_reserved; /* reserved field set to 0 */ + int rtm_use; /* from rtentry */ + u_int32_t rtm_inits; /* which metrics we are initializing */ + struct rt_metrics rtm_rmx; /* metrics themselves */ +}; + + +#define RTM_VERSION 5 /* Up the ante and ignore older versions */ + +/* + * Message types. + */ +#define RTM_ADD 0x1 /* Add Route */ +#define RTM_DELETE 0x2 /* Delete Route */ +#define RTM_CHANGE 0x3 /* Change Metrics or flags */ +#define RTM_GET 0x4 /* Report Metrics */ +#define RTM_LOSING 0x5 /* Kernel Suspects Partitioning */ +#define RTM_REDIRECT 0x6 /* Told to use different route */ +#define RTM_MISS 0x7 /* Lookup failed on this address */ +#define RTM_LOCK 0x8 /* fix specified metrics */ +#define RTM_OLDADD 0x9 /* caused by SIOCADDRT */ +#define RTM_OLDDEL 0xa /* caused by SIOCDELRT */ +#define RTM_RESOLVE 0xb /* req to resolve dst to LL addr */ +#define RTM_NEWADDR 0xc /* address being added to iface */ +#define RTM_DELADDR 0xd /* address being removed from iface */ +#define RTM_IFINFO 0xe /* iface going up/down etc. */ +#define RTM_NEWMADDR 0xf /* mcast group membership being added to if */ +#define RTM_DELMADDR 0x10 /* mcast group membership being deleted */ +#ifdef PRIVATE +#define RTM_GET_SILENT 0x11 +#endif /* PRIVATE */ +#define RTM_IFINFO2 0x12 /* */ +#define RTM_NEWMADDR2 0x13 /* */ +#define RTM_GET2 0x14 /* */ + +/* + * Bitmask values for rtm_inits and rmx_locks. + */ +#define RTV_MTU 0x1 /* init or lock _mtu */ +#define RTV_HOPCOUNT 0x2 /* init or lock _hopcount */ +#define RTV_EXPIRE 0x4 /* init or lock _expire */ +#define RTV_RPIPE 0x8 /* init or lock _recvpipe */ +#define RTV_SPIPE 0x10 /* init or lock _sendpipe */ +#define RTV_SSTHRESH 0x20 /* init or lock _ssthresh */ +#define RTV_RTT 0x40 /* init or lock _rtt */ +#define RTV_RTTVAR 0x80 /* init or lock _rttvar */ + +/* + * Bitmask values for rtm_addrs. + */ +#define RTA_DST 0x1 /* destination sockaddr present */ +#define RTA_GATEWAY 0x2 /* gateway sockaddr present */ +#define RTA_NETMASK 0x4 /* netmask sockaddr present */ +#define RTA_GENMASK 0x8 /* cloning mask sockaddr present */ +#define RTA_IFP 0x10 /* interface name sockaddr present */ +#define RTA_IFA 0x20 /* interface addr sockaddr present */ +#define RTA_AUTHOR 0x40 /* sockaddr for author of redirect */ +#define RTA_BRD 0x80 /* for NEWADDR, broadcast or p-p dest addr */ + +/* + * Index offsets for sockaddr array for alternate internal encoding. + */ +#define RTAX_DST 0 /* destination sockaddr present */ +#define RTAX_GATEWAY 1 /* gateway sockaddr present */ +#define RTAX_NETMASK 2 /* netmask sockaddr present */ +#define RTAX_GENMASK 3 /* cloning mask sockaddr present */ +#define RTAX_IFP 4 /* interface name sockaddr present */ +#define RTAX_IFA 5 /* interface addr sockaddr present */ +#define RTAX_AUTHOR 6 /* sockaddr for author of redirect */ +#define RTAX_BRD 7 /* for NEWADDR, broadcast or p-p dest addr */ +#define RTAX_MAX 8 /* size of array to allocate */ + +struct rt_addrinfo { + int rti_addrs; + struct sockaddr *rti_info[RTAX_MAX]; +}; + +struct route_cb { + int ip_count; + int ip6_count; + int ipx_count; + int ns_count; + int iso_count; + int any_count; +}; + +#ifdef PRIVATE +/* + * For scoped routing; a zero interface scope value means nil/no scope. + */ +#define IFSCOPE_NONE 0 +#endif /* PRIVATE */ + +#ifdef KERNEL_PRIVATE +/* + * Generic call trace used by some subsystems (e.g. route, ifaddr) + */ +#define CTRACE_STACK_SIZE 8 /* depth of stack trace */ +#define CTRACE_HIST_SIZE 4 /* refcnt history size */ +typedef struct ctrace { + void *th; /* thread ptr */ + void *pc[CTRACE_STACK_SIZE]; /* PC stack trace */ +} ctrace_t; + +extern void ctrace_record(ctrace_t *); + +#define RT_LOCK_ASSERT_HELD(_rt) +lck_mtx_assert(&(_rt)->rt_lock, LCK_MTX_ASSERT_OWNED) + +#define RT_LOCK_ASSERT_NOTHELD(_rt) + lck_mtx_assert(&(_rt)->rt_lock, LCK_MTX_ASSERT_NOTOWNED) + +#define RT_LOCK(_rt) do { + if (!rte_debug) lck_mtx_lock(&(_rt)->rt_lock); +else rt_lock(_rt, FALSE); +} +while (0) + +#define RT_LOCK_SPIN(_rt) do { + if (!rte_debug) + lck_mtx_lock_spin(&(_rt)->rt_lock); + else + rt_lock(_rt, TRUE); +} +while (0) + +#define RT_CONVERT_LOCK(_rt) do { + RT_LOCK_ASSERT_HELD(_rt); +lck_mtx_convert_spin(&(_rt)->rt_lock); +} +while (0) + +#define RT_UNLOCK(_rt) do { + if (!rte_debug) + lck_mtx_unlock(&(_rt)->rt_lock); + else + rt_unlock(_rt); +} +while (0) + +#define RT_ADDREF_LOCKED(_rt) do { + if (!rte_debug) { + RT_LOCK_ASSERT_HELD(_rt); + if (++(_rt)->rt_refcnt == 0) + panic("RT_ADDREF(%p) bad refcnt + ", _rt); + } else { + rtref(_rt); + } +} +while (0) + +/* + * Spin variant mutex is used here; caller is responsible for + * converting any previously-held similar lock to full mutex. + */ +#define RT_ADDREF(_rt) do { + RT_LOCK_SPIN(_rt); +RT_ADDREF_LOCKED(_rt); +RT_UNLOCK(_rt); +} +while (0) + +#define RT_REMREF_LOCKED(_rt) do { + if (!rte_debug) { + RT_LOCK_ASSERT_HELD(_rt); + if ((_rt)->rt_refcnt == 0) + panic("RT_REMREF(%p) bad refcnt + ", _rt); + --(_rt)->rt_refcnt; + } else { + (void)rtunref(_rt); + } +} +while (0) + +/* + * Spin variant mutex is used here; caller is responsible for + * converting any previously-held similar lock to full mutex. + */ +#define RT_REMREF(_rt) do { + RT_LOCK_SPIN(_rt); +RT_REMREF_LOCKED(_rt); +RT_UNLOCK(_rt); +} +while (0) + +#define RTFREE(_rt) rtfree(_rt) +#define RTFREE_LOCKED(_rt) rtfree_locked(_rt) + + extern struct route_cb route_cb; +extern struct radix_node_head *rt_tables[AF_MAX + 1]; +__private_extern__ lck_mtx_t *rnh_lock; +__private_extern__ int use_routegenid; +__private_extern__ uint32_t route_generation; +__private_extern__ int rttrash; +__private_extern__ unsigned int rte_debug; + +struct ifmultiaddr; +struct proc; + +extern void route_init(void) __attribute__((section("__TEXT, initcode"))); +extern void routegenid_update(void); +extern void rt_ifmsg(struct ifnet *); +extern void rt_missmsg(int, struct rt_addrinfo *, int, int); +extern void rt_newaddrmsg(int, struct ifaddr *, int, struct rtentry *); +extern void rt_newmaddrmsg(int, struct ifmultiaddr *); +extern int rt_setgate(struct rtentry *, struct sockaddr *, struct sockaddr *); +extern void set_primary_ifscope(unsigned int); +extern unsigned int get_primary_ifscope(void); +extern boolean_t rt_inet_default(struct rtentry *, struct sockaddr *); +extern struct rtentry *rt_lookup(boolean_t, struct sockaddr *, struct sockaddr *, + struct radix_node_head *, unsigned int); +extern void rtalloc(struct route *); +extern void rtalloc_ign(struct route *, uint32_t); +extern void rtalloc_ign_locked(struct route *, uint32_t); +extern void rtalloc_scoped_ign(struct route *, uint32_t, unsigned int); +extern void rtalloc_scoped_ign_locked(struct route *, uint32_t, unsigned int); +extern struct rtentry *rtalloc1(struct sockaddr *, int, uint32_t); +extern struct rtentry *rtalloc1_locked(struct sockaddr *, int, uint32_t); +extern struct rtentry *rtalloc1_scoped(struct sockaddr *, int, uint32_t, unsigned int); +extern struct rtentry *rtalloc1_scoped_locked(struct sockaddr *, int, uint32_t, unsigned int); +extern void rtfree(struct rtentry *); +extern void rtfree_locked(struct rtentry *); +extern void rtref(struct rtentry *); +/* + * rtunref will decrement the refcount, rtfree will decrement and free if + * the refcount has reached zero and the route is not up. + * Unless you have good reason to do otherwise, use rtfree. + */ +extern int rtunref(struct rtentry *); +extern void rtsetifa(struct rtentry *, struct ifaddr *); +extern int rtinit(struct ifaddr *, int, int); +extern int rtinit_locked(struct ifaddr *, int, int); +extern int rtioctl(unsigned long, caddr_t, struct proc *); +extern void rtredirect(struct ifnet *, struct sockaddr *, struct sockaddr *, struct sockaddr *, int, + struct sockaddr *, struct rtentry **); +extern int rtrequest(int, struct sockaddr *, struct sockaddr *, struct sockaddr *, int, + struct rtentry **); +extern int rtrequest_locked(int, struct sockaddr *, struct sockaddr *, struct sockaddr *, int, + struct rtentry **); +extern int rtrequest_scoped_locked(int, struct sockaddr *, struct sockaddr *, struct sockaddr *, + int, struct rtentry **, unsigned int); +extern unsigned int sa_get_ifscope(struct sockaddr *); +extern void rt_lock(struct rtentry *, boolean_t); +extern void rt_unlock(struct rtentry *); +extern struct sockaddr *rtm_scrub_ifscope(int, struct sockaddr *, struct sockaddr *, + struct sockaddr_storage *); +#endif /* KERNEL_PRIVATE */ + +#endif \ No newline at end of file diff --git a/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/net_route.h b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/net_route.h new file mode 100644 index 000000000..b2bcea3b8 --- /dev/null +++ b/Coding_iOS/Util/EADeviceToServerLog/LDNetDiagnoService/net_route.h @@ -0,0 +1,478 @@ +/* + * Copyright (c) 2000-2008 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * Copyright (c) 1980, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)route.h 8.3 (Berkeley) 4/19/94 + * $FreeBSD: src/sys/net/route.h,v 1.36.2.1 2000/08/16 06:14:23 jayanth Exp $ + */ + +#ifndef _NET_ROUTE_H_ +#define _NET_ROUTE_H_ +#include +#include +#include +#include + +/* + * Kernel resident routing tables. + * + * The routing tables are initialized when interface addresses + * are set by making entries for all directly connected interfaces. + */ + +/* + * A route consists of a destination address and a reference + * to a routing entry. These are often held by protocols + * in their control blocks, e.g. inpcb. + */ +#ifdef PRIVATE +struct rtentry; +struct route { + /* + * N.B: struct route must begin with ro_rt and ro_flags + * because the code does some casts of a 'struct route_in6 *' + * to a 'struct route *'. + */ + struct rtentry *ro_rt; + uint32_t ro_flags; /* route flags (see below) */ + struct sockaddr ro_dst; +}; + +#define ROF_SRCIF_SELECTED 0x1 /* source interface was selected */ + +#else +struct route; +#endif /* PRIVATE */ + +/* + * These numbers are used by reliable protocols for determining + * retransmission behavior and are included in the routing structure. + */ +struct rt_metrics { + u_int32_t rmx_locks; /* Kernel must leave these values alone */ + u_int32_t rmx_mtu; /* MTU for this path */ + u_int32_t rmx_hopcount; /* max hops expected */ + int32_t rmx_expire; /* lifetime for route, e.g. redirect */ + u_int32_t rmx_recvpipe; /* inbound delay-bandwidth product */ + u_int32_t rmx_sendpipe; /* outbound delay-bandwidth product */ + u_int32_t rmx_ssthresh; /* outbound gateway buffer limit */ + u_int32_t rmx_rtt; /* estimated round trip time */ + u_int32_t rmx_rttvar; /* estimated rtt variance */ + u_int32_t rmx_pksent; /* packets sent using this route */ + u_int32_t rmx_filler[4]; /* will be used for T/TCP later */ +}; + +/* + * rmx_rtt and rmx_rttvar are stored as microseconds; + */ +#define RTM_RTTUNIT 1000000 /* units for rtt, rttvar, as units per sec */ + +/* + * We distinguish between routes to hosts and routes to networks, + * preferring the former if available. For each route we infer + * the interface to use from the gateway address supplied when + * the route was entered. Routes that forward packets through + * gateways are marked so that the output routines know to address the + * gateway rather than the ultimate destination. + */ +#ifdef KERNEL_PRIVATE +#include +#ifndef RNF_NORMAL +#include +#endif +/* + * Kernel routing entry structure (private). + */ +struct rtentry { + struct radix_node rt_nodes[2]; /* tree glue, and other values */ +#define rt_key(r) ((struct sockaddr *)((r)->rt_nodes->rn_key)) +#define rt_mask(r) ((struct sockaddr *)((r)->rt_nodes->rn_mask)) + struct sockaddr *rt_gateway; /* value */ + int32_t rt_refcnt; /* # held references */ + uint32_t rt_flags; /* up/down?, host/net */ + struct ifnet *rt_ifp; /* the answer: interface to use */ + struct ifaddr *rt_ifa; /* the answer: interface addr to use */ + struct sockaddr *rt_genmask; /* for generation of cloned routes */ + void *rt_llinfo; /* pointer to link level info cache */ + void (*rt_llinfo_free)(void *); /* link level info free function */ + struct rt_metrics rt_rmx; /* metrics used by rx'ing protocols */ + struct rtentry *rt_gwroute; /* implied entry for gatewayed routes */ + struct rtentry *rt_parent; /* cloning parent of this route */ + uint32_t generation_id; /* route generation id */ + /* + * See bsd/net/route.c for synchronization notes. + */ + decl_lck_mtx_data(, rt_lock); /* lock for routing entry */ +}; +#endif /* KERNEL_PRIVATE */ + +#ifdef KERNEL_PRIVATE +#define rt_use rt_rmx.rmx_pksent +#endif /* KERNEL_PRIVATE */ + +#define RTF_UP 0x1 /* route usable */ +#define RTF_GATEWAY 0x2 /* destination is a gateway */ +#define RTF_HOST 0x4 /* host entry (net otherwise) */ +#define RTF_REJECT 0x8 /* host or net unreachable */ +#define RTF_DYNAMIC 0x10 /* created dynamically (by redirect) */ +#define RTF_MODIFIED 0x20 /* modified dynamically (by redirect) */ +#define RTF_DONE 0x40 /* message confirmed */ +#define RTF_DELCLONE 0x80 /* delete cloned route */ +#define RTF_CLONING 0x100 /* generate new routes on use */ +#define RTF_XRESOLVE 0x200 /* external daemon resolves name */ +#define RTF_LLINFO 0x400 /* generated by link layer (e.g. ARP) */ +#define RTF_STATIC 0x800 /* manually added */ +#define RTF_BLACKHOLE 0x1000 /* just discard pkts (during updates) */ +#define RTF_PROTO2 0x4000 /* protocol specific routing flag */ +#define RTF_PROTO1 0x8000 /* protocol specific routing flag */ + +#define RTF_PRCLONING 0x10000 /* protocol requires cloning */ +#define RTF_WASCLONED 0x20000 /* route generated through cloning */ +#define RTF_PROTO3 0x40000 /* protocol specific routing flag */ + /* 0x80000 unused */ +#define RTF_PINNED 0x100000 /* future use */ +#define RTF_LOCAL 0x200000 /* route represents a local address */ +#define RTF_BROADCAST 0x400000 /* route represents a bcast address */ +#define RTF_MULTICAST 0x800000 /* route represents a mcast address */ +#define RTF_IFSCOPE 0x1000000 /* has valid interface scope */ +#define RTF_CONDEMNED 0x2000000 /* defunct; no longer modifiable */ + /* 0x4000000 and up unassigned */ + +/* + * Routing statistics. + */ +struct rtstat { + short rts_badredirect; /* bogus redirect calls */ + short rts_dynamic; /* routes created by redirects */ + short rts_newgateway; /* routes modified by redirects */ + short rts_unreach; /* lookups which failed */ + short rts_wildcard; /* lookups satisfied by a wildcard */ +}; + +/* + * Structures for routing messages. + */ +struct rt_msghdr { + u_short rtm_msglen; /* to skip over non-understood messages */ + u_char rtm_version; /* future binary compatibility */ + u_char rtm_type; /* message type */ + u_short rtm_index; /* index for associated ifp */ + int rtm_flags; /* flags, incl. kern & message, e.g. DONE */ + int rtm_addrs; /* bitmask identifying sockaddrs in msg */ + pid_t rtm_pid; /* identify sender */ + int rtm_seq; /* for sender to identify action */ + int rtm_errno; /* why failed */ + int rtm_use; /* from rtentry */ + u_int32_t rtm_inits; /* which metrics we are initializing */ + struct rt_metrics rtm_rmx; /* metrics themselves */ +}; + +struct rt_msghdr2 { + u_short rtm_msglen; /* to skip over non-understood messages */ + u_char rtm_version; /* future binary compatibility */ + u_char rtm_type; /* message type */ + u_short rtm_index; /* index for associated ifp */ + int rtm_flags; /* flags, incl. kern & message, e.g. DONE */ + int rtm_addrs; /* bitmask identifying sockaddrs in msg */ + int32_t rtm_refcnt; /* reference count */ + int rtm_parentflags; /* flags of the parent route */ + int rtm_reserved; /* reserved field set to 0 */ + int rtm_use; /* from rtentry */ + u_int32_t rtm_inits; /* which metrics we are initializing */ + struct rt_metrics rtm_rmx; /* metrics themselves */ +}; + + +#define RTM_VERSION 5 /* Up the ante and ignore older versions */ + +/* + * Message types. + */ +#define RTM_ADD 0x1 /* Add Route */ +#define RTM_DELETE 0x2 /* Delete Route */ +#define RTM_CHANGE 0x3 /* Change Metrics or flags */ +#define RTM_GET 0x4 /* Report Metrics */ +#define RTM_LOSING 0x5 /* Kernel Suspects Partitioning */ +#define RTM_REDIRECT 0x6 /* Told to use different route */ +#define RTM_MISS 0x7 /* Lookup failed on this address */ +#define RTM_LOCK 0x8 /* fix specified metrics */ +#define RTM_OLDADD 0x9 /* caused by SIOCADDRT */ +#define RTM_OLDDEL 0xa /* caused by SIOCDELRT */ +#define RTM_RESOLVE 0xb /* req to resolve dst to LL addr */ +#define RTM_NEWADDR 0xc /* address being added to iface */ +#define RTM_DELADDR 0xd /* address being removed from iface */ +#define RTM_IFINFO 0xe /* iface going up/down etc. */ +#define RTM_NEWMADDR 0xf /* mcast group membership being added to if */ +#define RTM_DELMADDR 0x10 /* mcast group membership being deleted */ +#ifdef PRIVATE +#define RTM_GET_SILENT 0x11 +#endif /* PRIVATE */ +#define RTM_IFINFO2 0x12 /* */ +#define RTM_NEWMADDR2 0x13 /* */ +#define RTM_GET2 0x14 /* */ + +/* + * Bitmask values for rtm_inits and rmx_locks. + */ +#define RTV_MTU 0x1 /* init or lock _mtu */ +#define RTV_HOPCOUNT 0x2 /* init or lock _hopcount */ +#define RTV_EXPIRE 0x4 /* init or lock _expire */ +#define RTV_RPIPE 0x8 /* init or lock _recvpipe */ +#define RTV_SPIPE 0x10 /* init or lock _sendpipe */ +#define RTV_SSTHRESH 0x20 /* init or lock _ssthresh */ +#define RTV_RTT 0x40 /* init or lock _rtt */ +#define RTV_RTTVAR 0x80 /* init or lock _rttvar */ + +/* + * Bitmask values for rtm_addrs. + */ +#define RTA_DST 0x1 /* destination sockaddr present */ +#define RTA_GATEWAY 0x2 /* gateway sockaddr present */ +#define RTA_NETMASK 0x4 /* netmask sockaddr present */ +#define RTA_GENMASK 0x8 /* cloning mask sockaddr present */ +#define RTA_IFP 0x10 /* interface name sockaddr present */ +#define RTA_IFA 0x20 /* interface addr sockaddr present */ +#define RTA_AUTHOR 0x40 /* sockaddr for author of redirect */ +#define RTA_BRD 0x80 /* for NEWADDR, broadcast or p-p dest addr */ + +/* + * Index offsets for sockaddr array for alternate internal encoding. + */ +#define RTAX_DST 0 /* destination sockaddr present */ +#define RTAX_GATEWAY 1 /* gateway sockaddr present */ +#define RTAX_NETMASK 2 /* netmask sockaddr present */ +#define RTAX_GENMASK 3 /* cloning mask sockaddr present */ +#define RTAX_IFP 4 /* interface name sockaddr present */ +#define RTAX_IFA 5 /* interface addr sockaddr present */ +#define RTAX_AUTHOR 6 /* sockaddr for author of redirect */ +#define RTAX_BRD 7 /* for NEWADDR, broadcast or p-p dest addr */ +#define RTAX_MAX 8 /* size of array to allocate */ + +struct rt_addrinfo { + int rti_addrs; + struct sockaddr *rti_info[RTAX_MAX]; +}; + +struct route_cb { + int ip_count; + int ip6_count; + int ipx_count; + int ns_count; + int iso_count; + int any_count; +}; + +#ifdef PRIVATE +/* + * For scoped routing; a zero interface scope value means nil/no scope. + */ +#define IFSCOPE_NONE 0 +#endif /* PRIVATE */ + +#ifdef KERNEL_PRIVATE +/* + * Generic call trace used by some subsystems (e.g. route, ifaddr) + */ +#define CTRACE_STACK_SIZE 8 /* depth of stack trace */ +#define CTRACE_HIST_SIZE 4 /* refcnt history size */ +typedef struct ctrace { + void *th; /* thread ptr */ + void *pc[CTRACE_STACK_SIZE]; /* PC stack trace */ +} ctrace_t; + +extern void ctrace_record(ctrace_t *); + +#define RT_LOCK_ASSERT_HELD(_rt) \ + lck_mtx_assert(&(_rt)->rt_lock, LCK_MTX_ASSERT_OWNED) + +#define RT_LOCK_ASSERT_NOTHELD(_rt) \ + lck_mtx_assert(&(_rt)->rt_lock, LCK_MTX_ASSERT_NOTOWNED) + +#define RT_LOCK(_rt) do { \ + if (!rte_debug) \ + lck_mtx_lock(&(_rt)->rt_lock); \ + else \ + rt_lock(_rt, FALSE); \ +} while (0) + +#define RT_LOCK_SPIN(_rt) do { \ + if (!rte_debug) \ + lck_mtx_lock_spin(&(_rt)->rt_lock); \ + else \ + rt_lock(_rt, TRUE); \ +} while (0) + +#define RT_CONVERT_LOCK(_rt) do { \ + RT_LOCK_ASSERT_HELD(_rt); \ + lck_mtx_convert_spin(&(_rt)->rt_lock); \ +} while (0) + +#define RT_UNLOCK(_rt) do { \ + if (!rte_debug) \ + lck_mtx_unlock(&(_rt)->rt_lock); \ + else \ + rt_unlock(_rt); \ +} while (0) + +#define RT_ADDREF_LOCKED(_rt) do { \ + if (!rte_debug) { \ + RT_LOCK_ASSERT_HELD(_rt); \ + if (++(_rt)->rt_refcnt == 0) \ + panic("RT_ADDREF(%p) bad refcnt\n", _rt); \ + } else { \ + rtref(_rt); \ + } \ +} while (0) + +/* + * Spin variant mutex is used here; caller is responsible for + * converting any previously-held similar lock to full mutex. + */ +#define RT_ADDREF(_rt) do { \ + RT_LOCK_SPIN(_rt); \ + RT_ADDREF_LOCKED(_rt); \ + RT_UNLOCK(_rt); \ +} while (0) + +#define RT_REMREF_LOCKED(_rt) do { \ + if (!rte_debug) { \ + RT_LOCK_ASSERT_HELD(_rt); \ + if ((_rt)->rt_refcnt == 0) \ + panic("RT_REMREF(%p) bad refcnt\n", _rt); \ + --(_rt)->rt_refcnt; \ + } else { \ + (void) rtunref(_rt); \ + } \ +} while (0) + +/* + * Spin variant mutex is used here; caller is responsible for + * converting any previously-held similar lock to full mutex. + */ +#define RT_REMREF(_rt) do { \ + RT_LOCK_SPIN(_rt); \ + RT_REMREF_LOCKED(_rt); \ + RT_UNLOCK(_rt); \ +} while (0) + +#define RTFREE(_rt) rtfree(_rt) +#define RTFREE_LOCKED(_rt) rtfree_locked(_rt) + +extern struct route_cb route_cb; +extern struct radix_node_head *rt_tables[AF_MAX+1]; +__private_extern__ lck_mtx_t *rnh_lock; +__private_extern__ int use_routegenid; +__private_extern__ uint32_t route_generation; +__private_extern__ int rttrash; +__private_extern__ unsigned int rte_debug; + +struct ifmultiaddr; +struct proc; + +extern void route_init(void) __attribute__((section("__TEXT, initcode"))); +extern void routegenid_update(void); +extern void rt_ifmsg(struct ifnet *); +extern void rt_missmsg(int, struct rt_addrinfo *, int, int); +extern void rt_newaddrmsg(int, struct ifaddr *, int, struct rtentry *); +extern void rt_newmaddrmsg(int, struct ifmultiaddr *); +extern int rt_setgate(struct rtentry *, struct sockaddr *, struct sockaddr *); +extern void set_primary_ifscope(unsigned int); +extern unsigned int get_primary_ifscope(void); +extern boolean_t rt_inet_default(struct rtentry *, struct sockaddr *); +extern struct rtentry *rt_lookup(boolean_t, struct sockaddr *, + struct sockaddr *, struct radix_node_head *, unsigned int); +extern void rtalloc(struct route *); +extern void rtalloc_ign(struct route *, uint32_t); +extern void rtalloc_ign_locked(struct route *, uint32_t); +extern void rtalloc_scoped_ign(struct route *, uint32_t, unsigned int); +extern void rtalloc_scoped_ign_locked(struct route *, uint32_t, unsigned int); +extern struct rtentry *rtalloc1(struct sockaddr *, int, uint32_t); +extern struct rtentry *rtalloc1_locked(struct sockaddr *, int, uint32_t); +extern struct rtentry *rtalloc1_scoped(struct sockaddr *, int, uint32_t, + unsigned int); +extern struct rtentry *rtalloc1_scoped_locked(struct sockaddr *, int, + uint32_t, unsigned int); +extern void rtfree(struct rtentry *); +extern void rtfree_locked(struct rtentry *); +extern void rtref(struct rtentry *); +/* + * rtunref will decrement the refcount, rtfree will decrement and free if + * the refcount has reached zero and the route is not up. + * Unless you have good reason to do otherwise, use rtfree. + */ +extern int rtunref(struct rtentry *); +extern void rtsetifa(struct rtentry *, struct ifaddr *); +extern int rtinit(struct ifaddr *, int, int); +extern int rtinit_locked(struct ifaddr *, int, int); +extern int rtioctl(unsigned long, caddr_t, struct proc *); +extern void rtredirect(struct ifnet *, struct sockaddr *, struct sockaddr *, + struct sockaddr *, int, struct sockaddr *, struct rtentry **); +extern int rtrequest(int, struct sockaddr *, + struct sockaddr *, struct sockaddr *, int, struct rtentry **); +extern int rtrequest_locked(int, struct sockaddr *, + struct sockaddr *, struct sockaddr *, int, struct rtentry **); +extern int rtrequest_scoped_locked(int, struct sockaddr *, struct sockaddr *, + struct sockaddr *, int, struct rtentry **, unsigned int); +extern unsigned int sa_get_ifscope(struct sockaddr *); +extern void rt_lock(struct rtentry *, boolean_t); +extern void rt_unlock(struct rtentry *); +extern struct sockaddr *rtm_scrub_ifscope(int, struct sockaddr *, + struct sockaddr *, struct sockaddr_storage *); +#endif /* KERNEL_PRIVATE */ + +#endif diff --git a/Coding_iOS/Util/EADeviceToServerLog/NSData+gzip.h b/Coding_iOS/Util/EADeviceToServerLog/NSData+gzip.h new file mode 100644 index 000000000..f1271369b --- /dev/null +++ b/Coding_iOS/Util/EADeviceToServerLog/NSData+gzip.h @@ -0,0 +1,14 @@ +// +// NSData+gzip.h +// CodingMart +// +// Created by Ease on 2016/11/30. +// Copyright © 2016年 net.coding. All rights reserved. +// + +#import + +@interface NSData (gzip) ++ (NSData *)ungzipData:(NSData *)compressedData; ++ (NSData*)gzipData:(NSData*)pUncompressedData; +@end diff --git a/Coding_iOS/Util/EADeviceToServerLog/NSData+gzip.m b/Coding_iOS/Util/EADeviceToServerLog/NSData+gzip.m new file mode 100644 index 000000000..a805aaf85 --- /dev/null +++ b/Coding_iOS/Util/EADeviceToServerLog/NSData+gzip.m @@ -0,0 +1,161 @@ +// +// NSData+gzip.m +// CodingMart +// +// Created by Ease on 2016/11/30. +// Copyright © 2016年 net.coding. All rights reserved. +// + +#import "NSData+gzip.h" +#import +//libbz2.1.0 +@implementation NSData (gzip) ++ (NSData *)ungzipData:(NSData *)compressedData +{ + if ([compressedData length] == 0) + return compressedData; + + unsigned full_length = (unsigned int)[compressedData length]; + unsigned half_length = (unsigned int)([compressedData length] / 2); + + NSMutableData *decompressed = [NSMutableData dataWithLength: full_length + half_length]; + BOOL done = NO; + int status; + + z_stream strm; + strm.next_in = (Bytef *)[compressedData bytes]; + strm.avail_in = (unsigned int)[compressedData length]; + strm.total_out = 0; + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + if (inflateInit2(&strm, (15+32)) != Z_OK) + return nil; + + while (!done) { + // Make sure we have enough room and reset the lengths. + if (strm.total_out >= [decompressed length]) { + [decompressed increaseLengthBy: half_length]; + } + strm.next_out = [decompressed mutableBytes] + strm.total_out; + strm.avail_out = (unsigned int)([decompressed length] - strm.total_out); + // Inflate another chunk. + status = inflate (&strm, Z_SYNC_FLUSH); + if (status == Z_STREAM_END) { + done = YES; + } else if (status != Z_OK) { + break; + } + } + + if (inflateEnd (&strm) != Z_OK) + return nil; + // Set real length. + if (done) { + [decompressed setLength: strm.total_out]; + return [NSData dataWithData: decompressed]; + } + return nil; +} + ++ (NSData*)gzipData:(NSData*)pUncompressedData +{ + if (!pUncompressedData || [pUncompressedData length] == 0) + { + NSLog(@"%s: Error: Can't compress an empty or null NSData object.", __func__); + return nil; + } + + z_stream zlibStreamStruct; + zlibStreamStruct.zalloc = Z_NULL; // Set zalloc, zfree, and opaque to Z_NULL so + zlibStreamStruct.zfree = Z_NULL; // that when we call deflateInit2 they will be + zlibStreamStruct.opaque = Z_NULL; // updated to use default allocation functions. + zlibStreamStruct.total_out = 0; // Total number of output bytes produced so far + zlibStreamStruct.next_in = (Bytef*)[pUncompressedData bytes]; // Pointer to input bytes + zlibStreamStruct.avail_in = (unsigned int)[pUncompressedData length]; // Number of input bytes left to process + + int initError = deflateInit2(&zlibStreamStruct, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY); + if (initError != Z_OK) + { + NSString *errorMsg = nil; + switch (initError) + { + case Z_STREAM_ERROR: + errorMsg = @"Invalid parameter passed in to function."; + break; + case Z_MEM_ERROR: + errorMsg = @"Insufficient memory."; + break; + case Z_VERSION_ERROR: + errorMsg = @"The version of zlib.h and the version of the library linked do not match."; + break; + default: + errorMsg = @"Unknown error code."; + break; + } + NSLog(@"%s: deflateInit2() Error: \"%@\" Message: \"%s\"", __func__, errorMsg, zlibStreamStruct.msg); + + return nil; + } + + // Create output memory buffer for compressed data. The zlib documentation states that + // destination buffer size must be at least 0.1% larger than avail_in plus 12 bytes. + NSMutableData *compressedData = [NSMutableData dataWithLength:[pUncompressedData length] * 1.01 + 12]; + + int deflateStatus; + do + { + // Store location where next byte should be put in next_out + zlibStreamStruct.next_out = [compressedData mutableBytes] + zlibStreamStruct.total_out; + + // Calculate the amount of remaining free space in the output buffer + // by subtracting the number of bytes that have been written so far + // from the buffer's total capacity + zlibStreamStruct.avail_out = (unsigned int)([compressedData length] - zlibStreamStruct.total_out); + deflateStatus = deflate(&zlibStreamStruct, Z_FINISH); + + } while ( deflateStatus == Z_OK ); + + // Check for zlib error and convert code to usable error message if appropriate + if (deflateStatus != Z_STREAM_END) + { + NSString *errorMsg = nil; + switch (deflateStatus) + { + case Z_ERRNO: + errorMsg = @"Error occured while reading file."; + break; + case Z_STREAM_ERROR: + errorMsg = @"The stream state was inconsistent (e.g., next_in or next_out was NULL)."; + break; + case Z_DATA_ERROR: + errorMsg = @"The deflate data was invalid or incomplete."; + break; + case Z_MEM_ERROR: + errorMsg = @"Memory could not be allocated for processing."; + break; + case Z_BUF_ERROR: + errorMsg = @"Ran out of output buffer for writing compressed bytes."; + break; + case Z_VERSION_ERROR: + errorMsg = @"The version of zlib.h and the version of the library linked do not match."; + break; + default: + errorMsg = @"Unknown error code."; + break; + } + DebugLog(@"%s: zlib error while attempting compression: \"%@\" Message: \"%s\"", __func__, errorMsg, zlibStreamStruct.msg); + + // Free data structures that were dynamically created for the stream. + deflateEnd(&zlibStreamStruct); + + return nil; + } + // Free data structures that were dynamically created for the stream. + deflateEnd(&zlibStreamStruct); + [compressedData setLength: zlibStreamStruct.total_out]; + DebugLog(@"%s: Compressed file from %lu KB to %lu KB", __func__, [pUncompressedData length]/1024, [compressedData length]/1024); + + return compressedData; +} + +@end diff --git a/Coding_iOS/Util/Manager/CodingNetAPIClient.h b/Coding_iOS/Util/Manager/CodingNetAPIClient.h index aec2639de..f9fd65778 100755 --- a/Coding_iOS/Util/Manager/CodingNetAPIClient.h +++ b/Coding_iOS/Util/Manager/CodingNetAPIClient.h @@ -28,6 +28,11 @@ typedef NS_ENUM(NSInteger, IllegalContentType) { + (id)sharedJsonClient; + (id)changeJsonClient; ++ (id)changeSharedJsonClient; ++ (id)e_JsonClient; ++ (id)changeE_JsonClient; + + - (void)requestJsonDataWithPath:(NSString *)aPath withParams:(NSDictionary*)params withMethodType:(NetworkMethod)method @@ -54,6 +59,14 @@ typedef NS_ENUM(NSInteger, IllegalContentType) { failureBlock:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure progerssBlock:(void (^)(CGFloat progressValue))progress; +- (void)uploadAssets:(NSArray *)assets + path:(NSString *)path + name:(NSString *)name + params:(NSDictionary *)params + successBlock:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success + failureBlock:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure + progerssBlock:(void (^)(CGFloat progressValue))progress; + - (void)uploadVoice:(NSString *)file withPath:(NSString *)path withParams:(NSDictionary*)params diff --git a/Coding_iOS/Util/Manager/CodingNetAPIClient.m b/Coding_iOS/Util/Manager/CodingNetAPIClient.m index eb264a65a..811c54d05 100755 --- a/Coding_iOS/Util/Manager/CodingNetAPIClient.m +++ b/Coding_iOS/Util/Manager/CodingNetAPIClient.m @@ -14,7 +14,9 @@ @implementation CodingNetAPIClient static CodingNetAPIClient *_sharedClient = nil; +static CodingNetAPIClient *_eClient = nil; static dispatch_once_t onceToken; +static dispatch_once_t e_Token; + (CodingNetAPIClient *)sharedJsonClient { dispatch_once(&onceToken, ^{ @@ -28,6 +30,23 @@ + (id)changeJsonClient{ return _sharedClient; } ++ (id)changeSharedJsonClient{ + _sharedClient = [[CodingNetAPIClient alloc] initWithBaseURL:[NSURL URLWithString:[NSObject baseURLStr]]]; + return _sharedClient; +} + ++ (CodingNetAPIClient *)e_JsonClient { + dispatch_once(&e_Token, ^{ + _eClient = [[CodingNetAPIClient alloc] initWithBaseURL:[NSURL URLWithString:[NSObject e_URLStr]]]; + }); + return _eClient; +} + ++ (id)changeE_JsonClient{ + _eClient = [[CodingNetAPIClient alloc] initWithBaseURL:[NSURL URLWithString:[NSObject e_URLStr]]]; + return _eClient; +} + - (id)initWithBaseURL:(NSURL *)url { self = [super initWithBaseURL:url]; if (!self) { @@ -59,9 +78,20 @@ - (void)requestJsonDataWithPath:(NSString *)aPath if (!aPath || aPath.length <= 0) { return; } + //CSRF - 跨站请求伪造 + NSHTTPCookie *_CSRF = nil; + for (NSHTTPCookie *tempC in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]) { + if ([tempC.name isEqualToString:@"XSRF-TOKEN"]) { + _CSRF = tempC; + } + } + if (_CSRF) { + [self.requestSerializer setValue:_CSRF.value forHTTPHeaderField:@"X-XSRF-TOKEN"]; + } //log请求数据 DebugLog(@"\n===========request===========\n%@\n%@:\n%@", kNetworkMethodName[method], aPath, params); - aPath = [aPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + aPath = [aPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];//卧槽了,有些把 params 放在 path 里面的 GET 方法 +// aPath = [aPath stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLPathAllowedCharacterSet]; // 发起请求 switch (method) { case Get:{ @@ -92,8 +122,8 @@ - (void)requestJsonDataWithPath:(NSString *)aPath } } failure:^(AFHTTPRequestOperation *operation, NSError *error) { DebugLog(@"\n===========response===========\n%@:\n%@\n%@", aPath, error, operation.responseString); - !autoShowError || [NSObject showError:error]; id responseObject = [NSObject loadResponseWithPath:localPath]; + !autoShowError || (error.code == NSURLErrorNotConnectedToInternet && responseObject != nil) || [NSObject showError:error]; block(responseObject, error); }]; break;} @@ -151,8 +181,9 @@ - (void)requestJsonDataWithPath:(NSString *)aPath -(void)requestJsonDataWithPath:(NSString *)aPath file:(NSDictionary *)file withParams:(NSDictionary *)params withMethodType:(NetworkMethod)method andBlock:(void (^)(id, NSError *))block{ //log请求数据 DebugLog(@"\n===========request===========\n%@:\n%@", aPath, params); - aPath = [aPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; - +// aPath = [aPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + aPath = [aPath stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLPathAllowedCharacterSet]; + // Data NSData *data; NSString *name, *fileName; @@ -227,17 +258,133 @@ - (void)uploadImage:(UIImage *)image path:(NSString *)path name:(NSString *)name successBlock:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failureBlock:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure progerssBlock:(void (^)(CGFloat progressValue))progress{ + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + NSData *data = [image dataForCodingUpload]; + [self p_uploadImageData:data path:path name:name successBlock:success failureBlock:failure progerssBlock:progress]; + }); + +// NSData *data = [image dataForCodingUpload]; +// NSString *fileName = [NSString stringWithFormat:@"%@_%@.jpg", [Login curLoginUser].global_key, [NSUUID UUID].UUIDString]; +// DebugLog(@"\nuploadImageSize\n%@ : %.0f", fileName, (float)data.length/1024); +// +// __weak typeof(self) weakSelf = self; +// void (^uploadBlock)(NSDictionary *) = ^(NSDictionary *uploadParams){ +// AFHTTPRequestOperation *operation = [weakSelf POST:path parameters:uploadParams constructingBodyWithBlock:^(id formData) { +// [formData appendPartWithFileData:data name:name fileName:fileName mimeType:@"image/jpeg"]; +// } success:^(AFHTTPRequestOperation *operation, id responseObject) { +// DebugLog(@"Success: %@ ***** %@", operation.responseString, responseObject); +// id error = [self handleResponse:responseObject]; +// if (error && failure) { +// failure(operation, error); +// }else{ +// success(operation, responseObject); +// } +// } failure:^(AFHTTPRequestOperation *operation, NSError *error) { +// DebugLog(@"Error: %@ ***** %@", operation.responseString, error); +// if (failure) { +// failure(operation, error); +// } +// }]; +// [operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) { +// CGFloat progressValue = (float)totalBytesWritten/(float)totalBytesExpectedToWrite; +// if (progress) { +// progress(progressValue); +// } +// }]; +// [operation start]; +// }; +// if ([path isEqualToString:@"https://up.qbox.me/"]) {//先拿 token +// NSDictionary *params = @{ +// @"fileName": fileName, +// @"fileSize": @(data.length) +// }; +// [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:@"api/upload_token/public/images" withParams:params withMethodType:Get andBlock:^(id data, NSError *error) { +// if (data) { +// NSDictionary *result = data[@"data"]; +// NSMutableDictionary *uploadParams = @{}.mutableCopy; +// uploadParams[@"token"] = result[@"uptoken"]; +// uploadParams[@"x:time"] = result[@"time"]; +// uploadParams[@"x:authToken"] = result[@"authToken"]; +// uploadParams[@"x:userId"] = result[@"userId"]; +// uploadParams[@"key"] = fileName; +// uploadBlock(uploadParams); +// } +// }]; +// }else{ +// uploadBlock(nil); +// } +} - NSData *data = [image dataForCodingUpload]; +- (void)p_uploadImageData:(NSData *)data path:(NSString *)path name:(NSString *)name + successBlock:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success + failureBlock:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure + progerssBlock:(void (^)(CGFloat progressValue))progress{ - NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; - formatter.dateFormat = @"yyyyMMddHHmmss"; - NSString *str = [formatter stringFromDate:[NSDate date]]; - NSString *fileName = [NSString stringWithFormat:@"%@_%@.jpg", [Login curLoginUser].global_key, str]; + NSString *fileName = [NSString stringWithFormat:@"%@_%@.jpg", [Login curLoginUser].global_key, [NSUUID UUID].UUIDString]; DebugLog(@"\nuploadImageSize\n%@ : %.0f", fileName, (float)data.length/1024); + + __weak typeof(self) weakSelf = self; + void (^uploadBlock)(NSDictionary *) = ^(NSDictionary *uploadParams){ + AFHTTPRequestOperation *operation = [weakSelf POST:path parameters:uploadParams constructingBodyWithBlock:^(id formData) { + [formData appendPartWithFileData:data name:name fileName:fileName mimeType:@"image/jpeg"]; + } success:^(AFHTTPRequestOperation *operation, id responseObject) { + DebugLog(@"Success: %@ ***** %@", operation.responseString, responseObject); + id error = [self handleResponse:responseObject]; + if (error && failure) { + failure(operation, error); + }else{ + success(operation, responseObject); + } + } failure:^(AFHTTPRequestOperation *operation, NSError *error) { + DebugLog(@"Error: %@ ***** %@", operation.responseString, error); + if (failure) { + failure(operation, error); + } + }]; + [operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) { + CGFloat progressValue = (float)totalBytesWritten/(float)totalBytesExpectedToWrite; + if (progress) { + progress(progressValue); + } + }]; + [operation start]; + }; + if ([path isEqualToString:@"https://up.qbox.me/"]) {//先拿 token + NSDictionary *params = @{ + @"fileName": fileName, + @"fileSize": @(data.length) + }; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:@"api/upload_token/public/images" withParams:params withMethodType:Get andBlock:^(id data, NSError *error) { + if (data) { + NSDictionary *result = data[@"data"]; + NSMutableDictionary *uploadParams = @{}.mutableCopy; + uploadParams[@"token"] = result[@"uptoken"]; + uploadParams[@"x:time"] = result[@"time"]; + uploadParams[@"x:authToken"] = result[@"authToken"]; + uploadParams[@"x:userId"] = result[@"userId"]; + uploadParams[@"key"] = fileName; + uploadBlock(uploadParams); + } + }]; + }else{ + uploadBlock(nil); + } +} - AFHTTPRequestOperation *operation = [self POST:path parameters:nil constructingBodyWithBlock:^(id formData) { - [formData appendPartWithFileData:data name:name fileName:fileName mimeType:@"image/jpeg"]; +- (void)uploadAssets:(NSArray *)assets + path:(NSString *)path + name:(NSString *)name + params:(NSDictionary *)params + successBlock:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success + failureBlock:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure + progerssBlock:(void (^)(CGFloat progressValue))progress{ + AFHTTPRequestOperation *operation = [self POST:path parameters:params constructingBodyWithBlock:^(id formData) { + for (PHAsset *asset in assets) { + NSString *fileName = asset.fileName;; + NSData *data = [asset.loadImage dataForCodingUpload]; + [formData appendPartWithFileData:data name:name fileName:fileName mimeType:@"image/jpeg"]; + } } success:^(AFHTTPRequestOperation *operation, id responseObject) { DebugLog(@"Success: %@ ***** %@", operation.responseString, responseObject); id error = [self handleResponse:responseObject]; diff --git a/Coding_iOS/Util/Manager/CodingVipTipManager.h b/Coding_iOS/Util/Manager/CodingVipTipManager.h new file mode 100644 index 000000000..303e067d8 --- /dev/null +++ b/Coding_iOS/Util/Manager/CodingVipTipManager.h @@ -0,0 +1,15 @@ +// +// CodingVipTipManager.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2017/12/26. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import + +@interface CodingVipTipManager : NSObject + ++ (void)showTip; + +@end diff --git a/Coding_iOS/Util/Manager/CodingVipTipManager.m b/Coding_iOS/Util/Manager/CodingVipTipManager.m new file mode 100644 index 000000000..471e94f7f --- /dev/null +++ b/Coding_iOS/Util/Manager/CodingVipTipManager.m @@ -0,0 +1,130 @@ +// +// CodingVipTipManager.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2017/12/26. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "CodingVipTipManager.h" + +@interface CodingVipTipManager () +@property (strong, nonatomic) NSString *title, *imageName; + +@property (strong, nonatomic) UIView *bgView, *contentView; +@property (strong, nonatomic) UIImageView *logoImgV; +@property (strong, nonatomic) UILabel *titleL; +@property (strong, nonatomic) UIButton *closeBtn; + +@end + +@implementation CodingVipTipManager ++ (instancetype)shareManager{ + static CodingVipTipManager *shared_manager = nil; + static dispatch_once_t pred; + dispatch_once(&pred, ^{ + shared_manager = [[self alloc] init]; + }); + return shared_manager; +} + ++ (void)showTip{ + CodingVipTipManager *manager = [self shareManager]; + manager.title = @"恭喜你成为 Coding 银牌会员"; + manager.imageName = @"upgrade_success"; + [manager p_show]; +} + +- (instancetype)init{ + self = [super init]; + if (self) { + //层级关系 + _bgView = [UIView new]; + _contentView = [UIView new]; + + _logoImgV = [[UIImageView alloc] initWithImage:[UIImage imageNamed:_imageName]]; + _titleL = [UILabel labelWithFont:[UIFont systemFontOfSize:17] textColor:[UIColor colorWithHexString:@"0x222222"]]; + _titleL.textAlignment = NSTextAlignmentCenter; + _closeBtn = ({ + UIButton *button = [UIButton new]; + button.backgroundColor = kColorDark3; + button.cornerRadius = 4; + button.masksToBounds = YES; + button.titleLabel.font = [UIFont systemFontOfSize:17]; + [button setTitleColor:kColorWhite forState:UIControlStateNormal]; + [button setTitle:@"我知道了" forState:UIControlStateNormal]; + [button addTarget:self action:@selector(p_dismiss) forControlEvents:UIControlEventTouchUpInside]; + button; + }); + [_contentView addSubview:_logoImgV]; + [_contentView addSubview:_titleL]; + [_contentView addSubview:_closeBtn]; + [_bgView addSubview:_contentView]; + //属性设置 + _contentView.backgroundColor = kColorTableSectionBg; + _contentView.layer.masksToBounds = YES; + _contentView.layer.cornerRadius = 6; + _titleL.numberOfLines = 0; + //位置大小 + [_contentView mas_makeConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo(300); + make.centerX.equalTo(_bgView); + make.centerY.equalTo(_bgView).offset(-20); + }]; + [_logoImgV mas_makeConstraints:^(MASConstraintMaker *make) { + make.size.mas_equalTo(CGSizeMake(132, 109)); + make.centerX.equalTo(_contentView); + make.top.equalTo(_contentView).mas_offset(30); + }]; + [_titleL mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(_logoImgV.mas_bottom).offset(30); + make.left.equalTo(_contentView).offset(15); + make.right.equalTo(_contentView).offset(-15); + }]; + [_closeBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(_contentView); + make.top.equalTo(_titleL.mas_bottom).offset(30); + make.bottom.equalTo(_contentView).offset(-30); + make.size.mas_equalTo(CGSizeMake(120, 44)); + }]; + //关联事件 + [_bgView bk_whenTapped:^{ + [self p_dismiss]; + }]; + } + return self; +} + +- (void)setTitle:(NSString *)title{ + _title = title; + _titleL.text = _title; +} + +- (void)setImageName:(NSString *)imageName{ + _imageName = imageName; + _logoImgV.image = [UIImage imageNamed:_imageName]; +} + +- (void)p_show{ + //初始状态 + _bgView.backgroundColor = [UIColor clearColor]; + _contentView.alpha = 0; + UIView *spV = [BaseViewController presentingVC].navigationController.view; + _bgView.frame = spV.bounds; + [spV addSubview:_bgView]; + [UIView animateWithDuration:0.3 animations:^{ + _bgView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5]; + _contentView.alpha = 1; + } completion:nil]; +} + +- (void)p_dismiss{ + [UIView animateWithDuration:0.3 animations:^{ + _bgView.backgroundColor = [UIColor clearColor]; + _contentView.alpha = 0; + } completion:^(BOOL finished) { + [_bgView removeFromSuperview]; + }]; +} + +@end diff --git a/Coding_iOS/Util/Manager/Coding_FileManager.h b/Coding_iOS/Util/Manager/Coding_FileManager.h index a91ad056a..0e615ab1a 100755 --- a/Coding_iOS/Util/Manager/Coding_FileManager.h +++ b/Coding_iOS/Util/Manager/Coding_FileManager.h @@ -18,6 +18,7 @@ @class Coding_DownloadTask; @class Coding_UploadTask; @class ProjectFile; +@class Coding_UploadParams; @protocol Coding_FileManagerDelegate; @interface Coding_FileManager : NSObject @@ -39,7 +40,7 @@ //upload -+ (BOOL)writeUploadDataWithName:(NSString *)fileName andAsset:(ALAsset *)asset; ++ (BOOL)writeUploadDataWithName:(NSString *)fileName andAsset:(PHAsset *)asset; + (BOOL)writeUploadDataWithName:(NSString *)fileName andImage:(UIImage *)image; + (BOOL)deleteUploadDataWithName:(NSString *)fileName; @@ -48,6 +49,8 @@ + (void)cancelCUploadTaskForFile:(NSString *)diskFileName hasError:(BOOL)hasError; + (NSArray *)uploadFilesInProject:(NSString *)project_id andFolder:(NSString *)folder_id; +- (void)addUploadTaskWithFileName:(NSString *)fileName isQuick:(BOOL)isQuick resultBlock:(void (^)(Coding_UploadTask *uploadTask))block; + - (Coding_UploadTask *)addUploadTaskWithFileName:(NSString *)fileName projectIsPublic:(BOOL)is_public; @end @@ -66,3 +69,16 @@ + (Coding_UploadTask *)cUploadTaskWithTask:(NSURLSessionUploadTask *)task progress:(NSProgress *)progress fileName:(NSString *)fileName; - (void)cancel; @end + + +@interface Coding_UploadParams : NSObject +@property (strong, nonatomic) NSString *fileName, *authToken, *time, *uptoken, *fullName; +@property (strong, nonatomic) NSNumber *projectId, *fileSize, *userId, *dir; +@property (assign, nonatomic) BOOL isQuick; + ++ (instancetype)instanceWithFileName:(NSString *)fileName; +- (void)configWithFileName:(NSString *)fileName; +- (NSDictionary *)toTokenParams; +- (NSURL *)filePathUrl; +- (NSDictionary *)toUploadParams; +@end diff --git a/Coding_iOS/Util/Manager/Coding_FileManager.m b/Coding_iOS/Util/Manager/Coding_FileManager.m index 46b2d11d0..ac2741ef3 100755 --- a/Coding_iOS/Util/Manager/Coding_FileManager.m +++ b/Coding_iOS/Util/Manager/Coding_FileManager.m @@ -7,6 +7,8 @@ // #import "Coding_FileManager.h" +#import "Login.h" +#import "CodingNetAPIClient.h" @interface Coding_FileManager () @@ -64,16 +66,23 @@ - (instancetype)init + (NSString *)downloadPath{ NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; - NSString *downloadPath = [documentPath stringByAppendingPathComponent:@"Coding_Download"]; + NSString *pathComponent = kTarget_Enterprise? [NSString stringWithFormat:@"%@_Coding_Download", [self p_loginPrefix]]: @"Coding_Download"; + NSString *downloadPath = [documentPath stringByAppendingPathComponent:pathComponent]; return downloadPath; } + (NSString *)uploadPath{ NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; - NSString *uploadPath = [documentPath stringByAppendingPathComponent:@"Coding_Upload"]; + NSString *pathComponent = kTarget_Enterprise? [NSString stringWithFormat:@"%@_Coding_Upload", [self p_loginPrefix]]: @"Coding_Upload"; + NSString *uploadPath = [documentPath stringByAppendingPathComponent:pathComponent]; return uploadPath; } ++ (NSString *)p_loginPrefix{ + NSString *loginPrefix = [NSString stringWithFormat:@"%@_%@", [NSObject baseCompany], [Login curLoginUser].global_key ?: @""]; + return loginPrefix; +} + + (BOOL)createFolder:(NSString *)path{ BOOL isDir = NO; NSFileManager *fileManager = [NSFileManager defaultManager]; @@ -130,8 +139,7 @@ + (NSString *)keyStrFromResponse:(NSURLResponse *)response{ if (!response) { return nil; } - NSString *keyStr = response.URL.absoluteString; - keyStr = [[[[keyStr componentsSeparatedByString:@"?download"] firstObject] componentsSeparatedByString:@"/"] lastObject]; + NSString *keyStr = [response.URL.path componentsSeparatedByString:@"/"].lastObject; return keyStr; } + (Coding_DownloadTask *)cDownloadTaskForResponse:(NSURLResponse *)response{ @@ -164,7 +172,7 @@ - (Coding_DownloadTask *)addDownloadTaskWithPath:(NSString *)downloadPath NSURLRequest *request = [NSURLRequest requestWithURL:downloadURL]; NSURLSessionDownloadTask *downloadTask = [self.af_manager downloadTaskWithRequest:request progress:&progress destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) { NSURL *downloadUrl = [[Coding_FileManager sharedManager] urlForDownloadFolder]; - Coding_DownloadTask *cDownloadTask = [Coding_FileManager cDownloadTaskForResponse:response]; + Coding_DownloadTask *cDownloadTask = [Coding_FileManager cDownloadTaskForKey:storage_key] ?: [Coding_FileManager cDownloadTaskForResponse:response]; if (cDownloadTask) { downloadUrl = [downloadUrl URLByAppendingPathComponent:cDownloadTask.diskFileName]; }else{ @@ -178,6 +186,8 @@ - (Coding_DownloadTask *)addDownloadTaskWithPath:(NSString *)downloadPath [Coding_FileManager cancelCDownloadTaskForKey:storage_key]; }else{ [Coding_FileManager cancelCDownloadTaskForResponse:response]; + + [MobClick event:kUmeng_Event_File label:@"文件_下载成功"]; } if (completionHandler) { completionHandler(response, filePath, error); @@ -190,7 +200,7 @@ - (Coding_DownloadTask *)addDownloadTaskWithPath:(NSString *)downloadPath } #pragma upload -+ (BOOL)writeUploadDataWithName:(NSString *)fileName andAsset:(ALAsset *)asset{ ++ (BOOL)writeUploadDataWithName:(NSString *)fileName andAsset:(PHAsset *)asset{ if (![self createFolder:[self uploadPath]]) { return NO; } @@ -201,25 +211,7 @@ + (BOOL)writeUploadDataWithName:(NSString *)fileName andAsset:(ALAsset *)asset{ if (!handle) { return NO; } - static const NSUInteger BufferSize = 1024*1024; - - ALAssetRepresentation *rep = [asset defaultRepresentation]; - uint8_t *buffer = calloc(BufferSize, sizeof(*buffer)); - NSUInteger offset = 0, bytesRead = 0; - - do { - @try { - bytesRead = [rep getBytes:buffer fromOffset:offset length:BufferSize error:nil]; - [handle writeData:[NSData dataWithBytesNoCopy:buffer length:bytesRead freeWhenDone:NO]]; - offset += bytesRead; - } @catch (NSException *exception) { - free(buffer); - - return NO; - } - } while (bytesRead > 0); - - free(buffer); + [handle writeData:asset.loadImageData]; return YES; } + (BOOL)writeUploadDataWithName:(NSString *)fileName andImage:(UIImage *)image{ @@ -234,11 +226,90 @@ + (BOOL)deleteUploadDataWithName:(NSString *)fileName{ NSString *filePath = [[self uploadPath] stringByAppendingPathComponent:fileName]; NSFileManager *fm = [NSFileManager defaultManager]; if ([fm fileExistsAtPath:filePath]) { - return [fm removeItemAtPath:fileName error:nil]; + return [fm removeItemAtPath:filePath error:nil]; }else{ return YES; } } + + +- (void)addUploadTaskWithFileName:(NSString *)fileName isQuick:(BOOL)isQuick resultBlock:(void (^)(Coding_UploadTask *uploadTask))block{ + Coding_UploadParams *base_params = [Coding_UploadParams instanceWithFileName:fileName]; + if (!base_params) { + block(nil); + return; + } + __weak typeof(self) weakSelf = self; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:@"api/upload_token" withParams:[base_params toTokenParams] withMethodType:Get andBlock:^(id data, NSError *error) { + if (data) { + Coding_UploadParams *params = [NSObject objectOfClass:@"Coding_UploadParams" fromJSON:data[@"data"]]; + [params configWithFileName:fileName]; + params.isQuick = isQuick; + block([weakSelf p_addUploadTaskWithParams:params]); + } + }]; +} + +- (Coding_UploadTask *)p_addUploadTaskWithParams:(Coding_UploadParams *)params{ + NSString *fileName = params.fullName; + NSString *name = params.fileName; + NSURL *filePathUrl = [params filePathUrl]; + + NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:@"https://up.qbox.me/" parameters:[params toUploadParams] constructingBodyWithBlock:^(id formData) { + [formData appendPartWithFileURL:filePathUrl name:@"file" fileName:name mimeType:@"image/jpeg, image/png, image/gif" error:nil]; + } error:nil]; + + [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"上传文件"]; + + NSProgress *progress = nil; + NSURLSessionUploadTask *uploadTask = [self.af_manager uploadTaskWithStreamedRequest:request progress:&progress completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) { + Coding_FileManager *manager = [Coding_FileManager sharedManager]; + if (!error) { + error = [manager handleResponse:responseObject]; + } + response = response? response: [[NSURLResponse alloc] init]; + if (error){ + [NSObject showError:error]; + [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationUploadCompled object:manager userInfo:@{@"response" : response, + @"error" : error}]; + }else if (responseObject) { + [MobClick event:kUmeng_Event_File label:@"文件_上传成功"]; + + responseObject = [responseObject valueForKey:@"data"]; + + if ([responseObject isKindOfClass:[NSString class]]) { + //处理completionHandler + [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationUploadCompled object:manager userInfo:@{@"response" : response, + @"data" : responseObject}]; + }else{ + ProjectFile *curFile = [NSObject objectOfClass:@"ProjectFile" fromJSON:responseObject]; + NSString *block_fileName = [NSString stringWithFormat:@"%@|||%@|||%@", curFile.project_id.stringValue, curFile.parent_id.stringValue, curFile.name]; + NSString *block_filePath = [[[manager class] uploadPath] stringByAppendingPathComponent:block_fileName]; + + //移动文件到已下载 + NSString *diskFilePath = [[[manager class] downloadPath] stringByAppendingPathComponent:curFile.diskFileName]; + [[NSFileManager defaultManager] moveItemAtPath:block_filePath toPath:diskFilePath error:nil]; + [manager directoryDidChange:manager.docUploadWatcher]; + [manager directoryDidChange:manager.docDownloadWatcher]; + DebugLog(@"upload_fileName------\n%@", block_fileName); + + //移除任务 + [Coding_FileManager cancelCUploadTaskForFile:block_fileName hasError:(error != nil)]; + + //处理completionHandler + [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationUploadCompled object:manager userInfo:@{@"response" : response, + @"data" : curFile}]; + } + } + }]; + + [uploadTask resume]; + Coding_UploadTask *cUploadTask = [Coding_UploadTask cUploadTaskWithTask:uploadTask progress:progress fileName:fileName]; + [self.uploadDict setObject:cUploadTask forKey:fileName]; + + return cUploadTask; +} + - (Coding_UploadTask *)addUploadTaskWithFileName:(NSString *)fileName projectIsPublic:(BOOL)is_public{ if (!fileName) { return nil; @@ -279,7 +350,6 @@ - (Coding_UploadTask *)addUploadTaskWithFileName:(NSString *)fileName projectIsP [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationUploadCompled object:manager userInfo:@{@"response" : response, @"error" : error}]; }else if (responseObject) { - NSString *block_project_id = [[[[response.URL.absoluteString componentsSeparatedByString:@"/project/"] lastObject] componentsSeparatedByString:@"/"] firstObject]; responseObject = [responseObject valueForKey:@"data"]; if ([responseObject isKindOfClass:[NSString class]]) { @@ -288,12 +358,11 @@ - (Coding_UploadTask *)addUploadTaskWithFileName:(NSString *)fileName projectIsP @"data" : responseObject}]; }else{ ProjectFile *curFile = [NSObject objectOfClass:@"ProjectFile" fromJSON:responseObject]; - NSString *block_fileName = [NSString stringWithFormat:@"%@|||%@|||%@", block_project_id, curFile.parent_id.stringValue, curFile.name]; + NSString *block_fileName = [NSString stringWithFormat:@"%@|||%@|||%@", curFile.project_id.stringValue, curFile.parent_id.stringValue, curFile.name]; NSString *block_filePath = [[[manager class] uploadPath] stringByAppendingPathComponent:block_fileName]; //移动文件到已下载 - NSString *diskFileName = [NSString stringWithFormat:@"%@|||%@|||%@|%@", curFile.name, block_project_id, curFile.storage_type, curFile.storage_key]; - NSString *diskFilePath = [[[manager class] downloadPath] stringByAppendingPathComponent:diskFileName]; + NSString *diskFilePath = [[[manager class] downloadPath] stringByAppendingPathComponent:curFile.diskFileName]; [[NSFileManager defaultManager] moveItemAtPath:block_filePath toPath:diskFilePath error:nil]; [manager directoryDidChange:manager.docUploadWatcher]; [manager directoryDidChange:manager.docDownloadWatcher]; @@ -424,4 +493,59 @@ - (void)cancel{ } } -@end \ No newline at end of file +@end + +@implementation Coding_UploadParams + ++ (instancetype)instanceWithFileName:(NSString *)fileName{ + if ([fileName componentsSeparatedByString:@"|||"].count != 3 || + ![[NSFileManager defaultManager] fileExistsAtPath:[[Coding_FileManager uploadPath] stringByAppendingPathComponent:fileName]]) { + return nil; + } + Coding_UploadParams *params = [self new]; + [params configWithFileName:fileName]; + return params; +} + +- (void)configWithFileName:(NSString *)fileName{ + NSArray *fileInfos = [fileName componentsSeparatedByString:@"|||"]; + if (fileInfos.count == 3) { + NSString *filePath = [[Coding_FileManager uploadPath] stringByAppendingPathComponent:fileName]; + NSFileManager *fileManager = [NSFileManager defaultManager]; + if ([fileManager fileExistsAtPath:filePath]) { + _fullName = fileName; + _projectId = fileInfos[0]; + _dir = fileInfos[1]; + _fileName = fileInfos[2]; + _fileSize = @([fileManager attributesOfItemAtPath:filePath error:nil].fileSize); + } + } +} + +- (NSDictionary *)toTokenParams{ + return @{@"projectId": _projectId ?: @"", + @"fileName": _fileName ?: @"", + @"fileSize": _fileSize ?: @""}; +} + +- (NSURL *)filePathUrl{ + NSString *filePath = [[Coding_FileManager uploadPath] stringByAppendingPathComponent:_fullName]; + NSURL *filePathUrl = [NSURL fileURLWithPath:filePath]; + return filePathUrl; +} + +- (NSDictionary *)toUploadParams{ + NSMutableDictionary *params = @{}.mutableCopy; + // params[@"key"] = _fileName; + params[@"key"] = [NSString stringWithFormat:@"%@.%@", [NSUUID UUID].UUIDString, [_fileName componentsSeparatedByString:@"."].lastObject] ; + params[@"x:dir"] = _dir; + params[@"x:projectId"] = _projectId; + params[@"token"] = _uptoken; + params[@"x:time"] = _time; + params[@"x:authToken"] = _authToken; + params[@"x:userId"] = [Login curLoginUser].id; + params[@"x:folderType"] = params[@"folderType"] = _isQuick? @1: @0; + return params; +} + +@end diff --git a/Coding_iOS/Util/Manager/Coding_NetAPIManager.h b/Coding_iOS/Util/Manager/Coding_NetAPIManager.h index 7fda62ab0..dff0b9e02 100755 --- a/Coding_iOS/Util/Manager/Coding_NetAPIManager.h +++ b/Coding_iOS/Util/Manager/Coding_NetAPIManager.h @@ -39,8 +39,16 @@ #import "Shop.h" #import "ShopOrderModel.h" #import "ProjectCount.h" +#import "ActivenessModel.h" +#import "ProjectRole.h" +#import "MRPRPreInfo.h" +#import "EACodeBranches.h" +#import "EACodeReleases.h" +#import "EABoardTaskList.h" -@class CSTopic, Team; +#import + +@class CSTopic, Team, EAWiki, TeamMember; typedef NS_ENUM(NSUInteger, VerifyType){ VerifyTypeUnknow = 0, @@ -61,10 +69,15 @@ typedef NS_ENUM(NSInteger, PurposeType) { - (void)request_UnReadCountWithBlock:(void (^)(id data, NSError *error))block; - (void)request_UnReadNotificationsWithBlock:(void (^)(id data, NSError *error))block; +#pragma mark Company +- (void)request_CompanyExist:(NSString *)company andBlock:(void (^)(id data, NSError *error))block; +- (void)request_UpdateCompanyInfoBlock:(void (^)(id data, NSError *error))block; +- (void)request_UpdateIsAdministratorBlock:(void (^)(id data, NSError *error))block; #pragma mark - Login - (void)request_Login_With2FA:(NSString *)otpCode andBlock:(void (^)(id data, NSError *error))block; - (void)request_Login_WithPath:(NSString *)path Params:(id)params andBlock:(void (^)(id data, NSError *error))block; +- (void)request_Login_With_UMSocialResponse:(UMSocialResponse *)resp andBlock:(void (^)(id data, NSError *error))block; - (void)request_Register_V2_WithParams:(NSDictionary *)params andBlock:(void (^)(id data, NSError *error))block; - (void)request_CaptchaNeededWithPath:(NSString *)path andBlock:(void (^)(id data, NSError *error))block; - (void)request_SetPasswordToPath:(NSString *)path params:(NSDictionary *)params andBlock:(void (^)(id data, NSError *error))block; @@ -83,27 +96,38 @@ typedef NS_ENUM(NSInteger, PurposeType) { - (void)request_ProjectMembers_WithObj:(Project *)project andBlock:(void (^)(id data, NSError *error))block; - (void)request_ProjectMembersHaveTasks_WithObj:(Project *)project andBlock:(void (^)(NSArray *data, NSError *error))block; - (void)request_ProjectMember_Quit:(ProjectMember *)curMember andBlock:(void (^)(id data, NSError *error))block; +- (void)request_ProjectQuit:(NSNumber *)project_id andBlock:(void (^)(id data, NSError *error))block; - (void)request_Project_Pin:(Project *)project andBlock:(void (^)(id data, NSError *error))block; - (void)request_NewProject_WithObj:(Project *)project image:(UIImage *)image andBlock:(void (^)(NSString *data, NSError *error))block; - (void)request_UpdateProject_WithObj:(Project *)project andBlock:(void (^)(Project *data, NSError *error))block; - (void)request_UpdateProject_WithObj:(Project *)project icon:(UIImage *)icon andBlock:(void (^)(id data, NSError *error))block progerssBlock:(void (^)(CGFloat progressValue))progress;; - (void)request_DeleteProject_WithObj:(Project *)project passCode:(NSString *)passCode type:(VerifyType)type andBlock:(void (^)(Project *data, NSError *error))block; +- (void)request_ArchiveProject_WithObj:(Project *)project passCode:(NSString *)passCode type:(VerifyType)type andBlock:(void (^)(Project *data, NSError *error))block; - (void)request_TransferProject:(Project *)project toUser:(User *)user passCode:(NSString *)passCode type:(VerifyType)type andBlock:(void (^)(Project *data, NSError *error))block; - (void)request_EditAliasOfMember:(ProjectMember *)curMember inProject:(Project *)curPro andBlock:(void (^)(id data, NSError *error))block; - (void)request_EditTypeOfMember:(ProjectMember *)curMember inProject:(Project *)curPro andBlock:(void (^)(id data, NSError *error))block; +- (void)request_EditTypeOfUser:(NSString *)global_key inProjects:(NSArray *)pro_id_list roles:(NSArray *)role_list andBlock:(void (^)(id data, NSError *error))block; - (void)request_ProjectServiceInfo:(Project *)curPro andBlock:(void (^)(id data, NSError *error))block; + #pragma mark Team - (void)request_JoinedTeamsBlock:(void (^)(id data, NSError *error))block; - (void)request_DetailOfTeam:(Team *)team andBlock:(void (^)(id data, NSError *error))block; +- (void)request_InfoOfTeam:(Team *)team andBlock:(void (^)(id data, NSError *error))block; - (void)request_ProjectsInTeam:(Team *)team isJoined:(BOOL)isJoined andBlock:(void (^)(id data, NSError *error))block; - (void)request_MembersInTeam:(Team *)team andBlock:(void (^)(id data, NSError *error))block; +- (void)request_UpdateTeamInfo_WithObj:(Team *)curTeam andBlock:(void (^)(id data, NSError *error))block; +- (void)request_OrderListOfTeam:(Team *)team andBlock:(void (^)(id data, NSError *error))block; +- (void)request_BillingListOfTeam:(Team *)team andBlock:(void (^)(id data, NSError *error))block; +- (void)request_EditTeamTypeOfMember:(TeamMember *)curMember andBlock:(void (^)(id data, NSError *error))block; +- (void)request_ProjectRoleOfUser:(NSString *)global_key andBlock:(void (^)(id data, NSError *error))block; +- (void)request_DeleteTeamMember:(NSString *)golbal_key passCode:(NSString *)passCode type:(VerifyType)type andBlock:(void (^)(id data, NSError *error))block; #pragma mark - MRPR - (void)request_MRPRS_WithObj:(MRPRS *)curMRPRS andBlock:(void (^)(MRPRS *data, NSError *error))block; - (void)request_MRPRBaseInfo_WithObj:(MRPR *)curMRPR andBlock:(void (^)(MRPRBaseInfo *data, NSError *error))block; -- (void)request_MRPRPreInfo_WithObj:(MRPR *)curMRPR andBlock:(void (^)(MRPRBaseInfo *data, NSError *error))block; +- (void)request_MRPRPreInfo_WithObj:(MRPR *)curMRPR andBlock:(void (^)(MRPRPreInfo *data, NSError *error))block; - (void)request_MRReviewerInfo_WithObj:(MRPR *)curMRPR andBlock:(void (^)(ReviewersInfo *data, NSError *error))block; - (void)request_MRPRCommits_WithObj:(MRPR *)curMRPR andBlock:(void (^)(NSArray *data, NSError *error))block; - (void)request_MRPRFileChanges_WithObj:(MRPR *)curMRPR andBlock:(void (^)(FileChanges *data, NSError *error))block; @@ -118,14 +142,24 @@ typedef NS_ENUM(NSInteger, PurposeType) { - (void)request_DeleteLineNoteWithPath:(NSString *)path andBlock:(void (^)(id data, NSError *error))block; #pragma mark - File + - (void)request_Folders:(ProjectFolders *)folders inProject:(Project *)project andBlock:(void (^)(id data, NSError *error))block; -- (void)request_FilesInFolder:(ProjectFolder *)folder andBlock:(void (^)(id data, NSError *error))block; -- (void)request_DeleteFolder:(ProjectFolder *)folder andBlock:(void (^)(id data, NSError *error))block; -- (void)request_RenameFolder:(ProjectFolder *)folder andBlock:(void (^)(id data, NSError *error))block; +//- (void)request_FilesInFolder:(ProjectFolder *)folder andBlock:(void (^)(id data, NSError *error))block; +//- (void)request_DeleteFolder:(ProjectFolder *)folder andBlock:(void (^)(id data, NSError *error))block; +//- (void)request_RenameFolder:(ProjectFolder *)folder andBlock:(void (^)(id data, NSError *error))block; +//- (void)request_MoveFiles:(NSArray *)fileIdList toFolder:(ProjectFolder *)folder andBlock:(void (^)(id data, NSError *error))block; +//- (void)request_MoveFolder:(NSNumber *)folderId toFolder:(ProjectFolder *)folder inProject:(Project *)project andBlock:(void (^)(id data, NSError *error))block; +//- (void)request_CreatFolder:(NSString *)fileName inFolder:(ProjectFolder *)parentFolder inProject:(Project *)project andBlock:(void (^)(id data, NSError *error))block; + +- (void)request_FoldersInFolder:(ProjectFile *)folder andBlock:(void (^)(id data, NSError *error))block; +- (void)request_FilesInFolder:(ProjectFile *)folder andBlock:(void (^)(id data, NSError *error))block; +- (void)request_DeleteFolder:(ProjectFile *)folder andBlock:(void (^)(id data, NSError *error))block; +- (void)request_RenameFolder:(ProjectFile *)folder andBlock:(void (^)(id data, NSError *error))block; +- (void)request_MoveFiles:(NSArray *)fileIdList toFolder:(ProjectFile *)folder andBlock:(void (^)(id data, NSError *error))block; +- (void)request_MoveFolder:(NSNumber *)folderId toFolder:(ProjectFile *)folder inProject:(Project *)project andBlock:(void (^)(id data, NSError *error))block; +- (void)request_CreatFolder:(NSString *)fileName inFolder:(ProjectFile *)parentFolder inProject:(Project *)project andBlock:(void (^)(id data, NSError *error))block; + - (void)request_DeleteFiles:(NSArray *)fileIdList inProject:(NSNumber *)project_id andBlock:(void (^)(id data, NSError *error))block; -- (void)request_MoveFiles:(NSArray *)fileIdList toFolder:(ProjectFolder *)folder andBlock:(void (^)(id data, NSError *error))block; -- (void)request_MoveFolder:(NSNumber *)folderId toFolder:(ProjectFolder *)folder inProject:(Project *)project andBlock:(void (^)(id data, NSError *error))block; -- (void)request_CreatFolder:(NSString *)fileName inFolder:(ProjectFolder *)parentFolder inProject:(Project *)project andBlock:(void (^)(id data, NSError *error))block; - (void)request_FileDetail:(ProjectFile *)file andBlock:(void (^)(id data, NSError *error))block; - (void)request_FileContent:(ProjectFile *)file andBlock:(void (^)(id data, NSError *error))block; - (void)request_EditFile:(ProjectFile *)file withContent:(NSString *)contentStr andBlock:(void (^)(id data, NSError *error))block; @@ -137,15 +171,42 @@ typedef NS_ENUM(NSInteger, PurposeType) { - (void)request_RemarkFileVersion:(FileVersion *)curVersion withStr:(NSString *)remarkStr andBlock:(void (^)(id data, NSError *error))block; - (void)request_DeleteFileVersion:(FileVersion *)curVersion andBlock:(void (^)(id data, NSError *error))block; - (void)request_OpenShareOfFile:(ProjectFile *)file andBlock:(void (^)(id data, NSError *error))block; -- (void)request_CloseShareHash:(NSString *)hashStr andBlock:(void (^)(id data, NSError *error))block; +- (void)request_CloseFileShareHash:(NSString *)hashStr andBlock:(void (^)(id data, NSError *error))block; + +- (void)request_OpenShareOfWiki:(EAWiki *)wiki andBlock:(void (^)(id data, NSError *error))block; +- (void)request_CloseWikiShareHash:(NSString *)hashStr andBlock:(void (^)(id data, NSError *error))block; #pragma mark - Code - (void)request_CodeTree:(CodeTree *)codeTree withPro:(Project *)project codeTreeBlock:(void (^)(id codeTreeData, NSError *codeTreeError))block; - (void)request_CodeFile:(CodeFile *)codeFile withPro:(Project *)project andBlock:(void (^)(id data, NSError *error))block; - (void)request_EditCodeFile:(CodeFile *)codeFile withPro:(Project *)project andBlock:(void (^)(id data, NSError *error))block; +- (void)request_DeleteCodeFile:(CodeFile *)codeFile withPro:(Project *)project andBlock:(void (^)(id data, NSError *error))block; - (void)request_CodeBranchOrTagWithPath:(NSString *)path withPro:(Project *)project andBlock:(void (^)(id data, NSError *error))block; - (void)request_Commits:(Commits *)curCommits withPro:(Project *)project andBlock:(void (^)(id data, NSError *error))block; - +- (void)request_UploadAssets:(NSArray *)assets inCodeTree:(CodeTree *)codeTree withPro:(Project *)project andBlock:(void (^)(id data, NSError *error))block progerssBlock:(void (^)(CGFloat progressValue))progressBlock; +- (void)request_CreateCodeFile:(CodeFile *)codeFile withPro:(Project *)project andBlock:(void (^)(id data, NSError *error))block; + +- (void)request_CodeBranches_WithObj:(EACodeBranches *)curObj andBlock:(void (^)(EACodeBranches *data, NSError *error))block; +- (void)request_DeleteCodeBranch:(CodeBranchOrTag *)curB inProject:(Project *)curP andBlock:(void (^)(id data, NSError *error))block; +- (void)request_CodeReleases_WithObj:(EACodeReleases *)curObj andBlock:(void (^)(EACodeReleases *data, NSError *error))block; +- (void)request_CodeRelease_WithObj:(EACodeRelease *)curObj andBlock:(void (^)(EACodeRelease *data, NSError *error))block; +- (void)request_DeleteCodeRelease:(EACodeRelease *)curObj andBlock:(void (^)(id data, NSError *error))block; +- (void)request_ModifyCodeRelease:(EACodeRelease *)curObj andBlock:(void (^)(EACodeRelease *data, NSError *error))block; + +#pragma mark Wiki +- (void)request_WikiListWithPro:(Project *)pro andBlock:(void (^)(id data, NSError *error))block; +- (void)request_WikiDetailWithPro:(Project *)pro iid:(NSNumber *)iid version:(NSNumber *)version andBlock:(void (^)(id data, NSError *error))block; +- (void)request_DeleteWikiWithPro:(Project *)pro iid:(NSNumber *)iid andBlock:(void (^)(id data, NSError *error))block; +- (void)request_ModifyWiki:(EAWiki *)wiki pro:(Project *)pro andBlock:(void (^)(id data, NSError *error))block; +- (void)request_WikiHistoryWithWiki:(EAWiki *)wiki pro:(Project *)pro andBlock:(void (^)(id data, NSError *error))block; +- (void)request_RevertWiki:(NSNumber *)wikiIid toVersion:(NSNumber *)version pro:(Project *)pro andBlock:(void (^)(id data, NSError *error))block; + +//- (void)request_WikiListWithProName:(NSString *)proName andBlock:(void (^)(id data, NSError *error))block; +//- (void)request_WikiDetailWithProName:(NSString *)proName iid:(NSNumber *)iid version:(NSNumber *)version andBlock:(void (^)(id data, NSError *error))block; +//- (void)request_DeleteWikiWithProName:(NSString *)proName iid:(NSNumber *)iid andBlock:(void (^)(id data, NSError *error))block; +//- (void)request_ModifyWiki:(EAWiki *)wiki proName:(NSString *)proName andBlock:(void (^)(id data, NSError *error))block; +//- (void)request_WikiHistoryWithWiki:(EAWiki *)wiki proName:(NSString *)proName andBlock:(void (^)(id data, NSError *error))block; +//- (void)request_RevertWiki:(NSNumber *)wikiIid toVersion:(NSNumber *)version proName:(NSString *)proName andBlock:(void (^)(id data, NSError *error))block; #pragma mark - Task - (void)request_AddTask:(Task *)task andBlock:(void (^)(id data, NSError *error))block; @@ -162,6 +223,22 @@ typedef NS_ENUM(NSInteger, PurposeType) { - (void)request_DoCommentToTask:(Task *)task andBlock:(void (^)(id data, NSError *error))block; - (void)request_DeleteComment:(TaskComment *)comment ofTask:(Task *)task andBlock:(void (^)(id data, NSError *error))block; - (void)request_ChangeWatcher:(User *)watcher ofTask:(Task *)task andBlock:(void (^)(id data, NSError *error))block; +- (void)request_projects_tasks_labelsWithRole:(TaskRoleType)role projectId:(NSString *)projectId andBlock:(void (^)(id data, NSError *error))block; //任务标签 +- (void)request_tasks_searchWithUserId:(NSString *)userId role:(TaskRoleType )role project_id:(NSString *)project_id keyword:(NSString *)keyword status:(NSString *)status label:(NSString *)label page:(NSInteger)page andBlock:(void (^)(id data, NSError *error))block; +- (void)request_project_tasks_countWithProjectId:(NSString *)projectId andBlock:(void (^)(id data, NSError *error))block; +//项目内 +- (void)request_project_task_countWithProjectId:(NSString *)projectId andBlock:(void (^)(id data, NSError *error))block; +//- (void)request_project_user_tasks_countsWithProjectId:(NSString *)projectId memberId:(NSString *)memberId andBlock:(void (^)(id data, NSError *error))block; +- (void)request_tasks_searchWithUserId:(NSString *)userId role:(TaskRoleType )role project_id:(NSString *)project_id andBlock:(void (^)(id data, NSError *error))block; +- (void)request_projects_tasks_labelsWithRole:(TaskRoleType)role projectId:(NSString *)projectId projectName:(NSString *)projectName memberId:(NSString *)memberId owner_user_name:(NSString *)owner_user_name andBlock:(void (^)(id data, NSError *error))block; + +#pragma mark - TaskBoard +- (void)request_BoardTaskListsInPro:(Project *)pro andBlock:(void (^)(NSArray *data, NSError *error))block; +- (void)request_AddBoardTaskListsInPro:(Project *)pro withTitle:(NSString *)title andBlock:(void (^)(EABoardTaskList *data, NSError *error))block; +- (void)request_DeleteBoardTaskList:(EABoardTaskList *)boardTL andBlock:(void (^)(id data, NSError *error))block; +- (void)request_RenameBoardTaskList:(EABoardTaskList *)boardTL withTitle:(NSString *)title andBlock:(void (^)(EABoardTaskList *data, NSError *error))block; +- (void)request_TaskInBoardTaskList:(EABoardTaskList *)boardTL andBlock:(void (^)(EABoardTaskList *data, NSError *error))block;//这里返回的 data 主要是 list 和 page 数据,而没有 EABoardTaskList 的相关业务属性 +- (void)request_PutTask:(Task *)task toBoardTaskList:(EABoardTaskList *)boardTL andBlock:(void (^)(id data, NSError *error))block; #pragma mark - User - (void)request_AddUser:(User *)user ToProject:(Project *)project andBlock:(void (^)(id data, NSError *error))block; @@ -198,6 +275,7 @@ typedef NS_ENUM(NSInteger, PurposeType) { - (void)request_Tweet_DoComment_WithObj:(Tweet *)tweet andBlock:(void (^)(id data, NSError *error))block; - (void)request_Tweet_DoTweet_WithObj:(Tweet *)tweet andBlock:(void (^)(id data, NSError *error))block; - (void)request_Tweet_DoProjectTweet_WithPro:(NSNumber *)pro_id content:(NSString *)content andBlock:(void (^)(id data, NSError *error))block; +- (void)request_Tweet_EditProjectTweet:(Tweet *)tweet content:(NSString *)content andBlock:(void (^)(id data, NSError *error))block; - (void)request_Tweet_Likers_WithObj:(Tweet *)tweet andBlock:(void (^)(id data, NSError *error))block; - (void)request_Tweet_LikesAndRewards_WithObj:(Tweet *)tweet andBlock:(void (^)(id data, NSError *error))block; - (void)request_Tweet_Comments_WithObj:(Tweet *)tweet andBlock:(void (^)(id data, NSError *error))block; @@ -214,7 +292,7 @@ typedef NS_ENUM(NSInteger, PurposeType) { - (void)request_UserJobArrayWithBlock:(void (^)(id data, NSError *error))block; - (void)request_UserTagArrayWithBlock:(void (^)(id data, NSError *error))block; - (void)request_UpdateUserInfo_WithObj:(User *)curUser andBlock:(void (^)(id data, NSError *error))block; -- (void)request_GeneratePhoneCodeToResetPhone:(NSString *)phone phoneCountryCode:(NSString *)phoneCountryCode block:(void (^)(id data, NSError *error))block; +- (void)request_GeneratePhoneCodeToResetPhone:(NSString *)phone phoneCountryCode:(NSString *)phoneCountryCode withCaptcha:(NSString *)captcha block:(void (^)(id data, NSError *error))block; - (void)request_PointRecords:(PointRecords *)records andBlock:(void (^)(id data, NSError *error))block; - (void)request_RewardToTweet:(NSString *)tweet_id encodedPassword:(NSString *)encodedPassword andBlock:(void (^)(id data, NSError *error))block; - (void)request_ServiceInfoBlock:(void (^)(id data, NSError *error))block; @@ -248,6 +326,12 @@ typedef NS_ENUM(NSInteger, PurposeType) { successBlock:(void (^)(id responseObj))success failureBlock:(void (^)(NSError *error))failure progerssBlock:(void (^)(CGFloat progressValue))progress; + +- (void)request_UpdateTeamIconImage:(UIImage *)image + successBlock:(void (^)(id responseObj))success + failureBlock:(void (^)(NSError *error))failure + progerssBlock:(void (^)(CGFloat progressValue))progress; + - (void)loadImageWithPath:(NSString *)imageUrlStr completeBlock:(void (^)(UIImage *image, NSError *error))block; #pragma mark - Other @@ -257,9 +341,10 @@ typedef NS_ENUM(NSInteger, PurposeType) { - (void)request_Users_WithTopicID:(NSInteger)topicID andBlock:(void (^)(id data, NSError *error))block; - (void)request_JoinedUsers_WithTopicID:(NSInteger)topicID page:(NSInteger)page andBlock:(void (^)(id data, NSError *error))block; +- (void)request_Users_activenessWithGlobalKey:(NSString *)globalKey andBlock:(void (^)(ActivenessModel *data, NSError *error))block; #pragma mark - 2FA -- (void)post_Close2FAGeneratePhoneCode:(NSString *)phone block:(void (^)(id data, NSError *error))block; +- (void)post_Close2FAGeneratePhoneCode:(NSString *)phone withCaptcha:(NSString *)captcha block:(void (^)(id data, NSError *error))block; - (void)post_Close2FAWithPhone:(NSString *)phone code:(NSString *)code block:(void (^)(id data, NSError *error))block; - (void)get_is2FAOpenBlock:(void (^)(BOOL data, NSError *error))block; @@ -296,6 +381,10 @@ typedef NS_ENUM(NSInteger, PurposeType) { - (void)request_shop_check_passwordWithpwd:(NSString *)pwd andBlock:(void (^)(id data, NSError *error))block; - (void)request_shop_exchangeWithParms:(NSDictionary *)parms andBlock:(void (^)(id data, NSError *error))block; +- (void)request_shop_orderWithParms:(NSDictionary *)parms andBlock:(void (^)(ShopOrder *shopOrder, NSError *error))block; +- (void)request_shop_payOrder:(NSString *)orderId method:(NSString *)method andBlock:(void (^)(NSDictionary *payDict, NSError *error))block; +- (void)request_shop_deleteOrder:(NSString *)orderId andBlock:(void (^)(id data, NSError *error))block; + - (void)request_LocationListWithParams:(NSDictionary *)params block:(void (^)(id data, NSError *error))block; @end diff --git a/Coding_iOS/Util/Manager/Coding_NetAPIManager.m b/Coding_iOS/Util/Manager/Coding_NetAPIManager.m index 1202e3738..495362741 100644 --- a/Coding_iOS/Util/Manager/Coding_NetAPIManager.m +++ b/Coding_iOS/Util/Manager/Coding_NetAPIManager.m @@ -19,6 +19,10 @@ #import "Team.h" #import "TeamMember.h" #import "ProjectServiceInfo.h" +#import "CodingVipTipManager.h" +#import "EAWiki.h" +#import "TeamPurchaseOrder.h" +#import "TeamPurchaseBilling.h" @implementation Coding_NetAPIManager + (instancetype)sharedManager { @@ -72,6 +76,33 @@ - (void)request_UnReadNotificationsWithBlock:(void (^)(id data, NSError *error)) } }]; } + +#pragma mark Company +- (void)request_CompanyExist:(NSString *)company andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/enterprise/info/%@", company]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Get autoShowError:NO andBlock:^(id data, NSError *error) { + block(data, error); + }]; +} + +- (void)request_UpdateCompanyInfoBlock:(void (^)(id data, NSError *error))block{ + NSString *companyKey = [NSObject baseCompany]; + [[Coding_NetAPIManager sharedManager] request_DetailOfTeam:[Team teamWithGK:companyKey] andBlock:^(id data, NSError *error) { + block(data, error); + }]; +} + +- (void)request_UpdateIsAdministratorBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/team/%@/is_admin", [NSObject baseCompany]]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Get andBlock:^(id data, NSError *error) { + if (data) { + data = data[@"data"]; + [Login updateLoginIsAdministrator:data]; + } + block(data, error); + }]; +} + #pragma mark Login - (void)request_Login_With2FA:(NSString *)otpCode andBlock:(void (^)(id data, NSError *error))block{ if (otpCode.length <= 0) { @@ -115,6 +146,27 @@ - (void)request_Login_WithPath:(NSString *)path Params:(id)params andBlock:(void }]; } +- (void)request_Login_With_UMSocialResponse:(UMSocialResponse *)resp andBlock:(void (^)(id data, NSError *error))block{ + NSMutableDictionary *params = @{}.mutableCopy; + params[@"account"] = resp.unionId; + params[@"oauth_access_token"] = resp.accessToken; + params[@"response"] = [NSString stringWithFormat:@"{\"access_token\":\"%@\",\"openid\":\"%@\"}", resp.accessToken, resp.openid]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:@"api/oauth/wechat/mobile/login" withParams:params withMethodType:Post autoShowError:NO andBlock:^(id data, NSError *error) { + id resultData = [data valueForKeyPath:@"data"]; + if (resultData) { + [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"登录_第三方登录"]; + + User *curLoginUser = [NSObject objectOfClass:@"User" fromJSON:resultData]; + if (curLoginUser) { + [Login doLogin:resultData]; + } + block(curLoginUser, nil); + }else{ + block(nil, error); + } + }]; +} + - (void)request_Register_V2_WithParams:(NSDictionary *)params andBlock:(void (^)(id data, NSError *error))block{ NSString *path = @"api/v2/account/register"; [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:params withMethodType:Post andBlock:^(id data, NSError *error) { @@ -134,7 +186,7 @@ - (void)request_Register_V2_WithParams:(NSDictionary *)params andBlock:(void (^) } - (void)request_CaptchaNeededWithPath:(NSString *)path andBlock:(void (^)(id data, NSError *error))block{ - [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Get andBlock:^(id data, NSError *error) { + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Get autoShowError:NO andBlock:^(id data, NSError *error) { if (data) { [MobClick event:kUmeng_Event_Request_Get label:@"是否需要验证码"]; @@ -366,13 +418,28 @@ - (void)request_Project_Pin:(Project *)project andBlock:(void (^)(id data, NSErr }]; } +- (void)request_ProjectQuit:(NSNumber *)project_id andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/project/%@/quit", project_id]; + [NSObject showStatusBarQueryStr:@"正在退出项目"]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Post andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"退出项目"]; + + [NSObject showStatusBarSuccessStr:@"退出项目成功"]; + block(data, nil); + }else{ + [NSObject showStatusBarError:error]; + block(nil, error); + } + }]; +} + -(void)request_NewProject_WithObj:(Project *)project image:(UIImage *)image andBlock:(void (^)(NSString *, NSError *))block{ [NSObject showStatusBarQueryStr:@"正在创建项目"]; NSDictionary *fileDic; if (image) { fileDic = @{@"image":image,@"name":@"icon",@"fileName":@"icon.jpg"}; } - [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:[project toProjectPath] file:fileDic withParams:[project toCreateParams] withMethodType:Post andBlock:^(id data, NSError *error) { if (data) { [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"创建项目"]; @@ -425,22 +492,19 @@ - (void)request_DeleteProject_WithObj:(Project *)project passCode:(NSString *)pa if (!project.name || !passCode) { return; } - NSDictionary *params; + NSMutableDictionary *params; if (type == VerifyTypePassword) { - params = @{ - @"name": project.name, - @"two_factor_code": [passCode sha1Str] - }; + params = @{@"two_factor_code": [passCode sha1Str]}.mutableCopy; }else if (type == VerifyTypeTotp){ - params = @{ - @"name": project.name, - @"two_factor_code": passCode - }; + params = @{@"two_factor_code": passCode}.mutableCopy; }else{ return; } + if (!kTarget_Enterprise) { + params[@"name"] = project.name; + } [NSObject showStatusBarQueryStr:@"正在删除项目"]; - [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:[project toDeletePath] withParams:params withMethodType:Delete andBlock:^(id data, NSError *error) { + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:[project toDeletePath] withParams:params withMethodType:kTarget_Enterprise? Post: Delete andBlock:^(id data, NSError *error) { if (data) { [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"删除项目"]; @@ -452,6 +516,21 @@ - (void)request_DeleteProject_WithObj:(Project *)project passCode:(NSString *)pa } }]; } +- (void)request_ArchiveProject_WithObj:(Project *)project passCode:(NSString *)passCode type:(VerifyType)type andBlock:(void (^)(Project *data, NSError *error))block{ + NSDictionary *params = @{@"two_factor_code": (type == VerifyTypePassword? [passCode sha1Str]: passCode)};; + [NSObject showStatusBarQueryStr:@"正在归档项目"]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:[project toArchivePath] withParams:params withMethodType:Post andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"归档项目"]; + + [NSObject showStatusBarSuccessStr:@"归档项目成功"]; + block(data, nil); + }else{ + [NSObject showStatusBarError:error]; + block(nil, error); + } + }]; +} - (void)request_TransferProject:(Project *)project toUser:(User *)user passCode:(NSString *)passCode type:(VerifyType)type andBlock:(void (^)(Project *data, NSError *error))block{ if (project.id.stringValue.length <= 0 || user.global_key.length <= 0|| passCode.length <= 0) { @@ -510,15 +589,6 @@ - (void)request_ProjectMembers_WithObj:(Project *)project andBlock:(void (^)(id resultData = [resultData objectForKey:@"list"]; NSMutableArray *resultA = [NSObject arrayFromJSON:resultData ofObjects:@"ProjectMember"]; - [resultA sortUsingComparator:^NSComparisonResult(ProjectMember *obj1, ProjectMember *obj2) { - if ([obj1.user_id isEqualToNumber:[Login curLoginUser].id]) { - return NSOrderedAscending; - }else if ([obj2.user_id isEqualToNumber:[Login curLoginUser].id]){ - return NSOrderedDescending; - }else{ - return obj1.type.intValue < obj2.type.intValue; - } - }]; block(resultA, nil); }else{ block(nil, error); @@ -602,6 +672,25 @@ - (void)request_EditTypeOfMember:(ProjectMember *)curMember inProject:(Project * }]; } +- (void)request_EditTypeOfUser:(NSString *)global_key inProjects:(NSArray *)pro_id_list roles:(NSArray *)role_list andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/team/%@/member/%@/projects/role", [Login curLoginCompany].global_key, global_key]; + NSDictionary *params = @{@"projects": [pro_id_list componentsJoinedByString:@","] ?: @"", + @"roles": [role_list componentsJoinedByString:@","] ?: @""}; + [NSObject showStatusBarQueryStr:@"正在设置成员类型"]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:params withMethodType:Post andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"企业成员_设置项目成员类型"]; + + [MobClick event:kUmeng_Event_UserCenter label:@"成员管理_项目权限设置"]; + + [NSObject showStatusBarSuccessStr:@"成员类型设置成功"]; + }else{ + [NSObject showStatusBarError:error]; + } + block(data, error); + }]; +} + - (void)request_ProjectServiceInfo:(Project *)curPro andBlock:(void (^)(id data, NSError *error))block{ NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/service_info", curPro.owner_user_name, curPro.name]; [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Get andBlock:^(id data, NSError *error) { @@ -632,9 +721,35 @@ - (void)request_DetailOfTeam:(Team *)team andBlock:(void (^)(id data, NSError *e if (data) { [MobClick event:kUmeng_Event_Request_Get label:@"团队_详情"]; - data = [NSObject objectOfClass:@"Team" fromJSON:data[@"data"]]; + Team *team = [NSObject objectOfClass:@"Team" fromJSON:data[@"data"]]; + if ([team.global_key.lowercaseString isEqualToString:[NSObject baseCompany].lowercaseString]) { + [Login doLoginCompany:data[@"data"]]; + } + block(team, nil); + }else{ + block(nil, error); + } + }]; +} + +- (void)request_InfoOfTeam:(Team *)team andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/enterprise/%@", team.global_key]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Get andBlock:^(id data, NSError *error) { + if (data[@"data"]) { + TeamInfo *info = [NSObject objectOfClass:@"TeamInfo" fromJSON:data[@"data"]]; + [[Coding_NetAPIManager sharedManager] request_DetailOfTeam:team andBlock:^(id dataT, NSError *errorT) { + if (dataT) { + [MobClick event:kUmeng_Event_Request_Get label:@"团队_详情"]; + + info.locked = team.locked; + block(info, nil); + }else{ + block(nil, errorT); + } + }]; + }else{ + block(nil, error); } - block(data, error); }]; } @@ -661,6 +776,104 @@ - (void)request_MembersInTeam:(Team *)team andBlock:(void (^)(id data, NSError * }]; } +- (void)request_UpdateTeamInfo_WithObj:(Team *)curTeam andBlock:(void (^)(id data, NSError *error))block{ + [NSObject showStatusBarQueryStr:@"正在修改企业信息"]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:[curTeam toUpdateInfoPath] withParams:[curTeam toUpdateInfoParams] withMethodType:Post andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"企业信息_修改"]; + + [NSObject showStatusBarSuccessStr:@"企业信息修改成功"]; + id resultData = [data valueForKeyPath:@"data"]; + Team *team = [NSObject objectOfClass:@"Team" fromJSON:resultData]; + if (team) { + [Login doLoginCompany:resultData]; + } + block(team, nil); + }else{ + [NSObject showStatusBarError:error]; + block(nil, error); + } + }]; +} +- (void)request_OrderListOfTeam:(Team *)team andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/enterprise/%@/orders", team.global_key]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Get andBlock:^(id data, NSError *error) { + if (data) { + data = [NSObject arrayFromJSON:data[@"data"] ofObjects:@"TeamPurchaseOrder"]; + } + block(data, error); + }]; +} +- (void)request_BillingListOfTeam:(Team *)team andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/enterprise/%@/billings", team.global_key]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Get andBlock:^(id data, NSError *error) { + if (data) { + data = [NSObject arrayFromJSON:data[@"data"] ofObjects:@"TeamPurchaseBilling"]; + } + block(data, error); + }]; +} + +- (void)request_EditTeamTypeOfMember:(TeamMember *)curMember andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/team/%@/member/%@/role/%@", [Login curLoginCompany].global_key, curMember.user.global_key, curMember.editRole]; + [NSObject showStatusBarQueryStr:@"正在设置企业角色"]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Post andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"企业_设置成员角色"]; + + [MobClick event:kUmeng_Event_UserCenter label:@"企业管理_企业角色设置"]; + + [NSObject showStatusBarSuccessStr:@"企业角色设置成功"]; + }else{ + [NSObject showStatusBarError:error]; + } + block(data, error); + }]; +} + +- (void)request_ProjectRoleOfUser:(NSString *)global_key andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/team/%@/member/%@/projects/role", [Login curLoginCompany].global_key, global_key]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Get andBlock:^(id data, NSError *error) { + if (data) { + data = [NSObject arrayFromJSON:data[@"data"] ofObjects:@"ProjectRole"]; + } + block(data, error); + }]; +} + +- (void)request_DeleteTeamMember:(NSString *)golbal_key passCode:(NSString *)passCode type:(VerifyType)type andBlock:(void (^)(id data, NSError *error))block{ + if (!golbal_key || !passCode) { + return; + } + NSString *path = [NSString stringWithFormat:@"api/team/%@/member/%@", [Login curLoginCompany].global_key, golbal_key]; + NSDictionary *params; + if (type == VerifyTypePassword) { + params = @{ + @"two_factor_code": [passCode sha1Str] + }; + }else if (type == VerifyTypeTotp){ + params = @{ + @"two_factor_code": passCode + }; + }else{ + return; + } + [NSObject showStatusBarQueryStr:@"正在删除企业成员"]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:params withMethodType:Delete andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"删除企业成员"]; + + [MobClick event:kUmeng_Event_UserCenter label:@"成员管理_删除企业成员"]; + + [NSObject showStatusBarSuccessStr:@"删除企业成员成功"]; + block(data, nil); + }else{ + [NSObject showStatusBarError:error]; + block(nil, error); + } + }]; +} + #pragma mark MRPR - (void)request_MRPRS_WithObj:(MRPRS *)curMRPRS andBlock:(void (^)(MRPRS *data, NSError *error))block{ curMRPRS.isLoading = YES; @@ -693,13 +906,13 @@ - (void)request_MRPRBaseInfo_WithObj:(MRPR *)curMRPR andBlock:(void (^)(MRPRBase }]; } -- (void)request_MRPRPreInfo_WithObj:(MRPR *)curMRPR andBlock:(void (^)(MRPRBaseInfo *data, NSError *error))block{ +- (void)request_MRPRPreInfo_WithObj:(MRPR *)curMRPR andBlock:(void (^)(MRPRPreInfo *data, NSError *error))block{ [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:[curMRPR toPrePath] withParams:nil withMethodType:Get andBlock:^(id data, NSError *error) { if (data) { [MobClick event:kUmeng_Event_Request_Get label:@"MRPR_详情页面"]; id resultData = [data valueForKeyPath:@"data"]; - MRPRBaseInfo *resultA = [NSObject objectOfClass:@"MRPRPreInfo" fromJSON:resultData]; + MRPRPreInfo *resultA = [NSObject objectOfClass:@"MRPRPreInfo" fromJSON:resultData]; block(resultA, nil); }else{ block(nil, error); @@ -832,6 +1045,16 @@ - (void)request_PostCommentWithPath:(NSString *)path params:(NSDictionary *)para [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"LineNote_评论_添加"]; NSString *noteable_type = [params objectForKey:@"noteable_type"]; + if ([params[@"isLineNote"] boolValue]) { + [MobClick event:kUmeng_Event_Git label:@"Git_添加_Linenote_评论"]; + }else{ + if ([noteable_type isEqualToString:@"MergeRequestBean"] || + [noteable_type isEqualToString:@"PullRequestBean"]) { + [MobClick event:kUmeng_Event_Git label:@"Git_添加_MR/PR_评论"]; + }else if ([noteable_type isEqualToString:@"Commit"]){ + [MobClick event:kUmeng_Event_Git label:@"Git_添加_Commit_评论"]; + } + } if ([noteable_type isEqualToString:@"MergeRequestBean"] || [noteable_type isEqualToString:@"PullRequestBean"] || [noteable_type isEqualToString:@"Commit"]) { @@ -923,69 +1146,157 @@ - (void)request_Folders:(ProjectFolders *)folders inProject:(Project *)project a } }]; } -- (void)request_FilesInFolder:(ProjectFolder *)folder andBlock:(void (^)(id data, NSError *error))block{ - [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:[folder toFilesPath] withParams:[folder toFilesParams] withMethodType:Get andBlock:^(id data, NSError *error) { +//- (void)request_FilesInFolder:(ProjectFolder *)folder andBlock:(void (^)(id data, NSError *error))block{ +// [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:[folder toFilesPath] withParams:[folder toFilesParams] withMethodType:Get andBlock:^(id data, NSError *error) { +// if (data) { +// [MobClick event:kUmeng_Event_Request_Get label:@"文件列表"]; +// +// id resultData = [data valueForKeyPath:@"data"]; +// ProjectFiles *files = [NSObject objectOfClass:@"ProjectFiles" fromJSON:resultData]; +// for (ProjectFile *file in files.list) { +// file.project_id = folder.project_id; +// } +// block(files, nil); +// }else{ +// block(nil, error); +// } +// }]; +//} +//- (void)request_DeleteFolder:(ProjectFolder *)folder andBlock:(void (^)(id data, NSError *error))block{ +// [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:[folder toDeletePath] withParams:nil withMethodType:Delete andBlock:^(id data, NSError *error) { +// if (data) { +// [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"文件夹_删除"]; +// +// block(folder, nil); +// }else{ +// block(nil, error); +// } +// }]; +//} +//- (void)request_RenameFolder:(ProjectFolder *)folder andBlock:(void (^)(id data, NSError *error))block{ +// [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:[folder toRenamePath] withParams:nil withMethodType:Put andBlock:^(id data, NSError *error) { +// if (data) { +// [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"文件夹_重命名"]; +// +// block(folder, nil); +// }else{ +// block(nil, error); +// } +// }]; +//} +//- (void)request_MoveFiles:(NSArray *)fileIdList toFolder:(ProjectFolder *)folder andBlock:(void (^)(id data, NSError *error))block{ +// [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:[folder toMoveToPath] withParams:@{@"fileId": fileIdList} withMethodType:Put andBlock:^(id data, NSError *error) { +// if (data) { +// [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"文件_移动"]; +// +// block(fileIdList, nil); +// }else{ +// block(nil, error); +// } +// }]; +//} +//- (void)request_MoveFolder:(NSNumber *)folderId toFolder:(ProjectFolder *)folder inProject:(Project *)project andBlock:(void (^)(id data, NSError *error))block{ +// NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/folder/%@/move-to/%@", project.owner_user_name, project.name, folderId, folder.file_id]; +// [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Put andBlock:^(id data, NSError *error) { +// if (data) { +// [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"文件夹_移动"]; +// +// block(folderId, nil); +// }else{ +// block(nil, error); +// } +// }]; +//} +//- (void)request_CreatFolder:(NSString *)fileName inFolder:(ProjectFolder *)parentFolder inProject:(Project *)project andBlock:(void (^)(id data, NSError *error))block{ +// NSString *path = [NSString stringWithFormat:@"api/project/%@/mkdir", project.id.stringValue]; +// NSDictionary *params = @{@"name" : fileName, +// @"parentId" : (parentFolder && parentFolder.file_id)? parentFolder.file_id.stringValue : @"0" }; +// [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:params withMethodType:Post andBlock:^(id data, NSError *error) { +// if (data) { +// [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"文件夹_新建"]; +// +// id resultData = [data valueForKeyPath:@"data"]; +// ProjectFolder *createdFolder = [NSObject objectOfClass:@"ProjectFolder" fromJSON:resultData]; +// createdFolder.project_id = project.id; +// block(createdFolder, nil); +// }else{ +// block(nil, error); +// } +// }]; +//} + +- (void)request_FoldersInFolder:(ProjectFile *)folder andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/folder/%@/sub-folders", folder.project_owner_name, folder.project_name, folder.file_id]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Get andBlock:^(id data, NSError *error) { if (data) { [MobClick event:kUmeng_Event_Request_Get label:@"文件列表"]; - + id resultData = [data valueForKeyPath:@"data"]; - ProjectFiles *files = [NSObject objectOfClass:@"ProjectFiles" fromJSON:resultData]; - for (ProjectFile *file in files.list) { - file.project_id = folder.project_id; - } - block(files, nil); + NSArray *list = [NSObject arrayFromJSON:resultData ofObjects:@"ProjectFile"]; + [list setValue:folder.project_name forKey:@"project_name"]; + [list setValue:folder.project_owner_name forKey:@"project_owner_name"]; + block(list, nil); }else{ block(nil, error); } }]; } -- (void)request_DeleteFolder:(ProjectFolder *)folder andBlock:(void (^)(id data, NSError *error))block{ - [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:[folder toDeletePath] withParams:nil withMethodType:Delete andBlock:^(id data, NSError *error) { +- (void)request_FilesInFolder:(ProjectFile *)folder andBlock:(void (^)(id data, NSError *error))block{ + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:[folder toFolderFilesPath] withParams:[folder toFolderFilesParams] withMethodType:Get andBlock:^(id data, NSError *error) { if (data) { - [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"文件夹_删除"]; - - block(folder, nil); + [MobClick event:kUmeng_Event_Request_Get label:@"文件列表"]; + + id resultData = [data valueForKeyPath:@"data"]; + ProjectFiles *files = [NSObject objectOfClass:@"ProjectFiles" fromJSON:resultData]; + [files.list setValue:folder.project_name forKey:@"project_name"]; + [files.list setValue:folder.project_owner_name forKey:@"project_owner_name"]; + block(files, nil); }else{ block(nil, error); } }]; } -- (void)request_RenameFolder:(ProjectFolder *)folder andBlock:(void (^)(id data, NSError *error))block{ - [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:[folder toRenamePath] withParams:nil withMethodType:Put andBlock:^(id data, NSError *error) { +- (void)request_DeleteFolder:(ProjectFile *)folder andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/project/%@/file/delete", folder.project_id]; + NSDictionary *params = @{@"fileIds": folder.file_id}; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:params withMethodType:Delete andBlock:^(id data, NSError *error) { if (data) { - [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"文件夹_重命名"]; - + [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"文件夹_删除"]; + block(folder, nil); }else{ block(nil, error); } }]; } -- (void)request_DeleteFiles:(NSArray *)fileIdList inProject:(NSNumber *)project_id andBlock:(void (^)(id data, NSError *error))block{ - NSString *path = [NSString stringWithFormat:@"api/project/%@/file/delete", project_id.stringValue]; - [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:@{@"fileIds" : fileIdList} withMethodType:Delete andBlock:^(id data, NSError *error) { - if (data) { - [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"文件_删除"]; - block(fileIdList, nil); +- (void)request_RenameFolder:(ProjectFile *)folder andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/folder/%@", folder.project_owner_name, folder.project_name, folder.file_id]; + NSDictionary *params = @{@"name": folder.next_name}; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:params withMethodType:Put andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"文件夹_重命名"]; + + block(folder, nil); }else{ block(nil, error); } }]; } -- (void)request_MoveFiles:(NSArray *)fileIdList toFolder:(ProjectFolder *)folder andBlock:(void (^)(id data, NSError *error))block{ - [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:[folder toMoveToPath] withParams:@{@"fileId": fileIdList} withMethodType:Put andBlock:^(id data, NSError *error) { +- (void)request_MoveFiles:(NSArray *)fileIdList toFolder:(ProjectFile *)folder andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/folder/%@/move-files", folder.project_owner_name, folder.project_name, folder.file_id]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:@{@"fileId": fileIdList} withMethodType:Post andBlock:^(id data, NSError *error) { if (data) { [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"文件_移动"]; - + block(fileIdList, nil); }else{ block(nil, error); } }]; } -- (void)request_MoveFolder:(NSNumber *)folderId toFolder:(ProjectFolder *)folder inProject:(Project *)project andBlock:(void (^)(id data, NSError *error))block{ - NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/folder/%@/move-to/%@", project.owner_user_name, project.name, folderId, folder.file_id]; +- (void)request_MoveFolder:(NSNumber *)folderId toFolder:(ProjectFile *)folder inProject:(Project *)project andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/folder/%@/move-to/%@", project.owner_user_name, project.name, folderId, folder.file_id]; [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Put andBlock:^(id data, NSError *error) { if (data) { [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"文件夹_移动"]; @@ -996,23 +1307,38 @@ - (void)request_MoveFolder:(NSNumber *)folderId toFolder:(ProjectFolder *)folder } }]; } -- (void)request_CreatFolder:(NSString *)fileName inFolder:(ProjectFolder *)parentFolder inProject:(Project *)project andBlock:(void (^)(id data, NSError *error))block{ - NSString *path = [NSString stringWithFormat:@"api/project/%@/mkdir", project.id.stringValue]; +- (void)request_CreatFolder:(NSString *)fileName inFolder:(ProjectFile *)parentFolder inProject:(Project *)project andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/folder", project.owner_user_name, project.name]; NSDictionary *params = @{@"name" : fileName, - @"parentId" : (parentFolder && parentFolder.file_id)? parentFolder.file_id.stringValue : @"0" }; + @"parentId" : (parentFolder && parentFolder.file_id)? parentFolder.file_id : @0 }; [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:params withMethodType:Post andBlock:^(id data, NSError *error) { if (data) { [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"文件夹_新建"]; - + id resultData = [data valueForKeyPath:@"data"]; - ProjectFolder *createdFolder = [NSObject objectOfClass:@"ProjectFolder" fromJSON:resultData]; - createdFolder.project_id = project.id; + ProjectFile *createdFolder = [NSObject objectOfClass:@"ProjectFile" fromJSON:resultData]; + createdFolder.project_id = project.id ?: parentFolder.project_id; + createdFolder.project_owner_name = parentFolder.project_owner_name ?: project.owner_user_name; + createdFolder.project_name = parentFolder.project_name ?: project.name; block(createdFolder, nil); }else{ block(nil, error); } }]; } + +- (void)request_DeleteFiles:(NSArray *)fileIdList inProject:(NSNumber *)project_id andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/project/%@/file/delete", project_id.stringValue]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:@{@"fileIds" : fileIdList} withMethodType:Delete andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"文件_删除"]; + + block(fileIdList, nil); + }else{ + block(nil, error); + } + }]; +} - (void)request_FileDetail:(ProjectFile *)file andBlock:(void (^)(id data, NSError *error))block{ [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:[file toDetailPath] withParams:nil withMethodType:Get andBlock:^(id data, NSError *error) { if (data) { @@ -1064,7 +1390,8 @@ - (void)request_RenameFile:(ProjectFile *)file withName:(NSString *)nameStr andB if (!nameStr) { return; } - NSString *path = [NSString stringWithFormat:@"api/project/%@/files/%@/rename", file.project_id, file.file_id]; + NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/files/%@/rename", file.project_owner_name, file.project_name, file.file_id]; +// NSString *path = [NSString stringWithFormat:@"api/project/%@/files/%@/rename", file.project_id, file.file_id]; NSDictionary *params = @{@"name" : nameStr}; [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:params withMethodType:Put andBlock:^(id data, NSError *error) { if (data) { @@ -1158,12 +1485,39 @@ - (void)request_OpenShareOfFile:(ProjectFile *)file andBlock:(void (^)(id data, } }]; } -- (void)request_CloseShareHash:(NSString *)hashStr andBlock:(void (^)(id data, NSError *error))block{ +- (void)request_CloseFileShareHash:(NSString *)hashStr andBlock:(void (^)(id data, NSError *error))block{ NSString *path = [NSString stringWithFormat:@"api/share/%@", hashStr]; [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Delete andBlock:^(id data, NSError *error) { if (data) { [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"文件_关闭共享"]; + + block(data, nil); + }else{ + block(nil, error); + } + }]; +} +- (void)request_OpenShareOfWiki:(EAWiki *)wiki andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = @"api/share/create"; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:[wiki toShareParams] withMethodType:Post andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"Wiki_开启共享"]; + + NSString *share_url = [[data valueForKey:@"data"] valueForKey:@"url"]; + block(share_url, nil); + }else{ + block(nil, error); + } + }]; +} + +- (void)request_CloseWikiShareHash:(NSString *)hashStr andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/share/%@", hashStr]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Delete andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"Wiki_关闭共享"]; + block(data, nil); }else{ block(nil, error); @@ -1176,6 +1530,7 @@ - (void)request_CodeTree:(CodeTree *)codeTree withPro:(Project *)project codeTre NSString *refAndPath = [NSString handelRef:codeTree.ref path:codeTree.path]; NSString *treePath = [NSString stringWithFormat:@"api/user/%@/project/%@/git/tree/%@", project.owner_user_name, project.name, refAndPath]; NSString *treeinfoPath = [NSString stringWithFormat:@"api/user/%@/project/%@/git/treeinfo/%@", project.owner_user_name, project.name, refAndPath]; + NSString *treeListPath = [NSString stringWithFormat:@"api/user/%@/project/%@/git/treelist/%@", project.owner_user_name, project.name, codeTree.ref]; [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:treePath withParams:nil withMethodType:Get andBlock:^(id data, NSError *error) { if (data) { id resultData = [data valueForKeyPath:@"data"]; @@ -1183,14 +1538,19 @@ - (void)request_CodeTree:(CodeTree *)codeTree withPro:(Project *)project codeTre [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:treeinfoPath withParams:nil withMethodType:Get andBlock:^(id infoData, NSError *infoError) { if (infoData) { - [MobClick event:kUmeng_Event_Request_Get label:@"代码目录"]; - infoData = [infoData valueForKey:@"data"]; infoData = [infoData valueForKey:@"infos"]; NSMutableArray *infoArray = [NSObject arrayFromJSON:infoData ofObjects:@"CodeTree_CommitInfo"]; [rCodeTree configWithCommitInfos:infoArray]; - - block(rCodeTree, nil); + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:treeListPath withParams:nil withMethodType:Get andBlock:^(id listData, NSError *listError) { + if (listData) { + [MobClick event:kUmeng_Event_Request_Get label:@"代码目录"]; + rCodeTree.treeList = listData[@"data"]; + block(rCodeTree, nil); + }else{ + block(nil, listError); + } + }]; }else{ block(nil, infoError); } @@ -1230,6 +1590,19 @@ - (void)request_EditCodeFile:(CodeFile *)codeFile withPro:(Project *)project and }]; } +- (void)request_DeleteCodeFile:(CodeFile *)codeFile withPro:(Project *)project andBlock:(void (^)(id data, NSError *error))block{ + NSString *filePath = [NSString stringWithFormat:@"api/user/%@/project/%@/git/delete/%@", project.owner_user_name, project.name, [NSString handelRef:codeFile.ref path:codeFile.path]]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:filePath withParams:[codeFile toDeleteParams] withMethodType:Post andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_Get label:@"代码文件_删除"]; + + block(data, nil);//{"code":0} + }else{ + block(nil, error); + } + }]; +} + - (void)request_CodeBranchOrTagWithPath:(NSString *)path withPro:(Project *)project andBlock:(void (^)(id data, NSError *error))block{ [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:[project toBranchOrTagPath:path] withParams:nil withMethodType:Get andBlock:^(id data, NSError *error) { if (data) { @@ -1260,6 +1633,331 @@ - (void)request_Commits:(Commits *)curCommits withPro:(Project *)project andBloc }]; } +- (void)request_UploadAssets:(NSArray *)assets inCodeTree:(CodeTree *)codeTree withPro:(Project *)project andBlock:(void (^)(id data, NSError *error))block progerssBlock:(void (^)(CGFloat progressValue))progressBlock{ + NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/git/upload/%@", project.owner_user_name, project.name, [NSString handelRef:codeTree.ref path:codeTree.path]]; + NSMutableDictionary *params = @{}.mutableCopy; + params[@"message"] = @"Add files via upload"; + params[@"lastCommitSha"] = codeTree.headCommit.commitId; + + [[CodingNetAPIClient sharedJsonClient] uploadAssets:assets path:path name:@"files" params:params successBlock:^(AFHTTPRequestOperation *operation, id responseObject) { + [MobClick event:kUmeng_Event_Request_Get label:@"代码文件_上传图片"]; + + block(responseObject, nil); + } failureBlock:^(AFHTTPRequestOperation *operation, NSError *error) { + block(nil, error); + } progerssBlock:^(CGFloat progressValue) { + progressBlock(progressValue); + }]; +} + +- (void)request_CreateCodeFile:(CodeFile *)codeFile withPro:(Project *)project andBlock:(void (^)(id data, NSError *error))block{ + NSString *filePath = [NSString stringWithFormat:@"api/user/%@/project/%@/git/new/%@", project.owner_user_name, project.name, [NSString handelRef:codeFile.ref path:codeFile.path]]; + + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:filePath withParams:[codeFile toCreateParams] withMethodType:Post andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_Get label:@"代码文件_创建文本文件"]; + + block(data, nil);//{"code":0} + }else{ + block(nil, error); + } + }]; +} + +- (void)request_CodeBranches_WithObj:(EACodeBranches *)curObj andBlock:(void (^)(EACodeBranches *data, NSError *error))block{ + curObj.isLoading = YES; + //拿 branch 列表 + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:[curObj toPath] withParams:[curObj toParams] withMethodType:Get andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_Get label:@"分支管理_列表"]; + + id resultData = [data valueForKeyPath:@"data"]; + EACodeBranches *resultA = [NSObject objectOfClass:@"EACodeBranches" fromJSON:resultData]; + if (resultA.list.count > 0) { + //拿 branch 对应的 metrics + void (^metricsQueryBlock)() = ^(){ + NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/git/branch_metrics", curObj.curPro.owner_user_name, curObj.curPro.name]; + NSString *targetsStr = [[resultA.list valueForKeyPath:@"last_commit.commitId"] componentsJoinedByString:@","]; + NSDictionary *params = @{@"base": curObj.defaultBranch.last_commit.commitId ?: @"", + @"targets": targetsStr + }; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:params withMethodType:Get andBlock:^(id dataM, NSError *errorM) { + if (dataM) { + dataM = dataM[@"data"]; + for (CodeBranchOrTag *curB in resultA.list) { + curB.branch_metric = [NSObject objectOfClass:@"CodeBranchOrTagMetric" fromJSON:dataM[curB.last_commit.commitId]]; + } + block(resultA, nil); + }else{ + block(nil, errorM); + } + curObj.isLoading = NO; + }]; + }; + curObj.defaultBranch = curObj.defaultBranch ?: resultA.defaultBranch; + if (!curObj.defaultBranch) {//请求 default 分支 + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:[NSString stringWithFormat:@"api/user/%@/project/%@/git/branches/default", curObj.curPro.owner_user_name, curObj.curPro.name] withParams:nil withMethodType:Get andBlock:^(id dataD, NSError *errorD) { + if (dataD) { + curObj.defaultBranch = [NSObject objectOfClass:@"CodeBranchOrTag" fromJSON:dataD[@"data"]]; + metricsQueryBlock(); + }else{ + curObj.isLoading = NO; + block(nil, errorD); + } + }]; + }else{ + metricsQueryBlock(); + } + }else{ + curObj.isLoading = NO; + block(resultA, nil); + } + }else{ + curObj.isLoading = NO; + block(nil, error); + } + }]; +} + +- (void)request_DeleteCodeBranch:(CodeBranchOrTag *)curB inProject:(Project *)curP andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/git/branches/delete", curP.owner_user_name, curP.name]; + NSDictionary *params = @{@"branch_name": curB.name}; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:params withMethodType:Post andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_Get label:@"分支管理_删除"]; + } + block(data, error); + }]; +} + +- (void)request_CodeReleases_WithObj:(EACodeReleases *)curObj andBlock:(void (^)(EACodeReleases *data, NSError *error))block{ + curObj.isLoading = YES; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:[curObj toPath] withParams:[curObj toParams] withMethodType:Get andBlock:^(id data, NSError *error) { + curObj.isLoading = NO; + if (data) { + [MobClick event:kUmeng_Event_Request_Get label:@"发布管理_列表"]; + + id resultData = [data valueForKeyPath:@"data"]; + EACodeReleases *resultA = [NSObject objectOfClass:@"EACodeReleases" fromJSON:resultData]; + if (curObj.curPro) { + [resultA.list setValue:curObj.curPro forKey:@"project"]; + } + block(resultA, nil); + }else{ + block(nil, error); + } + }]; +} + +- (void)request_CodeRelease_WithObj:(EACodeRelease *)curObj andBlock:(void (^)(EACodeRelease *data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/git/releases/tag/%@", curObj.project.owner_user_name, curObj.project.name, curObj.tag_name]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Get andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_Get label:@"发布管理_详情"]; + + id resultData = [data valueForKeyPath:@"data"]; + EACodeRelease *resultA = [NSObject objectOfClass:@"EACodeRelease" fromJSON:resultData]; + resultA.project = curObj.project; + block(resultA, nil); + }else{ + block(nil, error); + } + }]; +} + +- (void)request_DeleteCodeRelease:(EACodeRelease *)curObj andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/git/releases/delete/%@", curObj.project.owner_user_name, curObj.project.name, curObj.tag_name]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Post andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_Get label:@"发布管理_删除"]; + } + block(data, error); + }]; +} + +- (void)request_ModifyCodeRelease:(EACodeRelease *)curObj andBlock:(void (^)(EACodeRelease *data, NSError *error))block{ + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:curObj.editPath withParams:curObj.editParams withMethodType:Post andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_Get label:@"发布管理_删除"]; + + id resultData = [data valueForKeyPath:@"data"]; + EACodeRelease *resultA = [NSObject objectOfClass:@"EACodeRelease" fromJSON:resultData]; + resultA.project = curObj.project; + block(resultA, nil); + }else{ + block(nil, error); + } + }]; +} + +#pragma mark Wiki +- (void)request_WikiListWithPro:(Project *)pro andBlock:(void (^)(id data, NSError *error))block{ + + NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/wikis", pro.owner_user_name, pro.name]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Get andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_Get label:@"Wiki_列表"]; + + data = [NSObject arrayFromJSON:data[@"data"] ofObjects:@"EAWiki"]; + } + block(data, error); + }]; +} + +- (void)request_WikiDetailWithPro:(Project *)pro iid:(NSNumber *)iid version:(NSNumber *)version andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/wiki/%@", pro.owner_user_name, pro.name, iid]; + NSMutableDictionary *params = @{}.mutableCopy; + params[@"version"] = version; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:params withMethodType:Get andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_Get label:@"Wiki_详情"]; + + data = [NSObject objectOfClass:@"EAWiki" fromJSON:data[@"data"]]; + } + block(data, error); + }]; +} +- (void)request_DeleteWikiWithPro:(Project *)pro iid:(NSNumber *)iid andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/wiki/%@", pro.owner_user_name, pro.name, iid]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Delete andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"Wiki_删除"]; + } + block(data, error); + }]; +} + +- (void)request_ModifyWiki:(EAWiki *)wiki pro:(Project *)pro andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/wiki", pro.owner_user_name, pro.name]; + NSMutableDictionary *params = @{}.mutableCopy; + params[@"iid"] = wiki.iid; + params[@"parentIid"] = wiki.parentIid; + params[@"order"] = wiki.order; + params[@"msg"] = @"Modified By App"; + params[@"title"] = wiki.mdTitle; + params[@"content"] = wiki.mdContent; + + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:params withMethodType:Post andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"Wiki_修改"]; + + data = [NSObject objectOfClass:@"EAWiki" fromJSON:data[@"data"]]; + } + block(data, error); + }]; +} + +- (void)request_WikiHistoryWithWiki:(EAWiki *)wiki pro:(Project *)pro andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/wiki/%@/histories", pro.owner_user_name, pro.name, wiki.iid]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Get andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_Get label:@"Wiki_历史版本"]; + + data = [NSObject arrayFromJSON:data[@"data"] ofObjects:@"EAWiki"]; + } + block(data, error); + }]; +} + +- (void)request_RevertWiki:(NSNumber *)wikiIid toVersion:(NSNumber *)version pro:(Project *)pro andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/wiki/%@/history", pro.owner_user_name, pro.name, wikiIid]; + NSMutableDictionary *params = @{}.mutableCopy; + params[@"version"] = version; + + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:params withMethodType:Post andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"Wiki_恢复"]; + + data = [NSObject objectOfClass:@"EAWiki" fromJSON:data[@"data"]]; + } + block(data, error); + }]; +} + +//- (void)request_WikiListWithProName:(NSString *)proName andBlock:(void (^)(id data, NSError *error))block{ +// NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/wikis", [Login curLoginCompany].global_key, proName]; +// [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Get andBlock:^(id data, NSError *error) { +// if (data) { +// [MobClick event:kUmeng_Event_Request_Get label:@"Wiki_列表"]; +// +// data = [NSObject arrayFromJSON:data[@"data"] ofObjects:@"EAWiki"]; +// } +// block(data, error); +// }]; +//} +// +//- (void)request_WikiDetailWithProName:(NSString *)proName iid:(NSNumber *)iid version:(NSNumber *)version andBlock:(void (^)(id data, NSError *error))block{ +// NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/wiki/%@", [Login curLoginCompany].global_key, proName, iid]; +// NSMutableDictionary *params = @{}.mutableCopy; +// params[@"version"] = version; +// [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:params withMethodType:Get andBlock:^(id data, NSError *error) { +// if (data) { +// [MobClick event:kUmeng_Event_Request_Get label:@"Wiki_详情"]; +// +// data = [NSObject objectOfClass:@"EAWiki" fromJSON:data[@"data"]]; +// } +// block(data, error); +// }]; +//} +//- (void)request_DeleteWikiWithProName:(NSString *)proName iid:(NSNumber *)iid andBlock:(void (^)(id data, NSError *error))block{ +// NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/wiki/%@", [Login curLoginCompany].global_key, proName, iid]; +// [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Delete andBlock:^(id data, NSError *error) { +// if (data) { +// [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"Wiki_删除"]; +// } +// block(data, error); +// }]; +//} +// +//- (void)request_ModifyWiki:(EAWiki *)wiki proName:(NSString *)proName andBlock:(void (^)(id data, NSError *error))block{ +// NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/wiki", [Login curLoginCompany].global_key, proName]; +// NSMutableDictionary *params = @{}.mutableCopy; +// params[@"iid"] = wiki.iid; +// params[@"parentIid"] = wiki.parentIid; +// params[@"order"] = wiki.order; +// params[@"msg"] = @"Modified By App"; +// params[@"title"] = wiki.mdTitle; +// params[@"content"] = wiki.mdContent; +// +// [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:params withMethodType:Post andBlock:^(id data, NSError *error) { +// if (data) { +// [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"Wiki_修改"]; +// +// [MobClick event:kUmeng_Event_Wiki label:@"Wiki_编辑_提交"]; +// +// data = [NSObject objectOfClass:@"EAWiki" fromJSON:data[@"data"]]; +// } +// block(data, error); +// }]; +//} +// +//- (void)request_WikiHistoryWithWiki:(EAWiki *)wiki proName:(NSString *)proName andBlock:(void (^)(id data, NSError *error))block{ +// NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/wiki/%@/histories", [Login curLoginCompany].global_key, proName, wiki.iid]; +// [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Get andBlock:^(id data, NSError *error) { +// if (data) { +// [MobClick event:kUmeng_Event_Request_Get label:@"Wiki_历史版本"]; +// +// data = [NSObject arrayFromJSON:data[@"data"] ofObjects:@"EAWiki"]; +// } +// block(data, error); +// }]; +//} +// +//- (void)request_RevertWiki:(NSNumber *)wikiIid toVersion:(NSNumber *)version proName:(NSString *)proName andBlock:(void (^)(id data, NSError *error))block{ +// NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/wiki/%@/history", [Login curLoginCompany].global_key, proName, wikiIid]; +// NSMutableDictionary *params = @{}.mutableCopy; +// params[@"version"] = version; +// +// [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:params withMethodType:Post andBlock:^(id data, NSError *error) { +// if (data) { +// [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"Wiki_恢复"]; +// +// data = [NSObject objectOfClass:@"EAWiki" fromJSON:data[@"data"]]; +// } +// block(data, error); +// }]; +//} + #pragma mark Task - (void)request_AddTask:(Task *)task andBlock:(void (^)(id data, NSError *error))block{ [NSObject showStatusBarQueryStr:@"正在添加任务"]; @@ -1472,6 +2170,298 @@ - (void)request_ChangeWatcher:(User *)watcher ofTask:(Task *)task andBlock:(void }]; } +- (void)request_projects_tasks_labelsWithRole:(TaskRoleType)role projectId:(NSString *)projectId andBlock:(void (^)(id data, NSError *error))block { + NSString *roleStr; + NSDictionary *param; + NSArray *roleArray = @[@"owner", @"watcher", @"creator"]; + if (role < roleArray.count) { + roleStr = roleArray[role]; + } + + if (roleStr != nil) { + param = @{@"role": roleStr}; + } + + NSString *urlStr; + if (projectId == nil) { + urlStr = @"api/projects/tasks/labels"; + } else { + urlStr = [NSString stringWithFormat:@"api/project/%@/tasks/labels", projectId]; + } + + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:urlStr withParams:param withMethodType:Get andBlock:^(id data, NSError *error) { + NSArray *dataArray = data[@"data"]; + NSMutableDictionary *pinyinDict = @{}.mutableCopy; + for (NSDictionary *dict in dataArray) { + NSString *pinyinName = dict[@"name"]; + pinyinName = [pinyinName stringByReplacingOccurrencesOfString:@"呵" withString:@"HE"];//一个多音字的..唉 + pinyinName = [pinyinName transformToPinyin]; + [pinyinDict setObject:dict forKey:pinyinName]; + } + + NSArray *nameSortArray = [[pinyinDict allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; + + NSMutableArray *newPinyinData = @[].mutableCopy; + for (NSString *pinyinName in nameSortArray) { + [newPinyinData addObject:pinyinDict[pinyinName]]; + } + + if (data) { + block(newPinyinData, nil); + }else{ + block(nil, error); + } + }]; + +} + +- (void)request_tasks_searchWithUserId:(NSString *)userId role:(TaskRoleType )role project_id:(NSString *)project_id keyword:(NSString *)keyword status:(NSString *)status label:(NSString *)label page:(NSInteger)page andBlock:(void (^)(id data, NSError *error))block { + NSMutableDictionary *param = @{@"page": @(page)}.mutableCopy; + if (userId != nil) { + [param setValue:userId forKey:@"owner"]; + } + if (project_id != nil && project_id.integerValue >= 0) { + [param setValue:project_id forKey:@"project_id"]; + } + if (keyword != nil) { + [param setValue:keyword forKey:@"keyword"]; + } + if (status != nil) { + [param setValue:status forKey:@"status"]; + } + if (label != nil) { + [param setValue:label forKey:@"label"]; + } + + NSArray *roleArray = @[@"owner", @"watcher", @"creator"]; + if (role < roleArray.count) { + [param setValue:[Login curLoginUser].id.stringValue forKey:roleArray[role]]; + + } + NSString *path = keyword.length > 0? @"api/tasks/search": @"api/tasks/list"; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:param withMethodType:Get andBlock:^(id data, NSError *error) { + + Tasks *pros = [NSObject objectOfClass:@"Tasks" fromJSON:data[@"data"]]; + pros.list = [NSObject arrayFromJSON:data[@"data"][@"list"] ofObjects:@"Task"]; + if (status.integerValue == 1) { + pros.processingList = pros.list; + } else if (status.integerValue == 2) { + pros.doneList = pros.list; + } + + if (data) { + block(pros, nil); + }else{ + block(nil, error); + } + }]; +} + +- (void)request_project_tasks_countWithProjectId:(NSString *)projectId andBlock:(void (^)(id data, NSError *error))block { + + NSString *urlStr; + if (projectId == nil) { + urlStr = @"api/tasks/count"; + } else { + urlStr = [NSString stringWithFormat:@"api/project/%@/tasks/counts", projectId]; + } + + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:urlStr withParams:nil withMethodType:Get andBlock:^(id data, NSError *error) { + if (data) { + block(data, nil); + }else{ + block(nil, error); + } + }]; +} + +- (void)request_project_task_countWithProjectId:(NSString *)projectId andBlock:(void (^)(id data, NSError *error))block { + + NSString *urlStr; + if (projectId == nil) { + urlStr = @"api/tasks/count"; + } else { + urlStr = [NSString stringWithFormat:@"api/project/%@/task/count", projectId]; + } + + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:urlStr withParams:nil withMethodType:Get andBlock:^(id data, NSError *error) { + if (data) { + block(data, nil); + }else{ + block(nil, error); + } + }]; +} + +//- (void)request_project_user_tasks_countsWithProjectId:(NSString *)projectId memberId:(NSString *)memberId andBlock:(void (^)(id data, NSError *error))block { +// +// NSString *urlStr; +// if (memberId == nil) { +// urlStr = @"api/tasks/search"; +// } else { +// urlStr = [NSString stringWithFormat:@"api/project/%@/user/%@/tasks/counts", projectId, memberId]; +// } +// +// [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:urlStr withParams:nil withMethodType:Get andBlock:^(id data, NSError *error) { +// if (data) { +// block(data, nil); +// }else{ +// block(nil, error); +// } +// }]; +//} + +- (void)request_tasks_searchWithUserId:(NSString *)userId role:(TaskRoleType )role project_id:(NSString *)project_id andBlock:(void (^)(id data, NSError *error))block { + + NSString *urlStr; + NSDictionary *param; + if (userId == nil) { //无成员时 + if (role == TaskRoleTypeWatcher || role == TaskRoleTypeCreator) { //创建和关注 + urlStr = [NSString stringWithFormat:@"api/project/%@/tasks/counts", project_id]; + } else { //全部任务 + urlStr = [NSString stringWithFormat:@"api/project/%@/task/count", project_id]; + } + } else { //有成员时 + urlStr = [NSString stringWithFormat:@"api/project/%@/user/%@/tasks/counts", project_id, userId]; + + } + + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:urlStr withParams:param withMethodType:Get andBlock:^(id data, NSError *error) { + + if (data) { + block(data, nil); + }else{ + block(nil, error); + } + }]; +} + +- (void)request_projects_tasks_labelsWithRole:(TaskRoleType)role projectId:(NSString *)projectId projectName:(NSString *)projectName memberId:(NSString *)memberId owner_user_name:(NSString *)owner_user_name andBlock:(void (^)(id data, NSError *error))block { + NSDictionary *param; + NSArray *roleArray = @[@"owner", @"watcher", @"creator"]; + if (role < roleArray.count) { + param = @{@"role": roleArray[role]}; + } + NSString *urlStr; + if (projectId != nil && memberId != nil) { //有成员 + urlStr = [NSString stringWithFormat:@"api/project/%@/user/%@/tasks/labels", projectId, memberId]; + + } else { + if (role == TaskRoleTypeWatcher || role == TaskRoleTypeCreator) { + urlStr = [NSString stringWithFormat:@"api/project/%@/tasks/labels", projectId]; + + } else { + urlStr = [NSString stringWithFormat:@"api/user/%@/project/%@/task/label?withCount=true", owner_user_name, projectName]; + } + } + + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:urlStr withParams:param withMethodType:Get andBlock:^(id data, NSError *error) { + NSArray *dataArray = data[@"data"]; + NSMutableDictionary *pinyinDict = @{}.mutableCopy; + for (NSDictionary *dict in dataArray) { + NSString *pinyinName = [dict[@"name"] transformToPinyin]; + [pinyinDict setObject:dict forKey:pinyinName]; + } + + NSArray *nameSortArray = [[pinyinDict allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; + + NSMutableArray *newPinyinData = @[].mutableCopy; + for (NSString *pinyinName in nameSortArray) { + [newPinyinData addObject:pinyinDict[pinyinName]]; + } + + if (data) { + block(newPinyinData, nil); + }else{ + block(nil, error); + } + }]; + +} + +#pragma mark - TaskBoard +- (void)request_BoardTaskListsInPro:(Project *)pro andBlock:(void (^)(NSArray *data, NSError *error))block{ +// NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/tasks/board/list", pro.owner_user_name, pro.name]; + NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/tasks/board", pro.owner_user_name, pro.name]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:@{@"pageSize": @999} withMethodType:Get andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_Get label:@"看板列表"]; + +// NSArray *resultA = [NSObject arrayFromJSON:data[@"data"][@"list"] ofObjects:@"EABoardTaskList"]; + NSArray *resultA = [NSObject arrayFromJSON:data[@"data"][@"board_lists"] ofObjects:@"EABoardTaskList"]; + if (resultA) { + if (resultA.count > 2) { + pro.hasEverHandledBoard = YES; + } + pro.board_id = resultA.firstObject.board_id; + [resultA setValue:pro forKey:@"curPro"];//辅助属性 + } + block(resultA, nil); + }else{ + block(nil, error); + } + }]; +} + +- (void)request_AddBoardTaskListsInPro:(Project *)pro withTitle:(NSString *)title andBlock:(void (^)(EABoardTaskList *data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/tasks/board/%@/list", pro.owner_user_name, pro.name, pro.board_id]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:@{@"title": title ?: @""} withMethodType:Post andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"看板列表_添加"]; + + data = [NSObject objectOfClass:@"EABoardTaskList" fromJSON:data[@"data"]]; + } + block(data, error); + }]; +} + +- (void)request_DeleteBoardTaskList:(EABoardTaskList *)boardTL andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/tasks/board/%@/list/%@", boardTL.curPro.owner_user_name, boardTL.curPro.name, boardTL.board_id, boardTL.id]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Delete andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"看板列表_删除"]; + } + block(data, error); + }]; + +} + +- (void)request_RenameBoardTaskList:(EABoardTaskList *)boardTL withTitle:(NSString *)title andBlock:(void (^)(EABoardTaskList *data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/tasks/board/%@/list/%@", boardTL.curPro.owner_user_name, boardTL.curPro.name, boardTL.board_id, boardTL.id]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:@{@"title": title ?: @""} withMethodType:Put andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"看板列表_修改"]; + + data = [NSObject objectOfClass:@"EABoardTaskList" fromJSON:data[@"data"]]; + } + block(data, error); + }]; +} + +- (void)request_TaskInBoardTaskList:(EABoardTaskList *)boardTL andBlock:(void (^)(EABoardTaskList *data, NSError *error))block{//这里返回的 data 主要是 list 和 page 数据,而没有 EABoardTaskList 的相关业务属性 + boardTL.isLoading = YES; + NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/tasks/board/%@/list/%@/tasks", boardTL.curPro.owner_user_name, boardTL.curPro.name, boardTL.board_id, boardTL.id]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:boardTL.toParams withMethodType:Get andBlock:^(id data, NSError *error) { + boardTL.isLoading = NO; + if (data) { + [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"看板列表_任务列表"]; + + data = [NSObject objectOfClass:@"EABoardTaskList" fromJSON:data[@"data"]]; + } + block(data, error); + }]; +} + +- (void)request_PutTask:(Task *)task toBoardTaskList:(EABoardTaskList *)boardTL andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/user/%@/project/%@/tasks/board/%@/list/%@/task/%@", task.project.owner_user_name, task.project.name, boardTL.board_id, boardTL.id, task.id]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Put andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"任务_修改看板列表"]; + } + block(data, error); + }]; +} + #pragma mark User - (void)request_AddUser:(User *)user ToProject:(Project *)project andBlock:(void (^)(id data, NSError *error))block{ // 一次添加多个成员(逗号分隔):users=102,4 (以后只支持 gk,不支持 id 了) @@ -1739,18 +2729,23 @@ - (void)request_ProjectTopic_LabelMy_WithPath:(NSString *)path #pragma mark - Project Tag - (void)request_TagListInProject:(Project *)project type:(ProjectTagType)type andBlock:(void (^)(id data, NSError *error))block{ NSString *path = nil; - switch (type) { - case ProjectTagTypeTopic: - path = [NSString stringWithFormat:@"api/project/%@/topic/label?withCount=true", project.id.stringValue]; - break; + NSDictionary *params = @{@"withCount": @(YES)}; + if (kTarget_Enterprise) { + path = [NSString stringWithFormat:@"api/user/%@/project/%@/labels", [Login curLoginCompany].global_key, project.name]; + }else{ + switch (type) { + case ProjectTagTypeTopic: + path = [NSString stringWithFormat:@"api/project/%@/topic/label", project.id.stringValue]; + break; case ProjectTagTypeTask: - path = [NSString stringWithFormat:@"api/user/%@/project/%@/task/label?withCount=true", project.owner_user_name, project.name]; - break; - default: - return; - break; + path = [NSString stringWithFormat:@"api/user/%@/project/%@/task/label", project.owner_user_name, project.name]; + break; + default: + return; + break; + } } - [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Get andBlock:^(id data, NSError *error) { + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:params withMethodType:Get andBlock:^(id data, NSError *error) { if (data) { [MobClick event:kUmeng_Event_Request_Get label:@"标签列表"]; @@ -1898,7 +2893,7 @@ - (void)request_Tweet_DoTweet_WithObj:(Tweet *)tweet andBlock:(void (^)(id data, whetherAllImagesUploadedAndSendTweetBlock(); } } progerssBlock:^(CGFloat progressValue) { - DebugLog(@"progressValue %@ : %.2f", imageItem.assetURL.query, progressValue); + DebugLog(@"progressValue %@ : %.2f", imageItem.assetLocalIdentifier, progressValue); }]; } } @@ -1921,6 +2916,22 @@ - (void)request_Tweet_DoProjectTweet_WithPro:(NSNumber *)pro_id content:(NSStrin }]; } +- (void)request_Tweet_EditProjectTweet:(Tweet *)tweet content:(NSString *)content andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/project/%@/tweet/%@", tweet.project_id, tweet.id]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:@{@"raw": content} withMethodType:Put andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"冒泡_修改_项目内冒泡"]; + + id resultData = [data valueForKeyPath:@"data"]; + Tweet *result = [NSObject objectOfClass:@"Tweet" fromJSON:resultData]; + block(result, nil); + }else{ + [NSObject showStatusBarError:error]; + block(nil, error); + } + }]; +} + - (void)request_Tweet_Likers_WithObj:(Tweet *)tweet andBlock:(void (^)(id data, NSError *error))block{ tweet.isLoading = YES; [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:[tweet toLikersPath] withParams:[tweet toLikersParams] withMethodType:Get andBlock:^(id data, NSError *error) { @@ -1995,7 +3006,7 @@ - (void)request_TweetComment_Delete_WithTweet:(Tweet *)tweet andComment:(Comment } - (void)request_Tweet_Detail_WithObj:(Tweet *)tweet andBlock:(void (^)(id data, NSError *error))block{ - [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:[tweet toDetailPath] withParams:nil withMethodType:Get andBlock:^(id data, NSError *error) { + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:[tweet toDetailPath] withParams:@{@"withRaw": @YES} withMethodType:Get andBlock:^(id data, NSError *error) { if (data) { [MobClick event:kUmeng_Event_Request_Get label:@"冒泡_详情"]; @@ -2039,6 +3050,12 @@ - (void)request_UserInfo_WithObj:(User *)curUser andBlock:(void (^)(id data, NSE id resultData = [data valueForKeyPath:@"data"]; User *user = [NSObject objectOfClass:@"User" fromJSON:resultData]; if (user.id.intValue == [Login curLoginUser].id.intValue) { + if (user.vip.integerValue == 2) { + User *loginU = [Login curLoginUser]; + if (loginU.vip.integerValue < 2) { + [CodingVipTipManager showTip]; + } + } [Login doLogin:resultData]; } block(user, nil); @@ -2080,6 +3097,11 @@ - (void)request_FollowersOrFriends_WithObj:(Users *)curUsers andBlock:(void (^)( NSObject *resultA = nil; if ([path hasSuffix:@"stargazers"] || [path hasSuffix:@"watchers"]) { resultA = [NSArray arrayFromJSON:resultData ofObjects:@"User"]; + }else if ([path hasSuffix:@"members"]){//企业成员 + if ([resultData isKindOfClass:[NSArray class]] && [(NSArray *)resultData count] > 0) { + resultData = [resultData valueForKey:@"user"]; + } + resultA = [NSArray arrayFromJSON:resultData ofObjects:@"User"]; }else{ resultA = [NSObject objectOfClass:@"Users" fromJSON:resultData]; } @@ -2136,6 +3158,12 @@ - (void)request_UpdateUserInfo_WithObj:(User *)curUser andBlock:(void (^)(id dat id resultData = [data valueForKeyPath:@"data"]; User *user = [NSObject objectOfClass:@"User" fromJSON:resultData]; if (user) { + if (user.vip.integerValue == 2) { + User *loginU = [Login curLoginUser]; + if (loginU.vip.integerValue < 2) { + [CodingVipTipManager showTip]; + } + } [Login doLogin:resultData]; } block(user, nil); @@ -2146,13 +3174,18 @@ - (void)request_UpdateUserInfo_WithObj:(User *)curUser andBlock:(void (^)(id dat }]; } -- (void)request_GeneratePhoneCodeToResetPhone:(NSString *)phone phoneCountryCode:(NSString *)phoneCountryCode block:(void (^)(id data, NSError *error))block{ +- (void)request_GeneratePhoneCodeToResetPhone:(NSString *)phone phoneCountryCode:(NSString *)phoneCountryCode withCaptcha:(NSString *)captcha block:(void (^)(id data, NSError *error))block{ NSString *path = @"api/account/phone/change/code"; - NSDictionary *params = @{@"phone": phone, - @"phoneCountryCode": phoneCountryCode}; - [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:params withMethodType:Post andBlock:^(id data, NSError *error) { + NSMutableDictionary *params = @{@"phone": phone, + @"phoneCountryCode": phoneCountryCode}.mutableCopy; + if (captcha.length > 0) { + params[@"j_captcha"] = captcha; + } + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:params withMethodType:Post autoShowError:captcha.length > 0 andBlock:^(id data, NSError *error) { if (data) { [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"生成手机验证码_绑定手机号"]; + }else if (captcha.length <= 0 && error && error.userInfo[@"msg"] && ![[error.userInfo[@"msg"] allKeys] containsObject:@"j_captcha_error"]) { + [NSObject showError:error]; } block(data, error); }]; @@ -2165,7 +3198,16 @@ - (void)request_PointRecords:(PointRecords *)records andBlock:(void (^)(id data, data = [data valueForKey:@"data"]; PointRecords *resultA = [NSObject objectOfClass:@"PointRecords" fromJSON:data]; - block(resultA, nil); + if (!records.points_left) { + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:@"api/point/points" withParams:nil withMethodType:Get andBlock:^(id data, NSError *error) { + if (data) { + records.points_left = data[@"data"][@"points_left"]; + } + block(resultA, nil); + }]; + }else{ + block(resultA, nil); + } }else{ block(nil, error); } @@ -2472,7 +3514,7 @@ - (void)request_ReadMeOFProject:(Project *)project andBlock:(void (^)(id data, N rCodeFile.file = realFile; block(rCodeFile, nil); }else{ - block(@"我们推荐每个项目都新建一个README文件(客户端暂时不支持创建和编辑README)", nil); + block(@"

该项目暂无 README.md ,我们推荐每个项目都新建一个 README.md 文件。(客户端暂不支持创建和编辑,请前往网站创建)

", nil); } }else{ block(nil, error); @@ -2481,7 +3523,7 @@ - (void)request_ReadMeOFProject:(Project *)project andBlock:(void (^)(id data, N }else{ [MobClick event:kUmeng_Event_Request_Get label:@"项目_README"]; - block(@"我们推荐每个项目都新建一个README文件(客户端暂时不支持创建和编辑README)", nil); + block(@"

该项目暂无 README.md ,我们推荐每个项目都新建一个 README.md 文件。(客户端暂不支持创建和编辑,请前往网站创建)

", nil); } }else{ block(@"加载失败...", errorTemp); @@ -2531,7 +3573,8 @@ - (void)uploadTweetImage:(UIImage *)image done(nil, [NSError errorWithDomain:@"DATA EMPTY" code:0 userInfo:@{NSLocalizedDescriptionKey : @"有张照片没有读取成功"}]); return; } - [[CodingNetAPIClient sharedJsonClient] uploadImage:image path:@"api/tweet/insert_image" name:@"tweetImg" successBlock:^(AFHTTPRequestOperation *operation, id responseObject) { + NSString *path = [NSObject isPrivateCloud].boolValue? @"api/message/send_image": @"https://up.qbox.me/"; + [[CodingNetAPIClient sharedJsonClient] uploadImage:image path:path name:@"file" successBlock:^(AFHTTPRequestOperation *operation, id responseObject) { NSString *reslutString = [responseObject objectForKey:@"data"]; DebugLog(@"%@", reslutString); done(reslutString, nil); @@ -2566,6 +3609,49 @@ - (void)request_UpdateUserIconImage:(UIImage *)image } progerssBlock:progress]; } +- (void)request_UpdateTeamIconImage:(UIImage *)image + successBlock:(void (^)(id responseObj))success + failureBlock:(void (^)(NSError *error))failure + progerssBlock:(void (^)(CGFloat progressValue))progress{ + if (!image) { + [NSObject showHudTipStr:@"读图失败"]; + return; + } + [NSObject showStatusBarQueryStr:@"正在上传头像"]; + CGSize maxSize = CGSizeMake(800, 800); + if (image.size.width > maxSize.width || image.size.height > maxSize.height) { + image = [image scaleToSize:maxSize usingMode:NYXResizeModeAspectFit]; + } + [[CodingNetAPIClient sharedJsonClient] uploadImage:image path:@"api/user/avatar" name:@"file" successBlock:^(AFHTTPRequestOperation *operation, id responseObject) { + id resultData = [responseObject valueForKeyPath:@"data"]; + if (resultData) { + NSString *path = [NSString stringWithFormat:@"api/team/%@/avatar", [NSObject baseCompany]]; + NSDictionary *params = @{@"url": resultData, + }; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:params withMethodType:Put andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_ActionOfServer label:@"企业信息_更换头像"]; + + [NSObject showStatusBarSuccessStr:@"上传头像成功"]; + Team *team = [NSObject objectOfClass:@"Team" fromJSON:data[@"data"]]; + if (team) { + [Login doLoginCompany:data[@"data"]]; + } + success(team); + }else{ + failure(error); + [NSObject showStatusBarError:error]; + } + }]; + }else{ + [NSObject showStatusBarErrorStr:@"上传失败"]; + } + } failureBlock:^(AFHTTPRequestOperation *operation, NSError *error) { + failure(error); + [NSObject showStatusBarError:error]; + } progerssBlock:progress]; +} + - (void)loadImageWithPath:(NSString *)imageUrlStr completeBlock:(void (^)(UIImage *image, NSError *error))block{ NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:imageUrlStr]]; AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; @@ -2630,6 +3716,22 @@ - (void)request_JoinedUsers_WithTopicID:(NSInteger)topicID page:(NSInteger)page }]; } +- (void)request_Users_activenessWithGlobalKey:(NSString *)globalKey andBlock:(void (^)(ActivenessModel *data, NSError *error))block { + NSString *path = [NSString stringWithFormat:@"api/user/activeness/data/%@",globalKey]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Get andBlock:^(id data, NSError *error) { + if (data) { + [MobClick event:kUmeng_Event_Request_Get label:@"用户活跃图"]; + + id resultData = [data valueForKeyPath:@"data"]; + ActivenessModel *resultA = [NSObject objectOfClass:@"ActivenessModel" fromJSON:resultData]; + resultA.dailyActiveness = [NSObject arrayFromJSON:resultData[@"daily_activeness"] ofObjects:@"DailyActiveness"]; + block(resultA, nil); + }else{ + block(nil, error); + } + }]; +} + - (void)request_MDHtmlStr_WithMDStr:(NSString *)mdStr inProject:(Project *)project andBlock:(void (^)(id data, NSError *error))block{ NSString *path = @"api/markdown/previewNoAt"; if (project.name && project.owner_user_name) { @@ -2682,8 +3784,15 @@ - (void)request_VerifyTypeWithBlock:(void (^)(VerifyType type, NSError *error))b } #pragma mark - 2FA -- (void)post_Close2FAGeneratePhoneCode:(NSString *)phone block:(void (^)(id data, NSError *error))block{ - [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:@"api/twofa/close/code" withParams:@{@"phone": phone, @"from": @"mart"} withMethodType:Post andBlock:^(id data, NSError *error) { +- (void)post_Close2FAGeneratePhoneCode:(NSString *)phone withCaptcha:(NSString *)captcha block:(void (^)(id data, NSError *error))block{ + NSMutableDictionary *params = @{@"phone": phone, @"from": @"mart"}.mutableCopy; + if (captcha.length > 0) { + params[@"j_captcha"] = captcha; + } + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:@"api/twofa/close/code" withParams:params withMethodType:Post autoShowError:captcha.length > 0 andBlock:^(id data, NSError *error) { + if (captcha.length <= 0 && error && error.userInfo[@"msg"] && ![[error.userInfo[@"msg"] allKeys] containsObject:@"j_captcha_error"]) { + [NSObject showError:error]; + } block(data, error); }]; } @@ -2794,7 +3903,8 @@ - (void)requestWithSearchString:(NSString *)strSearch typeStr:(NSString*)type an NSString *path = [NSString stringWithFormat:@"/api/esearch/%@?q=%@&page=%d",type,strSearch, (int)page]; if ([type isEqualToString:@"all"]) { - path=[NSString stringWithFormat:@"%@&types=projects,project_topics,tasks,tweets,files,friends,merge_requests,pull_requests",path]; +// path=[NSString stringWithFormat:@"%@&types=projects,project_topics,tasks,tweets,files,friends,merge_requests,pull_requests",path]; + path=[NSString stringWithFormat:@"%@&types=projects,tasks,tweets,files,friends,merge_requests",path]; }else if ([type isEqualToString:@"public_project"]) { path=[NSString stringWithFormat:@"/api/esearch/project?q=%@ related:false&page=%d",strSearch,(int)page]; } @@ -3000,7 +4110,28 @@ - (void)request_shop_exchangeWithParms:(NSDictionary *)parms andBlock:(void (^)( block(nil, error); } }]; +} + +- (void)request_shop_orderWithParms:(NSDictionary *)parms andBlock:(void (^)(ShopOrder *shopOrder, NSError *error))block{ + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:@"api/gifts/orders" withParams:parms withMethodType:Post andBlock:^(id data, NSError *error) { + block([NSObject objectOfClass:@"ShopOrder" fromJSON:data[@"data"]], error); + }]; +} + +- (void)request_shop_payOrder:(NSString *)orderId method:(NSString *)method andBlock:(void (^)(NSDictionary *payDict, NSError *error))block{ + NSDictionary *parms = @{@"pay_method": method}; + NSString *path = [NSString stringWithFormat:@"api/gifts/pay/%@", orderId]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:parms withMethodType:Post andBlock:^(id data, NSError *error) { + block(data[@"data"], error); + }]; +} + +- (void)request_shop_deleteOrder:(NSString *)orderId andBlock:(void (^)(id data, NSError *error))block{ + NSString *path = [NSString stringWithFormat:@"api/gifts/orders/%@", orderId]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:nil withMethodType:Delete andBlock:^(id data, NSError *error) { + block(data, error); + }]; } - (void)request_LocationListWithParams:(NSDictionary *)params block:(void (^)(id data, NSError *error))block{ diff --git a/Coding_iOS/Util/Manager/FunctionIntroManager.m b/Coding_iOS/Util/Manager/FunctionIntroManager.m index 0ab0b5fc1..73c8551bc 100644 --- a/Coding_iOS/Util/Manager/FunctionIntroManager.m +++ b/Coding_iOS/Util/Manager/FunctionIntroManager.m @@ -7,7 +7,9 @@ // #define kIntroPageKey @"intro_page_version" -#define kIntroPageNum 3 +#define kIntroPageNum 1 +#define kIntroShowSkipButton (NO) +#define kIntroShowUseImmediatelyButton (YES) #import "FunctionIntroManager.h" #import "EAIntroView.h" @@ -31,7 +33,7 @@ + (void)showIntroPage{ + (BOOL)needToShowIntro{ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSString *preVersion = [defaults stringForKey:kIntroPageKey]; - BOOL needToShow = ![preVersion isEqualToString:kVersionBuild_Coding]; + BOOL needToShow = ([kVersion_Coding isEqualToString:@"5.0"] && kIntroPageNum > 0 && ![preVersion isEqualToString:kVersionBuild_Coding]); return needToShow; } @@ -41,6 +43,16 @@ + (void)markHasBeenShowed{ [defaults synchronize]; } ++ (NSString *)p_imageNameForIndex:(NSInteger)index{ + NSString *imageName = [NSString stringWithFormat:@"intro_page%ld", (long)index]; + imageName = [imageName stringByAppendingString:(kDevice_Is_iPhone6Plus? @"_ip6+": + kDevice_Is_iPhone6? @"_ip6": + kDevice_Is_iPhone5? @"_ip5": + kDevice_Is_FullScreen? @"_ipX": + @"_ip4")]; + return imageName; +} + #pragma mark private M + (instancetype)shareManager{ @@ -80,6 +92,9 @@ - (instancetype)init - (UIPageControl *)p_pageControl{ UIImage *pageIndicatorImage = [UIImage imageNamed:@"intro_page_unselected"]; UIImage *currentPageIndicatorImage = [UIImage imageNamed:@"intro_page_selected"]; +// UIImage *pageIndicatorImage = [UIImage imageWithColor:[UIColor colorWithHexString:@"0x0060FF" andAlpha:.5] withFrame:CGRectMake(0, 0, 10, 3)]; +// UIImage *currentPageIndicatorImage = [UIImage imageWithColor:kColorBrandBlue withFrame:CGRectMake(0, 0, 20, 3)]; + if (!kDevice_Is_iPhone6 && !kDevice_Is_iPhone6Plus) { CGFloat desginWidth = 375.0;//iPhone6 的设计尺寸 CGFloat scaleFactor = kScreen_Width/desginWidth; @@ -108,12 +123,12 @@ - (UIButton *)p_skipButton{ - (UIButton *)p_useImmediatelyButton{ UIButton *button = [UIButton new]; [button addTarget:self action:@selector(dismissIntroView) forControlEvents:UIControlEventTouchUpInside]; - button.titleLabel.font = [UIFont boldSystemFontOfSize:20]; - button.backgroundColor = kColorBrandGreen; + button.titleLabel.font = [UIFont boldSystemFontOfSize:17]; + button.backgroundColor = kColorBrandBlue; [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; [button setTitleColor:[UIColor lightTextColor] forState:UIControlStateHighlighted]; [button setTitle:@"立即体验" forState:UIControlStateNormal]; - [button doBorderWidth:0 color:nil cornerRadius:4.0]; +// [button doBorderWidth:0 color:nil cornerRadius:4.0]; return button; } @@ -122,11 +137,7 @@ - (void)dismissIntroView{ } - (EAIntroPage *)p_pageWithIndex:(NSInteger)index{ - NSString *imageName = [NSString stringWithFormat:@"intro_page%ld", (long)index]; - imageName = [imageName stringByAppendingString:(kDevice_Is_iPhone6Plus? @"_ip6+": - kDevice_Is_iPhone6? @"_ip6": - kDevice_Is_iPhone5? @"_ip5": - @"_ip4")]; + NSString *imageName = [self.class p_imageNameForIndex:index]; UIImageView *imageView = [UIImageView new]; imageView.userInteractionEnabled = YES; imageView.contentMode = UIViewContentModeScaleAspectFill; @@ -134,21 +145,25 @@ - (EAIntroPage *)p_pageWithIndex:(NSInteger)index{ imageView.image = [UIImage imageNamed:imageName]; imageView.backgroundColor = imageView.image? [UIColor clearColor]: [UIColor randomColor]; if (index < kIntroPageNum - 1) { - UIButton *button = [self p_skipButton]; - [imageView addSubview:button]; - [button mas_makeConstraints:^(MASConstraintMaker *make) { - make.size.mas_equalTo(CGSizeMake(60, 30)); - make.top.equalTo(imageView).offset(30); - make.right.equalTo(imageView).offset(-20); - }]; + if (kIntroShowSkipButton) { + UIButton *button = [self p_skipButton]; + [imageView addSubview:button]; + [button mas_makeConstraints:^(MASConstraintMaker *make) { + make.size.mas_equalTo(CGSizeMake(60, 30)); + make.top.equalTo(imageView).offset(10 + kSafeArea_Top); + make.right.equalTo(imageView).offset(-20); + }]; + } }else{ - UIButton *button = [self p_useImmediatelyButton]; - [imageView addSubview:button]; - [button mas_makeConstraints:^(MASConstraintMaker *make) { - make.size.mas_equalTo(CGSizeMake(200, 44)); - make.centerX.equalTo(imageView); - make.bottom.equalTo(imageView).offset(kDevice_Is_iPhone4? -30: -40); - }]; + if (kIntroShowUseImmediatelyButton) { + UIButton *button = [self p_useImmediatelyButton]; + [imageView addSubview:button]; + [button mas_makeConstraints:^(MASConstraintMaker *make) { + make.size.mas_equalTo(CGSizeMake(200, (kDevice_Use_iPhone4_Layout || kDevice_Is_iPhone5)? 50: 55)); + make.centerX.equalTo(imageView); + make.bottom.equalTo(imageView).offset(kDevice_Use_iPhone4_Layout? -40: kDevice_Is_iPhone5? -65: kDevice_Is_iPhone6? -70: kDevice_Is_iPhone6Plus? -90: -120); + }]; + } } EAIntroPage *page = [EAIntroPage pageWithCustomView:imageView]; return page; @@ -156,13 +171,13 @@ - (EAIntroPage *)p_pageWithIndex:(NSInteger)index{ #pragma mark EAIntroDelegate - (void)intro:(EAIntroView *)introView pageStartScrolling:(EAIntroPage *)page withIndex:(NSUInteger)pageIndex{ - introView.pageControl.hidden = (pageIndex >= kIntroPageNum - 2); + introView.pageControl.hidden = (pageIndex >= kIntroPageNum - 2 && kDevice_Use_iPhone4_Layout); } - (void)intro:(EAIntroView *)introView pageAppeared:(EAIntroPage *)page withIndex:(NSUInteger)pageIndex{ - introView.pageControl.hidden = (pageIndex == kIntroPageNum - 1); + introView.pageControl.hidden = (pageIndex == kIntroPageNum - 1 && kDevice_Use_iPhone4_Layout); } - (void)intro:(EAIntroView *)introView pageEndScrolling:(EAIntroPage *)page withIndex:(NSUInteger)pageIndex{ - introView.pageControl.hidden = (pageIndex == kIntroPageNum - 1); + introView.pageControl.hidden = (pageIndex == kIntroPageNum - 1 && kDevice_Use_iPhone4_Layout); } @end diff --git a/Coding_iOS/Util/Manager/FunctionTipsManager.h b/Coding_iOS/Util/Manager/FunctionTipsManager.h index 1d36be806..351bf445c 100644 --- a/Coding_iOS/Util/Manager/FunctionTipsManager.h +++ b/Coding_iOS/Util/Manager/FunctionTipsManager.h @@ -6,25 +6,32 @@ // Copyright (c) 2015年 Coding. All rights reserved. // -//version: 3.0 -static NSString *kFunctionTipStr_MR = @"MergeRequest"; -static NSString *kFunctionTipStr_PR = @"PullRequest"; -static NSString *kFunctionTipStr_ReadMe = @"ReadMe"; -static NSString *kFunctionTipStr_CommitList = @"Code_CommitList"; -//version: 3.1.5 -static NSString *kFunctionTipStr_Search = @"hasSearch"; -static NSString *kFunctionTipStr_HotTopic = @"HotTopic"; -static NSString *kFunctionTipStr_TweetTopic = @"TweetTopic"; -//version: 3.2 -static NSString *kFunctionTipStr_VoiceMessage = @"VoiceMessage"; -static NSString *kFunctionTipStr_File_2V = @"File_2V"; -static NSString *kFunctionTipStr_File_2V_Version = @"File_2V_Version"; -static NSString *kFunctionTipStr_File_2V_Activity = @"File_2V_Activity"; -static NSString *kFunctionTipStr_LineNote_FileChange = @"LineNote_FileChange"; -static NSString *kFunctionTipStr_LineNote_MRPR = @"LineNote_MRPR"; -static NSString *kFunctionTipStr_Me_Points = @"Me_Points"; -//version: 3.7 -static NSString *kFunctionTipStr_Prefix = @"Prefix"; +////version: 3.0 +//static NSString *kFunctionTipStr_MR = @"MergeRequest"; +//static NSString *kFunctionTipStr_PR = @"PullRequest"; +//static NSString *kFunctionTipStr_ReadMe = @"ReadMe"; +//static NSString *kFunctionTipStr_CommitList = @"Code_CommitList"; +////version: 3.1.5 +//static NSString *kFunctionTipStr_Search = @"hasSearch"; +//static NSString *kFunctionTipStr_HotTopic = @"HotTopic"; +//static NSString *kFunctionTipStr_TweetTopic = @"TweetTopic"; +////version: 3.2 +//static NSString *kFunctionTipStr_VoiceMessage = @"VoiceMessage"; +//static NSString *kFunctionTipStr_File_2V = @"File_2V"; +//static NSString *kFunctionTipStr_File_2V_Version = @"File_2V_Version"; +//static NSString *kFunctionTipStr_File_2V_Activity = @"File_2V_Activity"; +//static NSString *kFunctionTipStr_LineNote_FileChange = @"LineNote_FileChange"; +//static NSString *kFunctionTipStr_LineNote_MRPR = @"LineNote_MRPR"; +//static NSString *kFunctionTipStr_Me_Points = @"Me_Points"; +////version: 3.7 +static NSString *kFunctionTipStr_StartLinkPrefix = @"StartLinkPrefix"; +////version 4.0.8 +//static NSString *kFunctionTipStr_File_3V = @"File_3V"; +//version 4.5 +static NSString *kFunctionTipStr_Me_Shop = @"Me_Shop"; +//version 4.9.5 +static NSString *kFunctionTipStr_TaskTitleViewTap = @"TaskTitleViewTap"; + #import diff --git a/Coding_iOS/Util/Manager/FunctionTipsManager.m b/Coding_iOS/Util/Manager/FunctionTipsManager.m index 5f254b858..2279090da 100644 --- a/Coding_iOS/Util/Manager/FunctionTipsManager.m +++ b/Coding_iOS/Util/Manager/FunctionTipsManager.m @@ -32,20 +32,9 @@ - (instancetype)init if (![[_tipsDict valueForKey:@"version"] isEqualToString:kVersionBuild_Coding]) { _tipsDict = [@{kFunctionTipStr_Version: kVersionBuild_Coding, //Function Need To Tip -// kFunctionTipStr_MR: @(YES), -// kFunctionTipStr_PR: @(YES), -// kFunctionTipStr_ReadMe: @(YES), -// kFunctionTipStr_CommitList: @(YES), -// kFunctionTipStr_Search: @(YES), -// kFunctionTipStr_HotTopic: @(YES), -// kFunctionTipStr_TweetTopic: @(YES), -// kFunctionTipStr_VoiceMessage: @(YES), -// kFunctionTipStr_File_2V: @(YES), -// kFunctionTipStr_File_2V_Activity: @(YES), -// kFunctionTipStr_File_2V_Version: @(YES), -// kFunctionTipStr_LineNote_MRPR: @(YES), -// kFunctionTipStr_LineNote_FileChange: @(YES), -// kFunctionTipStr_Me_Points: @(YES), +// kFunctionTipStr_File_3V: @(YES), +// kFunctionTipStr_Me_Shop: @(YES), +// kFunctionTipStr_TaskTitleViewTap: @(YES), } mutableCopy]; [_tipsDict writeToFile:[self p_cacheFilePath] atomically:YES]; } @@ -63,7 +52,7 @@ - (NSString *)p_cacheFilePath{ - (BOOL)needToTip:(NSString *)functionStr{ NSNumber *needToTip = [_tipsDict valueForKey:functionStr]; if (!needToTip) { - return [functionStr hasPrefix:kFunctionTipStr_Prefix]; + return [functionStr hasPrefix:kFunctionTipStr_StartLinkPrefix]; }else{ return needToTip.boolValue; } diff --git a/Coding_iOS/Util/Manager/RewardTipManager.h b/Coding_iOS/Util/Manager/RewardTipManager.h new file mode 100644 index 000000000..2fd992fea --- /dev/null +++ b/Coding_iOS/Util/Manager/RewardTipManager.h @@ -0,0 +1,14 @@ +// +// RewardTipManager.h +// Coding_iOS +// +// Created by Ease on 2016/12/14. +// Copyright © 2016年 Coding. All rights reserved. +// + +#import + +@interface RewardTipManager : NSObject + ++ (void)showTipWithTitle:(NSString *)title rewardPoint:(NSString *)rewardPoint;//rewardPoint:@"0.1 MB" +@end diff --git a/Coding_iOS/Util/Manager/RewardTipManager.m b/Coding_iOS/Util/Manager/RewardTipManager.m new file mode 100644 index 000000000..eaf3bc23c --- /dev/null +++ b/Coding_iOS/Util/Manager/RewardTipManager.m @@ -0,0 +1,175 @@ +// +// RewardTipManager.m +// Coding_iOS +// +// Created by Ease on 2016/12/14. +// Copyright © 2016年 Coding. All rights reserved. +// + +#import "RewardTipManager.h" +#import "PointRecordsViewController.h" +#import "Login.h" + +@interface RewardTipManager () +@property (strong, nonatomic) NSString *title, *rewardPoint; + +@property (strong, nonatomic) UIView *bgView, *contentView; +@property (strong, nonatomic) UIImageView *logoImgV; +@property (strong, nonatomic) UILabel *titleL, *rewardPointL; +@property (strong, nonatomic) UIButton *closeBtn, *knowMoreBtn; +@end + +@implementation RewardTipManager ++ (instancetype)shareManager{ + static RewardTipManager *shared_manager = nil; + static dispatch_once_t pred; + dispatch_once(&pred, ^{ + shared_manager = [[self alloc] init]; + }); + return shared_manager; +} + ++ (void)showTipWithTitle:(NSString *)title rewardPoint:(NSString *)rewardPoint{ + if (![Login isLogin]) { + return; + } + RewardTipManager *manager = [self shareManager]; + manager.title = title; + manager.rewardPoint = rewardPoint; + [manager p_show]; +} + +- (instancetype)init{ + self = [super init]; + if (self) { + //层级关系 + _bgView = [UIView new]; + _contentView = [UIView new]; + + _logoImgV = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"reward_tip_logo"]]; + _titleL = [UILabel labelWithFont:[UIFont boldSystemFontOfSize:18] textColor:[UIColor colorWithHexString:@"0x222222"]]; + _rewardPointL = [UILabel labelWithSystemFontSize:15 textColorHexString:@"0x222222"]; + _knowMoreBtn = ({ + UIButton *button = [UIButton new]; + button.backgroundColor = kColorTableSectionBg; + button.titleLabel.font = [UIFont systemFontOfSize:17]; + [button setTitleColor:kColorNavTitle forState:UIControlStateNormal]; + [button setTitle:@"了解码币" forState:UIControlStateNormal]; + [button addTarget:self action:@selector(knowMoreBtnClicked) forControlEvents:UIControlEventTouchUpInside]; + button; + }); + _closeBtn = ({ + UIButton *button = [UIButton new]; + button.backgroundColor = kColorTableSectionBg; + button.titleLabel.font = [UIFont systemFontOfSize:17]; + [button setTitleColor:kColorNavTitle forState:UIControlStateNormal]; + [button setTitle:@"知道了" forState:UIControlStateNormal]; + [button addTarget:self action:@selector(p_dismiss) forControlEvents:UIControlEventTouchUpInside]; + button; + }); + [_contentView addSubview:_logoImgV]; + [_contentView addSubview:_titleL]; + [_contentView addSubview:_rewardPointL]; + [_contentView addSubview:_knowMoreBtn]; + [_contentView addSubview:_closeBtn]; + [_bgView addSubview:_contentView]; + //属性设置 + _contentView.backgroundColor = kColorTableSectionBg; + _contentView.layer.masksToBounds = YES; + _contentView.layer.cornerRadius = 6; + _rewardPointL.textAlignment = _titleL.textAlignment = NSTextAlignmentCenter; + _titleL.numberOfLines = 0; + //位置大小 + [_contentView mas_makeConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo(270); + make.center.equalTo(_bgView); + }]; + [_logoImgV mas_makeConstraints:^(MASConstraintMaker *make) { + make.size.mas_equalTo(CGSizeMake(88, 67)); + make.centerX.equalTo(_contentView); + make.top.equalTo(_contentView).mas_offset(30); + }]; + [_titleL mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(_logoImgV.mas_bottom).offset(30); + make.left.equalTo(_contentView).offset(15); + make.right.equalTo(_contentView).offset(-15); + }]; + [_rewardPointL mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(_titleL.mas_bottom).offset(10); + make.left.right.equalTo(_titleL); + }]; + [_knowMoreBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(_rewardPointL.mas_bottom).offset(30); + make.left.equalTo(_contentView).offset(0); + make.bottom.equalTo(_contentView).offset(0); + make.right.equalTo(_closeBtn.mas_left).offset(0); + make.width.equalTo(_closeBtn); + make.height.mas_equalTo(44); + }]; + [_closeBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.equalTo(_contentView).offset(0); + make.top.bottom.equalTo(_knowMoreBtn); + }]; + //改 UI,加两条线 + UIView *hLineV = [UIView new]; + UIView *vLineV = [UIView new]; + hLineV.backgroundColor = vLineV.backgroundColor = kColorDDD; + [_contentView addSubview:hLineV]; + [_contentView addSubview:vLineV]; + [hLineV mas_makeConstraints:^(MASConstraintMaker *make) { + make.bottom.equalTo(_closeBtn.mas_top); + make.left.right.equalTo(_contentView); + make.height.mas_equalTo(kLine_MinHeight); + }]; + [vLineV mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(_contentView); + make.top.bottom.equalTo(_closeBtn); + make.width.mas_equalTo(kLine_MinHeight); + }]; + //关联事件 + [_bgView bk_whenTapped:^{ + [self p_dismiss]; + }]; + } + return self; +} + +- (void)setTitle:(NSString *)title{ + _title = title; + _titleL.text = _title; +} + +- (void)setRewardPoint:(NSString *)rewardPoint{ + _rewardPoint = rewardPoint; + [_rewardPointL setAttrStrWithStr:[NSString stringWithFormat:@"获得 %@ 的奖励", _rewardPoint] diffColorStr:_rewardPoint diffColor:[UIColor colorWithHexString:@"0xF5A623"]]; +} + +- (void)knowMoreBtnClicked{ + PointRecordsViewController *vc = [PointRecordsViewController new]; + [BaseViewController goToVC:vc]; + [self p_dismiss]; +} + +- (void)p_show{ + //初始状态 + _bgView.backgroundColor = [UIColor clearColor]; + _contentView.alpha = 0; + _bgView.frame = kScreen_Bounds; + + [kKeyWindow addSubview:_bgView]; + [UIView animateWithDuration:0.3 animations:^{ + _bgView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5]; + _contentView.alpha = 1; + } completion:nil]; +} + +- (void)p_dismiss{ + [UIView animateWithDuration:0.3 animations:^{ + _bgView.backgroundColor = [UIColor clearColor]; + _contentView.alpha = 0; + } completion:^(BOOL finished) { + [_bgView removeFromSuperview]; + }]; +} + +@end diff --git a/Coding_iOS/Util/Manager/SendRewardManager.m b/Coding_iOS/Util/Manager/SendRewardManager.m index d5ac61918..65b3041fa 100644 --- a/Coding_iOS/Util/Manager/SendRewardManager.m +++ b/Coding_iOS/Util/Manager/SendRewardManager.m @@ -73,7 +73,7 @@ - (instancetype)init _bgView = [UIView new]; _contentView = [UIView new]; _closeBtn = [UIButton new]; - _userImgV = [UIImageView new]; + _userImgV = [YLImageView new]; _titleL = [UILabel new]; _passwordF = [UITextField new]; _submitBtn = [UIButton buttonWithStyle:StrapSuccessStyle andTitle:@"确认打赏" andFrame:CGRectMake(0, 0, buttonHeight, buttonHeight) target:self action:@selector(submitBtnClicked)]; @@ -296,7 +296,7 @@ - (void)p_show{ [kKeyWindow addSubview:_bgView]; [UIView animateWithDuration:0.3 animations:^{ - _bgView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.6]; + _bgView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5]; _contentView.alpha = 1; } completion:^(BOOL finished) { if (_isNeedPassword) { diff --git a/Coding_iOS/Util/Manager/StartImagesManager.h b/Coding_iOS/Util/Manager/StartImagesManager.h index 5cf5b52cb..5a7d283a8 100644 --- a/Coding_iOS/Util/Manager/StartImagesManager.h +++ b/Coding_iOS/Util/Manager/StartImagesManager.h @@ -19,6 +19,8 @@ - (void)handleStartLink; - (void)refreshImagesPlist; +- (void)refreshImagesBlock:(void(^)(NSArray *images, NSError *error))bk; + - (void)startDownloadImages; @end @@ -37,4 +39,4 @@ @interface Group : NSObject @property (strong, nonatomic) NSString *name, *author, *link; -@end \ No newline at end of file +@end diff --git a/Coding_iOS/Util/Manager/StartImagesManager.m b/Coding_iOS/Util/Manager/StartImagesManager.m index 7e04af639..780b3ffc0 100644 --- a/Coding_iOS/Util/Manager/StartImagesManager.m +++ b/Coding_iOS/Util/Manager/StartImagesManager.m @@ -94,7 +94,7 @@ - (void)handleStartLink{ return; } NSString *global_key = [Login curLoginUser].global_key; - NSString *tipKey = [NSString stringWithFormat:@"%@_%@_%@", kFunctionTipStr_Prefix, global_key, link]; + NSString *tipKey = [NSString stringWithFormat:@"%@_%@_%@", kFunctionTipStr_StartLinkPrefix, global_key, link]; if (![[FunctionTipsManager shareManager] needToTip:tipKey]) { return; } @@ -144,24 +144,29 @@ - (void)loadStartImages{ } - (void)refreshImagesPlist{ + [self refreshImagesBlock:nil]; +} + +- (void)refreshImagesBlock:(void(^)(NSArray *images, NSError *error))bk{ NSString *aPath = @"api/wallpaper/wallpapers"; NSDictionary *params = @{@"type" : @"3"}; - [[CodingNetAPIClient sharedJsonClient] GET:aPath parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) { - DebugLog(@"\n===========response===========\n%@:\n%@", aPath, responseObject); - id error = [self handleResponse:responseObject]; + [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:aPath withParams:params withMethodType:Get autoShowError:NO andBlock:^(id data, NSError *error) { + NSArray *resultA = nil; if (!error) { - NSArray *resultA = [responseObject valueForKey:@"data"]; + resultA = data[@"data"]; if ([self createFolder:[self downloadPath]]) { if ([resultA writeToFile:[self pathOfSTPlist] atomically:YES]) { [[StartImagesManager shareManager] startDownloadImages]; } } } - } failure:^(AFHTTPRequestOperation *operation, NSError *error) { - DebugLog(@"\n===========response===========\n%@:\n%@", aPath, error); + if (bk) { + bk([NSObject arrayFromJSON:resultA ofObjects:@"StartImage"], error); + } }]; } + - (void)startDownloadImages{ if (![AFNetworkReachabilityManager sharedManager].reachableViaWiFi) { diff --git a/Coding_iOS/Util/Manager/WebContentManager.h b/Coding_iOS/Util/Manager/WebContentManager.h index af4f4de16..811c5a9bd 100755 --- a/Coding_iOS/Util/Manager/WebContentManager.h +++ b/Coding_iOS/Util/Manager/WebContentManager.h @@ -15,5 +15,6 @@ + (NSString *)bubblePatternedWithContent:(NSString *)content; + (NSString *)topicPatternedWithContent:(NSString *)content; + (NSString *)markdownPatternedWithContent:(NSString *)content; ++ (NSString *)wikiPatternedWithContent:(NSString *)content; + (NSString *)diffPatternedWithContent:(NSString *)content andComments:(NSString *)comments; @end diff --git a/Coding_iOS/Util/Manager/WebContentManager.m b/Coding_iOS/Util/Manager/WebContentManager.m index e00c6e80d..9f300db9f 100755 --- a/Coding_iOS/Util/Manager/WebContentManager.m +++ b/Coding_iOS/Util/Manager/WebContentManager.m @@ -13,6 +13,7 @@ @interface WebContentManager () @property (strong, nonatomic) NSString *topic_pattern_htmlStr; @property (strong, nonatomic) NSString *code_pattern_htmlStr; @property (strong, nonatomic) NSString *markdown_pattern_htmlStr; +@property (strong, nonatomic) NSString *wiki_pattern_htmlStr; @property (strong, nonatomic) NSString *diff_pattern_htmlStr; @end @@ -46,6 +47,11 @@ + (instancetype)sharedManager { if (error) { DebugLog(@"markdown_pattern_htmlStr fail: %@", error.description); } + path = [[NSBundle mainBundle] pathForResource:@"wiki" ofType:@"html"]; + shared_manager.wiki_pattern_htmlStr = [[NSString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; + if (error) { + DebugLog(@"wiki_pattern_htmlStr fail: %@", error.description); + } path = [[NSBundle mainBundle] pathForResource:@"diff-ios" ofType:@"html"]; shared_manager.diff_pattern_htmlStr = [[NSString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; if (error) { @@ -97,6 +103,14 @@ - (NSString *)markdownPatternedWithContent:(NSString *)content{ return patternedStr; } +- (NSString *)wikiPatternedWithContent:(NSString *)content{ + if (!content) { + return @""; + } + NSString *patternedStr = [self.wiki_pattern_htmlStr stringByReplacingOccurrencesOfString:@"${webview_content}" withString:content]; + return patternedStr; +} + - (NSString *)diffPatternedWithContent:(NSString *)content andComments:(NSString *)comments{ if (!content) { return @""; @@ -118,6 +132,9 @@ + (NSString *)topicPatternedWithContent:(NSString *)content{ + (NSString *)markdownPatternedWithContent:(NSString *)content{ return [[self sharedManager] markdownPatternedWithContent:content]; } ++ (NSString *)wikiPatternedWithContent:(NSString *)content{ + return [[self sharedManager] wikiPatternedWithContent:content]; +} + (NSString *)diffPatternedWithContent:(NSString *)content andComments:(NSString *)comments{ return [[self sharedManager] diffPatternedWithContent:content andComments:comments]; } diff --git a/Coding_iOS/Util/OC_Category/NSDate+Common.m b/Coding_iOS/Util/OC_Category/NSDate+Common.m index adbe7c5a5..b65aada41 100755 --- a/Coding_iOS/Util/OC_Category/NSDate+Common.m +++ b/Coding_iOS/Util/OC_Category/NSDate+Common.m @@ -9,7 +9,8 @@ #import "NSDate+Common.h" @implementation NSDate (Common) - +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" - (BOOL)isSameDay:(NSDate*)anotherDate{ NSCalendar* calendar = [NSCalendar currentCalendar]; NSDateComponents* components1 = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:self]; @@ -77,27 +78,32 @@ - (NSString *)stringTimesAgo{ NSString *text = nil; - NSInteger agoCount = [self monthsAgo]; + NSInteger agoCount = [self yearsAgo]; if (agoCount > 0) { - text = [NSString stringWithFormat:@"%ld个月前", (long)agoCount]; + text = [NSString stringWithFormat:@"%ld年前", (long)agoCount]; }else{ - agoCount = [self daysAgoAgainstMidnight]; + agoCount = [self monthsAgo]; if (agoCount > 0) { - text = [NSString stringWithFormat:@"%ld天前", (long)agoCount]; + text = [NSString stringWithFormat:@"%ld个月前", (long)agoCount]; }else{ - agoCount = [self hoursAgo]; + agoCount = [self daysAgoAgainstMidnight]; if (agoCount > 0) { - text = [NSString stringWithFormat:@"%ld小时前", (long)agoCount]; + text = [NSString stringWithFormat:@"%ld天前", (long)agoCount]; }else{ - agoCount = [self minutesAgo]; + agoCount = [self hoursAgo]; if (agoCount > 0) { - text = [NSString stringWithFormat:@"%ld分钟前", (long)agoCount]; + text = [NSString stringWithFormat:@"%ld小时前", (long)agoCount]; }else{ - agoCount = [self secondsAgo]; - if (agoCount > 15) { - text = [NSString stringWithFormat:@"%ld秒前", (long)agoCount]; + agoCount = [self minutesAgo]; + if (agoCount > 0) { + text = [NSString stringWithFormat:@"%ld分钟前", (long)agoCount]; }else{ - text = @"刚刚"; + agoCount = [self secondsAgo]; + if (agoCount > 15) { + text = [NSString stringWithFormat:@"%ld秒前", (long)agoCount]; + }else{ + text = @"刚刚"; + } } } } @@ -212,5 +218,5 @@ + (BOOL)isDuringMidAutumn{ } return isDuringMidAutumn; } - +#pragma clang diagnostic pop @end diff --git a/Coding_iOS/Util/OC_Category/NSDate+convenience.m b/Coding_iOS/Util/OC_Category/NSDate+convenience.m index 1453c821c..7a3a37a82 100755 --- a/Coding_iOS/Util/OC_Category/NSDate+convenience.m +++ b/Coding_iOS/Util/OC_Category/NSDate+convenience.m @@ -8,7 +8,8 @@ #import "NSDate+convenience.h" @implementation NSDate (Convenience) - +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" -(int)year { NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; @@ -153,4 +154,5 @@ +(NSDate *)dateEndOfWeek { endOfWeek = [gregorian dateFromComponents: componentsStripped]; return endOfWeek; } +#pragma clang diagnostic pop @end diff --git a/Coding_iOS/Util/OC_Category/NSObject+Common.h b/Coding_iOS/Util/OC_Category/NSObject+Common.h index 055d5568f..fab292e2b 100755 --- a/Coding_iOS/Util/OC_Category/NSObject+Common.h +++ b/Coding_iOS/Util/OC_Category/NSObject+Common.h @@ -7,6 +7,8 @@ // #import +#import +#import @interface NSObject (Common) @@ -14,19 +16,32 @@ + (NSString *)tipFromError:(NSError *)error; + (BOOL)showError:(NSError *)error; + (void)showHudTipStr:(NSString *)tipStr; -+ (instancetype)showHUDQueryStr:(NSString *)titleStr; ++ (MBProgressHUD *)showHUDQueryStr:(NSString *)titleStr; + (NSUInteger)hideHUDQuery; + (void)showStatusBarQueryStr:(NSString *)tipStr; + (void)showStatusBarSuccessStr:(NSString *)tipStr; + (void)showStatusBarErrorStr:(NSString *)errorStr; + (void)showStatusBarError:(NSError *)error; + (void)showCaptchaViewParams:(NSMutableDictionary *)params; ++ (void)showCaptchaViewParams:(NSMutableDictionary *)params success:(void (^)())block; #pragma mark BaseURL + (NSString *)baseURLStr; + (BOOL)baseURLStrIsProduction; + (void)changeBaseURLStrTo:(NSString *)baseURLStr; ++ (NSString *)e_URLStr; + ++ (NSString *)baseCompanySuffixStr; ++ (void)changeBaseCompanySuffixStrTo:(NSString *)companySuffixStr; ++ (NSString *)baseCompany; ++ (void)changeBaseCompanyTo:(NSString *)company; + ++ (NSNumber *)isPrivateCloud; ++ (void)setupIsPrivateCloud:(NSNumber *)isPrivateCloud; ++ (NSString *)privateCloud; ++ (void)changePrivateCloudTo:(NSString *)privateCloud; + #pragma mark File M //获取fileName的完整地址 + (NSString* )pathInCacheDirectory:(NSString *)fileName; @@ -49,4 +64,8 @@ -(id)handleResponse:(id)responseJSON; -(id)handleResponse:(id)responseJSON autoShowError:(BOOL)autoShowError; +#pragma Other ++ (void)logCookies; ++ (void)preCookieHandle; + @end diff --git a/Coding_iOS/Util/OC_Category/NSObject+Common.m b/Coding_iOS/Util/OC_Category/NSObject+Common.m index edf4c4ccd..5ce8d9600 100755 --- a/Coding_iOS/Util/OC_Category/NSObject+Common.m +++ b/Coding_iOS/Util/OC_Category/NSObject+Common.m @@ -10,14 +10,17 @@ #define kHUDQueryViewTag 101 #define kBaseURLStr @"https://coding.net/" +#define kBaseCompanySuffixStr @"coding.net" +#define kBaseCompanyKey @"k_base_company" + +#define kIsPrivateCloudKey @"k_is_private_cloud" +#define kPrivateCloudKey @"k_private_cloud" #import "NSObject+Common.h" #import "JDStatusBarNotification.h" #import "Login.h" #import "AppDelegate.h" -#import "MBProgressHUD+Add.h" #import "CodingNetAPIClient.h" -#import #import "Coding_NetAPIManager.h" @implementation NSObject (Common) @@ -40,10 +43,16 @@ + (NSString *)tipFromError:(NSError *)error{ } } }else{ - if ([error.userInfo objectForKey:@"NSLocalizedDescription"]) { - tipStr = [error.userInfo objectForKey:@"NSLocalizedDescription"]; + if (error.userInfo[NSUnderlyingErrorKey]) { + tipStr = [self tipFromError:error.userInfo[NSUnderlyingErrorKey]].mutableCopy; + }else if (error.userInfo[NSLocalizedDescriptionKey]) { + tipStr = error.userInfo[NSLocalizedDescriptionKey]; }else{ - [tipStr appendFormat:@"ErrorCode%ld", (long)error.code]; + if (error.code == 3840) {//Json 解析失败 + [tipStr appendFormat:@"服务器返回数据格式有误"]; + }else{ + [tipStr appendFormat:@"错误代码 %ld", (long)error.code]; + } } } return tipStr; @@ -70,7 +79,7 @@ + (void)showHudTipStr:(NSString *)tipStr{ [hud hide:YES afterDelay:1.0]; } } -+ (instancetype)showHUDQueryStr:(NSString *)titleStr{ ++ (MBProgressHUD *)showHUDQueryStr:(NSString *)titleStr{ titleStr = titleStr.length > 0? titleStr: @"正在获取数据..."; MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:kKeyWindow animated:YES]; hud.tag = kHUDQueryViewTag; @@ -124,17 +133,35 @@ + (void)showStatusBarError:(NSError *)error{ #pragma mark BaseURL + (NSString *)baseURLStr{ - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - return [defaults valueForKey:kBaseURLStr] ?: kBaseURLStr; + if (kTarget_Enterprise) { + if ([self isPrivateCloud].boolValue) { + return [self privateCloud]; + }else{ + if (![self baseCompany]) { + return nil; + } + NSString *baseURLStr = [NSString stringWithFormat:@"%@://%@.%@/", ([self baseURLStrIsProduction]? @"https": @"http"), [self baseCompany], [self baseCompanySuffixStr]]; + return baseURLStr; + } + }else{ + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + return [defaults valueForKey:kBaseURLStr] ?: kBaseURLStr; + } } + (BOOL)baseURLStrIsProduction{ - return [[self baseURLStr] isEqualToString:kBaseURLStr]; + if (kTarget_Enterprise) { + return [[self baseCompanySuffixStr] isEqualToString:kBaseCompanySuffixStr]; + }else{ + return [[self baseURLStr] isEqualToString:kBaseURLStr]; + } } + (void)changeBaseURLStrTo:(NSString *)baseURLStr{ if (baseURLStr.length <= 0) { baseURLStr = kBaseURLStr; + }else if (![baseURLStr hasSuffix:@"/"]){ + baseURLStr = [baseURLStr stringByAppendingString:@"/"]; } NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; @@ -143,7 +170,86 @@ + (void)changeBaseURLStrTo:(NSString *)baseURLStr{ [CodingNetAPIClient changeJsonClient]; - [[UINavigationBar appearance] setBackgroundImage:[UIImage imageWithColor:[self baseURLStrIsProduction]? kColorNavBG: kColorBrandGreen] forBarMetrics:UIBarMetricsDefault]; + [[UINavigationBar appearance] setBackgroundImage:[UIImage imageWithColor:[self baseURLStrIsProduction]? kColorNavBG: kColorActionYellow] forBarMetrics:UIBarMetricsDefault]; +} + ++ (NSString *)e_URLStr{ + NSString *baseURLStr = [NSString stringWithFormat:@"%@://e.%@/", ([self baseURLStrIsProduction]? @"https": @"http"), [self baseCompanySuffixStr]]; + return [self isPrivateCloud].boolValue? [self privateCloud]: baseURLStr; +} + ++ (NSString *)baseCompanySuffixStr{ + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + NSString *baseCompanySuffixStr = [defaults valueForKey:kBaseCompanySuffixStr] ?: kBaseCompanySuffixStr; + return [baseCompanySuffixStr lowercaseString]; +} ++ (void)changeBaseCompanySuffixStrTo:(NSString *)companySuffixStr{ + if (companySuffixStr.length <= 0) { + companySuffixStr = kBaseCompanySuffixStr; + } + if (![companySuffixStr isEqualToString:[self baseCompanySuffixStr]]) { + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + [defaults setObject:companySuffixStr forKey:kBaseCompanySuffixStr]; + [defaults synchronize]; + + [[UINavigationBar appearance] setBackgroundImage:[UIImage imageWithColor:[self baseURLStrIsProduction]? kColorNavBG: kColorBrandBlue] forBarMetrics:UIBarMetricsDefault]; + + if ([self baseCompany]) { + [CodingNetAPIClient changeSharedJsonClient]; + } + [CodingNetAPIClient changeE_JsonClient]; + } +} + ++ (NSString *)baseCompany{ + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + NSString *baseCompany = [defaults valueForKey:kBaseCompanyKey]; + return [self isPrivateCloud].boolValue? @"ce": baseCompany; +} ++ (void)changeBaseCompanyTo:(NSString *)company{ + if ([self isPrivateCloud].boolValue) { + [self changePrivateCloudTo:company]; + }else if (![company isEqualToString:[self baseCompany]]) { + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + [defaults setObject:company ?: @"" forKey:kBaseCompanyKey]; + [defaults synchronize]; + + [CodingNetAPIClient changeSharedJsonClient]; + } +} + ++ (NSNumber *)isPrivateCloud{ + // return @(YES); + return [[NSUserDefaults standardUserDefaults] valueForKey:kIsPrivateCloudKey]; +} ++ (void)setupIsPrivateCloud:(NSNumber *)isPrivateCloud{ + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + if (isPrivateCloud) { + [defaults setObject:isPrivateCloud forKey:kIsPrivateCloudKey]; + }else{ + [defaults removeObjectForKey:kIsPrivateCloudKey]; + } + [defaults synchronize]; + [CodingNetAPIClient changeSharedJsonClient]; +} ++ (NSString *)privateCloud{ + // return @"http://pd.codingprod.net/"; + return [[NSUserDefaults standardUserDefaults] valueForKey:kPrivateCloudKey]; +} ++ (void)changePrivateCloudTo:(NSString *)privateCloud{ + if (privateCloud.length > 0) { + if (![privateCloud hasPrefix:@"http"]) { + privateCloud = [NSString stringWithFormat:@"http://%@", privateCloud]; + } + if (![privateCloud hasSuffix:@"/"]) { + privateCloud = [privateCloud stringByAppendingString:@"/"]; + } + } + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + [defaults setObject:privateCloud ?: @"" forKey:kPrivateCloudKey]; + [defaults synchronize]; + + [CodingNetAPIClient changeSharedJsonClient]; } #pragma mark File M @@ -345,8 +451,11 @@ -(id)handleResponse:(id)responseJSON autoShowError:(BOOL)autoShowError{ return error; } - + (void)showCaptchaViewParams:(NSMutableDictionary *)params{ + [self showCaptchaViewParams:params success:nil]; +} + ++ (void)showCaptchaViewParams:(NSMutableDictionary *)params success:(void (^)())block{ //Data if (!params) { params = @{}.mutableCopy; @@ -357,12 +466,12 @@ + (void)showCaptchaViewParams:(NSMutableDictionary *)params{ NSString *path = @"api/request_valid"; NSURL *imageURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@api/getCaptcha?type=%@", [NSObject baseURLStr], params[@"type"]]]; //UI - SDCAlertController *alertV = [SDCAlertController alertControllerWithTitle:@"提示" message:@"亲,您操作这么快,不会是机器人吧?\n来,输个验证码先?" preferredStyle:SDCAlertControllerStyleAlert]; + SDCAlertController *alertV = [SDCAlertController alertControllerWithTitle:@"提示" message:@"请输入图片验证码" preferredStyle:SDCAlertControllerStyleAlert]; UITextField *textF = [UITextField new]; textF.layer.sublayerTransform = CATransform3DMakeTranslation(5, 0, 0); textF.backgroundColor = [UIColor whiteColor]; [textF doBorderWidth:0.5 color:nil cornerRadius:2.0]; - UIImageView *imageV = [UIImageView new]; + UIImageView *imageV = [YLImageView new]; imageV.backgroundColor = [UIColor lightGrayColor]; imageV.contentMode = UIViewContentModeScaleAspectFit; imageV.clipsToBounds = YES; @@ -391,7 +500,7 @@ + (void)showCaptchaViewParams:(NSMutableDictionary *)params{ }]; __weak typeof(alertV) weakAlertV = alertV; [alertV addAction:[SDCAlertAction actionWithTitle:@"取消" style:SDCAlertActionStyleCancel handler:nil]]; - [alertV addAction:[SDCAlertAction actionWithTitle:@"还真不是" style:SDCAlertActionStyleDefault handler:nil]]; + [alertV addAction:[SDCAlertAction actionWithTitle:@"确定" style:SDCAlertActionStyleDefault handler:nil]]; alertV.shouldDismissBlock = ^BOOL (SDCAlertAction *action){ BOOL shouldDismiss = [action.title isEqualToString:@"取消"]; if (!shouldDismiss) { @@ -399,7 +508,11 @@ + (void)showCaptchaViewParams:(NSMutableDictionary *)params{ [[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:params withMethodType:Post andBlock:^(id data, NSError *error) { if (data) { [weakAlertV dismissWithCompletion:^{ - [NSObject showHudTipStr:@"验证码正确"]; + if (block) { + block(); + }else{ + [NSObject showHudTipStr:@"验证码正确"]; + } }]; }else{ [weakImageV sd_setImageWithURL:imageURL placeholderImage:nil options:(SDWebImageRetryFailed | SDWebImageRefreshCached | SDWebImageHandleCookies)]; @@ -413,4 +526,25 @@ + (void)showCaptchaViewParams:(NSMutableDictionary *)params{ }]; } + +#pragma Other ++ (void)logCookies{ + NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]; + [cookies enumerateObjectsUsingBlock:^(NSHTTPCookie * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + NSLog(@"cookie: %@", obj.description); + }]; +} + ++ (void)preCookieHandle{ + NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; + NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:@{NSHTTPCookieName: @"e_dev", + NSHTTPCookieValue: @"1", + NSHTTPCookieDomain: @".coding.net", + NSHTTPCookieOriginURL: @".coding.net", + NSHTTPCookiePath: @"/"}]; + [storage setCookie:cookie]; + + // [self logCookies]; +} + @end diff --git a/Coding_iOS/Util/OC_Category/NSObject+ObjectMap.h b/Coding_iOS/Util/OC_Category/NSObject+ObjectMap.h index 9f228cfad..f0f55a5c0 100755 --- a/Coding_iOS/Util/OC_Category/NSObject+ObjectMap.h +++ b/Coding_iOS/Util/OC_Category/NSObject+ObjectMap.h @@ -11,6 +11,7 @@ #define OMDateFormat @"yyyy-MM-dd'T'HH:mm:ss.SSS" #define OMTimeZone @"UTC" +#define EADateFormat @"yyyy-MM-dd HH:mm:ss" @interface NSObject (ObjectMap) @@ -52,4 +53,4 @@ @interface SOAPObject : NSObject @property (nonatomic, retain) id Header; @property (nonatomic, retain) id Body; -@end \ No newline at end of file +@end diff --git a/Coding_iOS/Util/OC_Category/NSObject+ObjectMap.m b/Coding_iOS/Util/OC_Category/NSObject+ObjectMap.m index a8fd44780..9d1ba8aaa 100755 --- a/Coding_iOS/Util/OC_Category/NSObject+ObjectMap.m +++ b/Coding_iOS/Util/OC_Category/NSObject+ObjectMap.m @@ -187,6 +187,27 @@ -(id)getNodeValue:(NSString *)node fromXML:(NSString *)xml { } #pragma mark - Dictionary to Object ++ (NSDate *)p_dateFromObj:(id)obj{ + NSDate *date; + if ([obj isKindOfClass:[NSNumber class]]) { + // 1970年的long型数字 + NSNumber *timeSince1970 = (NSNumber *)obj; + NSTimeInterval timeSince1970TimeInterval = timeSince1970.doubleValue/1000; + date = [NSDate dateWithTimeIntervalSince1970:timeSince1970TimeInterval]; + }else if ([obj isKindOfClass:[NSString class]]){ + // 日期字符串 + NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; + [formatter setDateFormat:OMDateFormat]; + [formatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:OMTimeZone]]; + date = [formatter dateFromString:(NSString *)obj]; + if (!date) { + [formatter setDateFormat:EADateFormat]; + date = [formatter dateFromString:(NSString *)obj]; + } + } + return date; +} + +(id)objectOfClass:(NSString *)object fromJSON:(NSDictionary *)dict { if (!dict || ![dict isKindOfClass:[NSDictionary class]]) { return nil; @@ -231,21 +252,7 @@ +(id)objectOfClass:(NSString *)object fromJSON:(NSDictionary *)dict { // check if NSDate or not if ([classType isEqualToString:@"T@\"NSDate\""]) { -// 1970年的long型数字 - NSObject *obj = [dict objectForKey:key]; - if ([obj isKindOfClass:[NSNumber class]]) { - NSNumber *timeSince1970 = (NSNumber *)obj; - NSTimeInterval timeSince1970TimeInterval = timeSince1970.doubleValue/1000; - NSDate *date = [NSDate dateWithTimeIntervalSince1970:timeSince1970TimeInterval]; - [newObject setValue:date forKey:propertyName]; - }else{ -// 日期字符串 - NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; - [formatter setDateFormat:OMDateFormat]; - [formatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:OMTimeZone]]; - NSString *dateString = [[dict objectForKey:key] stringByReplacingOccurrencesOfString:@"T" withString:@" "]; - [newObject setValue:[formatter dateFromString:dateString] forKey:propertyName]; - } + [newObject setValue:[self p_dateFromObj:[dict objectForKey:key]] forKey:propertyName]; } else { if ([dict objectForKey:key] != [NSNull null]) { @@ -370,22 +377,7 @@ +(NSMutableArray *)arrayMapFromArray:(NSArray *)nestedArray forPropertyName:(NSS NSString *classType = [self typeFromProperty:property]; // check if NSDate or not if ([classType isEqualToString:@"T@\"NSDate\""]) { -// 1970年的long型数字 - NSObject *obj = [nestedArray[xx] objectForKey:newKey]; - if ([obj isKindOfClass:[NSNumber class]]) { - NSNumber *timeSince1970 = (NSNumber *)obj; - NSTimeInterval timeSince1970TimeInterval = timeSince1970.doubleValue/1000; - NSDate *date = [NSDate dateWithTimeIntervalSince1970:timeSince1970TimeInterval]; - [nestedObj setValue:date forKey:tempNewKey]; - }else{ -// 日期字符串 - NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; - [formatter setDateFormat:OMDateFormat]; - [formatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:OMTimeZone]]; - - NSString *dateString = [[nestedArray[xx] objectForKey:newKey] stringByReplacingOccurrencesOfString:@"T" withString:@" "]; - [nestedObj setValue:[formatter dateFromString:dateString] forKey:tempNewKey]; - } + [nestedObj setValue:[self p_dateFromObj:[nestedArray[xx] objectForKey:newKey]] forKey:tempNewKey]; } else { [nestedObj setValue:[nestedArray[xx] objectForKey:newKey] forKey:tempNewKey]; diff --git a/Coding_iOS/Util/OC_Category/NSString+Common.h b/Coding_iOS/Util/OC_Category/NSString+Common.h index d205b529b..a67f3f0f8 100755 --- a/Coding_iOS/Util/OC_Category/NSString+Common.h +++ b/Coding_iOS/Util/OC_Category/NSString+Common.h @@ -32,6 +32,7 @@ - (CGFloat)getWidthWithFont:(UIFont *)font constrainedToSize:(CGSize)size; -(BOOL)containsEmoji; +- (NSString *)emotionSpecailName; - (NSString *)emotionMonkeyName; + (NSString *)sizeDisplayWithByte:(CGFloat)sizeOfByte; @@ -48,6 +49,7 @@ - (BOOL)isPhoneNo; - (BOOL)isEmail; - (BOOL)isGK; +- (BOOL)isFileName; - (NSRange)rangeByTrimmingLeftCharactersInSet:(NSCharacterSet *)characterSet; - (NSRange)rangeByTrimmingRightCharactersInSet:(NSCharacterSet *)characterSet; diff --git a/Coding_iOS/Util/OC_Category/NSString+Common.m b/Coding_iOS/Util/OC_Category/NSString+Common.m index 52a1a1f6b..af65478c5 100755 --- a/Coding_iOS/Util/OC_Category/NSString+Common.m +++ b/Coding_iOS/Util/OC_Category/NSString+Common.m @@ -18,7 +18,10 @@ + (NSString *)userAgentStr{ struct utsname systemInfo; uname(&systemInfo); NSString *deviceString = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding]; - return [NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleIdentifierKey], (__bridge id)CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), kCFBundleVersionKey) ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleVersionKey], deviceString, [[UIDevice currentDevice] systemVersion], ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] ? [[UIScreen mainScreen] scale] : 1.0f)]; + NSString *userAgent = [NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleIdentifierKey], (__bridge id)CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), kCFBundleVersionKey) ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleVersionKey], deviceString, [[UIDevice currentDevice] systemVersion], ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] ? [[UIScreen mainScreen] scale] : 1.0f)]; + return userAgent; + //Coding_iOS/4.0.8.201611041630 (x86_64; iOS 10.1; Scale/2.00) + //Coding_Enterprise_iOS/4.0.8.201611041630 (x86_64; iOS 10.1; Scale/2.00) } - (NSString *)URLEncoding @@ -78,7 +81,7 @@ - (NSURL *)urlWithCodePath{ return nil; }else{ if (![self hasPrefix:@"http"]) { - urlStr = [NSString stringWithFormat:@"%@%@", [NSObject baseURLStr], self]; + urlStr = [NSString stringWithFormat:@"%@%@", [NSObject baseURLStr], [self hasPrefix:@"/"]? [self substringFromIndex:1]: self]; }else{ urlStr = self; } @@ -96,12 +99,10 @@ - (NSURL *)urlImageWithCodePathResize:(CGFloat)width crop:(BOOL)needCrop{ }else{ if (![self hasPrefix:@"http"]) { NSString *imageName = [self stringByMatching:@"/static/fruit_avatar/([a-zA-Z0-9\\-._]+)$" capture:1]; - if (imageName && imageName.length > 0) { - urlStr = [NSString stringWithFormat:@"http://coding-net-avatar.qiniudn.com/%@?imageMogr2/auto-orient/thumbnail/!%.0fx%.0fr", imageName, width, width]; - canCrop = YES; - }else{ - urlStr = [NSString stringWithFormat:@"%@%@", [NSObject baseURLStr], self]; + if (!imageName) { + imageName = [self stringByMatching:@"/static/project_icon/([a-zA-Z0-9\\-._]+)$" capture:1]; } + urlStr = [NSString stringWithFormat:@"%@%@", [NSObject baseURLStr], [self hasPrefix:@"/"]? [self substringFromIndex:1]: self]; }else{ urlStr = self; if ([urlStr rangeOfString:@"qbox.me"].location != NSNotFound) { @@ -150,7 +151,8 @@ + (NSString *)handelRef:(NSString *)ref path:(NSString *)path{ if (path.length > 0) { [result appendFormat:@"%@%@", ref.length > 0? @"/": @"", path]; } - return [result URLEncoding]; + return result; +// return [result URLEncoding]; } - (CGSize)getSizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size{ CGSize resultSize = CGSizeZero; @@ -218,71 +220,88 @@ -(BOOL)containsEmoji{ return returnValue; } #pragma mark emotion_monkey -+ (NSDictionary *)emotion_monkey_dict { - static NSDictionary *_emotion_monkey_dict; ++ (NSDictionary *)emotion_specail_dict { + static NSDictionary *_emotion_specail_dict; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - _emotion_monkey_dict = @{ + _emotion_specail_dict = @{ //猴子大表情 - @"coding_emoji_01": @"哈哈", - @"coding_emoji_02": @"吐", - @"coding_emoji_03": @"压力山大", - @"coding_emoji_04": @"忧伤", - @"coding_emoji_05": @"坏人", - @"coding_emoji_06": @"酷", - @"coding_emoji_07": @"哼", - @"coding_emoji_08": @"你咬我啊", - @"coding_emoji_09": @"内急", - @"coding_emoji_10": @"32个赞", - @"coding_emoji_11": @"加油", - @"coding_emoji_12": @"闭嘴", - @"coding_emoji_13": @"wow", - @"coding_emoji_14": @"泪流成河", - @"coding_emoji_15": @"NO!", - @"coding_emoji_16": @"疑问", - @"coding_emoji_17": @"耶", - @"coding_emoji_18": @"生日快乐", - @"coding_emoji_19": @"求包养", - @"coding_emoji_20": @"吹泡泡", - @"coding_emoji_21": @"睡觉", - @"coding_emoji_22": @"惊讶", - @"coding_emoji_23": @"Hi", - @"coding_emoji_24": @"打发点咯", - @"coding_emoji_25": @"呵呵", - @"coding_emoji_26": @"喷血", - @"coding_emoji_27": @"Bug", - @"coding_emoji_28": @"听音乐", - @"coding_emoji_29": @"垒码", - @"coding_emoji_30": @"我打你哦", - @"coding_emoji_31": @"顶足球", - @"coding_emoji_32": @"放毒气", - @"coding_emoji_33": @"表白", - @"coding_emoji_34": @"抓瓢虫", - @"coding_emoji_35": @"下班", - @"coding_emoji_36": @"冒泡", - @"coding_emoji_38": @"2015", - @"coding_emoji_39": @"拜年", - @"coding_emoji_40": @"发红包", - @"coding_emoji_41": @"放鞭炮", - @"coding_emoji_42": @"求红包", - @"coding_emoji_43": @"新年快乐", + @"coding_emoji_01": @" :哈哈: ", + @"coding_emoji_02": @" :吐: ", + @"coding_emoji_03": @" :压力山大: ", + @"coding_emoji_04": @" :忧伤: ", + @"coding_emoji_05": @" :坏人: ", + @"coding_emoji_06": @" :酷: ", + @"coding_emoji_07": @" :哼: ", + @"coding_emoji_08": @" :你咬我啊: ", + @"coding_emoji_09": @" :内急: ", + @"coding_emoji_10": @" :32个赞: ", + @"coding_emoji_11": @" :加油: ", + @"coding_emoji_12": @" :闭嘴: ", + @"coding_emoji_13": @" :wow: ", + @"coding_emoji_14": @" :泪流成河: ", + @"coding_emoji_15": @" :NO!: ", + @"coding_emoji_16": @" :疑问: ", + @"coding_emoji_17": @" :耶: ", + @"coding_emoji_18": @" :生日快乐: ", + @"coding_emoji_19": @" :求包养: ", + @"coding_emoji_20": @" :吹泡泡: ", + @"coding_emoji_21": @" :睡觉: ", + @"coding_emoji_22": @" :惊讶: ", + @"coding_emoji_23": @" :Hi: ", + @"coding_emoji_24": @" :打发点咯: ", + @"coding_emoji_25": @" :呵呵: ", + @"coding_emoji_26": @" :喷血: ", + @"coding_emoji_27": @" :Bug: ", + @"coding_emoji_28": @" :听音乐: ", + @"coding_emoji_29": @" :垒码: ", + @"coding_emoji_30": @" :我打你哦: ", + @"coding_emoji_31": @" :顶足球: ", + @"coding_emoji_32": @" :放毒气: ", + @"coding_emoji_33": @" :表白: ", + @"coding_emoji_34": @" :抓瓢虫: ", + @"coding_emoji_35": @" :下班: ", + @"coding_emoji_36": @" :冒泡: ", + @"coding_emoji_38": @" :2015: ", + @"coding_emoji_39": @" :拜年: ", + @"coding_emoji_40": @" :发红包: ", + @"coding_emoji_41": @" :放鞭炮: ", + @"coding_emoji_42": @" :求红包: ", + @"coding_emoji_43": @" :新年快乐: ", //猴子大表情 Gif - @"coding_emoji_gif_01": @"奔月", - @"coding_emoji_gif_02": @"吃月饼", - @"coding_emoji_gif_03": @"捞月", - @"coding_emoji_gif_04": @"打招呼", - @"coding_emoji_gif_05": @"悠闲", - @"coding_emoji_gif_06": @"赏月", - @"coding_emoji_gif_07": @"中秋快乐", - @"coding_emoji_gif_08": @"爬爬", + @"coding_emoji_gif_01": @" :奔月: ", + @"coding_emoji_gif_02": @" :吃月饼: ", + @"coding_emoji_gif_03": @" :捞月: ", + @"coding_emoji_gif_04": @" :打招呼: ", + @"coding_emoji_gif_05": @" :悠闲: ", + @"coding_emoji_gif_06": @" :赏月: ", + @"coding_emoji_gif_07": @" :中秋快乐: ", + @"coding_emoji_gif_08": @" :爬爬: ", + //特殊 emoji 字符 + @"0️⃣": @"0", + @"1️⃣": @"1", + @"2️⃣": @"2", + @"3️⃣": @"3", + @"4️⃣": @"4", + @"5️⃣": @"5", + @"6️⃣": @"6", + @"7️⃣": @"7", + @"8️⃣": @"8", + @"9️⃣": @"9", + @"↩️": @"\n", }; }); - return _emotion_monkey_dict; + return _emotion_specail_dict; } +- (NSString *)emotionSpecailName{ + return [NSString emotion_specail_dict][self]; +} + - (NSString *)emotionMonkeyName{ - return [NSString emotion_monkey_dict][self]; + return [self emotionSpecailName]; } + + (NSString *)sizeDisplayWithByte:(CGFloat)sizeOfByte{ NSString *sizeDisplayStr; if (sizeOfByte < 1024) { @@ -359,6 +378,11 @@ - (BOOL)isGK{ NSPredicate *gkTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", gkRegex]; return [gkTest evaluateWithObject:self]; } +- (BOOL)isFileName{ + NSString *phoneRegex = @"[a-zA-Z0-9\\u4e00-\\u9fa5\\./_-]+$"; + NSPredicate *phoneTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", phoneRegex]; + return [phoneTest evaluateWithObject:self]; +} - (NSRange)rangeByTrimmingLeftCharactersInSet:(NSCharacterSet *)characterSet{ diff --git a/Coding_iOS/Util/OC_Category/NSURL+Common.h b/Coding_iOS/Util/OC_Category/NSURL+Common.h index d2e35b3b2..cb54905ea 100644 --- a/Coding_iOS/Util/OC_Category/NSURL+Common.h +++ b/Coding_iOS/Util/OC_Category/NSURL+Common.h @@ -11,4 +11,14 @@ @interface NSURL (Common) +(BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL; - (NSDictionary *)queryParams; + +- (BOOL)isTextData; +- (NSString *)ea_lang; + +//https://developer.apple.com/library/content/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html ++ (NSArray *)ea_textUTIList; ++ (NSArray *)ea_imageUTIList; ++ (NSArray *)ea_audioUTIList; ++ (NSArray *)ea_movieUTIList; + @end diff --git a/Coding_iOS/Util/OC_Category/NSURL+Common.m b/Coding_iOS/Util/OC_Category/NSURL+Common.m index 328b9d4e1..d361094df 100644 --- a/Coding_iOS/Util/OC_Category/NSURL+Common.m +++ b/Coding_iOS/Util/OC_Category/NSURL+Common.m @@ -47,4 +47,102 @@ - (NSDictionary *)queryParams{ } return params; } + +- (BOOL)isTextData{ + NSDictionary *attributes = [self resourceValuesForKeys:@[NSURLTypeIdentifierKey] error:nil]; + NSString *itemType = attributes[NSURLTypeIdentifierKey]; + NSString *fileSuffix = [self.lastPathComponent componentsSeparatedByString:@"."].lastObject; + return ((itemType.length > 0 && [[self.class ea_textUTIList] containsObject:itemType]) || + (fileSuffix.length > 0 && [[self.class p_sufToLangDict].allKeys containsObject:fileSuffix])); +} + +- (NSString *)ea_lang{ + NSString *fileSuffix = [self.lastPathComponent componentsSeparatedByString:@"."].lastObject; + return [[self.class p_sufToLangDict][fileSuffix] firstObject] ?: @""; +} + ++ (NSDictionary *)p_sufToLangDict{ + static NSDictionary *sufToLangDict = nil; + if (!sufToLangDict) { + sufToLangDict = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"code_lang" ofType:@"plist"]]; + } + return sufToLangDict; +} + ++ (NSArray *)ea_textUTIList{ + return @[ + @"public.data",//其实这个是根,就是看不出来是啥东西的东西 + @"public.text", + @"public.plain-text ", + @"public.utf8-plain-text ", + @"public.utf16-external-plain-​text", + @"public.utf16-plain-text", + @"com.apple.traditional-mac-​plain-text", + @"com.apple.ink.inktext", + @"com.apple.applescript.text", + @"com.apple.txn.text-​multimedia-data", + @"public.unix-executable",//私加的 + ]; +} ++ (NSArray *)ea_imageUTIList{ + return @[ + @"public.image", + @"public.fax", + @"public.jpeg", + @"public.jpeg-2000", + @"public.camera-raw-image", + @"public.png", + @"public.xbitmap-image", + @"com.apple.pict", + @"com.apple.macpaint-image", + @"com.apple.quicktime-image", + @"com.apple.icns", + @"com.adobe.photoshop-​image", + @"com.adobe.illustrator.ai-​image", + @"com.compuserve.gif", + @"com.microsoft.bmp", + @"com.microsoft.ico", + @"com.truevision.tga-image", + @"com.sgi.sgi-image", + @"com.ilm.openexr-image", + @"com.kodak.flashpix.image", + ]; +} ++ (NSArray *)ea_audioUTIList{ + return @[ + @"public.audio", + @"public.mp3", + @"public.mpeg-4-audio", + @"com.apple.protected-​mpeg-4-audio", + @"public.ulaw-audio", + @"public.aifc-audio", + @"public.aiff-audio", + @"com.apple.coreaudio-​format", + @"com.microsoft.waveform-​audio", + @"com.microsoft.windows-​media-wma", + @"com.microsoft.advanced-​stream-redirector", + @"com.microsoft.windows-​media-wmx", + @"com.microsoft.windows-​media-wvx", + @"com.microsoft.windows-​media-wax", + @"com.digidesign.sd2-audio", + @"com.real.realaudio", + ]; +} ++ (NSArray *)ea_movieUTIList{ + return @[ + @"public.movie", + @"public.video", + @"public.avi", + @"public.mpeg", + @"public.mpeg-4", + @"public.3gpp", + @"public.3gpp2", + @"com.apple.quicktime-movie", + @"com.microsoft.windows-​media-wmp", + @"com.microsoft.windows-​media-wmv", + @"com.microsoft.windows-​media-wm", + @"com.real.realmedia", + ]; +} + @end diff --git a/Coding_iOS/Util/OC_Category/PHAsset+Common.h b/Coding_iOS/Util/OC_Category/PHAsset+Common.h new file mode 100644 index 000000000..425dbbc4b --- /dev/null +++ b/Coding_iOS/Util/OC_Category/PHAsset+Common.h @@ -0,0 +1,22 @@ +// +// PHAsset+Common.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/1/3. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import + +@interface PHAsset (Common) + ++ (PHAsset *)assetWithLocalIdentifier:(NSString *)localIdentifier; ++ (UIImage *)loadImageWithLocalIdentifier:(NSString *)localIdentifier; + +- (UIImage *)loadThumbnailImage; +- (UIImage *)loadImage; +- (NSData *)loadImageData; +- (NSString *)fileName; + +- (void)loadImageWithProgressHandler:(PHAssetImageProgressHandler)progressHandler resultHandler:(void (^)(UIImage *result, NSDictionary *info))resultHandler; +@end diff --git a/Coding_iOS/Util/OC_Category/PHAsset+Common.m b/Coding_iOS/Util/OC_Category/PHAsset+Common.m new file mode 100644 index 000000000..9d78b86be --- /dev/null +++ b/Coding_iOS/Util/OC_Category/PHAsset+Common.m @@ -0,0 +1,98 @@ +// +// PHAsset+Common.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/1/3. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "PHAsset+Common.h" +#import "YLGIFImage.h" + +@implementation PHAsset (Common) + ++ (PHAsset *)assetWithLocalIdentifier:(NSString *)localIdentifier{ + PHAsset *asset = [PHAsset fetchAssetsWithLocalIdentifiers:@[localIdentifier] options:nil].firstObject; + return asset; +} + ++ (UIImage *)loadImageWithLocalIdentifier:(NSString *)localIdentifier{ + return [self assetWithLocalIdentifier:localIdentifier].loadImage; +} + +- (UIImage *)loadThumbnailImage{ + PHImageRequestOptions *imageOptions = [[PHImageRequestOptions alloc] init]; + imageOptions.synchronous = YES; + imageOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat; + imageOptions.resizeMode = PHImageRequestOptionsResizeModeFast; + imageOptions.networkAccessAllowed = YES; + PHImageManager *imageManager = [PHImageManager defaultManager]; + CGFloat width = ((kScreen_Width - 15*2- 10*3)/4) * [UIScreen mainScreen].scale; + CGSize targetSize =CGSizeMake(width, width); + __block UIImage *assetImage; + [imageManager requestImageForAsset:self targetSize:targetSize contentMode:PHImageContentModeAspectFill options:imageOptions resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) { + assetImage = result; + }]; + return assetImage; +} + + +- (UIImage *)loadImage{ + PHImageRequestOptions *imageOptions = [[PHImageRequestOptions alloc] init]; + imageOptions.synchronous = YES; + imageOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat; + imageOptions.resizeMode = PHImageRequestOptionsResizeModeExact; + imageOptions.networkAccessAllowed = YES; + PHImageManager *imageManager = [PHImageManager defaultManager]; + __block UIImage *assetImage; + [imageManager requestImageForAsset:self targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeDefault options:imageOptions resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) { + assetImage = result; + }]; + return assetImage; +} + +- (NSData *)loadImageData{ + PHImageRequestOptions *imageOptions = [[PHImageRequestOptions alloc] init]; + imageOptions.synchronous = YES; + imageOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat; + imageOptions.resizeMode = PHImageRequestOptionsResizeModeExact; + imageOptions.networkAccessAllowed = YES; + PHImageManager *imageManager = [PHImageManager defaultManager]; + __block NSData *assetData; + [imageManager requestImageDataForAsset:self options:imageOptions resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) { + assetData = imageData; + }]; + return assetData; +} + +- (NSString *)fileName{ + NSString *fileName; + if ([self respondsToSelector:NSSelectorFromString(@"filename")]) { + fileName = [self valueForKey:@"filename"]; + }else{ + fileName = [NSString stringWithFormat:@"%@.JPG", [self.localIdentifier componentsSeparatedByString:@"/"].firstObject]; + } + return fileName; +} + +- (void)loadImageWithProgressHandler:(PHAssetImageProgressHandler)progressHandler resultHandler:(void (^)(UIImage *result, NSDictionary *info))resultHandler{ + PHImageRequestOptions *imageOptions = [[PHImageRequestOptions alloc] init]; + imageOptions.synchronous = NO; + imageOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat; + imageOptions.resizeMode = PHImageRequestOptionsResizeModeExact; + imageOptions.networkAccessAllowed = YES; + imageOptions.progressHandler = progressHandler; + PHImageManager *imageManager = [PHImageManager defaultManager]; + + [imageManager requestImageDataForAsset:self options:imageOptions resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) { + if (resultHandler) { + resultHandler([YLGIFImage imageWithData:imageData], info); + } + }]; +// gif 图片对应的 mediaSubtypes。有这个值,但是 API 没有这个枚举,有点迷 +// NSUInteger PHAssetMediaSubtypePhotoGif = (1UL << 5); +// if (self.mediaSubtypes & PHAssetMediaSubtypePhotoGif) { +// } +} + +@end diff --git a/Coding_iOS/Util/OC_Category/UIActionSheet+Common.h b/Coding_iOS/Util/OC_Category/UIActionSheet+Common.h deleted file mode 100644 index eaa9cd5c2..000000000 --- a/Coding_iOS/Util/OC_Category/UIActionSheet+Common.h +++ /dev/null @@ -1,14 +0,0 @@ -// -// UIActionSheet+Common.h -// Coding_iOS -// -// Created by Ease on 15/1/14. -// Copyright (c) 2015年 Coding. All rights reserved. -// - -#import - -@interface UIActionSheet (Common) -+ (instancetype)bk_actionSheetCustomWithTitle:(NSString *)title buttonTitles:(NSArray *)buttonTitles destructiveTitle:(NSString *)destructiveTitle cancelTitle:(NSString *)cancelTitle andDidDismissBlock:(void (^)(UIActionSheet *sheet, NSInteger index))block; - -@end diff --git a/Coding_iOS/Util/OC_Category/UIActionSheet+Common.m b/Coding_iOS/Util/OC_Category/UIActionSheet+Common.m deleted file mode 100644 index 4ffce1ea7..000000000 --- a/Coding_iOS/Util/OC_Category/UIActionSheet+Common.m +++ /dev/null @@ -1,29 +0,0 @@ -// -// UIActionSheet+Common.m -// Coding_iOS -// -// Created by Ease on 15/1/14. -// Copyright (c) 2015年 Coding. All rights reserved. -// - -#import "UIActionSheet+Common.h" - -@implementation UIActionSheet (Common) -+ (instancetype)bk_actionSheetCustomWithTitle:(NSString *)title buttonTitles:(NSArray *)buttonTitles destructiveTitle:(NSString *)destructiveTitle cancelTitle:(NSString *)cancelTitle andDidDismissBlock:(void (^)(UIActionSheet *sheet, NSInteger index))block{ - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetWithTitle:title]; - if (buttonTitles && buttonTitles.count > 0) { - for (NSString *buttonTitle in buttonTitles) { - [actionSheet bk_addButtonWithTitle:buttonTitle handler:nil]; - } - } - if (destructiveTitle) { - [actionSheet bk_setDestructiveButtonWithTitle:destructiveTitle handler:nil]; - } - if (cancelTitle) { - [actionSheet bk_setCancelButtonWithTitle:cancelTitle handler:nil]; - } - [actionSheet bk_setDidDismissBlock:block]; - return actionSheet; -} - -@end diff --git a/Coding_iOS/Util/OC_Category/UIActionSheet+Front.h b/Coding_iOS/Util/OC_Category/UIActionSheet+Front.h deleted file mode 100644 index 483ff9378..000000000 --- a/Coding_iOS/Util/OC_Category/UIActionSheet+Front.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// UIActionSheet+Front.h -// Coding_iOS -// -// Created by Ease on 15/10/13. -// Copyright © 2015年 Coding. All rights reserved. -// - -#import - -@interface UIActionSheet (Front) - -@end - -void swizzleAllActionSheet(); diff --git a/Coding_iOS/Util/OC_Category/UIActionSheet+Front.m b/Coding_iOS/Util/OC_Category/UIActionSheet+Front.m deleted file mode 100644 index 527193319..000000000 --- a/Coding_iOS/Util/OC_Category/UIActionSheet+Front.m +++ /dev/null @@ -1,31 +0,0 @@ -// -// UIActionSheet+Front.m -// Coding_iOS -// -// Created by Ease on 15/10/13. -// Copyright © 2015年 Coding. All rights reserved. -// - -#import "UIActionSheet+Front.h" -#import - -@implementation UIActionSheet (Front) -- (void)customShowInView:(UIView *)view{ - for(UIWindow * tmpWin in [[UIApplication sharedApplication] windows]){ - [tmpWin endEditing:NO]; - } - [self customShowInView:view]; -} -+ (void)load{ - swizzleAllActionSheet(); -} -@end - -void swizzleAllActionSheet(){ - Class c = [UIActionSheet class]; - SEL origSEL = @selector(showInView:); - SEL newSEL = @selector(customShowInView:); - Method origMethod = class_getInstanceMethod(c, origSEL); - Method newMethod = class_getInstanceMethod(c, newSEL); - method_exchangeImplementations(origMethod, newMethod); -} \ No newline at end of file diff --git a/Coding_iOS/Util/OC_Category/UIAlertController+Common.h b/Coding_iOS/Util/OC_Category/UIAlertController+Common.h new file mode 100644 index 000000000..83d1d2636 --- /dev/null +++ b/Coding_iOS/Util/OC_Category/UIAlertController+Common.h @@ -0,0 +1,24 @@ +// +// UIAlertController+Common.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/7/10. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import + +@interface UIAlertController (Common) + +#pragma mark kTipAlert ++ (void)ea_showTipStr:(NSString *)tipStr; + +#pragma mark ActionSheet ++ (instancetype)ea_actionSheetCustomWithTitle:(NSString *)title buttonTitles:(NSArray *)buttonTitles destructiveTitle:(NSString *)destructiveTitle cancelTitle:(NSString *)cancelTitle andDidDismissBlock:(void (^)(UIAlertAction *action, NSInteger index))block; +- (void)showInView:(UIView *)view; + +#pragma mark Alert ++ (instancetype)ea_alertViewWithTitle:(NSString *)title message:(NSString *)message buttonTitles:(NSArray *)buttonTitles destructiveTitle:(NSString *)destructiveTitle cancelTitle:(NSString *)cancelTitle andDidDismissBlock:(void (^)(UIAlertAction *action, NSInteger index))block; +- (void)show; + +@end diff --git a/Coding_iOS/Util/OC_Category/UIAlertController+Common.m b/Coding_iOS/Util/OC_Category/UIAlertController+Common.m new file mode 100644 index 000000000..888c6482c --- /dev/null +++ b/Coding_iOS/Util/OC_Category/UIAlertController+Common.m @@ -0,0 +1,75 @@ +// +// UIAlertController+Common.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/7/10. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "UIAlertController+Common.h" + +@implementation UIAlertController (Common) + ++ (void)ea_showTipStr:(NSString *)tipStr{ + if (tipStr.length <= 0) { + return; + } + UIAlertController *alertCtrl = [UIAlertController alertControllerWithTitle:@"提示" message:tipStr preferredStyle:UIAlertControllerStyleAlert]; + UIAlertAction *cancelA = [UIAlertAction actionWithTitle:@"知道了" style:UIAlertActionStyleCancel handler:nil]; + [alertCtrl addAction:cancelA]; + [[BaseViewController presentingVC] presentViewController:alertCtrl animated:YES completion:nil]; +} + ++ (instancetype)ea_actionSheetCustomWithTitle:(NSString *)title buttonTitles:(NSArray *)buttonTitles destructiveTitle:(NSString *)destructiveTitle cancelTitle:(NSString *)cancelTitle andDidDismissBlock:(void (^)(UIAlertAction *action, NSInteger index))block{ + UIAlertController *alertCtrl = [UIAlertController alertControllerWithTitle:title message:nil preferredStyle:UIAlertControllerStyleActionSheet]; + void (^handler)(UIAlertAction *) = ^(UIAlertAction *action){ + NSInteger index = [alertCtrl.actions indexOfObject:action]; + if (block) { + block(action, index); + } + }; + if (buttonTitles && buttonTitles.count > 0) { + for (NSString *buttonTitle in buttonTitles) { + [alertCtrl addAction:[UIAlertAction actionWithTitle:buttonTitle style:UIAlertActionStyleDefault handler:handler]]; + } + } + if (destructiveTitle) { + [alertCtrl addAction:[UIAlertAction actionWithTitle:destructiveTitle style:UIAlertActionStyleDestructive handler:handler]]; + } + if (cancelTitle) { + [alertCtrl addAction:[UIAlertAction actionWithTitle:cancelTitle style:UIAlertActionStyleCancel handler:handler]]; + } + return alertCtrl; +} + +- (void)showInView:(UIView *)view{ + [self show]; +} + ++ (instancetype)ea_alertViewWithTitle:(NSString *)title message:(NSString *)message buttonTitles:(NSArray *)buttonTitles destructiveTitle:(NSString *)destructiveTitle cancelTitle:(NSString *)cancelTitle andDidDismissBlock:(void (^)(UIAlertAction *action, NSInteger index))block{ + UIAlertController *alertCtrl = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert]; + void (^handler)(UIAlertAction *) = ^(UIAlertAction *action){ + NSInteger index = [alertCtrl.actions indexOfObject:action]; + if (block) { + block(action, index); + } + }; + if (buttonTitles && buttonTitles.count > 0) { + for (NSString *buttonTitle in buttonTitles) { + [alertCtrl addAction:[UIAlertAction actionWithTitle:buttonTitle style:UIAlertActionStyleDefault handler:handler]]; + } + } + if (destructiveTitle) { + [alertCtrl addAction:[UIAlertAction actionWithTitle:destructiveTitle style:UIAlertActionStyleDestructive handler:handler]]; + } + if (cancelTitle) { + [alertCtrl addAction:[UIAlertAction actionWithTitle:cancelTitle style:UIAlertActionStyleCancel handler:handler]]; + } + return alertCtrl; +} + +- (void)show{ + [[BaseViewController presentingVC] presentViewController:self animated:YES completion:nil]; +} + +@end diff --git a/Coding_iOS/Util/OC_Category/UIBarButtonItem+Common.m b/Coding_iOS/Util/OC_Category/UIBarButtonItem+Common.m index b63b975ba..5abab6b6c 100755 --- a/Coding_iOS/Util/OC_Category/UIBarButtonItem+Common.m +++ b/Coding_iOS/Util/OC_Category/UIBarButtonItem+Common.m @@ -11,7 +11,7 @@ @implementation UIBarButtonItem (Common) + (UIBarButtonItem *)itemWithBtnTitle:(NSString *)title target:(id)obj action:(SEL)selector{ UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithTitle:title style:UIBarButtonItemStylePlain target:obj action:selector]; - [buttonItem setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor lightGrayColor]} forState:UIControlStateDisabled]; + [buttonItem setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor colorWithHexString:@"0x0060FF" andAlpha:.5]} forState:UIControlStateDisabled]; return buttonItem; } diff --git a/Coding_iOS/Util/OC_Category/UIButton+Bootstrap.h b/Coding_iOS/Util/OC_Category/UIButton+Bootstrap.h index 08a541704..934cd8c29 100755 --- a/Coding_iOS/Util/OC_Category/UIButton+Bootstrap.h +++ b/Coding_iOS/Util/OC_Category/UIButton+Bootstrap.h @@ -16,7 +16,7 @@ typedef enum { StrapSuccessStyle, StrapInfoStyle, StrapWarningStyle, - StrapDangerStyle + StrapDangerStyle, } StrapButtonStyle; @interface UIButton (Bootstrap) diff --git a/Coding_iOS/Util/OC_Category/UIButton+Bootstrap.m b/Coding_iOS/Util/OC_Category/UIButton+Bootstrap.m index 054443bbc..fd9874133 100755 --- a/Coding_iOS/Util/OC_Category/UIButton+Bootstrap.m +++ b/Coding_iOS/Util/OC_Category/UIButton+Bootstrap.m @@ -20,8 +20,8 @@ -(void)bootstrapStyle{ -(void)defaultStyle{ [self bootstrapStyle]; - [self setTitleColor:kColorBrandGreen forState:UIControlStateNormal]; - [self setTitleColor:kColorBrandGreen forState:UIControlStateHighlighted]; + [self setTitleColor:kColorBrandBlue forState:UIControlStateNormal]; + [self setTitleColor:kColorBrandBlue forState:UIControlStateHighlighted]; self.backgroundColor = [UIColor whiteColor]; self.layer.borderColor = [[UIColor colorWithRed:204/255.0 green:204/255.0 blue:204/255.0 alpha:1] CGColor]; [self setBackgroundImage:[self buttonImageFromColor:[UIColor colorWithRed:235/255.0 green:235/255.0 blue:235/255.0 alpha:1]] forState:UIControlStateHighlighted]; @@ -29,21 +29,21 @@ -(void)defaultStyle{ -(void)primaryStyle{ [self bootstrapStyle]; - self.backgroundColor = kColorBrandGreen; - self.layer.borderColor = [kColorBrandGreen CGColor]; + self.backgroundColor = kColorBrandBlue; + self.layer.borderColor = [kColorBrandBlue CGColor]; [self setBackgroundImage:[self buttonImageFromColor:[UIColor colorWithHexString:@"0x28a464"]] forState:UIControlStateHighlighted]; } -(void)successStyle{ - [self bootstrapStyle]; - self.layer.borderColor = [[UIColor clearColor] CGColor]; - [self setBackgroundImage:[self buttonImageFromColor:kColorBrandGreen] forState:UIControlStateNormal]; - [self setBackgroundImage:[self buttonImageFromColor:[UIColor colorWithHexString:@"0x3bbc79" andAlpha:0.5]] forState:UIControlStateDisabled]; - [self setBackgroundImage:[self buttonImageFromColor:[UIColor colorWithHexString:@"0x32a067"]] forState:UIControlStateHighlighted]; + [self setAdjustsImageWhenHighlighted:NO]; + [self setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [self.titleLabel setFont:[UIFont systemFontOfSize:MIN(17, self.titleLabel.font.pointSize) weight:UIFontWeightMedium]]; + [self setBackgroundImage:[self buttonImageFromColor:kColorBrandBlue] forState:UIControlStateNormal]; + [self setBackgroundImage:[self buttonImageFromColor:[UIColor colorWithHexString:@"0x0060FF" andAlpha:0.5]] forState:UIControlStateDisabled]; + [self setBackgroundImage:[self buttonImageFromColor:[UIColor colorWithHexString:@"0x0060FF" andAlpha:.8]] forState:UIControlStateHighlighted]; [self setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; [self setTitleColor:[UIColor colorWithWhite:1.0 alpha:0.5] forState:UIControlStateDisabled]; [self setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted]; - } -(void)infoStyle{ @@ -104,7 +104,7 @@ + (UIButton *)buttonWithStyle:(StrapButtonStyle)style andTitle:(NSString *)title UIButton *btn = [[UIButton alloc] initWithFrame:rect]; [btn setTitle:title forState:UIControlStateNormal]; [btn addTarget:target action:selector forControlEvents:UIControlEventTouchUpInside]; - const SEL selArray[] = {@selector(bootstrapStyle), @selector(defaultManager), @selector(primaryStyle), @selector(successStyle), @selector(infoStyle), @selector(warningStyle), @selector(dangerStyle)}; + const SEL selArray[] = {@selector(bootstrapStyle), @selector(defaultStyle), @selector(primaryStyle), @selector(successStyle), @selector(infoStyle), @selector(warningStyle), @selector(dangerStyle)}; if ([btn respondsToSelector:selArray[style]]) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" diff --git a/Coding_iOS/Util/OC_Category/UIButton+Common.m b/Coding_iOS/Util/OC_Category/UIButton+Common.m index f2fe119ed..eef641148 100755 --- a/Coding_iOS/Util/OC_Category/UIButton+Common.m +++ b/Coding_iOS/Util/OC_Category/UIButton+Common.m @@ -32,7 +32,7 @@ + (UIButton *)buttonWithTitle:(NSString *)title titleColor:(UIColor *)color{ return btn; } + (UIButton *)buttonWithTitle_ForNav:(NSString *)title{ - return [UIButton buttonWithTitle:title titleColor:kColorBrandGreen]; + return [UIButton buttonWithTitle:title titleColor:kColorBrandBlue]; } + (UIButton *)buttonWithUserStyle{ UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; @@ -52,7 +52,7 @@ - (void)userNameStyle{ self.layer.cornerRadius = 2.0; self.titleLabel.font = [UIFont systemFontOfSize:17]; // [self setTitleColor:kColor222 forState:UIControlStateNormal]; - [self setTitleColor:kColorBrandGreen forState:UIControlStateNormal]; + [self setTitleColor:kColorDark3 forState:UIControlStateNormal]; [self setBackgroundImage:[UIImage imageWithColor:[UIColor clearColor]] forState:UIControlStateNormal]; [self setBackgroundImage:[UIImage imageWithColor:[UIColor lightGrayColor]] forState:UIControlStateHighlighted]; } @@ -129,7 +129,7 @@ + (UIButton *)tweetBtnWithFrame:(CGRect)frame alignmentLeft:(BOOL)alignmentLeft{ UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.frame = frame; button.titleLabel.font = [UIFont systemFontOfSize:12]; - [button setTitleColor:kColor999 forState:UIControlStateNormal]; + [button setTitleColor:kColorDark7 forState:UIControlStateNormal]; if (alignmentLeft) { button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; button.imageEdgeInsets = UIEdgeInsetsMake(0, 5, 0, -5); diff --git a/Coding_iOS/Util/OC_Category/UIImage+Common.h b/Coding_iOS/Util/OC_Category/UIImage+Common.h index 5e5264529..b93a49985 100755 --- a/Coding_iOS/Util/OC_Category/UIImage+Common.h +++ b/Coding_iOS/Util/OC_Category/UIImage+Common.h @@ -17,11 +17,12 @@ -(UIImage*)scaledToSize:(CGSize)targetSize; -(UIImage*)scaledToSize:(CGSize)targetSize highQuality:(BOOL)highQuality; -(UIImage*)scaledToMaxSize:(CGSize )size; -+ (UIImage *)fullResolutionImageFromALAsset:(ALAsset *)asset; -+ (UIImage *)fullScreenImageALAsset:(ALAsset *)asset; +//+ (UIImage *)fullResolutionImageFromALAsset:(ALAsset *)asset; +//+ (UIImage *)fullScreenImageALAsset:(ALAsset *)asset; + (UIImage *)imageWithFileType:(NSString *)fileType; ++ (UIImage *)big_imageWithFileType:(NSString *)fileType; -- (NSData *)dataSmallerThan:(NSUInteger)dataLength; +- (NSData *)dataSmallerThan:(CGFloat)maxLength; - (NSData *)dataForCodingUpload; @end diff --git a/Coding_iOS/Util/OC_Category/UIImage+Common.m b/Coding_iOS/Util/OC_Category/UIImage+Common.m index 1023ea76f..f3f1870a0 100755 --- a/Coding_iOS/Util/OC_Category/UIImage+Common.m +++ b/Coding_iOS/Util/OC_Category/UIImage+Common.m @@ -7,6 +7,7 @@ // #import "UIImage+Common.h" +#import "AnimatedGIFImageSerialization.h" @implementation UIImage (Common) +(UIImage *)imageWithColor:(UIColor *)aColor{ @@ -89,21 +90,21 @@ -(UIImage *)scaledToMaxSize:(CGSize)size{ return newImage; } -+ (UIImage *)fullResolutionImageFromALAsset:(ALAsset *)asset{ - ALAssetRepresentation *assetRep = [asset defaultRepresentation]; - CGImageRef imgRef = [assetRep fullResolutionImage]; - UIImage *img = [UIImage imageWithCGImage:imgRef scale:assetRep.scale orientation:(UIImageOrientation)assetRep.orientation]; - return img; -} - -+ (UIImage *)fullScreenImageALAsset:(ALAsset *)asset{ - ALAssetRepresentation *assetRep = [asset defaultRepresentation]; - CGImageRef imgRef = [assetRep fullScreenImage];//fullScreenImage已经调整过方向了 - UIImage *img = [UIImage imageWithCGImage:imgRef]; - return img; -} +//+ (UIImage *)fullResolutionImageFromALAsset:(ALAsset *)asset{ +// ALAssetRepresentation *assetRep = [asset defaultRepresentation]; +// CGImageRef imgRef = [assetRep fullResolutionImage]; +// UIImage *img = [UIImage imageWithCGImage:imgRef scale:assetRep.scale orientation:(UIImageOrientation)assetRep.orientation]; +// return img; +//} +// +//+ (UIImage *)fullScreenImageALAsset:(ALAsset *)asset{ +// ALAssetRepresentation *assetRep = [asset defaultRepresentation]; +// CGImageRef imgRef = [assetRep fullScreenImage];//fullScreenImage已经调整过方向了 +// UIImage *img = [UIImage imageWithCGImage:imgRef]; +// return img; +//} -+ (UIImage *)imageWithFileType:(NSString *)fileType{ ++(NSString *)p_iconNameWithFileType:(NSString *)fileType{ fileType = [fileType lowercaseString]; NSString *iconName; //XXX(s) @@ -165,21 +166,93 @@ + (UIImage *)imageWithFileType:(NSString *)fileType{ else{ iconName = @"icon_file_unknown"; } - return [UIImage imageNamed:iconName]; + return iconName; } -- (NSData *)dataSmallerThan:(NSUInteger)dataLength{ - CGFloat compressionQuality = 1.0; - NSData *data = UIImageJPEGRepresentation(self, compressionQuality); - while (data.length > dataLength) { - CGFloat mSize = data.length / (1024 * 1000.0); - compressionQuality *= pow(0.7, log(mSize)/ log(3));//大概每压缩 0.7,mSize 会缩小为原来的三分之一 - data = UIImageJPEGRepresentation(self, compressionQuality); ++ (UIImage *)imageWithFileType:(NSString *)fileType{ + return [UIImage imageNamed:[self p_iconNameWithFileType:fileType]]; +} + ++ (UIImage *)big_imageWithFileType:(NSString *)fileType{ + return [UIImage imageNamed:[NSString stringWithFormat:@"%@_big", [self p_iconNameWithFileType:fileType]]]; +} + +- (NSData *)dataSmallerThan:(CGFloat)maxLength{ + NSAssert(maxLength > 0, @"maxLength 必须是个大于零的数"); + if (self.images.count > 0) {//gif 不压缩 + NSData *data = [AnimatedGIFImageSerialization animatedGIFDataWithImage:self error:nil]; + return data; + } + //先调整 compression(图片质量)进行压缩 + //当 compression 减小到一定程度时,再继续减小,data 的值也不会改变了。这也是之前压缩会进到死循环的原因 + //compressionFixed 之后,再调整 ratio(图片尺寸) + //percentInStep 是每步压缩的百分比 + //maxLoopCount 表示调整 compression 或者 ratio 的最大迭代次数。 + //因为有 maxLoopCount,所以这是个不能保证结果正确的方法 + static NSInteger maxLoopCount = 5; + NSInteger loopCount = 0; + CGFloat compression = 1.0; + CGFloat ratio = 1.0; + CGFloat percentInStep = 1.0; + UIImage *tempImage = self; + NSData *data = UIImageJPEGRepresentation(self, compression); + NSUInteger dataLengthBeforeCompression = data.length; + BOOL compressionFixed = NO; + DebugLog(@"\n=============================================dataSmallerThan Start"); + while (data.length > maxLength) { + percentInStep = maxLength / dataLengthBeforeCompression; + percentInStep = percentInStep < .8? MAX(sqrtf(percentInStep), .3): percentInStep; + if (!compressionFixed) { + compression *= percentInStep; + data = UIImageJPEGRepresentation(tempImage, compression); + DebugLog(@"\ncompression:\t%.6f\ + \nloopCount:\t%ld\ + \npreLength:\t%lu\ + \ncurLength:\t%lu\ + \nmaxLength:\t%.f", + compression, + (long)loopCount, + (unsigned long)dataLengthBeforeCompression, + (unsigned long)data.length, + maxLength); + if (data.length / (CGFloat)dataLengthBeforeCompression > .99 + || ++loopCount >= maxLoopCount) { + loopCount = 0; + compressionFixed = YES; + } + dataLengthBeforeCompression = data.length; + }else{ + ratio = percentInStep; + // Use NSUInteger to prevent white blank + CGSize size = CGSizeMake((NSUInteger)(tempImage.size.width * ratio), + (NSUInteger)(tempImage.size.height * ratio)); + UIGraphicsBeginImageContext(size); + [tempImage drawInRect:CGRectMake(0, 0, size.width, size.height)]; + tempImage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + data = UIImageJPEGRepresentation(tempImage, compression); + DebugLog(@"\nratio:\t%.6f\ + \nloopCount:\t%ld\ + \npreLength:\t%lu\ + \ncurLength:\t%lu\ + \nmaxLength:\t%.f", + ratio, + (long)loopCount, + (unsigned long)dataLengthBeforeCompression, + (unsigned long)data.length, + maxLength); + if (dataLengthBeforeCompression == data.length + || ++loopCount >= maxLoopCount) { + break; + } + dataLengthBeforeCompression = data.length; + } } + DebugLog(@"\n=============================================dataSmallerThan End"); return data; } - (NSData *)dataForCodingUpload{ - return [self dataSmallerThan:1024 * 1000]; + return [self dataSmallerThan:1024 * 5000]; } diff --git a/Coding_iOS/Util/OC_Category/UILabel+Common.h b/Coding_iOS/Util/OC_Category/UILabel+Common.h index f17d49afb..155f14f90 100755 --- a/Coding_iOS/Util/OC_Category/UILabel+Common.h +++ b/Coding_iOS/Util/OC_Category/UILabel+Common.h @@ -20,4 +20,10 @@ + (instancetype)labelWithFont:(UIFont *)font textColor:(UIColor *)textColor; + (instancetype)labelWithSystemFontSize:(CGFloat)fontSize textColorHexString:(NSString *)stringToConvert; + +- (void)colorTextWithColor:(UIColor *)color range:(NSRange)range; +- (void)fontTextWithFont:(UIFont *)font range:(NSRange)range; + +- (void)ea_setText:(NSString*)text lineSpacing:(CGFloat)lineSpacing; + @end diff --git a/Coding_iOS/Util/OC_Category/UILabel+Common.m b/Coding_iOS/Util/OC_Category/UILabel+Common.m index 1bbd51f73..75ca801a3 100755 --- a/Coding_iOS/Util/OC_Category/UILabel+Common.m +++ b/Coding_iOS/Util/OC_Category/UILabel+Common.m @@ -15,15 +15,12 @@ - (void)setLongString:(NSString *)str withFitWidth:(CGFloat)width{ - (void) setLongString:(NSString *)str withFitWidth:(CGFloat)width maxHeight:(CGFloat)maxHeight{ self.numberOfLines = 0; - CGSize resultSize = [str getSizeWithFont:self.font constrainedToSize:CGSizeMake(width, CGFLOAT_MAX)]; - CGFloat resultHeight = resultSize.height; - if (maxHeight > 0 && resultHeight > maxHeight) { - resultHeight = maxHeight; - } - CGRect frame = self.frame; - frame.size.height = resultHeight; - [self setFrame:frame]; self.text = str; + CGSize resultSize = [self sizeThatFits:CGSizeMake(width, maxHeight)]; + if (maxHeight > 0 && resultSize.height > maxHeight) { + resultSize.height = maxHeight; + } + self.size = resultSize; } - (void) setLongString:(NSString *)str withVariableWidth:(CGFloat)maxWidth{ @@ -84,4 +81,37 @@ + (instancetype)labelWithSystemFontSize:(CGFloat)fontSize textColorHexString:(NS return label; } +- (void)colorTextWithColor:(UIColor *)color range:(NSRange)range { + NSMutableAttributedString *attrStr = self.attributedText? self.attributedText.mutableCopy: [[NSMutableAttributedString alloc] initWithString:self.text]; + + [attrStr addAttribute:NSForegroundColorAttributeName value:color range:range]; + self.attributedText = attrStr; +} + +- (void)fontTextWithFont:(UIFont *)font range:(NSRange)range { + NSMutableAttributedString *attrStr = self.attributedText? self.attributedText.mutableCopy: [[NSMutableAttributedString alloc] initWithString:self.text]; + + [attrStr addAttribute:NSFontAttributeName value:font range:range]; + self.attributedText = attrStr; +} + +- (void)ea_setText:(NSString*)text lineSpacing:(CGFloat)lineSpacing{ + if (lineSpacing < 0.01 || !text) { + self.text = text; + return; + } + self.numberOfLines = 0; + NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:text]; + [attributedString addAttribute:NSFontAttributeName value:self.font range:NSMakeRange(0, [text length])]; + + NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; + [paragraphStyle setLineSpacing:lineSpacing]; + [paragraphStyle setLineBreakMode:self.lineBreakMode]; + [paragraphStyle setAlignment:self.textAlignment]; + [attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [text length])]; + + self.attributedText = attributedString; +} + + @end diff --git a/Coding_iOS/Util/OC_Category/UINavigationBar+Common.h b/Coding_iOS/Util/OC_Category/UINavigationBar+Common.h new file mode 100644 index 000000000..79f72cac7 --- /dev/null +++ b/Coding_iOS/Util/OC_Category/UINavigationBar+Common.h @@ -0,0 +1,14 @@ +// +// UINavigationBar+Common.h +// CodingMart +// +// Created by Ease on 16/3/22. +// Copyright © 2016年 net.coding. All rights reserved. +// + +#import + +@interface UINavigationBar (Common) +- (void)setupBrandStyle; +- (void)setupClearBGStyle; +@end diff --git a/Coding_iOS/Util/OC_Category/UINavigationBar+Common.m b/Coding_iOS/Util/OC_Category/UINavigationBar+Common.m new file mode 100644 index 000000000..1029a62f3 --- /dev/null +++ b/Coding_iOS/Util/OC_Category/UINavigationBar+Common.m @@ -0,0 +1,41 @@ +// +// UINavigationBar+Common.m +// CodingMart +// +// Created by Ease on 16/3/22. +// Copyright © 2016年 net.coding. All rights reserved. +// + +#import "UINavigationBar+Common.h" + +@implementation UINavigationBar (Common) +- (void)setupBrandStyle{ + self.translucent = NO; + [self setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault]; + [self setShadowImage:nil]; + self.barTintColor = kColorBrandBlue; + [self p_hideBorderInView:self]; +} +- (void)setupClearBGStyle{ +// self.translucent = YES; +// [self setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault]; +// [self setShadowImage:[UIImage new]]; +// self.barTintColor = [UIColor clearColor]; + [self setBackgroundImage:[UIImage imageWithColor:kColorWhite] forBarMetrics:UIBarMetricsDefault]; + [self p_hideBorderInView:self]; +} + +- (BOOL)p_hideBorderInView:(UIView *)view{ + if ([view isKindOfClass:[UIImageView class]] + && view.frame.size.height <= 1) { + view.hidden = YES; + return YES; + } + for (UIView *subView in view.subviews) { + if ([self p_hideBorderInView:subView]) { + return YES; + } + } + return NO; +} +@end diff --git a/Coding_iOS/Util/OC_Category/UINavigationController+FullscreenPopGesture.h b/Coding_iOS/Util/OC_Category/UINavigationController+FullscreenPopGesture.h new file mode 100644 index 000000000..f8942c562 --- /dev/null +++ b/Coding_iOS/Util/OC_Category/UINavigationController+FullscreenPopGesture.h @@ -0,0 +1,14 @@ +// +// UINavigationController+FullscreenPopGesture.h +// Coding_Enterprise_iOS +// +// Created by Ease on 2017/2/24. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import + +@interface UINavigationController (FullscreenPopGesture) +- (void)addFullscreenPopGesture; +- (void)removeFullscreenPopGesture; +@end diff --git a/Coding_iOS/Util/OC_Category/UINavigationController+FullscreenPopGesture.m b/Coding_iOS/Util/OC_Category/UINavigationController+FullscreenPopGesture.m new file mode 100644 index 000000000..0ccc018be --- /dev/null +++ b/Coding_iOS/Util/OC_Category/UINavigationController+FullscreenPopGesture.m @@ -0,0 +1,97 @@ +// +// UINavigationController+FullscreenPopGesture.m +// Coding_Enterprise_iOS +// +// Created by Ease on 2017/2/24. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "UINavigationController+FullscreenPopGesture.h" + + +@interface _FDFullscreenPopGestureRecognizerDelegate : NSObject + +@property (nonatomic, weak) UINavigationController *navigationController; + +@end + +@implementation _FDFullscreenPopGestureRecognizerDelegate + +- (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer +{ + // Ignore when no view controller is pushed into the navigation stack. + if (self.navigationController.viewControllers.count <= 1) { + return NO; + } + + // Ignore pan gesture when the navigation controller is currently in transition. + if ([[self.navigationController valueForKey:@"_isTransitioning"] boolValue]) { + return NO; + } + + // Prevent calling the handler when the gesture begins in an opposite direction. + CGPoint translation = [gestureRecognizer translationInView:gestureRecognizer.view]; + if (translation.x <= 0) { + return NO; + } + + return YES; +} + +@end + +@implementation UINavigationController (FullscreenPopGesture) + +- (void)addFullscreenPopGesture{ + if (![self.interactivePopGestureRecognizer.view.gestureRecognizers containsObject:self.fd_fullscreenPopGestureRecognizer]) { + + // Add our own gesture recognizer to where the onboard screen edge pan gesture recognizer is attached to. + [self.interactivePopGestureRecognizer.view addGestureRecognizer:self.fd_fullscreenPopGestureRecognizer]; + + // Forward the gesture events to the private handler of the onboard gesture recognizer. + NSArray *internalTargets = [self.interactivePopGestureRecognizer valueForKey:@"targets"]; + id internalTarget = [internalTargets.firstObject valueForKey:@"target"]; + SEL internalAction = NSSelectorFromString(@"handleNavigationTransition:"); + self.fd_fullscreenPopGestureRecognizer.delegate = self.fd_popGestureRecognizerDelegate; + [self.fd_fullscreenPopGestureRecognizer addTarget:internalTarget action:internalAction]; + } +} + +- (void)removeFullscreenPopGesture{ + if ([self.interactivePopGestureRecognizer.view.gestureRecognizers containsObject:self.fd_fullscreenPopGestureRecognizer]) { + NSArray *internalTargets = [self.interactivePopGestureRecognizer valueForKey:@"targets"]; + id internalTarget = [internalTargets.firstObject valueForKey:@"target"]; + SEL internalAction = NSSelectorFromString(@"handleNavigationTransition:"); + self.fd_fullscreenPopGestureRecognizer.delegate = nil; + [self.fd_fullscreenPopGestureRecognizer removeTarget:internalTarget action:internalAction]; + + [self.interactivePopGestureRecognizer.view removeGestureRecognizer:self.fd_fullscreenPopGestureRecognizer]; + } +} + +- (_FDFullscreenPopGestureRecognizerDelegate *)fd_popGestureRecognizerDelegate +{ + _FDFullscreenPopGestureRecognizerDelegate *delegate = objc_getAssociatedObject(self, _cmd); + + if (!delegate) { + delegate = [[_FDFullscreenPopGestureRecognizerDelegate alloc] init]; + delegate.navigationController = self; + + objc_setAssociatedObject(self, _cmd, delegate, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + } + return delegate; +} + +- (UIPanGestureRecognizer *)fd_fullscreenPopGestureRecognizer +{ + UIPanGestureRecognizer *panGestureRecognizer = objc_getAssociatedObject(self, _cmd); + + if (!panGestureRecognizer) { + panGestureRecognizer = [[UIPanGestureRecognizer alloc] init]; + panGestureRecognizer.maximumNumberOfTouches = 1; + + objc_setAssociatedObject(self, _cmd, panGestureRecognizer, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + } + return panGestureRecognizer; +} +@end diff --git a/Coding_iOS/Util/OC_Category/UISearchBar+Common.h b/Coding_iOS/Util/OC_Category/UISearchBar+Common.h index 192a95086..90739e214 100644 --- a/Coding_iOS/Util/OC_Category/UISearchBar+Common.h +++ b/Coding_iOS/Util/OC_Category/UISearchBar+Common.h @@ -11,4 +11,6 @@ @interface UISearchBar (Common) - (void)insertBGColor:(UIColor *)backgroundColor; - (UITextField *)eaTextField; +- (void)setPlaceholderColor:(UIColor *)color; +- (void)setSearchIcon:(UIImage *)image; @end diff --git a/Coding_iOS/Util/OC_Category/UISearchBar+Common.m b/Coding_iOS/Util/OC_Category/UISearchBar+Common.m index 488243527..68d451484 100644 --- a/Coding_iOS/Util/OC_Category/UISearchBar+Common.m +++ b/Coding_iOS/Util/OC_Category/UISearchBar+Common.m @@ -31,5 +31,10 @@ - (UITextField *)eaTextField{ }]; return [self.subviews.firstObject.subviews filteredArrayUsingPredicate:predicate].lastObject; } - +- (void)setPlaceholderColor:(UIColor *)color{ + [[self valueForKey:@"_searchField"] setValue:kColorDarkA forKeyPath:@"_placeholderLabel.textColor"]; +} +- (void)setSearchIcon:(UIImage *)image{ + [self setImage:image forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal]; +} @end diff --git a/Coding_iOS/Util/OC_Category/UITableView+Common.m b/Coding_iOS/Util/OC_Category/UITableView+Common.m index 4a6c6e372..9f6b699a5 100755 --- a/Coding_iOS/Util/OC_Category/UITableView+Common.m +++ b/Coding_iOS/Util/OC_Category/UITableView+Common.m @@ -152,7 +152,7 @@ - (void)addLineforPlainCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPa layer.fillColor = [UIColor colorWithWhite:1.f alpha:0.8f].CGColor; } - CGColorRef lineColor = kColorDDD.CGColor; + CGColorRef lineColor = kColorD8DDE4.CGColor; CGColorRef sectionLineColor = lineColor; if (indexPath.row == 0 && indexPath.row == [self numberOfRowsInSection:indexPath.section]-1) { diff --git a/Coding_iOS/Util/OC_Category/UITableViewCell+Common.h b/Coding_iOS/Util/OC_Category/UITableViewCell+Common.h new file mode 100644 index 000000000..eafb2d113 --- /dev/null +++ b/Coding_iOS/Util/OC_Category/UITableViewCell+Common.h @@ -0,0 +1,15 @@ +// +// UITableViewCell+Common.h +// Coding_Enterprise_iOS +// +// Created by Easeeeeeeeee on 2017/4/18. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import + +@interface UITableViewCell (Common) + +@end + +void swizzleAllCell(); diff --git a/Coding_iOS/Util/OC_Category/UITableViewCell+Common.m b/Coding_iOS/Util/OC_Category/UITableViewCell+Common.m new file mode 100644 index 000000000..82754853e --- /dev/null +++ b/Coding_iOS/Util/OC_Category/UITableViewCell+Common.m @@ -0,0 +1,70 @@ +// +// UITableViewCell+Common.m +// Coding_Enterprise_iOS +// +// Created by Easeeeeeeeee on 2017/4/18. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "UITableViewCell+Common.h" +#import "ObjcRuntime.h" + +@implementation UITableViewCell (Common) +- (void)customSetAccessoryType:(UITableViewCellAccessoryType)type{ + self.tintColor = kColorLightBlue; + NSInteger accessoryTag = 1234; + if (type == UITableViewCellAccessoryDisclosureIndicator) { + if (self.accessoryView.tag != accessoryTag) { + UIView *accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cell_arrow_left"] highlightedImage:[UIImage imageNamed:@"cell_arrow_left"]]; + accessoryView.tag = accessoryTag; + self.accessoryView = accessoryView; + } + self.accessoryView.hidden = NO; + [self customSetAccessoryType:type]; + }else{ + if (self.accessoryView.tag == accessoryTag) { + self.accessoryView.hidden = YES; + } + [self customSetAccessoryType:type]; + } +} + +//- (void)customSetSelectionStyle:(UITableViewCellSelectionStyle)selectionStyle{ +// NSInteger selectionTag = 1235; +// if (selectionStyle == UITableViewCellSelectionStyleDefault) { +// if (self.selectedBackgroundView.tag != selectionTag) { +// UIView *selectedBGV = [UIView new]; +// selectedBGV.backgroundColor = [UIColor randomColor]; +// self.selectedBackgroundView = selectedBGV; +// } +// [self customSetSelectionStyle:selectionStyle]; +// }else{ +// [self customSetSelectionStyle:selectionStyle]; +// } +//} + +- (void)customSetSelected:(BOOL)selected{ + NSInteger selectionTag = 1235; + if (self.selectionStyle == UITableViewCellSelectionStyleDefault) { + if (self.selectedBackgroundView.tag != selectionTag) { + UIView *selectedBGV = [UIView new]; + selectedBGV.backgroundColor = kColorD8DDE4; + self.selectedBackgroundView = selectedBGV; + } + [self customSetSelected:selected]; + }else{ + [self customSetSelected:selected]; + } +} + ++ (void)load{ + swizzleAllCell(); +} + +@end + +void swizzleAllCell(){ + Swizzle([UITableViewCell class], @selector(setAccessoryType:), @selector(customSetAccessoryType:)); +// Swizzle([UITableViewCell class], @selector(setSelectionStyle:), @selector(customSetSelectionStyle:)); + Swizzle([UITableViewCell class], @selector(setSelected:), @selector(customSetSelected:)); +} diff --git a/Coding_iOS/Util/OC_Category/UIView+Common.h b/Coding_iOS/Util/OC_Category/UIView+Common.h index b1a3dbccd..320ee23bc 100755 --- a/Coding_iOS/Util/OC_Category/UIView+Common.h +++ b/Coding_iOS/Util/OC_Category/UIView+Common.h @@ -21,7 +21,9 @@ typedef NS_ENUM(NSInteger, EaseBlankPageType) EaseBlankPageTypeTask, EaseBlankPageTypeTopic, EaseBlankPageTypeTweet, + EaseBlankPageTypeTweetAction, EaseBlankPageTypeTweetOther, + EaseBlankPageTypeTweetProject, EaseBlankPageTypeProject, EaseBlankPageTypeProjectOther, EaseBlankPageTypeFileDleted, @@ -35,6 +37,7 @@ typedef NS_ENUM(NSInteger, EaseBlankPageType) EaseBlankPageTypeFileTypeCannotSupport, EaseBlankPageTypeViewTips, EaseBlankPageTypeShopOrders, + EaseBlankPageTypeShopUnPayOrders, EaseBlankPageTypeShopSendOrders, EaseBlankPageTypeShopUnSendOrders, EaseBlankPageTypeNoExchangeGoods, @@ -44,6 +47,12 @@ typedef NS_ENUM(NSInteger, EaseBlankPageType) EaseBlankPageTypeProject_WATCHED, EaseBlankPageTypeProject_STARED, EaseBlankPageTypeProject_SEARCH, + EaseBlankPageTypeTeam, + EaseBlankPageTypeFile, + EaseBlankPageTypeMessageList, + EaseBlankPageTypeViewPurchase, + EaseBlankPageTypeCode, + EaseBlankPageTypeWiki, }; typedef NS_ENUM(NSInteger, BadgePositionType) { @@ -119,8 +128,8 @@ typedef NS_ENUM(NSInteger, BadgePositionType) { @interface EaseBlankPageView : UIView @property (strong, nonatomic) UIImageView *monkeyView; -@property (strong, nonatomic) UILabel *tipLabel; -@property (strong, nonatomic) UIButton *reloadButton; +@property (strong, nonatomic) UILabel *tipLabel, *titleLabel; +@property (strong, nonatomic) UIButton *reloadButton, *actionButton; @property (assign, nonatomic) EaseBlankPageType curType; @property (copy, nonatomic) void(^reloadButtonBlock)(id sender); @property (copy, nonatomic) void(^loadAndShowStatusBlock)(); diff --git a/Coding_iOS/Util/OC_Category/UIView+Common.m b/Coding_iOS/Util/OC_Category/UIView+Common.m index 52fb2e4e8..a9521325e 100755 --- a/Coding_iOS/Util/OC_Category/UIView+Common.m +++ b/Coding_iOS/Util/OC_Category/UIView+Common.m @@ -11,6 +11,8 @@ #define kTagBadgePointView 1001 #define kTagLineView 1007 #import +#import "YLImageView.h" +#import "YLGIFImage.h" #import "Login.h" #import "User.h" @@ -105,7 +107,7 @@ - (void)addBadgePoint:(NSInteger)pointRadius withPointPosition:(CGPoint)point { UIView *badgeView = [[UIView alloc]init]; badgeView.tag = kTagBadgePointView; badgeView.layer.cornerRadius = pointRadius; - badgeView.backgroundColor = [UIColor colorWithHexString:@"0xf75388"]; + badgeView.backgroundColor = [UIColor colorWithHexString:@"0xFF0000"]; badgeView.frame = CGRectMake(0, 0, 2 * pointRadius, 2 * pointRadius); badgeView.center = point; [self addSubview:badgeView]; @@ -204,7 +206,7 @@ - (CGFloat)maxXOfFrame{ - (void)setSubScrollsToTop:(BOOL)scrollsToTop{ [[self subviews] enumerateObjectsUsingBlock:^(UIView *obj, NSUInteger idx, BOOL *stop) { if ([obj isKindOfClass:[UIScrollView class]]) { - [(UIScrollView *)obj setScrollEnabled:scrollsToTop]; + [(UIScrollView *)obj setScrollsToTop:scrollsToTop]; *stop = YES; } }]; @@ -296,17 +298,6 @@ - (void)addLineUp:(BOOL)hasUp andDown:(BOOL)hasDown{ } - (void)addLineUp:(BOOL)hasUp andDown:(BOOL)hasDown andColor:(UIColor *)color{ - [self removeViewWithTag:kTagLineView]; - if (hasUp) { - UIView *upView = [UIView lineViewWithPointYY:0 andColor:color]; - upView.tag = kTagLineView; - [self addSubview:upView]; - } - if (hasDown) { - UIView *downView = [UIView lineViewWithPointYY:CGRectGetMaxY(self.bounds)-0.5 andColor:color]; - downView.tag = kTagLineView; - [self addSubview:downView]; - } return [self addLineUp:hasUp andDown:hasDown andColor:color andLeftSpace:0]; } - (void)addLineUp:(BOOL)hasUp andDown:(BOOL)hasDown andColor:(UIColor *)color andLeftSpace:(CGFloat)leftSpace{ @@ -355,10 +346,14 @@ - (EaseLoadingView *)loadingView{ } - (void)beginLoading{ - for (UIView *aView in [self.blankPageContainer subviews]) { - if ([aView isKindOfClass:[EaseBlankPageView class]] && !aView.hidden) { - return; - } +// 这里处理有点迷啊。。为啥有空白页就不 loading 了 +// for (UIView *aView in [self.blankPageContainer subviews]) { +// if ([aView isKindOfClass:[EaseBlankPageView class]] && !aView.hidden) { +// return; +// } +// } + if (self.blankPageView) { + self.blankPageView.hidden = YES; } if (!self.loadingView) { //初始化LoadingView @@ -366,7 +361,8 @@ - (void)beginLoading{ } [self addSubview:self.loadingView]; [self.loadingView mas_makeConstraints:^(MASConstraintMaker *make) { - make.self.edges.equalTo(self); + make.height.width.centerX.centerY.equalTo(self); +// make.self.edges.equalTo(self);//self 是 scrollView 的时候,貌似会跟 contentSize 扯上关系 }]; [self.loadingView startAnimating]; } @@ -434,23 +430,32 @@ - (instancetype)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if (self) { self.backgroundColor = [UIColor clearColor]; - _loopView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"loading_loop"]]; - _monkeyView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"loading_monkey"]]; - [_loopView setCenter:self.center]; - [_monkeyView setCenter:self.center]; - [self addSubview:_loopView]; + _monkeyView = [YLImageView new]; + _monkeyView.image = [YLGIFImage imageNamed:@"loading_monkey@2x.gif"]; [self addSubview:_monkeyView]; - [_loopView mas_makeConstraints:^(MASConstraintMaker *make) { - make.center.equalTo(self); - }]; [_monkeyView mas_makeConstraints:^(MASConstraintMaker *make) { - make.center.equalTo(self); + make.centerX.equalTo(self); + make.centerY.equalTo(self).offset(-30); + make.size.mas_equalTo(CGSizeMake(100, 100)); }]; - - _loopAngle = 0.0; - _monkeyAlpha = 1.0; - _angleStep = 360/3; - _alphaStep = 1.0/3.0; + +// _loopView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"loading_loop"]]; +// _monkeyView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"loading_monkey"]]; +// [_loopView setCenter:self.center]; +// [_monkeyView setCenter:self.center]; +// [self addSubview:_loopView]; +// [self addSubview:_monkeyView]; +// [_loopView mas_makeConstraints:^(MASConstraintMaker *make) { +// make.center.equalTo(self); +// }]; +// [_monkeyView mas_makeConstraints:^(MASConstraintMaker *make) { +// make.center.equalTo(self); +// }]; +// +// _loopAngle = 0.0; +// _monkeyAlpha = 1.0; +// _angleStep = 360/3; +// _alphaStep = 1.0/3.0; } return self; } @@ -461,7 +466,7 @@ - (void)startAnimating{ return; } _isLoading = YES; - [self loadingAnimation]; +// [self loadingAnimation]; } - (void)stopAnimating{ @@ -487,7 +492,7 @@ - (void)loadingAnimation{ [self removeFromSuperview]; _loopAngle = 0.0; - _monkeyAlpha = 1,0; + _monkeyAlpha = 1.0; _alphaStep = ABS(_alphaStep); CGAffineTransform loopAngleTransform = CGAffineTransformMakeRotation(_loopAngle * (M_PI / 180.0f)); _loopView.transform = loopAngleTransform; @@ -502,13 +507,15 @@ @implementation EaseBlankPageView - (instancetype)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if (self) { - self.backgroundColor = [UIColor clearColor]; + self.backgroundColor = [UIColor whiteColor]; } return self; } - (void)configWithType:(EaseBlankPageType)blankPageType hasData:(BOOL)hasData hasError:(BOOL)hasError offsetY:(CGFloat)offsetY reloadButtonBlock:(void (^)(id))block{ - + _curType = blankPageType; + _reloadButtonBlock = block; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ if (_loadAndShowStatusBlock) { _loadAndShowStatusBlock(); @@ -524,275 +531,317 @@ - (void)configWithType:(EaseBlankPageType)blankPageType hasData:(BOOL)hasData ha // 图片 if (!_monkeyView) { _monkeyView = [[UIImageView alloc] initWithFrame:CGRectZero]; + _monkeyView.contentMode = UIViewContentModeScaleAspectFill; [self addSubview:_monkeyView]; } + // 标题 + if (!_titleLabel) { + _titleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + _titleLabel.backgroundColor = [UIColor clearColor]; + _titleLabel.numberOfLines = 0; + _titleLabel.font = [UIFont systemFontOfSize:15]; + _titleLabel.textColor = [UIColor colorWithHexString:@"0x425063"]; + _titleLabel.textAlignment = NSTextAlignmentCenter; + [self addSubview:_titleLabel]; + } // 文字 if (!_tipLabel) { _tipLabel = [[UILabel alloc] initWithFrame:CGRectZero]; _tipLabel.backgroundColor = [UIColor clearColor]; _tipLabel.numberOfLines = 0; - _tipLabel.font = [UIFont systemFontOfSize:15]; - _tipLabel.textColor = [UIColor lightGrayColor]; + _tipLabel.font = [UIFont systemFontOfSize:14]; + _tipLabel.textColor = [UIColor colorWithHexString:@"0x76808E"]; _tipLabel.textAlignment = NSTextAlignmentCenter; [self addSubview:_tipLabel]; } - - // 布局 - [_monkeyView mas_makeConstraints:^(MASConstraintMaker *make) { - make.centerX.equalTo(self); - if (ABS(offsetY) > 1.0) { - make.top.equalTo(self).offset(offsetY); - }else{ - make.bottom.equalTo(self.mas_centerY); - } - }]; - [_tipLabel mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.right.centerX.equalTo(self); - make.top.equalTo(_monkeyView.mas_bottom); - make.height.mas_equalTo(50); - }]; - - _reloadButtonBlock = nil; + // 按钮 + if (!_actionButton) {//新增按钮 + _actionButton = ({ + UIButton *button = [UIButton new]; + button.backgroundColor = [UIColor colorWithHexString:@"0x425063"]; + button.titleLabel.font = [UIFont systemFontOfSize:15]; + [button addTarget:self action:@selector(btnAction) forControlEvents:UIControlEventTouchUpInside]; + button.layer.cornerRadius = 4; + button.layer.masksToBounds = YES; + button; + }); + [self addSubview:_actionButton]; + } + if (!_reloadButton) {//重新加载按钮 + _reloadButton = ({ + UIButton *button = [UIButton new]; + button.backgroundColor = [UIColor colorWithHexString:@"0x425063"]; + button.titleLabel.font = [UIFont systemFontOfSize:15]; + [button addTarget:self action:@selector(reloadButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; + button.layer.cornerRadius = 4; + button.layer.masksToBounds = YES; + button; + }); + [self addSubview:_reloadButton]; + } + NSString *imageName, *titleStr, *tipStr; + NSString *buttonTitle; if (hasError) { // 加载失败 - if (!_reloadButton) { - _reloadButton = [[UIButton alloc] initWithFrame:CGRectZero]; - [_reloadButton setImage:[UIImage imageNamed:@"blankpage_button_reload"] forState:UIControlStateNormal]; - _reloadButton.adjustsImageWhenHighlighted = YES; - [_reloadButton addTarget:self action:@selector(reloadButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; - [self addSubview:_reloadButton]; - [_reloadButton mas_makeConstraints:^(MASConstraintMaker *make) { - make.centerX.equalTo(self); - make.top.equalTo(_tipLabel.mas_bottom); - make.size.mas_equalTo(CGSizeMake(160, 60)); - }]; - } - _reloadButton.hidden = NO; - _reloadButtonBlock = block; - [_monkeyView setImage:[UIImage imageNamed:@"blankpage_image_loadFail"]]; - _tipLabel.text = @"貌似出了点差错\n真忧伤呢"; + _actionButton.hidden = YES; + + tipStr = @"呀,网络出了问题"; + imageName = @"blankpage_image_LoadFail"; + buttonTitle = @"重新连接网络"; }else{ // 空白数据 - if (_reloadButton) { - _reloadButton.hidden = YES; - } + _reloadButton.hidden = YES; - NSString *imageName, *tipStr; - _curType=blankPageType; - switch (blankPageType) { + switch (_curType) { case EaseBlankPageTypeTaskResource: { - imageName = @"blankpage_image_Sleep"; - tipStr = @"暂时没有相关的资源"; - break; + tipStr = @"暂无关联资源"; } + break; case EaseBlankPageTypeActivity://项目动态 { - imageName = @"blankpage_image_Sleep"; - tipStr = @"这里还什么都没有\n赶快起来弄出一点动静吧"; + imageName = @"blankpage_image_Activity"; + tipStr = @"当前项目暂无相关动态"; } break; case EaseBlankPageTypeTask://任务列表 { - imageName = @"blankpage_image_Sleep"; - tipStr = @"这里还没有任务\n赶快起来为团队做点贡献吧"; + imageName = @"blankpage_image_Task"; + tipStr = @"这里还没有任务哦"; } break; case EaseBlankPageTypeTopic://讨论列表 { - imageName = @"blankpage_image_Sleep"; - tipStr = @"这里怎么空空的\n发个讨论让它热闹点吧"; + imageName = @"blankpage_image_Topic"; + tipStr = @"这里还没有讨论哦"; } break; case EaseBlankPageTypeTweet://冒泡列表(自己的) { - imageName = @"blankpage_image_Hi"; - tipStr = @"来,冒个泡吧~"; + imageName = @"blankpage_image_Tweet"; + tipStr = @"您还没有发表过冒泡呢~"; } break; - case EaseBlankPageTypeTweetOther://冒泡列表(别人的、项目内的) + case EaseBlankPageTypeTweetAction://冒泡列表(自己的)。有发冒泡的按钮 { - imageName = @"blankpage_image_Sleep"; - tipStr = @"这里很空\n一个冒泡都木有~"; + imageName = @"blankpage_image_Tweet"; + tipStr = @"您还没有发表过冒泡呢~"; + buttonTitle = @"冒个泡吧"; + } + break; + case EaseBlankPageTypeTweetOther://冒泡列表(别人的) + { + imageName = @"blankpage_image_Tweet"; + tipStr = @"这里还没有冒泡哦~"; + } + break; + case EaseBlankPageTypeTweetProject://冒泡列表(项目内的) + { + imageName = @"blankpage_image_Notice"; + tipStr = @"当前项目没有公告哦~"; } break; case EaseBlankPageTypeProject://项目列表(自己的) { - imageName = @"blankpage_image_Sleep"; - tipStr = @"您还木有项目呢,赶快起来创建吧~"; + imageName = @"blankpage_image_Project"; + titleStr = @"欢迎来到 CODING"; + tipStr = @"协作从项目开始,赶快创建项目吧"; } break; case EaseBlankPageTypeProjectOther://项目列表(别人的) { - imageName = @"blankpage_image_Sleep"; - tipStr = @"这个人很懒,一个项目都木有~"; + imageName = @"blankpage_image_Project"; + tipStr = @"这里还没有项目哦"; } break; case EaseBlankPageTypeFileDleted://去了文件页面,发现文件已经被删除了 { - imageName = @"blankpage_image_loadFail"; - tipStr = @"晚了一步\n文件刚刚被人删除了~"; + tipStr = @"晚了一步,此文件刚刚被人删除了~"; } + break; case EaseBlankPageTypeMRForbidden://去了MR页面,发现没有权限 { - imageName = @"blankpage_image_loadFail"; - tipStr = @"无权访问\n请联系项目管理员进行代码权限设置"; + tipStr = @"抱歉,请联系项目管理员进行代码权限设置"; } break; case EaseBlankPageTypeFolderDleted://文件夹 { - imageName = @"blankpage_image_loadFail"; - tipStr = @"晚了一步\n文件夹貌似被人删除了~"; + tipStr = @"晚了一步,此文件夹刚刚被人删除了~"; } break; case EaseBlankPageTypePrivateMsg://私信列表 { - imageName = @"blankpage_image_Hi"; - tipStr = @"打个招呼吧~"; + imageName = @"";//就是空 + tipStr = @""; } break; case EaseBlankPageTypeMyJoinedTopic://我参与的话题 + { + imageName = @"blankpage_image_Tweet"; + tipStr = @"您还没有参与过话题讨论呢~"; + } + break; case EaseBlankPageTypeMyWatchedTopic://我关注的话题 { - imageName = @"blankpage_image_Sleep"; - tipStr = @"您还没有话题呢~"; + imageName = @"blankpage_image_Tweet"; + tipStr = @"您还没有关注过话题讨论呢~"; } break; case EaseBlankPageTypeOthersJoinedTopic://ta参与的话题 + { + imageName = @"blankpage_image_Tweet"; + tipStr = @"Ta 还没有参与过话题讨论呢~"; + } + break; case EaseBlankPageTypeOthersWatchedTopic://ta关注的话题 { - imageName = @"blankpage_image_Sleep"; - tipStr = @"这个人很懒,一个话题都木有~"; + imageName = @"blankpage_image_Tweet"; + tipStr = @"Ta 还没有关注过话题讨论呢~"; } break; case EaseBlankPageTypeFileTypeCannotSupport: { - imageName = @"blankpage_image_loadFail"; - tipStr = @"不支持这种类型的文件\n试试右上角的按钮,用其他应用打开吧"; + tipStr = @"还不支持查看此类型的文件呢"; } break; case EaseBlankPageTypeViewTips: { - imageName = @"blankpage_image_Sleep"; - tipStr = @"这里没有未读的消息"; + imageName = @"blankpage_image_Tip"; + tipStr = @"您还没有收到通知哦"; } break; case EaseBlankPageTypeShopOrders: { - imageName = @"blankpage_image_Sleep"; - tipStr = @"您还木有订单呢\n努力做任务,把洋葱猴带回家~"; + imageName = @"blankpage_image_ShopOrder"; + tipStr = @"还没有订单记录~"; + } + break; + case EaseBlankPageTypeShopUnPayOrders: + { + imageName = @"blankpage_image_ShopOrder"; + tipStr = @"没有待支付的订单记录~"; } break; case EaseBlankPageTypeShopSendOrders: { - imageName = @"blankpage_image_Sleep"; - tipStr = @"您还木有已发货的订单呢~"; + imageName = @"blankpage_image_ShopOrder"; + tipStr = @"没有已发货的订单记录~"; } break; case EaseBlankPageTypeShopUnSendOrders: { - imageName = @"blankpage_image_Sleep"; - tipStr = @"您还木有未发货的订单呢~"; + imageName = @"blankpage_image_ShopOrder"; + tipStr = @"没有未发货的订单记录~"; } break; case EaseBlankPageTypeNoExchangeGoods:{ - imageName = @"blankpage_image_Sleep"; - tipStr = @"还木有可兑换的商品呢\n努力做任务,把洋葱猴带回家~"; - } - break; - case EaseBlankPageTypeProject_ALL:{ - imageName = @"blankpage_image_Sleep"; - tipStr = @"您还木有项目呢,赶快起来创建吧~"; - } - break; - case EaseBlankPageTypeProject_CREATE:{ - imageName = @"blankpage_image_Sleep"; - tipStr = @"您还木有项目呢,赶快起来创建吧~"; + tipStr = @"还没有可兑换的商品呢~"; } break; + case EaseBlankPageTypeProject_ALL: + case EaseBlankPageTypeProject_CREATE: case EaseBlankPageTypeProject_JOIN:{ - imageName = @"blankpage_image_Sleep"; - tipStr = @"您还木有项目呢,赶快起来创建吧~"; + imageName = @"blankpage_image_Project"; + titleStr = @"欢迎来到 CODING"; + tipStr = @"协作从项目开始,赶快创建项目吧"; + buttonTitle=@"创建项目"; } break; case EaseBlankPageTypeProject_WATCHED:{ - imageName = @"blankpage_image_Sleep"; - tipStr = @"您还木有项目呢,赶快起来创建吧~"; + imageName = @"blankpage_image_Project"; + tipStr = @"您还没有关注过项目呢~"; + buttonTitle=@"去关注"; } break; case EaseBlankPageTypeProject_STARED:{ - imageName = @"blankpage_image_Sleep"; - tipStr = @"您还木有项目呢,赶快起来创建吧~"; + imageName = @"blankpage_image_Project"; + tipStr = @"您还没有收藏过项目呢~"; + buttonTitle=@"去收藏"; } break; case EaseBlankPageTypeProject_SEARCH:{ - imageName = @"blankpage_image_Sleep"; tipStr = @"什么都木有搜到,换个词再试试?"; } break; + case EaseBlankPageTypeTeam:{ + imageName = @"blankpage_image_Team"; + tipStr = @"您还没有参与过团队哦~"; + } + break; + case EaseBlankPageTypeFile:{ + imageName = @"blankpage_image_File"; + tipStr = @"这里还没有任何文件~"; + } + break; + case EaseBlankPageTypeMessageList:{ + imageName = @"blankpage_image_MessageList"; + tipStr = @"还没有新消息~"; + } + break; + case EaseBlankPageTypeViewPurchase:{ + imageName = @"blankpage_image_ShopOrder"; + tipStr = @"还没有订购记录~"; + } + break; + case EaseBlankPageTypeCode: + { + tipStr = @"当前项目还没有提交过代码呢~"; + } + break; + case EaseBlankPageTypeWiki: + { + tipStr = @"当前项目还没有创建 Wiki~"; + } + break; default://其它页面(这里没有提到的页面,都属于其它) { - imageName = @"blankpage_image_Sleep"; - tipStr = @"这里还什么都没有\n赶快起来弄出一点动静吧"; + tipStr = @"这里什么都没有~"; } break; } - [_monkeyView setImage:[UIImage imageNamed:imageName]]; - _tipLabel.text = tipStr; - - if ((blankPageType>=EaseBlankPageTypeProject_ALL)&&(blankPageType<=EaseBlankPageTypeProject_STARED)) { - [_monkeyView mas_updateConstraints:^(MASConstraintMaker *make) { - make.centerX.equalTo(self); - make.bottom.equalTo(self.mas_centerY).offset(-35); - }]; - - //新增按钮 - UIButton *actionBtn=({ - UIButton *button=[UIButton new]; - button.backgroundColor=kColorBrandGreen; - button.titleLabel.font=[UIFont systemFontOfSize:15]; - [button addTarget:self action:@selector(btnAction) forControlEvents:UIControlEventTouchUpInside]; - button.layer.cornerRadius=18; - button.layer.masksToBounds=TRUE; - button; - }); - [self addSubview:actionBtn]; - - [actionBtn mas_makeConstraints:^(MASConstraintMaker *make) { - make.size.mas_equalTo(CGSizeMake(125 , 36)); - make.top.equalTo(_tipLabel.mas_bottom).offset(15); - make.centerX.equalTo(self); - }]; - - NSString *titleStr; - switch (blankPageType) { - case EaseBlankPageTypeProject_ALL: - case EaseBlankPageTypeProject_CREATE: - case EaseBlankPageTypeProject_JOIN: - titleStr=@"+ 创建项目"; - // [actionBtn setTitle:@"+ 创建项目" forState:UIControlStateNormal]; - break; - case EaseBlankPageTypeProject_WATCHED: - titleStr=@"+ 去关注"; - // [actionBtn setTitle:@"+ 去关注" forState:UIControlStateNormal]; - break; - case EaseBlankPageTypeProject_STARED: - titleStr=@"+ 去收藏"; - // [actionBtn setTitle:@"+去收藏" forState:UIControlStateNormal]; - break; - default: - break; - } - // NSMutableAttributedString *titleFontStr=[[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"+ %@",titleStr]]; - // NSRange range; - // range.location=0; - // range.length=1; - // [titleFontStr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:20] range:range]; - // [actionBtn setAttributedTitle:titleFontStr forState:UIControlStateNormal]; - - [actionBtn setTitle:titleStr forState:UIControlStateNormal]; - + } + imageName = imageName ?: @"blankpage_image_Default"; + UIButton *bottomBtn = hasError? _reloadButton: _actionButton; + _monkeyView.image = [UIImage imageNamed:imageName]; + _titleLabel.text = titleStr; + _tipLabel.text = tipStr; + [bottomBtn setTitle:buttonTitle forState:UIControlStateNormal]; + _titleLabel.hidden = titleStr.length <= 0; + bottomBtn.hidden = buttonTitle.length <= 0; + + // 布局 + if (ABS(offsetY) > 0) { + self.frame = CGRectMake(0, offsetY, self.width, self.height); + } + [_monkeyView mas_remakeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self); + // if (ABS(offsetY) > 1.0) { + // make.top.equalTo(self).offset(offsetY); + // }else{ + make.top.equalTo(self.mas_bottom).multipliedBy(0.15); + // } + make.size.mas_equalTo(CGSizeMake(160, 160)); + }]; + [_titleLabel mas_remakeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self).offset(30); + make.right.equalTo(self).offset(-30); + make.top.equalTo(_monkeyView.mas_bottom); + }]; + [_tipLabel mas_remakeConstraints:^(MASConstraintMaker *make) { + make.left.right.equalTo(_titleLabel); + if (titleStr.length > 0) { + make.top.equalTo(_titleLabel.mas_bottom).offset(10); + }else{ + make.top.equalTo(_monkeyView.mas_bottom); } + }]; + if (buttonTitle.length > 0) { + } + [bottomBtn mas_remakeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self); + make.size.mas_equalTo(CGSizeMake(130, 44)); + make.top.equalTo(_tipLabel.mas_bottom).offset(25); + }]; } - (void)reloadButtonClicked:(id)sender{ diff --git a/Coding_iOS/Util/OC_Category/UIViewController+Swizzle.m b/Coding_iOS/Util/OC_Category/UIViewController+Swizzle.m index 1a58b181f..9a644ad7d 100755 --- a/Coding_iOS/Util/OC_Category/UIViewController+Swizzle.m +++ b/Coding_iOS/Util/OC_Category/UIViewController+Swizzle.m @@ -40,18 +40,20 @@ - (void)customviewWillAppear:(BOOL)animated{ #pragma mark BackBtn M - (UIBarButtonItem *)backButton{ - NSDictionary*textAttributes; +// NSDictionary*textAttributes; +// if ([[UIBarButtonItem appearance] respondsToSelector:@selector(setTitleTextAttributes:forState:)]){ +// textAttributes = @{ +// NSFontAttributeName: [UIFont systemFontOfSize:kBackButtonFontSize], +// NSForegroundColorAttributeName: kColorLightBlue, +// }; +// +// [[UIBarButtonItem appearance] setTitleTextAttributes:textAttributes forState:UIControlStateNormal]; +// +// [[UIBarButtonItem appearance] setTitleTextAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:kBackButtonFontSize]} forState:UIControlStateDisabled | UIControlStateHighlighted]; +// } UIBarButtonItem *temporaryBarButtonItem = [[UIBarButtonItem alloc] init]; - temporaryBarButtonItem.title = @"返回"; + temporaryBarButtonItem.title = @""; temporaryBarButtonItem.target = self; - if ([temporaryBarButtonItem respondsToSelector:@selector(setTitleTextAttributes:forState:)]){ - textAttributes = @{ - NSFontAttributeName: [UIFont systemFontOfSize:kBackButtonFontSize], - NSForegroundColorAttributeName: kColorBrandGreen, - }; - - [[UIBarButtonItem appearance] setTitleTextAttributes:textAttributes forState:UIControlStateNormal]; - } temporaryBarButtonItem.action = @selector(goBack_Swizzle); return temporaryBarButtonItem; } diff --git a/Coding_iOS/Vendor/AGEmojiKeyboard/AGEmojiKeyBoardView.h b/Coding_iOS/Vendor/AGEmojiKeyboard/AGEmojiKeyBoardView.h index 7d14e8c90..e2d8481e1 100755 --- a/Coding_iOS/Vendor/AGEmojiKeyboard/AGEmojiKeyBoardView.h +++ b/Coding_iOS/Vendor/AGEmojiKeyboard/AGEmojiKeyBoardView.h @@ -12,6 +12,7 @@ typedef NS_ENUM(NSInteger, AGEmojiKeyboardViewCategoryImage) { AGEmojiKeyboardViewCategoryImageEmoji, + AGEmojiKeyboardViewCategoryImageEmoji_Code, AGEmojiKeyboardViewCategoryImageMonkey, AGEmojiKeyboardViewCategoryImageMonkey_Gif, }; diff --git a/Coding_iOS/Vendor/AGEmojiKeyboard/AGEmojiKeyBoardView.m b/Coding_iOS/Vendor/AGEmojiKeyboard/AGEmojiKeyBoardView.m index ce680b287..06cb1bdde 100755 --- a/Coding_iOS/Vendor/AGEmojiKeyboard/AGEmojiKeyBoardView.m +++ b/Coding_iOS/Vendor/AGEmojiKeyboard/AGEmojiKeyBoardView.m @@ -41,8 +41,8 @@ - (NSDictionary *)emojis { - (NSString *)categoryNameAtIndex:(NSUInteger)index { // NSArray *categoryList = @[segmentRecentName, @"People", @"Objects", @"Nature", @"Places", @"Symbols"]; - NSArray *categoryList = @[@"emoji", @"big_monkey", @"big_monkey_gif"]; - return categoryList[index]; + NSArray *categoryList = @[@"emoji", @"emoji_code", @"big_monkey", @"big_monkey_gif"]; + return index < categoryList.count? categoryList[index]: categoryList.lastObject; } - (AGEmojiKeyboardViewCategoryImage)defaultSelectedCategory { @@ -64,8 +64,8 @@ - (NSArray *)imagesForSelectedSegments { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ array = [NSMutableArray array]; - for (AGEmojiKeyboardViewCategoryImage i = AGEmojiKeyboardViewCategoryImageEmoji; - i <= AGEmojiKeyboardViewCategoryImageMonkey_Gif; + for (int i = 0; + i < self.emojis.allKeys.count; ++i) { [array addObject:[self.dataSource emojiKeyboardView:self imageForSelectedCategory:i]]; } @@ -78,8 +78,8 @@ - (NSArray *)imagesForNonSelectedSegments { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ array = [NSMutableArray array]; - for (AGEmojiKeyboardViewCategoryImage i = AGEmojiKeyboardViewCategoryImageEmoji; - i <= AGEmojiKeyboardViewCategoryImageMonkey_Gif; + for (int i = 0; + i < self.emojis.allKeys.count; ++i) { [array addObject:[self.dataSource emojiKeyboardView:self imageForNonSelectedCategory:i]]; } @@ -118,8 +118,8 @@ - (instancetype)initWithFrame:(CGRect)frame dataSource:(id📖 🙏 + emoji_code + + 1️⃣ + 2️⃣ + 3️⃣ + 4️⃣ + 5️⃣ + 6️⃣ + 7️⃣ + 8️⃣ + 9️⃣ + 0️⃣ + 👉 + 👀 + 📝 + 🐒 + 🐵 + 🙈 + 👍 + 👎 + 🍗 + ↩️ + 💩 + + 🍌 + 👻 + 😱 + 📭 + 📢 + ↩️ + big_monkey coding_emoji_01 diff --git a/Coding_iOS/Vendor/AMPopTip/AMPopTip+Animation.h b/Coding_iOS/Vendor/AMPopTip/AMPopTip+Animation.h new file mode 100755 index 000000000..60ce6cc7a --- /dev/null +++ b/Coding_iOS/Vendor/AMPopTip/AMPopTip+Animation.h @@ -0,0 +1,25 @@ +// +// AMPopTip+Animation.h +// AMPopTip +// +// Created by Andrea Mazzini on 10/06/15. +// Copyright (c) 2015 Fancy Pixel. All rights reserved. +// + +#import "AMPopTip.h" + +@interface AMPopTip (Animation) + +/** Start the popover action animation + * + * Starts the popover action animation. Does nothing if the popover wasn't animating in the first place. + */ +- (void)performActionAnimation; + +/** Stops the popover action animation + * + * Stops the popover action animation. Does nothing if the popover wasn't animating in the first place. + */ +- (void)dismissActionAnimation; + +@end diff --git a/Coding_iOS/Vendor/AMPopTip/AMPopTip+Animation.m b/Coding_iOS/Vendor/AMPopTip/AMPopTip+Animation.m new file mode 100755 index 000000000..fb07d3dbf --- /dev/null +++ b/Coding_iOS/Vendor/AMPopTip/AMPopTip+Animation.m @@ -0,0 +1,112 @@ +// +// AMPopTip+Animation.m +// AMPopTip +// +// Created by Andrea Mazzini on 10/06/15. +// Copyright (c) 2015 Fancy Pixel. All rights reserved. +// + +#import "AMPopTip+Animation.h" +#import + +@implementation AMPopTip (Animation) + +- (void)setShouldBounce:(BOOL)shouldBounce { objc_setAssociatedObject(self, @selector(shouldBounce), [NSNumber numberWithBool:shouldBounce], OBJC_ASSOCIATION_RETAIN);} +- (BOOL)shouldBounce { return [objc_getAssociatedObject(self, @selector(shouldBounce)) boolValue]; } + +- (void)performActionAnimation { + switch (self.actionAnimation) { + case AMPopTipActionAnimationBounce: + self.shouldBounce = YES; + [self bounceAnimation]; + break; + case AMPopTipActionAnimationFloat: + [self floatAnimation]; + break; + case AMPopTipActionAnimationPulse: + [self pulseAnimation]; + break; + case AMPopTipActionAnimationNone: + return; + break; + default: + break; + } +} + +- (void)floatAnimation { + CGFloat xOffset = 0; + CGFloat yOffset = 0; + switch (self.direction) { + case AMPopTipDirectionUp: + yOffset = -self.actionFloatOffset; + break; + case AMPopTipDirectionDown: + yOffset = self.actionFloatOffset; + break; + case AMPopTipDirectionLeft: + xOffset = -self.actionFloatOffset; + break; + case AMPopTipDirectionRight: + xOffset = self.actionFloatOffset; + break; + case AMPopTipDirectionNone: + yOffset = -self.actionFloatOffset; + break; + } + + [UIView animateWithDuration:(self.actionAnimationIn / 2) delay:self.actionDelayIn options:(UIViewAnimationOptionRepeat | UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAutoreverse | UIViewAnimationOptionAllowUserInteraction) animations:^{ + self.transform = CGAffineTransformMakeTranslation(xOffset, yOffset); + } completion:nil]; +} + +- (void)bounceAnimation { + CGFloat xOffset = 0; + CGFloat yOffset = 0; + switch (self.direction) { + case AMPopTipDirectionUp: + yOffset = -self.actionBounceOffset; + break; + case AMPopTipDirectionDown: + yOffset = self.actionBounceOffset; + break; + case AMPopTipDirectionLeft: + xOffset = -self.actionBounceOffset; + break; + case AMPopTipDirectionRight: + xOffset = self.actionBounceOffset; + break; + case AMPopTipDirectionNone: + yOffset = -self.actionBounceOffset; + break; + } + + [UIView animateWithDuration:(self.actionAnimationIn / 10) delay:self.actionDelayIn options:(UIViewAnimationOptionCurveEaseIn | UIViewAnimationOptionAllowUserInteraction) animations:^{ + self.transform = CGAffineTransformMakeTranslation(xOffset, yOffset); + } completion:^(BOOL finished) { + [UIView animateWithDuration:(self.actionAnimationIn - self.actionAnimationIn / 10) delay:0 usingSpringWithDamping:0.4 initialSpringVelocity:1 options:UIViewAnimationOptionAllowUserInteraction animations:^{ + self.transform = CGAffineTransformIdentity; + } completion:^(BOOL done) { + if (self.shouldBounce && done) { + [self bounceAnimation]; + } + }]; + }]; +} + +- (void)pulseAnimation { + [UIView animateWithDuration:(self.actionAnimationIn / 2) delay:self.actionDelayIn options:(UIViewAnimationOptionRepeat | UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAutoreverse | UIViewAnimationOptionAllowUserInteraction) animations:^{ + self.transform = CGAffineTransformMakeScale(self.actionPulseOffset, self.actionPulseOffset); + } completion:nil]; +} + +- (void)dismissActionAnimation { + self.shouldBounce = NO; + [UIView animateWithDuration:(self.actionAnimationOut / 2) delay:self.actionDelayOut options:UIViewAnimationOptionBeginFromCurrentState animations:^{ + self.transform = CGAffineTransformIdentity; + } completion:^(BOOL finished) { + [self.layer removeAllAnimations]; + }]; +} + +@end diff --git a/Coding_iOS/Vendor/AMPopTip/AMPopTip+Draw.h b/Coding_iOS/Vendor/AMPopTip/AMPopTip+Draw.h new file mode 100755 index 000000000..150b6008e --- /dev/null +++ b/Coding_iOS/Vendor/AMPopTip/AMPopTip+Draw.h @@ -0,0 +1,23 @@ +// +// AMPopTip+Draw.h +// AMPopTip +// +// Created by Andrea Mazzini on 10/06/15. +// Copyright (c) 2015 Fancy Pixel. All rights reserved. +// + +#import "AMPopTip.h" + +@interface AMPopTip (Draw) + +/** Poptip's Bezier path + * + * Returns the path used to draw the poptip, used internally by the poptip. + * + * @param rect The rect holding the poptip + * @param direction The direction of the poptip appearance + * @return UIBezierPath The poptip's path + */ +- (nonnull UIBezierPath *)pathWithRect:(CGRect)rect direction:(AMPopTipDirection)direction; + +@end diff --git a/Coding_iOS/Vendor/AMPopTip/AMPopTip+Draw.m b/Coding_iOS/Vendor/AMPopTip/AMPopTip+Draw.m new file mode 100755 index 000000000..a0406c29d --- /dev/null +++ b/Coding_iOS/Vendor/AMPopTip/AMPopTip+Draw.m @@ -0,0 +1,107 @@ +// +// AMPopTip+Draw.m +// AMPopTip +// +// Created by Andrea Mazzini on 10/06/15. +// Copyright (c) 2015 Fancy Pixel. All rights reserved. +// + +#import "AMPopTip+Draw.h" + +#define DEGREES_TO_RADIANS(degrees) ((3.14159265359 * degrees)/ 180) + +@implementation AMPopTip (Draw) + +- (UIBezierPath *)pathWithRect:(CGRect)rect direction:(AMPopTipDirection)direction { + UIBezierPath *path = [[UIBezierPath alloc] init]; + CGRect baloonFrame; + + // Drawing a round rect and the arrow alone sometime shows a white halfpixel line, so here's a fun bit of code... feel free to fall asleep + switch (direction) { + case AMPopTipDirectionNone: { + baloonFrame = (CGRect){ (CGPoint) { self.borderWidth, self.borderWidth }, (CGSize){ self.frame.size.width - self.borderWidth * 2, self.frame.size.height - self.borderWidth * 2} }; + path = [UIBezierPath bezierPathWithRoundedRect:baloonFrame cornerRadius:self.radius]; + + break; + } + case AMPopTipDirectionDown: { + baloonFrame = (CGRect){ (CGPoint) { 0, self.arrowSize.height }, (CGSize){ rect.size.width - self.borderWidth * 2, rect.size.height - self.arrowSize.height - self.borderWidth * 2} }; + + [path moveToPoint:(CGPoint){ self.arrowPosition.x + self.borderWidth, self.arrowPosition.y }]; + [path addLineToPoint:(CGPoint){ self.borderWidth + self.arrowPosition.x + self.arrowSize.width / 2, self.arrowPosition.y + self.arrowSize.height }]; + [path addLineToPoint:(CGPoint){ baloonFrame.size.width - self.radius, self.arrowSize.height }]; + [path addArcWithCenter:(CGPoint){ baloonFrame.size.width - self.radius, self.arrowSize.height + self.radius } radius:self.radius startAngle:DEGREES_TO_RADIANS(270) endAngle:DEGREES_TO_RADIANS(0) clockwise:YES]; + [path addLineToPoint:(CGPoint){ baloonFrame.size.width, self.arrowSize.height + baloonFrame.size.height - self.radius }]; + [path addArcWithCenter:(CGPoint){ baloonFrame.size.width - self.radius, self.arrowSize.height + baloonFrame.size.height - self.radius } radius:self.radius startAngle:DEGREES_TO_RADIANS(0) endAngle:DEGREES_TO_RADIANS(90) clockwise:YES]; + [path addLineToPoint:(CGPoint){ self.borderWidth + self.radius, self.arrowSize.height + baloonFrame.size.height }]; + [path addArcWithCenter:(CGPoint){ self.borderWidth + self.radius, self.arrowSize.height + baloonFrame.size.height - self.radius } radius:self.radius startAngle:DEGREES_TO_RADIANS(90) endAngle:DEGREES_TO_RADIANS(180) clockwise:YES]; + [path addLineToPoint:(CGPoint){ self.borderWidth, self.arrowSize.height + self.radius }]; + [path addArcWithCenter:(CGPoint){ self.borderWidth + self.radius, self.arrowSize.height + self.radius } radius:self.radius startAngle:DEGREES_TO_RADIANS(180) endAngle:DEGREES_TO_RADIANS(270) clockwise:YES]; + [path addLineToPoint:(CGPoint){ self.borderWidth + self.arrowPosition.x - self.arrowSize.width / 2, self.arrowPosition.y + self.arrowSize.height }]; + [path closePath]; + + break; + } + case AMPopTipDirectionUp: { + baloonFrame = (CGRect){ (CGPoint) { 0, 0 }, (CGSize){ rect.size.width - self.borderWidth * 2, rect.size.height - self.arrowSize.height - self.borderWidth * 2 } }; + + [path moveToPoint:(CGPoint){ self.arrowPosition.x + self.borderWidth, self.arrowPosition.y - self.borderWidth }]; + [path addLineToPoint:(CGPoint){ self.borderWidth + self.arrowPosition.x + self.arrowSize.width / 2, self.arrowPosition.y - self.arrowSize.height - self.borderWidth }]; + [path addLineToPoint:(CGPoint){ baloonFrame.size.width - self.radius, baloonFrame.origin.y + baloonFrame.size.height + self.borderWidth }]; + [path addArcWithCenter:(CGPoint){ baloonFrame.size.width - self.radius, baloonFrame.origin.y + baloonFrame.size.height - self.radius + self.borderWidth } radius:self.radius startAngle:DEGREES_TO_RADIANS(90) endAngle:DEGREES_TO_RADIANS(0) clockwise:NO]; + [path addLineToPoint:(CGPoint){ baloonFrame.size.width, baloonFrame.origin.y + self.radius + self.borderWidth }]; + [path addArcWithCenter:(CGPoint){ baloonFrame.size.width - self.radius, baloonFrame.origin.y + self.radius + self.borderWidth } radius:self.radius startAngle:DEGREES_TO_RADIANS(0) endAngle:DEGREES_TO_RADIANS(270) clockwise:NO]; + [path addLineToPoint:(CGPoint){ self.borderWidth + self.radius, baloonFrame.origin.y + self.borderWidth }]; + [path addArcWithCenter:(CGPoint){ self.borderWidth + self.radius, baloonFrame.origin.y + self.radius + self.borderWidth } radius:self.radius startAngle:DEGREES_TO_RADIANS(270) endAngle:DEGREES_TO_RADIANS(180) clockwise:NO]; + [path addLineToPoint:(CGPoint){ self.borderWidth, baloonFrame.origin.y + baloonFrame.size.height - self.radius + self.borderWidth }]; + [path addArcWithCenter:(CGPoint){ self.borderWidth + self.radius, baloonFrame.origin.y + baloonFrame.size.height - self.radius + self.borderWidth } radius:self.radius startAngle:DEGREES_TO_RADIANS(180) endAngle:DEGREES_TO_RADIANS(90) clockwise:NO]; + [path addLineToPoint:(CGPoint){ self.borderWidth + self.arrowPosition.x - self.arrowSize.width / 2, self.arrowPosition.y - self.arrowSize.height - self.borderWidth }]; + [path closePath]; + + break; + } + case AMPopTipDirectionLeft: { + // Flip the size around for the left/right poptip + CGSize arrowSize = CGSizeMake(self.arrowSize.height, self.arrowSize.width); + baloonFrame = (CGRect){ (CGPoint) { 0, 0 }, (CGSize){ rect.size.width - arrowSize.width - self.borderWidth * 2, rect.size.height - self.borderWidth * 2} }; + + [path moveToPoint:(CGPoint){ self.arrowPosition.x - self.borderWidth, self.arrowPosition.y }]; + [path addLineToPoint:(CGPoint){ self.arrowPosition.x - arrowSize.width - self.borderWidth, self.arrowPosition.y - arrowSize.height / 2 }]; + [path addLineToPoint:(CGPoint){ baloonFrame.size.width - self.borderWidth, baloonFrame.origin.y + self.radius }]; + [path addArcWithCenter:(CGPoint){ baloonFrame.size.width - self.radius - self.borderWidth, baloonFrame.origin.y + self.radius + self.borderWidth } radius:self.radius startAngle:DEGREES_TO_RADIANS(0) endAngle:DEGREES_TO_RADIANS(270) clockwise:NO]; + [path addLineToPoint:(CGPoint){ self.radius + self.borderWidth, baloonFrame.origin.y + self.borderWidth}]; + [path addArcWithCenter:(CGPoint){ self.radius + self.borderWidth, baloonFrame.origin.y + self.radius + self.borderWidth } radius:self.radius startAngle:DEGREES_TO_RADIANS(270) endAngle:DEGREES_TO_RADIANS(180) clockwise:NO]; + [path addLineToPoint:(CGPoint){ self.borderWidth, baloonFrame.origin.y + baloonFrame.size.height - self.radius - self.borderWidth }]; + [path addArcWithCenter:(CGPoint){ self.radius + self.borderWidth, baloonFrame.origin.y + baloonFrame.size.height - self.radius - self.borderWidth } radius:self.radius startAngle:DEGREES_TO_RADIANS(180) endAngle:DEGREES_TO_RADIANS(90) clockwise:NO]; + [path addLineToPoint:(CGPoint){ baloonFrame.size.width - self.radius - self.borderWidth, baloonFrame.origin.y + baloonFrame.size.height - self.borderWidth }]; + [path addArcWithCenter:(CGPoint){ baloonFrame.size.width - self.radius - self.borderWidth, baloonFrame.origin.y + baloonFrame.size.height - self.radius - self.borderWidth } radius:self.radius startAngle:DEGREES_TO_RADIANS(90) endAngle:DEGREES_TO_RADIANS(0) clockwise:NO]; + [path addLineToPoint:(CGPoint){ self.arrowPosition.x - arrowSize.width - self.borderWidth, self.arrowPosition.y + arrowSize.height / 2 }]; + [path closePath]; + + break; + } + case AMPopTipDirectionRight: { + // Flip the size around for the left/right poptip + CGSize arrowSize = CGSizeMake(self.arrowSize.height, self.arrowSize.width); + baloonFrame = (CGRect){ (CGPoint) { arrowSize.width, 0 }, (CGSize){ rect.size.width - arrowSize.width - self.borderWidth * 2, rect.size.height - self.borderWidth * 2} }; + + [path moveToPoint:(CGPoint){ self.arrowPosition.x + self.borderWidth, self.arrowPosition.y }]; + [path addLineToPoint:(CGPoint){ self.arrowPosition.x + arrowSize.width + self.borderWidth, self.arrowPosition.y - arrowSize.height / 2 }]; + [path addLineToPoint:(CGPoint){ baloonFrame.origin.x + self.borderWidth, baloonFrame.origin.y + self.radius + self.borderWidth }]; + [path addArcWithCenter:(CGPoint){ baloonFrame.origin.x + self.radius + self.borderWidth, baloonFrame.origin.y + self.radius + self.borderWidth } radius:self.radius startAngle:DEGREES_TO_RADIANS(180) endAngle:DEGREES_TO_RADIANS(270) clockwise:YES]; + [path addLineToPoint:(CGPoint){ baloonFrame.origin.x + baloonFrame.size.width - self.radius - self.borderWidth, baloonFrame.origin.y + self.borderWidth}]; + [path addArcWithCenter:(CGPoint){ baloonFrame.origin.x + baloonFrame.size.width - self.radius - self.borderWidth, baloonFrame.origin.y + self.radius + self.borderWidth } radius:self.radius startAngle:DEGREES_TO_RADIANS(270) endAngle:DEGREES_TO_RADIANS(0) clockwise:YES]; + [path addLineToPoint:(CGPoint){ baloonFrame.origin.x + baloonFrame.size.width - self.borderWidth, baloonFrame.origin.y + baloonFrame.size.height - self.radius - self.borderWidth }]; + [path addArcWithCenter:(CGPoint){ baloonFrame.origin.x + baloonFrame.size.width - self.radius - self.borderWidth, baloonFrame.origin.y + baloonFrame.size.height - self.radius - self.borderWidth} radius:self.radius startAngle:DEGREES_TO_RADIANS(0) endAngle:DEGREES_TO_RADIANS(90) clockwise:YES]; + [path addLineToPoint:(CGPoint){ baloonFrame.origin.x + self.radius + self.borderWidth, baloonFrame.origin.y + baloonFrame.size.height - self.borderWidth}]; + [path addArcWithCenter:(CGPoint){ baloonFrame.origin.x + self.radius + self.borderWidth, baloonFrame.origin.y + baloonFrame.size.height - self.radius - self.borderWidth } radius:self.radius startAngle:DEGREES_TO_RADIANS(90) endAngle:DEGREES_TO_RADIANS(180) clockwise:YES]; + [path addLineToPoint:(CGPoint){ self.arrowPosition.x + arrowSize.width + self.borderWidth, self.arrowPosition.y + arrowSize.height / 2 }]; + [path closePath]; + + break; + } + } + return path; +} + +@end diff --git a/Coding_iOS/Vendor/AMPopTip/AMPopTip+Entrance.h b/Coding_iOS/Vendor/AMPopTip/AMPopTip+Entrance.h new file mode 100755 index 000000000..5875f306a --- /dev/null +++ b/Coding_iOS/Vendor/AMPopTip/AMPopTip+Entrance.h @@ -0,0 +1,21 @@ +// +// AMPopTip+Entrance.h +// AMPopTip +// +// Created by Andrea Mazzini on 10/06/15. +// Copyright (c) 2015 Fancy Pixel. All rights reserved. +// + +#import "AMPopTip.h" + +@interface AMPopTip (Entrance) + +/** Perform entrance animation + * + * Triggers the chosen entrance animation + * + * @param completion Completion handler + */ +- (void)performEntranceAnimation:(nullable void (^)())completion; + +@end diff --git a/Coding_iOS/Vendor/AMPopTip/AMPopTip+Entrance.m b/Coding_iOS/Vendor/AMPopTip/AMPopTip+Entrance.m new file mode 100755 index 000000000..66c884c22 --- /dev/null +++ b/Coding_iOS/Vendor/AMPopTip/AMPopTip+Entrance.m @@ -0,0 +1,107 @@ +// +// AMPopTip+Entrance.m +// AMPopTip +// +// Created by Andrea Mazzini on 10/06/15. +// Copyright (c) 2015 Fancy Pixel. All rights reserved. +// + +#import "AMPopTip+Entrance.h" + +@implementation AMPopTip (Entrance) + +- (void)performEntranceAnimation:(void (^)())completion { + switch (self.entranceAnimation) { + case AMPopTipEntranceAnimationScale: { + [self entranceScale:completion]; + break; + } + case AMPopTipEntranceAnimationTransition: { + [self entranceTransition:completion]; + break; + } + case AMPopTipEntranceAnimationFadeIn: { + [self entranceFadeIn:completion]; + break; + } + case AMPopTipEntranceAnimationCustom: { + [self.containerView addSubview:self]; + if (self.entranceAnimationHandler) { + self.entranceAnimationHandler(^{ + completion(); + }); + } + } + case AMPopTipEntranceAnimationNone: { + [self.containerView addSubview:self]; + completion(); + break; + } + default: { + [self.containerView addSubview:self]; + completion(); + break; + } + } +} + +- (void)entranceTransition:(void (^)())completion { + self.transform = CGAffineTransformMakeScale(0.6, 0.6); + switch (self.direction) { + case AMPopTipDirectionUp: + self.transform = CGAffineTransformTranslate(self.transform, 0, -self.fromFrame.origin.y); + break; + case AMPopTipDirectionDown: + self.transform = CGAffineTransformTranslate(self.transform, 0, (self.containerView.frame.size.height - self.fromFrame.origin.y)); + break; + case AMPopTipDirectionLeft: + self.transform = CGAffineTransformTranslate(self.transform, -self.fromFrame.origin.x, 0); + break; + case AMPopTipDirectionRight: + self.transform = CGAffineTransformTranslate(self.transform, (self.containerView.frame.size.width - self.fromFrame.origin.x), 0); + break; + case AMPopTipDirectionNone: + self.transform = CGAffineTransformTranslate(self.transform, 0, (self.containerView.frame.size.height - self.fromFrame.origin.y)); + break; + + default: + break; + } + [self.containerView addSubview:self]; + + [UIView animateWithDuration:self.animationIn delay:self.delayIn usingSpringWithDamping:0.6 initialSpringVelocity:1.5 options:(UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionBeginFromCurrentState) animations:^{ + self.transform = CGAffineTransformIdentity; + } completion:^(BOOL completed){ + if (completed && completion) { + completion(); + } + }]; +} + +- (void)entranceScale:(void (^)())completion { + self.transform = CGAffineTransformMakeScale(0, 0); + [self.containerView addSubview:self]; + + [UIView animateWithDuration:self.animationIn delay:self.delayIn usingSpringWithDamping:0.6 initialSpringVelocity:1.5 options:(UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionBeginFromCurrentState) animations:^{ + self.transform = CGAffineTransformIdentity; + } completion:^(BOOL completed){ + if (completed && completion) { + completion(); + } + }]; +} + +- (void)entranceFadeIn:(void (^)())completion { + [self.containerView addSubview:self]; + + self.alpha = 0.0; + [UIView animateWithDuration:self.animationIn delay:self.delayIn options:(UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionBeginFromCurrentState) animations:^{ + self.alpha = 1.0; + } completion:^(BOOL completed){ + if (completed && completion) { + completion(); + } + }]; +} + +@end diff --git a/Coding_iOS/Vendor/AMPopTip/AMPopTip+Exit.h b/Coding_iOS/Vendor/AMPopTip/AMPopTip+Exit.h new file mode 100755 index 000000000..f43a9eb23 --- /dev/null +++ b/Coding_iOS/Vendor/AMPopTip/AMPopTip+Exit.h @@ -0,0 +1,21 @@ +// +// AMPopTip+Exit.h +// AMPopTip +// +// Created by Valerio Mazzeo on 09/02/2016. +// Copyright © 2016 Valerio Mazzeo. All rights reserved. +// + +#import "AMPopTip.h" + +@interface AMPopTip (Exit) + +/** Perform exit animation + * + * Triggers the chosen exit animation + * + * @param completion Completion handler + */ +- (void)performExitAnimation:(nullable void (^)())completion; + +@end diff --git a/Coding_iOS/Vendor/AMPopTip/AMPopTip+Exit.m b/Coding_iOS/Vendor/AMPopTip/AMPopTip+Exit.m new file mode 100755 index 000000000..f0c72661b --- /dev/null +++ b/Coding_iOS/Vendor/AMPopTip/AMPopTip+Exit.m @@ -0,0 +1,74 @@ +// +// AMPopTip+Exit.m +// AMPopTip +// +// Created by Valerio Mazzeo on 09/02/2016. +// Copyright © 2016 Valerio Mazzeo. All rights reserved. +// + +#import "AMPopTip+Exit.h" + +@implementation AMPopTip (Exit) + +- (void)performExitAnimation:(void (^)())completion { + switch (self.exitAnimation) { + case AMPopTipExitAnimationScale: { + [self exitScale:completion]; + break; + } + case AMPopTipExitAnimationFadeOut: { + [self exitFadeOut:completion]; + break; + } + case AMPopTipExitAnimationCustom: { + [self.containerView addSubview:self]; + if (self.exitAnimationHandler) { + self.exitAnimationHandler(^{ + if (completion) { + completion(); + } + }); + } + break; + } + case AMPopTipExitAnimationNone: { + [self.containerView addSubview:self]; + if (completion) { + completion(); + } + break; + } + default: { + [self.containerView addSubview:self]; + if (completion) { + completion(); + } + break; + } + } +} + +- (void)exitScale:(void (^)())completion { + self.transform = CGAffineTransformIdentity; + + [UIView animateWithDuration:self.animationOut delay:self.delayOut options:(UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionBeginFromCurrentState) animations:^{ + self.transform = CGAffineTransformMakeScale(0.000001, 0.000001); + } completion:^(BOOL completed){ + if (completed && completion) { + completion(); + } + }]; +} + +- (void)exitFadeOut:(void (^)())completion { + self.alpha = 1.0; + [UIView animateWithDuration:self.animationOut delay:self.delayOut options:(UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionBeginFromCurrentState) animations:^{ + self.alpha = 0.0; + } completion:^(BOOL completed){ + if (completed && completion) { + completion(); + } + }]; +} + +@end diff --git a/Coding_iOS/Vendor/AMPopTip/AMPopTip.h b/Coding_iOS/Vendor/AMPopTip/AMPopTip.h new file mode 100755 index 000000000..806628da0 --- /dev/null +++ b/Coding_iOS/Vendor/AMPopTip/AMPopTip.h @@ -0,0 +1,478 @@ +// +// AMPopTip.h +// AMPopTip +// +// Created by Andrea Mazzini on 11/07/14. +// Copyright (c) 2014 Fancy Pixel. All rights reserved. +// + +#import + +/**----------------------------------------------------------------------------- + * @name AMPopTip Options + * ----------------------------------------------------------------------------- + */ + +/** @enum AMPopTipDirection + * + * Enum that specifies the direction of the poptip. + */ +typedef NS_ENUM(NSInteger, AMPopTipDirection) { + /** Shows the poptip up */ + AMPopTipDirectionUp, + /** Shows the poptip down */ + AMPopTipDirectionDown, + /** Shows the poptip to the left */ + AMPopTipDirectionLeft, + /** Shows the poptip to the right */ + AMPopTipDirectionRight, + /** Shows the poptip up, with no arrow */ + AMPopTipDirectionNone +}; + +/** @enum AMPopTipEntranceAnimation + * + * Enum that specifies the type of entrance animation. Entrance animations are performed + * while showing the poptip. + */ +typedef NS_ENUM(NSInteger, AMPopTipEntranceAnimation) { + /** The poptip scales from 0% to 100% */ + AMPopTipEntranceAnimationScale, + /** The poptip moves in position from the edge of the screen */ + AMPopTipEntranceAnimationTransition, + /** The poptip fade in */ + AMPopTipEntranceAnimationFadeIn, + /** No animation */ + AMPopTipEntranceAnimationNone, + /** The Animation is provided by the user */ + AMPopTipEntranceAnimationCustom +}; + +/** @enum AMPopTipExitAnimation + * + * Enum that specifies the type of entrance animation. Entrance animations are performed + * while showing the poptip. + */ +typedef NS_ENUM(NSInteger, AMPopTipExitAnimation) { + /** The poptip scales from 0% to 100% */ + AMPopTipExitAnimationScale, + /** The poptip fade in */ + AMPopTipExitAnimationFadeOut, + /** No animation */ + AMPopTipExitAnimationNone, + /** The Animation is provided by the user */ + AMPopTipExitAnimationCustom +}; + +/** @enum AMPopTipActionAnimation + * + * Enum that specifies the type of action animation. Action animations are performed + * after the poptip is visible and the entrance animation completed. + */ +typedef NS_ENUM(NSInteger, AMPopTipActionAnimation) { + /** The poptip bounces following its direction */ + AMPopTipActionAnimationBounce, + /** The poptip floats in place */ + AMPopTipActionAnimationFloat, + /** The poptip pulsates by changing its size */ + AMPopTipActionAnimationPulse, + /** No animation */ + AMPopTipActionAnimationNone +}; + +@interface AMPopTip : UIView + +/**----------------------------------------------------------------------------- + * @name AMPopTip + * ----------------------------------------------------------------------------- + */ + +/** Create a popotip + * + * Create a new popotip object + */ ++ (nonnull instancetype)popTip; + +/** Show the popover + * + * Shows an animated popover in a given view, from a given rectangle. + * The property isVisible will be set as YES as soon as the popover is added to the given view. + * + * @param text The text displayed. + * @param direction The direction of the popover. + * @param maxWidth The maximum width of the popover. If the popover won't fit in the given space, this will be overridden. + * @param view The view that will hold the popover. + * @param frame The originating frame. The popover's arrow will point to the center of this frame. + */ +- (void)showText:(nonnull NSString *)text direction:(AMPopTipDirection)direction maxWidth:(CGFloat)maxWidth inView:(nonnull UIView *)view fromFrame:(CGRect)frame; + +/** Show the popover + * + * Shows an animated popover in a given view, from a given rectangle. + * The property isVisible will be set as YES as soon as the popover is added to the given view. + * + * @param text The attributed text displayed. + * @param direction The direction of the popover. + * @param maxWidth The maximum width of the popover. If the popover won't fit in the given space, this will be overridden. + * @param view The view that will hold the popover. + * @param frame The originating frame. The popover's arrow will point to the center of this frame. + */ +- (void)showAttributedText:(nonnull NSAttributedString *)text direction:(AMPopTipDirection)direction maxWidth:(CGFloat)maxWidth inView:(nonnull UIView *)view fromFrame:(CGRect)frame; + +/** Show the popover with a custom view + * + * Shows an animated popover in a given view, from a given rectangle. + * The property isVisible will be set as YES as soon as the popover is added to the given view. + * + * @param customView The custom view + * @param direction The direction of the popover. + * @param view The view that will hold the popover. + * @param frame The originating frame. The popover's arrow will point to the center of this frame. + */ +- (void)showCustomView:(nonnull UIView *)customView direction:(AMPopTipDirection)direction inView:(nonnull UIView *)view fromFrame:(CGRect)frame; + +/** Show the popover + * + * Shows an animated popover in a given view, from a given rectangle. + * The property isVisible will be set as YES as soon as the popover is added to the given view. + * + * @param text The text displayed. + * @param direction The direction of the popover. + * @param maxWidth The maximum width of the popover. If the popover won't fit in the given space, this will be overridden. + * @param view The view that will hold the popover. + * @param frame The originating frame. The popover's arrow will point to the center of this frame. + * @param interval The time interval that determines when the poptip will self-dismiss + */ +- (void)showText:(nonnull NSString *)text direction:(AMPopTipDirection)direction maxWidth:(CGFloat)maxWidth inView:(nonnull UIView *)view fromFrame:(CGRect)frame duration:(NSTimeInterval)interval; + +/** Show the popover + * + * Shows an animated popover in a given view, from a given rectangle. + * The property isVisible will be set as YES as soon as the popover is added to the given view. + * + * @param text The attributed text displayed. + * @param direction The direction of the popover. + * @param maxWidth The maximum width of the popover. If the popover won't fit in the given space, this will be overridden. + * @param view The view that will hold the popover. + * @param frame The originating frame. The popover's arrow will point to the center of this frame. + * @param interval The time interval that determines when the poptip will self-dismiss + */ +- (void)showAttributedText:(nonnull NSAttributedString *)text direction:(AMPopTipDirection)direction maxWidth:(CGFloat)maxWidth inView:(nonnull UIView *)view fromFrame:(CGRect)frame duration:(NSTimeInterval)interval; + +/** Show the popover with a custom view + * + * Shows an animated popover in a given view, from a given rectangle. + * The property isVisible will be set as YES as soon as the popover is added to the given view. + * + * @param customView The custom view + * @param direction The direction of the popover. + * @param view The view that will hold the popover. + * @param frame The originating frame. The popover's arrow will point to the center of this frame. + * @param interval The time interval that determines when the poptip will self-dismiss + */ +- (void)showCustomView:(nonnull UIView *)customView direction:(AMPopTipDirection)direction inView:(nonnull UIView *)view fromFrame:(CGRect)frame duration:(NSTimeInterval)interval; + +/** Hide the popover + * + * Hides the popover and removes it from the view. + * The property isVisible will be set to NO when the animation is complete and the popover is removed from the parent view. + */ +- (void)hide; + +/** Hide the popover with the option to force the removal. This will ignore current animations. + * + * @param forced Force the removal. + */ +- (void)hideForced:(BOOL)forced; + +/** Update the text + * + * Set the new text shown in the poptip + * @param text The new text + */ +- (void)updateText:(nonnull NSString *)text; + +/** Makes the popover perform the action animation + * + * Makes the popover perform the action indefinitely. The action animation calls for the user's attention after the popover is shown + */ +- (void)startActionAnimation; + +/** Stops the popover action animation + * + * Stops the popover action animation. Does nothing if the popover wasn't animating in the first place. + */ +- (void)stopActionAnimation; + +/**----------------------------------------------------------------------------- +* @name AMPopTip Properties +* ----------------------------------------------------------------------------- +*/ + +NS_ASSUME_NONNULL_BEGIN +/** Font + * + * Holds the UIFont used in the popover + */ +@property (nonatomic, strong) UIFont *font; + +/** Text Color + * + * Holds the UIColor of the text + */ +@property (nonatomic, strong) UIColor *textColor UI_APPEARANCE_SELECTOR; + +/** Text Alignment + * Holds the NSTextAlignment of the text + */ +@property (nonatomic, assign) NSTextAlignment textAlignment UI_APPEARANCE_SELECTOR; + +/** Popover Background Color + * + * Holds the UIColor for the popover's background + */ +@property (nonatomic, strong) UIColor *popoverColor UI_APPEARANCE_SELECTOR; + +/** Popover Border Color + * + * Holds the UIColor for the popover's bordedr + */ +@property (nonatomic, strong) UIColor *borderColor UI_APPEARANCE_SELECTOR; + +/** Popover Border Width + * + * Holds the width for the popover's border + */ +@property (nonatomic, assign) CGFloat borderWidth UI_APPEARANCE_SELECTOR; + +/** Popover border radius + * + * Holds the CGFloat with the popover's border radius + */ +@property (nonatomic, assign) CGFloat radius UI_APPEARANCE_SELECTOR; + +/** Rounded popover + * + * Holds the BOOL that determines wether the popover is rounded. If set to YES the radius will equal frame.height / 2 + */ +@property (nonatomic, assign, getter=isRounded) BOOL rounded UI_APPEARANCE_SELECTOR; + +/** Offset from the origin + * + * Holds the offset between the popover and origin + */ +@property (nonatomic, assign) CGFloat offset UI_APPEARANCE_SELECTOR; + +/** Text Padding + * + * Holds the CGFloat with the padding used for the inner text + */ +@property (nonatomic, assign) CGFloat padding UI_APPEARANCE_SELECTOR; + +/** Text EdgeInsets + * + * Holds the insets setting for padding different direction + */ +@property (nonatomic, assign) UIEdgeInsets edgeInsets UI_APPEARANCE_SELECTOR; + +/** Arrow size + * + * Holds the CGSize with the width and height of the arrow + */ +@property (nonatomic, assign) CGSize arrowSize UI_APPEARANCE_SELECTOR; + +/** Revealing Animation time + * + * Holds the NSTimeInterval with the duration of the revealing animation + */ +@property (nonatomic, assign) NSTimeInterval animationIn UI_APPEARANCE_SELECTOR; + +/** Disappearing Animation time + * + * Holds the NSTimeInterval with the duration of the disappearing animation + */ +@property (nonatomic, assign) NSTimeInterval animationOut UI_APPEARANCE_SELECTOR; + +/** Revealing Animation delay + * + * Holds the NSTimeInterval with the delay of the revealing animation + */ +@property (nonatomic, assign) NSTimeInterval delayIn UI_APPEARANCE_SELECTOR; + +/** Disappearing Animation delay + * + * Holds the NSTimeInterval with the delay of the disappearing animation + */ +@property (nonatomic, assign) NSTimeInterval delayOut UI_APPEARANCE_SELECTOR; + +/** Entrance animation type + * + * Holds the enum with the type of entrance animation (triggered once the popover is shown) + */ +@property (nonatomic, assign) AMPopTipEntranceAnimation entranceAnimation UI_APPEARANCE_SELECTOR; + +/** Exit animation type + * + * Holds the enum with the type of exit animation (triggered once the popover is dismissed) + */ +@property (nonatomic, assign) AMPopTipExitAnimation exitAnimation UI_APPEARANCE_SELECTOR; + +/** Action animation type + * + * Holds the enum with the type of action animation (triggered once the popover is shown) + */ +@property (nonatomic, assign) AMPopTipActionAnimation actionAnimation UI_APPEARANCE_SELECTOR; + +/** Offset for the float action animation + * + * Holds the offset between the popover initial and ending state during the float action animation + */ +@property (nonatomic, assign) CGFloat actionFloatOffset UI_APPEARANCE_SELECTOR; + +/** Offset for the float action animation + * + * Holds the offset between the popover initial and ending state during the float action animation + */ +@property (nonatomic, assign) CGFloat actionBounceOffset UI_APPEARANCE_SELECTOR; + +/** Offset for the pulse action animation + * + * Holds the offset in the popover size during the pulse action animation + */ +@property (nonatomic, assign) CGFloat actionPulseOffset UI_APPEARANCE_SELECTOR; + +/** Action Animation time + * + * Holds the NSTimeInterval with the duration of the action animation + */ +@property (nonatomic, assign) NSTimeInterval actionAnimationIn UI_APPEARANCE_SELECTOR; + +/** Action Animation stop time + * + * Holds the NSTimeInterval with the duration of the action stop animation + */ +@property (nonatomic, assign) NSTimeInterval actionAnimationOut UI_APPEARANCE_SELECTOR; + +/** Action Animation delay + * + * Holds the NSTimeInterval with the delay of the action animation + */ +@property (nonatomic, assign) NSTimeInterval actionDelayIn UI_APPEARANCE_SELECTOR; + +/** Action Animation stop delay + * + * Holds the NSTimeInterval with the delay of the action animation stop + */ +@property (nonatomic, assign) NSTimeInterval actionDelayOut UI_APPEARANCE_SELECTOR; + +/** Margin from the left efge + * + * CGfloat value that determines the leftmost margin from the screen + */ +@property (nonatomic, assign) CGFloat edgeMargin UI_APPEARANCE_SELECTOR; + +/** Offset for the Bubble + * + * Holds the offset between the bubble and origin + */ +@property (nonatomic, assign) CGFloat bubbleOffset UI_APPEARANCE_SELECTOR; + +/** The frame the poptip is pointing to + * + * Holds the CGrect with the rect the tip is pointing to + */ +@property (nonatomic, assign) CGRect fromFrame; + +/** Visibility + * + * Holds the readonly BOOL with the popover visiblity. The popover is considered visible as soon as + * the animation is complete, and invisible when the subview is removed from its parent. + */ +@property (nonatomic, assign, readonly) BOOL isVisible; + +/** Animating + * + * Holds the readonly BOOL with the popover animation state. + */ +@property (nonatomic, assign, readonly) BOOL isAnimating; + +/** Dismiss on tap + * + * A boolean value that determines whether the poptip is dismissed on tap. + */ +@property (nonatomic, assign) BOOL shouldDismissOnTap; + +/** Dismiss on tap outside + * + * A boolean value that determines whether to dismiss when tapping outside the popover. + */ +@property (nonatomic, assign) BOOL shouldDismissOnTapOutside; + +/** Dismiss on swipe outside +* +* A boolean value that determines whether to dismiss when swiping outside the popover. +*/ +@property (nonatomic, assign) BOOL shouldDismissOnSwipeOutside; + +/** Direction to dismiss on swipe outside +* +* A direction that determines what swipe direction to dismiss when swiping outside the popover. +* The default direction is UISwipeGestureRecognizerDirectionRight if this is not set. +*/ +@property (nonatomic, assign) UISwipeGestureRecognizerDirection swipeRemoveGestureDirection; +NS_ASSUME_NONNULL_END + +/** Tap handler + * + * A block that will be fired when the user taps the popover. + */ +@property (nonatomic, copy) void (^_Nullable tapHandler)(); + +/** Dismiss handler + * + * A block that will be fired when the popover appears. + */ +@property (nonatomic, copy) void (^_Nullable appearHandler)(); + +/** Dismiss handler + * + * A block that will be fired when the popover is dismissed. + */ +@property (nonatomic, copy) void (^_Nullable dismissHandler)(); + +/** Entrance animation + * + * A block that handles the entrance animation of the poptip. Should be provided + * when using a AMPopTipActionAnimationCustom entrance animation type. + * Please note that the poptip will be automatically added as a subview before firing the block + * Remember to call the completion block provided + */ +@property (nonatomic, copy) void (^_Nullable entranceAnimationHandler)(void (^_Nonnull completion)(void)); + +/** Exit animation + * + * A block block that handles the exit animation of the poptip. Should be provided + * when using a AMPopTipActionAnimationCustom exit animation type. + * Remember to call the completion block provided + */ +@property (nonatomic, copy) void (^_Nullable exitAnimationHandler)(void (^_Nonnull completion)(void)); + +/** Arrow position + * + * The CGPoint originating the arrow. Read only. + */ +@property (nonatomic, readonly) CGPoint arrowPosition; + +/** Container View + * + * A read only reference to the view containing the poptip + */ +@property (nonatomic, weak, readonly) UIView *_Nullable containerView; + +/** Direction + * + * The direction from which the poptip is shown. Read only. + */ +@property (nonatomic, assign, readonly) AMPopTipDirection direction; + +@end diff --git a/Coding_iOS/Vendor/AMPopTip/AMPopTip.m b/Coding_iOS/Vendor/AMPopTip/AMPopTip.m new file mode 100755 index 000000000..bcde0a8cd --- /dev/null +++ b/Coding_iOS/Vendor/AMPopTip/AMPopTip.m @@ -0,0 +1,513 @@ +// +// AMPopTip.m +// PopTipDemo +// +// Created by Andrea Mazzini on 11/07/14. +// Copyright (c) 2014 Fancy Pixel. All rights reserved. +// + +#import "AMPopTip.h" +#import "AMPopTipDefaults.h" +#import "AMPopTip+Draw.h" +#import "AMPopTip+Entrance.h" +#import "AMPopTip+Exit.h" +#import "AMPopTip+Animation.h" + +@interface AMPopTip() + +@property (nonatomic, strong) NSString *text; +@property (nonatomic, strong) NSAttributedString *attributedText; +@property (nonatomic, strong) NSMutableParagraphStyle *paragraphStyle; +@property (nonatomic, strong) UITapGestureRecognizer *gestureRecognizer; +@property (nonatomic, strong) UITapGestureRecognizer *tapRemoveGesture; +@property (nonatomic, strong) UISwipeGestureRecognizer *swipeRemoveGesture; +@property (nonatomic, strong) NSTimer *dismissTimer; +@property (nonatomic, weak, readwrite) UIView *containerView; +@property (nonatomic, assign, readwrite) AMPopTipDirection direction; +@property (nonatomic, assign, readwrite) CGPoint arrowPosition; +@property (nonatomic, assign, readwrite) BOOL isVisible; +@property (nonatomic, assign, readwrite) BOOL isAnimating; +@property (nonatomic, assign) CGRect textBounds; +@property (nonatomic, assign) CGFloat maxWidth; +@property (nonatomic, strong) UIView *customView; + +@end + +@implementation AMPopTip + ++ (instancetype)popTip { + return [[AMPopTip alloc] init]; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + self = [super initWithCoder:aDecoder]; + if (self) { + [self commonInit]; + } + return self; +} + +- (instancetype)initWithFrame:(CGRect)ignoredFrame { + self = [super initWithFrame:CGRectZero]; + if (self) { + [self commonInit]; + } + return self; +} + +- (instancetype)init { + self = [super initWithFrame:CGRectZero]; + if (self) { + [self commonInit]; + } + return self; +} + +- (void)commonInit { + _paragraphStyle = [[NSMutableParagraphStyle alloc] init]; + _textAlignment = NSTextAlignmentCenter; + _font = kDefaultFont; + _textColor = kDefaultTextColor; + _popoverColor = kDefaultBackgroundColor; + _borderColor = kDefaultBorderColor; + _borderWidth = kDefaultBorderWidth; + _radius = kDefaultRadius; + _padding = kDefaultPadding; + _arrowSize = kDefaultArrowSize; + _animationIn = kDefaultAnimationIn; + _animationOut = kDefaultAnimationOut; + _isVisible = NO; + _shouldDismissOnTapOutside = YES; + _edgeMargin = kDefaultEdgeMargin; + _edgeInsets = kDefaultEdgeInsets; + _rounded = NO; + _offset = kDefaultOffset; + _entranceAnimation = AMPopTipEntranceAnimationScale; + _exitAnimation = AMPopTipExitAnimationScale; + _actionAnimation = AMPopTipActionAnimationNone; + _actionFloatOffset = kDefaultFloatOffset; + _actionBounceOffset = kDefaultBounceOffset; + _actionPulseOffset = kDefaultPulseOffset; + _actionAnimationIn = kDefaultBounceAnimationIn; + _actionAnimationOut = kDefaultBounceAnimationOut; + _bubbleOffset = kDefaultBubbleOffset; + _tapRemoveGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapRemoveGestureHandler)]; + _swipeRemoveGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeRemoveGestureHandler)]; +} + +- (void)layoutSubviews { + [super layoutSubviews]; +} + +- (void)setup { + if (self.direction == AMPopTipDirectionLeft) { + self.maxWidth = MIN(self.maxWidth, self.fromFrame.origin.x - self.padding * 2 - self.edgeInsets.left - self.edgeInsets.right - self.arrowSize.width); + } + if (self.direction == AMPopTipDirectionRight) { + self.maxWidth = MIN(self.maxWidth, self.containerView.bounds.size.width - self.fromFrame.origin.x - self.fromFrame.size.width - self.padding * 2 - self.edgeInsets.left - self.edgeInsets.right - self.arrowSize.width); + } + + if (self.text != nil) { + self.textBounds = [self.text boundingRectWithSize:(CGSize){self.maxWidth, DBL_MAX } + options:NSStringDrawingUsesLineFragmentOrigin + attributes:@{NSFontAttributeName: self.font} + context:nil]; + } else if (self.attributedText != nil) { + self.textBounds = [self.attributedText boundingRectWithSize:(CGSize){self.maxWidth, DBL_MAX } + options:NSStringDrawingUsesLineFragmentOrigin + context:nil]; + } else if (self.customView != nil) { + self.textBounds = self.customView.frame; + } + + _textBounds.origin = (CGPoint){self.padding + self.edgeInsets.left, self.padding + self.edgeInsets.top}; + + CGRect frame = CGRectZero; + float offset = self.offset * ((self.direction == AMPopTipDirectionUp || self.direction == AMPopTipDirectionLeft || self.direction == AMPopTipDirectionNone) ? -1 : 1); + + if (self.direction == AMPopTipDirectionUp || self.direction == AMPopTipDirectionDown) { + frame.size = (CGSize){self.textBounds.size.width + self.padding * 2.0 + self.edgeInsets.left + self.edgeInsets.right, self.textBounds.size.height + self.padding * 2.0 + self.edgeInsets.top + self.edgeInsets.bottom + self.arrowSize.height}; + + CGFloat x = self.fromFrame.origin.x + self.fromFrame.size.width / 2 - frame.size.width / 2; + if (x < 0) { x = self.edgeMargin; } + if (x + frame.size.width > self.containerView.bounds.size.width) { x = self.containerView.bounds.size.width - frame.size.width - self.edgeMargin; } + if (self.direction == AMPopTipDirectionDown) { + frame.origin = (CGPoint){ x, self.fromFrame.origin.y + self.fromFrame.size.height }; + } else { + frame.origin = (CGPoint){ x, self.fromFrame.origin.y - frame.size.height}; + } + + frame.origin.y += offset; + + // Make sure that the bubble doesn't leaves the boundaries of the view + CGFloat yPoint = (self.direction == AMPopTipDirectionUp) ? frame.size.height : self.fromFrame.origin.y + self.fromFrame.size.height - frame.origin.y + offset; + CGPoint arrowPosition = (CGPoint){ self.fromFrame.origin.x + self.fromFrame.size.width / 2 - frame.origin.x, yPoint }; + + if (self.bubbleOffset > 0 && arrowPosition.x < self.bubbleOffset) { + self.bubbleOffset = arrowPosition.x - self.arrowSize.width; + } else if (self.bubbleOffset < 0 && frame.size.width < fabs(self.bubbleOffset)) { + self.bubbleOffset = -(arrowPosition.x - self.arrowSize.width); + } else if (self.bubbleOffset < 0 && (frame.origin.x - arrowPosition.x) < fabs(self.bubbleOffset)) { + self.bubbleOffset = -(self.arrowSize.width + self.edgeMargin); + } + + // Make sure that the bubble doesn't leaves the boundaries of the view + CGFloat leftSpace = frame.origin.x - self.containerView.frame.origin.x; + CGFloat rightSpace = self.containerView.frame.size.width - leftSpace - frame.size.width; + + if (self.bubbleOffset < 0 && leftSpace < fabs(self.bubbleOffset)) { + self.bubbleOffset = -leftSpace + self.edgeMargin; + } else if (self.bubbleOffset > 0 && rightSpace < self.bubbleOffset) { + self.bubbleOffset = rightSpace - self.edgeMargin; + } + + frame.origin.x += self.bubbleOffset; + + } else if (self.direction == AMPopTipDirectionLeft || self.direction == AMPopTipDirectionRight) { + frame.size = (CGSize){ self.textBounds.size.width + self.padding * 2.0 + self.edgeInsets.left + self.edgeInsets.right + self.arrowSize.height, self.textBounds.size.height + self.padding * 2.0 + self.edgeInsets.top + self.edgeInsets.bottom}; + + CGFloat x = 0; + if (self.direction == AMPopTipDirectionLeft) { + x = self.fromFrame.origin.x - frame.size.width; + } + if (self.direction == AMPopTipDirectionRight) { + x = self.fromFrame.origin.x + self.fromFrame.size.width; + } + + x += offset; + + CGFloat y = self.fromFrame.origin.y + self.fromFrame.size.height / 2 - frame.size.height / 2; + + if (y < 0) { y = self.edgeMargin; } + if (y + frame.size.height > self.containerView.bounds.size.height) { y = self.containerView.bounds.size.height - frame.size.height - self.edgeMargin; } + frame.origin = (CGPoint){ x, y }; + + // Make sure that the bubble doesn't leaves the boundaries of the view + CGFloat xPoint = (self.direction == AMPopTipDirectionLeft) ? self.fromFrame.origin.x - frame.origin.x + offset : self.fromFrame.origin.x + self.fromFrame.size.width - frame.origin.x + offset; + + CGPoint arrowPosition = (CGPoint){ xPoint, self.fromFrame.origin.y + self.fromFrame.size.height / 2 - frame.origin.y }; + + if (self.bubbleOffset > 0 && arrowPosition.y < self.bubbleOffset) { + self.bubbleOffset = arrowPosition.y - self.arrowSize.width; + } else if (self.bubbleOffset < 0 && frame.size.height < fabs(self.bubbleOffset)) { + self.bubbleOffset = -(arrowPosition.y - self.arrowSize.height); + } + + // Make sure that the bubble doesn't leaves the boundaries of the view + CGFloat topSpace = frame.origin.y - self.containerView.frame.origin.y; + CGFloat bottomSpace = self.containerView.frame.size.height - topSpace - frame.size.height; + + if (self.bubbleOffset < 0 && topSpace < fabs(self.bubbleOffset)) { + self.bubbleOffset = -topSpace + self.edgeMargin; + } else if (self.bubbleOffset > 0 && bottomSpace < self.bubbleOffset) { + self.bubbleOffset = bottomSpace - self.edgeMargin; + } + + frame.origin.y += self.bubbleOffset; + + } else { + frame.size = (CGSize){ self.textBounds.size.width + self.padding * 2.0 + self.edgeInsets.left + self.edgeInsets.right, self.textBounds.size.height + self.padding * 2.0 + self.edgeInsets.top + self.edgeInsets.bottom }; + frame.origin = (CGPoint){ CGRectGetMidX(self.fromFrame) - frame.size.width / 2, CGRectGetMidY(self.fromFrame) - frame.size.height / 2 + offset }; + } + + frame.size = (CGSize){ frame.size.width + self.borderWidth * 2, frame.size.height + self.borderWidth * 2 }; + + switch (self.direction) { + case AMPopTipDirectionNone: { + self.arrowPosition = CGPointZero; + self.layer.anchorPoint = (CGPoint){ 0.5, 0.5 }; + self.layer.position = (CGPoint){ CGRectGetMidX(self.fromFrame), CGRectGetMidY(self.fromFrame) }; + break; + } + case AMPopTipDirectionDown: { + self.arrowPosition = (CGPoint){ + self.fromFrame.origin.x + self.fromFrame.size.width / 2 - frame.origin.x, + self.fromFrame.origin.y + self.fromFrame.size.height - frame.origin.y + offset + }; + CGFloat anchor = self.arrowPosition.x / frame.size.width; + _textBounds.origin = (CGPoint){ self.textBounds.origin.x, self.textBounds.origin.y + self.arrowSize.height }; + self.layer.anchorPoint = (CGPoint){ anchor, 0 }; + self.layer.position = (CGPoint){ self.layer.position.x + frame.size.width * anchor, self.layer.position.y - frame.size.height / 2 }; + + break; + } + case AMPopTipDirectionUp: { + self.arrowPosition = (CGPoint){ + self.fromFrame.origin.x + self.fromFrame.size.width / 2 - frame.origin.x, + frame.size.height + }; + CGFloat anchor = self.arrowPosition.x / frame.size.width; + self.layer.anchorPoint = (CGPoint){ anchor, 1 }; + self.layer.position = (CGPoint){ self.layer.position.x + frame.size.width * anchor, self.layer.position.y + frame.size.height / 2 }; + + break; + } + case AMPopTipDirectionLeft: { + self.arrowPosition = (CGPoint){ + self.fromFrame.origin.x - frame.origin.x + offset, + self.fromFrame.origin.y + self.fromFrame.size.height / 2 - frame.origin.y + }; + CGFloat anchor = self.arrowPosition.y / frame.size.height; + self.layer.anchorPoint = (CGPoint){ 1, anchor }; + self.layer.position = (CGPoint){ self.layer.position.x - frame.size.width / 2, self.layer.position.y + frame.size.height * anchor }; + + break; + } + case AMPopTipDirectionRight: { + self.arrowPosition = (CGPoint){ + self.fromFrame.origin.x + self.fromFrame.size.width - frame.origin.x + offset, + self.fromFrame.origin.y + self.fromFrame.size.height / 2 - frame.origin.y + }; + _textBounds.origin = (CGPoint){ self.textBounds.origin.x + self.arrowSize.height, self.textBounds.origin.y }; + CGFloat anchor = self.arrowPosition.y / frame.size.height; + self.layer.anchorPoint = (CGPoint){ 0, anchor }; + self.layer.position = (CGPoint){ self.layer.position.x + frame.size.width / 2, self.layer.position.y + frame.size.height * anchor }; + + break; + } + } + + self.backgroundColor = [UIColor clearColor]; + self.frame = frame; + + if (self.customView) { + self.customView.frame = self.textBounds; + } + + self.gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)]; + [self.gestureRecognizer setCancelsTouchesInView:NO]; + [self addGestureRecognizer:self.gestureRecognizer]; + [self setNeedsDisplay]; +} + +- (void)handleTap:(UITapGestureRecognizer *)gesture { + if (self.shouldDismissOnTap) { + [self hide]; + } + if (self.tapHandler) { + self.tapHandler(); + } +} + +- (void)tapRemoveGestureHandler { + if (self.shouldDismissOnTapOutside) { + [self hide]; + } +} + +- (void)swipeRemoveGestureHandler { + if (self.shouldDismissOnSwipeOutside) { + [self hide]; + } +} + +- (void)drawRect:(CGRect)rect { + if (self.isRounded) { + BOOL showHorizontally = self.direction == AMPopTipDirectionLeft || self.direction == AMPopTipDirectionRight; + self.radius = (self.frame.size.height - (showHorizontally ? 0 : self.arrowSize.height)) / 2 ; + } + + UIBezierPath *path = [self pathWithRect:rect direction:self.direction]; + + [self.popoverColor setFill]; + [path fill]; + + [self.borderColor setStroke]; + [path setLineWidth:self.borderWidth]; + [path stroke]; + + self.paragraphStyle.alignment = self.textAlignment; + + NSDictionary *titleAttributes = @{ + NSParagraphStyleAttributeName: self.paragraphStyle, + NSFontAttributeName: self.font, + NSForegroundColorAttributeName: self.textColor + }; + + if (self.text != nil) { + [self.text drawInRect:self.textBounds withAttributes:titleAttributes]; + } else if (self.attributedText != nil) { + [self.attributedText drawInRect:self.textBounds]; + } +} + +- (void)show { + self.isAnimating = YES; + [self setup]; + [self setNeedsLayout]; + [self performEntranceAnimation:^{ + [self.containerView addGestureRecognizer:self.tapRemoveGesture]; + [self.containerView addGestureRecognizer:self.swipeRemoveGesture]; + if (self.appearHandler) { + self.appearHandler(); + } + if (self.actionAnimation != AMPopTipActionAnimationNone) { + [self startActionAnimation]; + } + self.isVisible = YES; + self.isAnimating = NO; + }]; +} + +- (void)showText:(NSString *)text direction:(AMPopTipDirection)direction maxWidth:(CGFloat)maxWidth inView:(UIView *)view fromFrame:(CGRect)frame { + self.attributedText = nil; + self.text = text; + self.accessibilityLabel = text; + self.direction = direction; + self.containerView = view; + self.maxWidth = maxWidth; + _fromFrame = frame; + [self.customView removeFromSuperview]; + self.customView = nil; + + [self show]; +} + +- (void)showAttributedText:(NSAttributedString *)text direction:(AMPopTipDirection)direction maxWidth:(CGFloat)maxWidth inView:(UIView *)view fromFrame:(CGRect)frame { + self.text = nil; + self.attributedText = text; + self.accessibilityLabel = [text string]; + self.direction = direction; + self.containerView = view; + self.maxWidth = maxWidth; + _fromFrame = frame; + [self.customView removeFromSuperview]; + self.customView = nil; + + [self show]; +} + +- (void)showCustomView:(UIView *)customView direction:(AMPopTipDirection)direction inView:(UIView *)view fromFrame:(CGRect)frame { + self.text = nil; + self.attributedText = nil; + self.direction = direction; + self.containerView = view; + self.maxWidth = customView.frame.size.width; + _fromFrame = frame; + [self.customView removeFromSuperview]; + self.customView = customView; + [self addSubview:self.customView]; + [self.customView layoutIfNeeded]; + + [self show]; +} + +- (void)setFromFrame:(CGRect)fromFrame { + _fromFrame = fromFrame; + [self setup]; +} + +- (void)showText:(NSString *)text direction:(AMPopTipDirection)direction maxWidth:(CGFloat)maxWidth inView:(UIView *)view fromFrame:(CGRect)frame duration:(NSTimeInterval)interval { + [self showText:text direction:direction maxWidth:maxWidth inView:view fromFrame:frame]; + [self.dismissTimer invalidate]; + if (interval > 0) { + self.dismissTimer = [NSTimer scheduledTimerWithTimeInterval:interval + target:self + selector:@selector(hide) + userInfo:nil + repeats:NO]; + } +} + +- (void)showAttributedText:(NSAttributedString *)text direction:(AMPopTipDirection)direction maxWidth:(CGFloat)maxWidth inView:(UIView *)view fromFrame:(CGRect)frame duration:(NSTimeInterval)interval { + [self showAttributedText:text direction:direction maxWidth:maxWidth inView:view fromFrame:frame]; + [self.dismissTimer invalidate]; + if (interval > 0){ + self.dismissTimer = [NSTimer scheduledTimerWithTimeInterval:interval + target:self + selector:@selector(hide) + userInfo:nil + repeats:NO]; + } +} + +- (void)showCustomView:(UIView *)customView direction:(AMPopTipDirection)direction inView:(UIView *)view fromFrame:(CGRect)frame duration:(NSTimeInterval)interval { + [self showCustomView:customView direction:direction inView:view fromFrame:frame]; + [self.dismissTimer invalidate]; + if (interval > 0){ + self.dismissTimer = [NSTimer scheduledTimerWithTimeInterval:interval + target:self + selector:@selector(hide) + userInfo:nil + repeats:NO]; + } +} + +- (void)hide { + [self hideForced:NO]; +} + +- (void)hideForced:(BOOL)forced { + if (!forced && self.isAnimating) { + return; + } + self.isAnimating = YES; + [self.dismissTimer invalidate]; + self.dismissTimer = nil; + [self.containerView removeGestureRecognizer:self.tapRemoveGesture]; + [self.containerView removeGestureRecognizer:self.swipeRemoveGesture]; + + void (^completion)() = ^{ + [self.customView removeFromSuperview]; + self.customView = nil; + [self stopActionAnimation]; + [self removeFromSuperview]; + [self.layer removeAllAnimations]; + self.transform = CGAffineTransformIdentity; + self->_isVisible = NO; + self->_isAnimating = NO; + if (self.dismissHandler) { + self.dismissHandler(); + } + }; + + BOOL isActive = YES; +#ifndef AM_POPTIP_EXTENSION + UIApplicationState state = [[UIApplication sharedApplication] applicationState]; + isActive = (state == UIApplicationStateActive); +#endif + if (!isActive) { + completion(); + } else if (self.superview) { + [self performExitAnimation:completion]; + } +} + +- (void)updateText:(NSString *)text { + self.text = text; + self.accessibilityLabel = text; + [self setNeedsLayout]; +} + +- (void)startActionAnimation { + [self performActionAnimation]; +} + +- (void)stopActionAnimation { + [self dismissActionAnimation]; +} + +- (void)setShouldDismissOnTapOutside:(BOOL)shouldDismissOnTapOutside { + _shouldDismissOnTapOutside = shouldDismissOnTapOutside; + _tapRemoveGesture.enabled = shouldDismissOnTapOutside; +} + +- (void)setShouldDismissOnSwipeOutside:(BOOL)shouldDismissOnSwipeOutside { + _shouldDismissOnSwipeOutside = shouldDismissOnSwipeOutside; + _swipeRemoveGesture.enabled = shouldDismissOnSwipeOutside; +} + +- (void)setSwipeRemoveGestureDirection:(UISwipeGestureRecognizerDirection)swipeRemoveGestureDirection { + _swipeRemoveGestureDirection = swipeRemoveGestureDirection; + _swipeRemoveGesture.direction = swipeRemoveGestureDirection; +} + +- (void)dealloc { + [_tapRemoveGesture removeTarget:self action:@selector(tapRemoveGestureHandler)]; + _tapRemoveGesture = nil; + + [_swipeRemoveGesture removeTarget:self action:@selector(swipeRemoveGestureHandler)]; + _swipeRemoveGesture = nil; +} + +@end diff --git a/Coding_iOS/Vendor/AMPopTip/AMPopTipDefaults.h b/Coding_iOS/Vendor/AMPopTip/AMPopTipDefaults.h new file mode 100755 index 000000000..2f582aea7 --- /dev/null +++ b/Coding_iOS/Vendor/AMPopTip/AMPopTipDefaults.h @@ -0,0 +1,28 @@ +// +// AMPopTipDefaults.h +// AMPopTip +// +// Created by Andrea Mazzini on 10/06/15. +// Copyright (c) 2015 Fancy Pixel. All rights reserved. +// + +/** @constant AMPopTip default values */ +#define kDefaultFont [UIFont systemFontOfSize:[UIFont systemFontSize]] +#define kDefaultTextColor [UIColor whiteColor] +#define kDefaultBackgroundColor [UIColor redColor] +#define kDefaultBorderColor [UIColor colorWithWhite:0.182 alpha:1.000] +#define kDefaultBorderWidth 0 +#define kDefaultRadius 4 +#define kDefaultPadding 6 +#define kDefaultArrowSize CGSizeMake(8, 8) +#define kDefaultAnimationIn 0.4 +#define kDefaultAnimationOut 0.2 +#define kDefaultBounceAnimationIn 1.2 +#define kDefaultBounceAnimationOut 1.0 +#define kDefaultEdgeInsets UIEdgeInsetsZero +#define kDefaultEdgeMargin 0 +#define kDefaultOffset 0 +#define kDefaultBubbleOffset 0 +#define kDefaultBounceOffset 8 +#define kDefaultFloatOffset 8 +#define kDefaultPulseOffset 1.1 diff --git a/Coding_iOS/Vendor/ActionSheetPicker/ActionSheetStringPicker.m b/Coding_iOS/Vendor/ActionSheetPicker/ActionSheetStringPicker.m index 4eb728447..97cc4d8a0 100755 --- a/Coding_iOS/Vendor/ActionSheetPicker/ActionSheetStringPicker.m +++ b/Coding_iOS/Vendor/ActionSheetPicker/ActionSheetStringPicker.m @@ -100,7 +100,11 @@ - (void)notifyTarget:(id)target didSucceedWithAction:(SEL)successAction origin:( [selectedObject addObject:(curData)[curSelectedIndex.integerValue]]; if (self.selectedIndex.count > 1) { - curData = [self.data.lastObject objectForKey:(curData)[curSelectedIndex.integerValue]]; + if ([self.data.lastObject isKindOfClass:[NSDictionary class]]) { + curData = [self.data.lastObject objectForKey:(curData)[curSelectedIndex.integerValue]]; + }else{ + curData = self.data.lastObject; + } curSelectedIndex = self.selectedIndex.lastObject; [selectedObject addObject:(curData)[curSelectedIndex.integerValue]]; } @@ -151,7 +155,11 @@ - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSIn curComponentData = (self.data)[(NSUInteger) component]; }else{ NSNumber *curSelectedIndex = self.selectedIndex.firstObject; - curComponentData = [self.data.lastObject objectForKey:[self.data.firstObject objectAtIndex:curSelectedIndex.intValue]]; + if ([self.data.lastObject isKindOfClass:[NSDictionary class]]) { + curComponentData = [self.data.lastObject objectForKey:[self.data.firstObject objectAtIndex:curSelectedIndex.intValue]]; + }else{ + curComponentData = self.data.lastObject; + } } return curComponentData.count; } @@ -162,7 +170,11 @@ - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row f curComponentData = (self.data)[(NSUInteger) component]; }else{ NSNumber *curSelectedIndex = self.selectedIndex.firstObject; - curComponentData = [self.data.lastObject objectForKey:[self.data.firstObject objectAtIndex:curSelectedIndex.intValue]]; + if ([self.data.lastObject isKindOfClass:[NSDictionary class]]) { + curComponentData = [self.data.lastObject objectForKey:[self.data.firstObject objectAtIndex:curSelectedIndex.intValue]]; + }else{ + curComponentData = self.data.lastObject; + } } id obj = (curComponentData)[(NSUInteger) row]; @@ -184,4 +196,4 @@ - (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)co } -@end \ No newline at end of file +@end diff --git a/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.bundle/bar@2x.png b/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.bundle/bar@2x.png new file mode 100644 index 000000000..9f5fa5608 Binary files /dev/null and b/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.bundle/bar@2x.png differ diff --git a/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.bundle/refresh@2x.png b/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.bundle/refresh@2x.png new file mode 100644 index 000000000..d5209d4fb Binary files /dev/null and b/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.bundle/refresh@2x.png differ diff --git a/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.bundle/refresh_click@2x.png b/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.bundle/refresh_click@2x.png new file mode 100644 index 000000000..ea18bbf93 Binary files /dev/null and b/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.bundle/refresh_click@2x.png differ diff --git a/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.bundle/shutdown@2x.png b/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.bundle/shutdown@2x.png new file mode 100644 index 000000000..e576e6265 Binary files /dev/null and b/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.bundle/shutdown@2x.png differ diff --git a/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.bundle/shutdown_click@2x.png b/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.bundle/shutdown_click@2x.png new file mode 100644 index 000000000..c0ee0e77f Binary files /dev/null and b/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.bundle/shutdown_click@2x.png differ diff --git a/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.framework/AlipaySDK b/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.framework/AlipaySDK new file mode 100644 index 000000000..673878c9e Binary files /dev/null and b/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.framework/AlipaySDK differ diff --git a/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.framework/Headers/APayAuthInfo.h b/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.framework/Headers/APayAuthInfo.h new file mode 100644 index 000000000..59236e42e --- /dev/null +++ b/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.framework/Headers/APayAuthInfo.h @@ -0,0 +1,33 @@ +// +// APAuthInfo.h +// AliSDKDemo +// +// Created by alipay on 16-12-12. +// Copyright (c) 2016年 Alipay.com. All rights reserved. +// + +#import + +@interface APayAuthInfo : NSObject + +@property(nonatomic, copy)NSString *appID; +@property(nonatomic, copy)NSString *pid; +@property(nonatomic, copy)NSString *redirectUri; + +/** + * 初始化AuthInfo + * + * @param appIDStr 应用ID + * @param pidStr 商户ID 可不填 + * @param uriStr 授权的应用回调地址 比如:alidemo://auth + * + * @return authinfo实例 + */ +- (id)initWithAppID:(NSString *)appIDStr + pid:(NSString *)pidStr + redirectUri:(NSString *)uriStr; + +- (NSString *)description; +- (NSString *)wapDescription; + +@end diff --git a/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.framework/Headers/AlipaySDK.h b/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.framework/Headers/AlipaySDK.h new file mode 100644 index 000000000..f2b6c0fd8 --- /dev/null +++ b/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.framework/Headers/AlipaySDK.h @@ -0,0 +1,178 @@ +// +// AlipaySDK.h +// AlipaySDK +// +// Created by alipay on 16-12-12. +// Copyright (c) 2016年 Alipay. All rights reserved. +// + + +//////////////////////////////////////////////////////// +///////////////// 支付宝标准版本支付SDK /////////////////// +/////////// version:15.3.3 motify:2017.03.07 /////////// +//////////////////////////////////////////////////////// + + +#import "APayAuthInfo.h" +typedef enum { + ALIPAY_TIDFACTOR_IMEI, + ALIPAY_TIDFACTOR_IMSI, + ALIPAY_TIDFACTOR_TID, + ALIPAY_TIDFACTOR_CLIENTKEY, + ALIPAY_TIDFACTOR_VIMEI, + ALIPAY_TIDFACTOR_VIMSI, + ALIPAY_TIDFACTOR_CLIENTID, + ALIPAY_TIDFACTOR_APDID, + ALIPAY_TIDFACTOR_MAX +} AlipayTidFactor; + +typedef void(^CompletionBlock)(NSDictionary *resultDic); + +@interface AlipaySDK : NSObject + +/** + * 创建支付单例服务 + * + * @return 返回单例对象 + */ ++ (AlipaySDK *)defaultService; + +/** + * 用于设置SDK使用的window,如果没有自行创建window无需设置此接口 + */ +@property (nonatomic, weak) UIWindow *targetWindow; + +/** + * 支付接口 + * + * @param orderStr 订单信息 + * @param schemeStr 调用支付的app注册在info.plist中的scheme + * @param compltionBlock 支付结果回调Block,用于wap支付结果回调(非跳转钱包支付) + */ +- (void)payOrder:(NSString *)orderStr + fromScheme:(NSString *)schemeStr + callback:(CompletionBlock)completionBlock; + +/** + * 处理钱包或者独立快捷app支付跳回商户app携带的支付结果Url + * + * @param resultUrl 支付结果url + * @param completionBlock 支付结果回调 + */ +- (void)processOrderWithPaymentResult:(NSURL *)resultUrl + standbyCallback:(CompletionBlock)completionBlock; + + + +/** + * 获取交易token。 + * + * @return 交易token,若无则为空。 + */ +- (NSString *)fetchTradeToken; + +/** + * 是否已经使用过 + * + * @return YES为已经使用过,NO反之 + */ +- (BOOL)isLogined; + +/** + * 获取当前版本号 + * + * @return 当前版本字符串 + */ +- (NSString *)currentVersion; + +/** + * 获取当前tid相关信息 + * + * @return tid相关信息 + */ +- (NSString*)queryTidFactor:(AlipayTidFactor)factor; + +/** + * 測試所用,realse包无效 + * + * @param url 测试环境 + */ +- (void)setUrl:(NSString *)url; + + +////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////h5 拦截支付入口/////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * 从h5链接中获取订单串接口 + * + * @param urlStr 拦截的 url string + * + * @return 获取到的url order info + */ +- (NSString*)fetchOrderInfoFromH5PayUrl:(NSString*)urlStr; + + +/** + * h5链接获取到的订单串支付接口 + * + * @param orderStr 订单信息 + * @param schemeStr 调用支付的app注册在info.plist中的scheme + * @param compltionBlock 支付结果回调Block + */ +- (void)payUrlOrder:(NSString *)orderStr + fromScheme:(NSString *)schemeStr + callback:(CompletionBlock)completionBlock; + + +////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////授权1.0////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * 快登授权 + * @param authInfo 需授权信息 + * @param completionBlock 授权结果回调,若在授权过程中,调用方应用被系统终止,则此block无效, + 需要调用方在appDelegate中调用processAuthResult:standbyCallback:方法获取授权结果 + */ +- (void)authWithInfo:(APayAuthInfo *)authInfo + callback:(CompletionBlock)completionBlock; + + +/** + * 处理授权信息Url + * + * @param resultUrl 钱包返回的授权结果url + * @param completionBlock 授权结果回调 + */ +- (void)processAuthResult:(NSURL *)resultUrl + standbyCallback:(CompletionBlock)completionBlock; + + +////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////授权2.0////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * 快登授权2.0 + * + * @param infoStr 授权请求信息字符串 + * @param schemeStr 调用授权的app注册在info.plist中的scheme + * @param completionBlock 授权结果回调,若在授权过程中,调用方应用被系统终止,则此block无效, + 需要调用方在appDelegate中调用processAuth_V2Result:standbyCallback:方法获取授权结果 + */ +- (void)auth_V2WithInfo:(NSString *)infoStr + fromScheme:(NSString *)schemeStr + callback:(CompletionBlock)completionBlock; + +/** + * 处理授权信息Url + * + * @param resultUrl 钱包返回的授权结果url + * @param completionBlock 授权结果回调 + */ +- (void)processAuth_V2Result:(NSURL *)resultUrl + standbyCallback:(CompletionBlock)completionBlock; + +@end diff --git a/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.framework/Info.plist b/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.framework/Info.plist new file mode 100644 index 000000000..8ba4a0cb8 Binary files /dev/null and b/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.framework/Info.plist differ diff --git a/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.framework/en.lproj/InfoPlist.strings b/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.framework/en.lproj/InfoPlist.strings new file mode 100644 index 000000000..3967e063f Binary files /dev/null and b/Coding_iOS/Vendor/AlipaySDK/AlipaySDK.framework/en.lproj/InfoPlist.strings differ diff --git a/Coding_iOS/Vendor/AnimatedGIFImageSerialization/AnimatedGIFImageSerialization.h b/Coding_iOS/Vendor/AnimatedGIFImageSerialization/AnimatedGIFImageSerialization.h new file mode 100755 index 000000000..af4417b88 --- /dev/null +++ b/Coding_iOS/Vendor/AnimatedGIFImageSerialization/AnimatedGIFImageSerialization.h @@ -0,0 +1,96 @@ +// AnimatedGIFImageSerialization.h +// +// Copyright (c) 2014 Mattt Thompson (http://mattt.me/) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) + +#import + +/** + + */ +extern __attribute__((overloadable)) UIImage * UIImageWithAnimatedGIFData(NSData *data); + +/** + + */ +extern __attribute__((overloadable)) UIImage * UIImageWithAnimatedGIFData(NSData *data, CGFloat scale, NSTimeInterval duration, NSError * __autoreleasing *error); + +#pragma mark - + +/** + + */ +extern __attribute__((overloadable)) NSData * UIImageAnimatedGIFRepresentation(UIImage *image); + +/** + + */ +extern __attribute__((overloadable)) NSData * UIImageAnimatedGIFRepresentation(UIImage *image, NSTimeInterval duration, NSUInteger loopCount, NSError * __autoreleasing *error); + +#pragma mark - + +/** + + */ +@interface AnimatedGIFImageSerialization : NSObject + +/// @name Creating an Animated GIF + +/** + + */ ++ (UIImage *)imageWithData:(NSData *)data + error:(NSError * __autoreleasing *)error; + +/** + + */ ++ (UIImage *)imageWithData:(NSData *)data + scale:(CGFloat)scale + duration:(NSTimeInterval)duration + error:(NSError * __autoreleasing *)error; + +/// @name Creating Animated Gif Data + +/** + + */ ++ (NSData *)animatedGIFDataWithImage:(UIImage *)image + error:(NSError * __autoreleasing *)error; + +/** + + */ ++ (NSData *)animatedGIFDataWithImage:(UIImage *)image + duration:(NSTimeInterval)duration + loopCount:(NSUInteger)loopCount + error:(NSError * __autoreleasing *)error; + +@end + +/** + + */ +extern NSString * const AnimatedGIFImageErrorDomain; +#endif diff --git a/Coding_iOS/Vendor/AnimatedGIFImageSerialization/AnimatedGIFImageSerialization.m b/Coding_iOS/Vendor/AnimatedGIFImageSerialization/AnimatedGIFImageSerialization.m new file mode 100755 index 000000000..381edee5b --- /dev/null +++ b/Coding_iOS/Vendor/AnimatedGIFImageSerialization/AnimatedGIFImageSerialization.m @@ -0,0 +1,313 @@ +// AnimatedGIFImageSerialization.m +// +// Copyright (c) 2014 Mattt Thompson (http://mattt.me/) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "AnimatedGIFImageSerialization.h" +#import "YLGIFImage.h" + +#import +#import + +NSString * const AnimatedGIFImageErrorDomain = @"com.compuserve.gif.image.error"; + +__attribute__((overloadable)) UIImage * UIImageWithAnimatedGIFData(NSData *data) { + return UIImageWithAnimatedGIFData(data, [[UIScreen mainScreen] scale], 0.0f, nil); +} + +__attribute__((overloadable)) UIImage * UIImageWithAnimatedGIFData(NSData *data, CGFloat scale, NSTimeInterval duration, NSError * __autoreleasing *error) { + if (!data) { + return nil; + } + + NSDictionary *userInfo = nil; + { + NSMutableDictionary *mutableOptions = [NSMutableDictionary dictionary]; + [mutableOptions setObject:@(YES) forKey:(NSString *)kCGImageSourceShouldCache]; + [mutableOptions setObject:(NSString *)kUTTypeGIF forKey:(NSString *)kCGImageSourceTypeIdentifierHint]; + + CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)data, (__bridge CFDictionaryRef)mutableOptions); + + size_t numberOfFrames = CGImageSourceGetCount(imageSource); + NSMutableArray *mutableImages = [NSMutableArray arrayWithCapacity:numberOfFrames]; + + NSTimeInterval calculatedDuration = 0.0f; + for (size_t idx = 0; idx < numberOfFrames; idx++) { + CGImageRef imageRef = CGImageSourceCreateImageAtIndex(imageSource, idx, (__bridge CFDictionaryRef)mutableOptions); + + NSDictionary *properties = (__bridge_transfer NSDictionary *)CGImageSourceCopyPropertiesAtIndex(imageSource, idx, NULL); + calculatedDuration += [[[properties objectForKey:(__bridge NSString *)kCGImagePropertyGIFDictionary] objectForKey:(__bridge NSString *)kCGImagePropertyGIFDelayTime] doubleValue]; + + [mutableImages addObject:[UIImage imageWithCGImage:imageRef scale:scale orientation:UIImageOrientationUp]]; + + CGImageRelease(imageRef); + } + + CFRelease(imageSource); + + if (numberOfFrames == 1) { + return [mutableImages firstObject]; + } else { + return [UIImage animatedImageWithImages:mutableImages duration:(duration <= 0.0f ? calculatedDuration : duration)]; + } + } + _error: { + if (error) { + *error = [[NSError alloc] initWithDomain:AnimatedGIFImageErrorDomain code:-1 userInfo:userInfo]; + } + + return nil; + } +} + +static BOOL AnimatedGifDataIsValid(NSData *data) { + if (data.length > 4) { + const unsigned char * bytes = [data bytes]; + + return bytes[0] == 0x47 && bytes[1] == 0x49 && bytes[2] == 0x46; + } + + return NO; +} + +__attribute__((overloadable)) NSData * UIImageAnimatedGIFRepresentation(UIImage *image) { + return UIImageAnimatedGIFRepresentation(image, 0.0f, 0, nil); +} + +__attribute__((overloadable)) NSData * UIImageAnimatedGIFRepresentation(UIImage *image, NSTimeInterval duration, NSUInteger loopCount, NSError * __autoreleasing *error) { + if (!image.images) { + return nil; + } + + NSDictionary *userInfo = nil; + { + size_t frameCount = image.images.count; + NSTimeInterval frameDuration = (duration <= 0.0 ? image.duration / frameCount : duration / frameCount); + NSDictionary *frameProperties = @{ + (__bridge NSString *)kCGImagePropertyGIFDictionary: @{ + (__bridge NSString *)kCGImagePropertyGIFDelayTime: @(frameDuration) + } + }; + + NSMutableData *mutableData = [NSMutableData data]; + CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)mutableData, kUTTypeGIF, frameCount, NULL); + + NSDictionary *imageProperties = @{ (__bridge NSString *)kCGImagePropertyGIFDictionary: @{ + (__bridge NSString *)kCGImagePropertyGIFLoopCount: @(loopCount) + } + }; + CGImageDestinationSetProperties(destination, (__bridge CFDictionaryRef)imageProperties); + + if ([image isKindOfClass:YLGIFImage.class]) {//easeeeeeeeee + for (size_t idx = 0; idx < image.images.count; idx++) { + UIImage *frame = [(YLGIFImage *)image getFrameWithIndex:idx]; + + if (image.images.count > 50) { + DebugLog(@"=============== %lu : %@", (unsigned long)idx, frame.class); + } + + if ([frame isKindOfClass:NSNull.class]) { + continue; + } + CGImageDestinationAddImage(destination, frame.CGImage, (__bridge CFDictionaryRef)frameProperties); + } + }else{ + for (size_t idx = 0; idx < image.images.count; idx++) { + CGImageDestinationAddImage(destination, [[image.images objectAtIndex:idx] CGImage], (__bridge CFDictionaryRef)frameProperties); + } + } + + BOOL success = CGImageDestinationFinalize(destination); + CFRelease(destination); + + if (!success) { + userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Could not finalize image destination", nil) + }; + + goto _error; + } + + return [NSData dataWithData:mutableData]; + } + _error: { + if (error) { + *error = [[NSError alloc] initWithDomain:AnimatedGIFImageErrorDomain code:-1 userInfo:userInfo]; + } + + return nil; + } +} + +@implementation AnimatedGIFImageSerialization + ++ (UIImage *)imageWithData:(NSData *)data + error:(NSError * __autoreleasing *)error +{ + return [self imageWithData:data scale:1.0f duration:0.0f error:error]; +} + ++ (UIImage *)imageWithData:(NSData *)data + scale:(CGFloat)scale + duration:(NSTimeInterval)duration + error:(NSError * __autoreleasing *)error +{ + return UIImageWithAnimatedGIFData(data, scale, duration, error); +} + +#pragma mark - + ++ (NSData *)animatedGIFDataWithImage:(UIImage *)image + error:(NSError * __autoreleasing *)error +{ + return [self animatedGIFDataWithImage:image duration:0.0f loopCount:0 error:error]; +} + ++ (NSData *)animatedGIFDataWithImage:(UIImage *)image + duration:(NSTimeInterval)duration + loopCount:(NSUInteger)loopCount + error:(NSError *__autoreleasing *)error +{ + return UIImageAnimatedGIFRepresentation(image, duration, loopCount, error); +} + +@end + +#pragma mark - + +#ifndef ANIMATED_GIF_NO_UIIMAGE_INITIALIZER_SWIZZLING +#import + +static inline void animated_gif_swizzleSelector(Class class, SEL originalSelector, SEL swizzledSelector) { + Method originalMethod = class_getInstanceMethod(class, originalSelector); + Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector); + if (class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))) { + class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); + } else { + method_exchangeImplementations(originalMethod, swizzledMethod); + } +} + +@interface UIImage (_AnimatedGIFImageSerialization) +@end + +@implementation UIImage (_AnimatedGIFImageSerialization) + ++ (void)load { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + @autoreleasepool { + animated_gif_swizzleSelector(object_getClass((id)self), @selector(imageNamed:), @selector(animated_gif_imageNamed:)); + animated_gif_swizzleSelector(object_getClass((id)self), @selector(imageWithData:), @selector(animated_gif_imageWithData:)); + animated_gif_swizzleSelector(object_getClass((id)self), @selector(imageWithData:scale:), @selector(animated_gif_imageWithData:scale:)); + animated_gif_swizzleSelector(object_getClass((id)self), @selector(imageWithContentsOfFile:), @selector(animated_gif_imageWithContentsOfFile:)); + animated_gif_swizzleSelector(self, @selector(initWithContentsOfFile:), @selector(animated_gif_initWithContentsOfFile:)); + animated_gif_swizzleSelector(self, @selector(initWithData:), @selector(animated_gif_initWithData:)); + animated_gif_swizzleSelector(self, @selector(initWithData:scale:), @selector(animated_gif_initWithData:scale:)); + } + }); +} + +#pragma mark - + ++ (UIImage *)animated_gif_imageNamed:(NSString *)name __attribute__((objc_method_family(new))) { + NSString *path = [[NSBundle mainBundle] pathForResource:[name stringByDeletingPathExtension] ofType:[name pathExtension]]; + if (!path) { + path = [[NSBundle mainBundle] pathForResource:[[name stringByDeletingPathExtension] stringByAppendingString:@"@2x"] ofType:[name pathExtension]]; + } + + if (path) { + NSData *data = [NSData dataWithContentsOfFile:path]; + if (AnimatedGifDataIsValid(data)) { + return UIImageWithAnimatedGIFData(data); + } + } + + return [self animated_gif_imageNamed:name]; +} + ++ (UIImage *)animated_gif_imageWithContentsOfFile:(NSString *)path __attribute__((objc_method_family(new))) { + if (path) { + NSData *data = [NSData dataWithContentsOfFile:path]; + if (AnimatedGifDataIsValid(data)) { + if ([[path stringByDeletingPathExtension] hasSuffix:@"@2x"]) { + return UIImageWithAnimatedGIFData(data, 2.0f, 0.0f, nil); + } else { + return UIImageWithAnimatedGIFData(data); + } + } + } + + return [self animated_gif_imageWithContentsOfFile:path]; +} + ++ (UIImage *)animated_gif_imageWithData:(NSData *)data __attribute__((objc_method_family(init))) { + if (AnimatedGifDataIsValid(data)) { + return UIImageWithAnimatedGIFData(data); + } + + return [self animated_gif_imageWithData:data]; +} + ++ (UIImage *)animated_gif_imageWithData:(NSData *)data + scale:(CGFloat)scale __attribute__((objc_method_family(init))) +{ + if (AnimatedGifDataIsValid(data)) { + return UIImageWithAnimatedGIFData(data, scale, 0.0f, nil); + } + + return [self animated_gif_imageWithData:data scale:scale]; +} + +#pragma mark - + +- (id)animated_gif_initWithContentsOfFile:(NSString *)path __attribute__((objc_method_family(init))) { + NSData *data = [NSData dataWithContentsOfFile:path]; + if (AnimatedGifDataIsValid(data)) { + if ([[path stringByDeletingPathExtension] hasSuffix:@"@2x"]) { + return UIImageWithAnimatedGIFData(data, 2.0, 0.0f, nil); + } else { + return UIImageWithAnimatedGIFData(data); + } + } + + return [self animated_gif_initWithContentsOfFile:path]; +} + +- (id)animated_gif_initWithData:(NSData *)data __attribute__((objc_method_family(init))) { + if (AnimatedGifDataIsValid(data)) { + return UIImageWithAnimatedGIFData(data); + } + + return [self animated_gif_initWithData:data]; +} + +- (id)animated_gif_initWithData:(NSData *)data + scale:(CGFloat)scale __attribute__((objc_method_family(init))) +{ + if (AnimatedGifDataIsValid(data)) { + return UIImageWithAnimatedGIFData(data, scale, 0.0f, nil); + } + + return [self animated_gif_initWithData:data scale:scale]; +} + +@end +#endif diff --git a/Coding_iOS/Vendor/JDStatusBarNotification/JDStatusBarLayoutMarginHelper.h b/Coding_iOS/Vendor/JDStatusBarNotification/JDStatusBarLayoutMarginHelper.h new file mode 100755 index 000000000..70de2afbd --- /dev/null +++ b/Coding_iOS/Vendor/JDStatusBarNotification/JDStatusBarLayoutMarginHelper.h @@ -0,0 +1,10 @@ +// +// JDStatusBarLayoutMarginHelper.h +// JDStatusBarNotificationExample +// +// Copyright (c) 2013 Markus. All rights reserved. +// + +#import + +extern UIEdgeInsets JDStatusBarRootVCLayoutMargin(void); diff --git a/Coding_iOS/Vendor/JDStatusBarNotification/JDStatusBarLayoutMarginHelper.m b/Coding_iOS/Vendor/JDStatusBarNotification/JDStatusBarLayoutMarginHelper.m new file mode 100755 index 000000000..d668b4fd9 --- /dev/null +++ b/Coding_iOS/Vendor/JDStatusBarNotification/JDStatusBarLayoutMarginHelper.m @@ -0,0 +1,19 @@ +// +// JDStatusBarView.m +// JDStatusBarNotificationExample +// +// Created by Markus on 04.12.13. +// Copyright (c) 2013 Markus. All rights reserved. +// + +#import "JDStatusBarLayoutMarginHelper.h" + +UIEdgeInsets JDStatusBarRootVCLayoutMargin(void) +{ + UIEdgeInsets layoutMargins = [[[[[UIApplication sharedApplication] keyWindow] rootViewController] view] layoutMargins]; + if (layoutMargins.top > 8 && layoutMargins.bottom > 8) { + return layoutMargins; + } else { + return UIEdgeInsetsZero; // ignore default margins + } +} diff --git a/Coding_iOS/Vendor/JDStatusBarNotification/JDStatusBarNotification.h b/Coding_iOS/Vendor/JDStatusBarNotification/JDStatusBarNotification.h index 99d45bea1..b9b07e745 100755 --- a/Coding_iOS/Vendor/JDStatusBarNotification/JDStatusBarNotification.h +++ b/Coding_iOS/Vendor/JDStatusBarNotification/JDStatusBarNotification.h @@ -23,7 +23,7 @@ typedef JDStatusBarStyle*(^JDPrepareStyleBlock)(JDStatusBarStyle *style); /** - * This class is a singletion which is used to present notifications + * This class is a singletion which is used to present notifications * on top of the status bar. To present a notification, use one of the * given class methods. */ @@ -115,7 +115,7 @@ typedef JDStatusBarStyle*(^JDPrepareStyleBlock)(JDStatusBarStyle *style); * when a method without styleName is used for presentation, or * styleName is nil, or no style is found with this name. * - * @param prepareBlock A block, which has a JDStatusBarStyle instance as + * @param prepareBlock A block, which has a JDStatusBarStyle instance as * parameter. This instance can be modified to suit your needs. You need * to return the modified style again. */ @@ -125,7 +125,7 @@ typedef JDStatusBarStyle*(^JDPrepareStyleBlock)(JDStatusBarStyle *style); * Adds a custom style, which than can be used * in the presentation methods. * - * @param identifier The identifier, which will + * @param identifier The identifier, which will * later be used to reference the configured style. * @param prepareBlock A block, which has a JDStatusBarStyle instance as * parameter. This instance can be modified to suit your needs. You need @@ -149,8 +149,8 @@ typedef JDStatusBarStyle*(^JDPrepareStyleBlock)(JDStatusBarStyle *style); /** * Shows an activity indicator in front of the notification text * - * @param show Use this flag to show or hide the activity indicator - * @param indicatorStyle Sets the style of the activity indicator + * @param show Use this flag to show or hide the activity indicator + * @param style Sets the style of the activity indicator */ + (void)showActivityIndicator:(BOOL)show indicatorStyle:(UIActivityIndicatorViewStyle)style; diff --git a/Coding_iOS/Vendor/JDStatusBarNotification/JDStatusBarNotification.m b/Coding_iOS/Vendor/JDStatusBarNotification/JDStatusBarNotification.m index d6ece6f42..d51f5fce3 100755 --- a/Coding_iOS/Vendor/JDStatusBarNotification/JDStatusBarNotification.m +++ b/Coding_iOS/Vendor/JDStatusBarNotification/JDStatusBarNotification.m @@ -9,6 +9,7 @@ #import +#import "JDStatusBarLayoutMarginHelper.h" #import "JDStatusBarNotification.h" @interface JDStatusBarStyle (Hidden) @@ -19,7 +20,11 @@ + (JDStatusBarStyle*)defaultStyleWithName:(NSString*)styleName; @interface JDStatusBarNotificationViewController : UIViewController @end -@interface JDStatusBarNotification () +@interface UIApplication (mainWindow) +- (UIWindow*)mainApplicationWindowIgnoringWindow:(UIWindow*)ignoringWindow; +@end + +@interface JDStatusBarNotification () @property (nonatomic, strong, readonly) UIWindow *overlayWindow; @property (nonatomic, strong, readonly) UIView *progressView; @property (nonatomic, strong, readonly) JDStatusBarView *topBar; @@ -41,133 +46,133 @@ @implementation JDStatusBarNotification #pragma mark Class methods + (JDStatusBarNotification*)sharedInstance { - static dispatch_once_t once; - static JDStatusBarNotification *sharedInstance; - dispatch_once(&once, ^ { - sharedInstance = [[JDStatusBarNotification alloc] init]; - }); - return sharedInstance; + static dispatch_once_t once; + static JDStatusBarNotification *sharedInstance; + dispatch_once(&once, ^ { + sharedInstance = [[self alloc] init]; + }); + return sharedInstance; } + (UIView*)showWithStatus:(NSString *)status; { - return [[self sharedInstance] showWithStatus:status - styleName:nil]; + return [[self sharedInstance] showWithStatus:status + styleName:nil]; } + (UIView*)showWithStatus:(NSString *)status styleName:(NSString*)styleName; { - return [[self sharedInstance] showWithStatus:status - styleName:styleName]; + return [[self sharedInstance] showWithStatus:status + styleName:styleName]; } + (UIView*)showWithStatus:(NSString *)status dismissAfter:(NSTimeInterval)timeInterval; { - UIView *view = [[self sharedInstance] showWithStatus:status - styleName:nil]; - [self dismissAfter:timeInterval]; - return view; + UIView *view = [[self sharedInstance] showWithStatus:status + styleName:nil]; + [self dismissAfter:timeInterval]; + return view; } + (UIView*)showWithStatus:(NSString *)status dismissAfter:(NSTimeInterval)timeInterval styleName:(NSString*)styleName; { - UIView *view = [[self sharedInstance] showWithStatus:status - styleName:styleName]; - [self dismissAfter:timeInterval]; - return view; + UIView *view = [[self sharedInstance] showWithStatus:status + styleName:styleName]; + [self dismissAfter:timeInterval]; + return view; } + (void)dismiss; { - [self dismissAnimated:YES]; + [self dismissAnimated:YES]; } + (void)dismissAnimated:(BOOL)animated; { - [[JDStatusBarNotification sharedInstance] dismissAnimated:animated]; + [[self sharedInstance] dismissAnimated:animated]; } + (void)dismissAfter:(NSTimeInterval)delay; { - [[JDStatusBarNotification sharedInstance] setDismissTimerWithInterval:delay]; + [[self sharedInstance] setDismissTimerWithInterval:delay]; } + (void)setDefaultStyle:(JDPrepareStyleBlock)prepareBlock; { - NSAssert(prepareBlock != nil, @"No prepareBlock provided"); - - JDStatusBarStyle *style = [[self sharedInstance].defaultStyle copy]; - [JDStatusBarNotification sharedInstance].defaultStyle = prepareBlock(style); + NSAssert(prepareBlock != nil, @"No prepareBlock provided"); + + JDStatusBarStyle *style = [[self sharedInstance].defaultStyle copy]; + [self sharedInstance].defaultStyle = prepareBlock(style); } + (NSString*)addStyleNamed:(NSString*)identifier prepare:(JDPrepareStyleBlock)prepareBlock; { - return [[JDStatusBarNotification sharedInstance] addStyleNamed:identifier - prepare:prepareBlock]; + return [[self sharedInstance] addStyleNamed:identifier + prepare:prepareBlock]; } + (void)showProgress:(CGFloat)progress; { - [[JDStatusBarNotification sharedInstance] setProgress:progress]; + [[self sharedInstance] setProgress:progress]; } + (void)showActivityIndicator:(BOOL)show indicatorStyle:(UIActivityIndicatorViewStyle)style; { - [[JDStatusBarNotification sharedInstance] showActivityIndicator:show indicatorStyle:style]; + [[self sharedInstance] showActivityIndicator:show indicatorStyle:style]; } + (BOOL)isVisible; { - return [[JDStatusBarNotification sharedInstance] isVisible]; + return [[self sharedInstance] isVisible]; } #pragma mark Implementation - (id)init { - if ((self = [super init])) - { - // set defaults - [self setupDefaultStyles]; - - // register for orientation changes - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willChangeStatusBarFrame:) - name:UIApplicationWillChangeStatusBarFrameNotification object:nil]; - } - return self; + if ((self = [super init])) + { + // set defaults + [self setupDefaultStyles]; + + // register for orientation changes + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willChangeStatusBarFrame:) + name:UIApplicationWillChangeStatusBarFrameNotification object:nil]; + } + return self; } - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; } #pragma mark Custom styles - (void)setupDefaultStyles; { - self.defaultStyle = [JDStatusBarStyle defaultStyleWithName:JDStatusBarStyleDefault]; + self.defaultStyle = [JDStatusBarStyle defaultStyleWithName:JDStatusBarStyleDefault]; - self.userStyles = [NSMutableDictionary dictionary]; - for (NSString *styleName in [JDStatusBarStyle allDefaultStyleIdentifier]) { - [self.userStyles setObject:[JDStatusBarStyle defaultStyleWithName:styleName] forKey:styleName]; - } + self.userStyles = [NSMutableDictionary dictionary]; + for (NSString *styleName in [JDStatusBarStyle allDefaultStyleIdentifier]) { + [self.userStyles setObject:[JDStatusBarStyle defaultStyleWithName:styleName] forKey:styleName]; + } } - (NSString*)addStyleNamed:(NSString*)identifier prepare:(JDPrepareStyleBlock)prepareBlock; { - NSAssert(identifier != nil, @"No identifier provided"); - NSAssert(prepareBlock != nil, @"No prepareBlock provided"); - - JDStatusBarStyle *style = [self.defaultStyle copy]; - [self.userStyles setObject:prepareBlock(style) forKey:identifier]; - return identifier; + NSAssert(identifier != nil, @"No identifier provided"); + NSAssert(prepareBlock != nil, @"No prepareBlock provided"); + + JDStatusBarStyle *style = [self.defaultStyle copy]; + [self.userStyles setObject:prepareBlock(style) forKey:identifier]; + return identifier; } #pragma mark Presentation @@ -175,318 +180,345 @@ - (NSString*)addStyleNamed:(NSString*)identifier - (UIView*)showWithStatus:(NSString *)status styleName:(NSString*)styleName; { - JDStatusBarStyle *style = nil; - if (styleName != nil) { - style = self.userStyles[styleName]; - } - - if (style == nil) style = self.defaultStyle; - return [self showWithStatus:status style:style]; + JDStatusBarStyle *style = nil; + if (styleName != nil) { + style = self.userStyles[styleName]; + } + + if (style == nil) style = self.defaultStyle; + return [self showWithStatus:status style:style]; } - (UIView*)showWithStatus:(NSString *)status style:(JDStatusBarStyle*)style; { - // first, check if status bar is visible at all - if ([UIApplication sharedApplication].statusBarHidden) return nil; - - // prepare for new style - if (style != self.activeStyle) { - self.activeStyle = style; - if (self.activeStyle.animationType == JDStatusBarAnimationTypeFade) { - self.topBar.alpha = 0.0; - self.topBar.transform = CGAffineTransformIdentity; - } else { - self.topBar.alpha = 1.0; - self.topBar.transform = CGAffineTransformMakeTranslation(0, -self.topBar.frame.size.height); - } - } - - // cancel previous dismissing & remove animations - [[NSRunLoop currentRunLoop] cancelPerformSelector:@selector(dismiss) target:self argument:nil]; - [self.topBar.layer removeAllAnimations]; - - // create & show window - [self.overlayWindow setHidden:NO]; - - // update style - self.topBar.backgroundColor = style.barColor; - self.topBar.textVerticalPositionAdjustment = style.textVerticalPositionAdjustment; - UILabel *textLabel = self.topBar.textLabel; - textLabel.textColor = style.textColor; - textLabel.font = style.font; - textLabel.accessibilityLabel = status; - textLabel.text = status; - - if (style.textShadow) { - textLabel.shadowColor = style.textShadow.shadowColor; - textLabel.shadowOffset = style.textShadow.shadowOffset; - } else { - textLabel.shadowColor = nil; - textLabel.shadowOffset = CGSizeZero; - } - - // reset progress & activity - self.progress = 0.0; - [self showActivityIndicator:NO indicatorStyle:0]; - - // animate in - BOOL animationsEnabled = (style.animationType != JDStatusBarAnimationTypeNone); - if (animationsEnabled && style.animationType == JDStatusBarAnimationTypeBounce) { - [self animateInWithBounceAnimation]; + // first, check if status bar is visible at all + if ([UIApplication sharedApplication].statusBarHidden) return nil; + + // prepare for new style + if (style != self.activeStyle) { + self.activeStyle = style; + if (self.activeStyle.animationType == JDStatusBarAnimationTypeFade) { + self.topBar.alpha = 0.0; + self.topBar.transform = CGAffineTransformIdentity; } else { - [UIView animateWithDuration:(animationsEnabled ? 0.4 : 0.0) animations:^{ - self.topBar.alpha = 1.0; - self.topBar.transform = CGAffineTransformIdentity; - }]; + self.topBar.alpha = 1.0; + self.topBar.transform = CGAffineTransformMakeTranslation(0, -self.topBar.frame.size.height); } - - return self.topBar; + } + + // cancel previous dismissing & remove animations + [[NSRunLoop currentRunLoop] cancelPerformSelector:@selector(dismiss) target:self argument:nil]; + [self.topBar.layer removeAllAnimations]; + + // create & show window + [self.overlayWindow setHidden:NO]; + + // update style + self.topBar.backgroundColor = style.barColor; + self.topBar.textVerticalPositionAdjustment = style.textVerticalPositionAdjustment; + UILabel *textLabel = self.topBar.textLabel; + textLabel.textColor = style.textColor; + textLabel.font = style.font; + textLabel.accessibilityLabel = status; + textLabel.text = status; + + if (style.textShadow) { + textLabel.shadowColor = style.textShadow.shadowColor; + textLabel.shadowOffset = style.textShadow.shadowOffset; + } else { + textLabel.shadowColor = nil; + textLabel.shadowOffset = CGSizeZero; + } + + // reset progress & activity + self.progress = 0.0; + [self showActivityIndicator:NO indicatorStyle:0]; + + // animate in + BOOL animationsEnabled = (style.animationType != JDStatusBarAnimationTypeNone); + if (animationsEnabled && style.animationType == JDStatusBarAnimationTypeBounce) { + [self animateInWithBounceAnimation]; + } else { + [UIView animateWithDuration:(animationsEnabled ? 0.4 : 0.0) animations:^{ + self.topBar.alpha = 1.0; + self.topBar.transform = CGAffineTransformIdentity; + }]; + } + + return self.topBar; } #pragma mark Dismissal - (void)setDismissTimerWithInterval:(NSTimeInterval)interval; { - [self.dismissTimer invalidate]; - self.dismissTimer = [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:interval] - interval:0 target:self selector:@selector(dismiss:) userInfo:nil repeats:NO]; - [[NSRunLoop currentRunLoop] addTimer:self.dismissTimer forMode:NSRunLoopCommonModes]; + [self.dismissTimer invalidate]; + self.dismissTimer = [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:interval] + interval:0 target:self selector:@selector(dismiss:) userInfo:nil repeats:NO]; + [[NSRunLoop currentRunLoop] addTimer:self.dismissTimer forMode:NSRunLoopCommonModes]; } - (void)dismiss:(NSTimer*)timer; { - [self dismissAnimated:YES]; + [self dismissAnimated:YES]; } - (void)dismissAnimated:(BOOL)animated; { - [self.dismissTimer invalidate]; - self.dismissTimer = nil; - - // check animation type - BOOL animationsEnabled = (self.activeStyle.animationType != JDStatusBarAnimationTypeNone); - animated &= animationsEnabled; - + [self.dismissTimer invalidate]; + self.dismissTimer = nil; + + // check animation type + BOOL animationsEnabled = (self.activeStyle.animationType != JDStatusBarAnimationTypeNone); + animated &= animationsEnabled; + + dispatch_block_t animation = ^{ + if (self.activeStyle.animationType == JDStatusBarAnimationTypeFade) { + self.topBar.alpha = 0.0; + } else { + self.topBar.transform = CGAffineTransformMakeTranslation(0, -self.topBar.frame.size.height); + } + }; + + void(^complete)(BOOL) = ^(BOOL finished) { + [self.overlayWindow removeFromSuperview]; + [self.overlayWindow setHidden:YES]; + _overlayWindow.rootViewController = nil; + _overlayWindow = nil; + _progressView = nil; + _topBar = nil; + }; + + if (animated) { // animate out - [UIView animateWithDuration:animated ? 0.4 : 0.0 animations:^{ - if (self.activeStyle.animationType == JDStatusBarAnimationTypeFade) { - self.topBar.alpha = 0.0; - } else { - self.topBar.transform = CGAffineTransformMakeTranslation(0, -self.topBar.frame.size.height); - } - } completion:^(BOOL finished) { - [self.overlayWindow removeFromSuperview]; - [self.overlayWindow setHidden:YES]; - _overlayWindow.rootViewController = nil; - _overlayWindow = nil; - _progressView = nil; - _topBar = nil; - }]; + [UIView animateWithDuration:0.4 animations:animation completion:complete]; + } else { + animation(); + complete(YES); + } } #pragma mark Bounce Animation - (void)animateInWithBounceAnimation; { - //don't animate in, if topBar is already fully visible - if (self.topBar.frame.origin.y >= 0) { - return; - } - - // easing function (based on github.com/robb/RBBAnimation) - CGFloat(^RBBEasingFunctionEaseOutBounce)(CGFloat) = ^CGFloat(CGFloat t) { - if (t < 4.0 / 11.0) return pow(11.0 / 4.0, 2) * pow(t, 2); - if (t < 8.0 / 11.0) return 3.0 / 4.0 + pow(11.0 / 4.0, 2) * pow(t - 6.0 / 11.0, 2); - if (t < 10.0 / 11.0) return 15.0 /16.0 + pow(11.0 / 4.0, 2) * pow(t - 9.0 / 11.0, 2); - return 63.0 / 64.0 + pow(11.0 / 4.0, 2) * pow(t - 21.0 / 22.0, 2); - }; - - // create values - int fromCenterY=-20, toCenterY=0, animationSteps=100; - NSMutableArray *values = [NSMutableArray arrayWithCapacity:animationSteps]; - for (int t = 1; t<=animationSteps; t++) { - float easedTime = RBBEasingFunctionEaseOutBounce((t*1.0)/animationSteps); - float easedValue = fromCenterY + easedTime * (toCenterY-fromCenterY); - [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeTranslation(0, easedValue, 0)]]; - } - - // build animation - CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"]; - animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; - animation.duration = 0.66; - animation.values = values; - animation.removedOnCompletion = NO; - animation.fillMode = kCAFillModeForwards; - animation.delegate = self; - [self.topBar.layer setValue:@(toCenterY) forKeyPath:animation.keyPath]; - [self.topBar.layer addAnimation:animation forKey:@"JDBounceAnimation"]; + //don't animate in, if topBar is already fully visible + if (self.topBar.frame.origin.y >= 0) { + return; + } + + // easing function (based on github.com/robb/RBBAnimation) + CGFloat(^RBBEasingFunctionEaseOutBounce)(CGFloat) = ^CGFloat(CGFloat t) { + if (t < 4.0 / 11.0) return pow(11.0 / 4.0, 2) * pow(t, 2); + if (t < 8.0 / 11.0) return 3.0 / 4.0 + pow(11.0 / 4.0, 2) * pow(t - 6.0 / 11.0, 2); + if (t < 10.0 / 11.0) return 15.0 /16.0 + pow(11.0 / 4.0, 2) * pow(t - 9.0 / 11.0, 2); + return 63.0 / 64.0 + pow(11.0 / 4.0, 2) * pow(t - 21.0 / 22.0, 2); + }; + + // create values + int fromCenterY=-20, toCenterY=0, animationSteps=100; + NSMutableArray *values = [NSMutableArray arrayWithCapacity:animationSteps]; + for (int t = 1; t<=animationSteps; t++) { + float easedTime = RBBEasingFunctionEaseOutBounce((t*1.0)/animationSteps); + float easedValue = fromCenterY + easedTime * (toCenterY-fromCenterY); + [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeTranslation(0, easedValue, 0)]]; + } + + // build animation + CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"]; + animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; + animation.duration = 0.66; + animation.values = values; + animation.removedOnCompletion = NO; + animation.fillMode = kCAFillModeForwards; + animation.delegate = self; + [self.topBar.layer setValue:@(toCenterY) forKeyPath:animation.keyPath]; + [self.topBar.layer addAnimation:animation forKey:@"JDBounceAnimation"]; } - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag; { - self.topBar.transform = CGAffineTransformIdentity; - [self.topBar.layer removeAllAnimations]; + self.topBar.transform = CGAffineTransformIdentity; + [self.topBar.layer removeAllAnimations]; } #pragma mark Progress & Activity - (void)setProgress:(CGFloat)progress; { - if (_topBar == nil) return; - - // trim progress - _progress = MIN(1.0, MAX(0.0,progress)); - - if (_progress == 0.0) { - _progressView.frame = CGRectZero; - return; + if (_topBar == nil) return; + + // trim progress + _progress = MIN(1.0, MAX(0.0,progress)); + + if (_progress == 0.0) { + _progressView.frame = CGRectZero; + return; + } + + // update superview + if (self.activeStyle.progressBarPosition == JDStatusBarProgressBarPositionBelow || + self.activeStyle.progressBarPosition == JDStatusBarProgressBarPositionNavBar) { + [self.topBar.superview addSubview:self.progressView]; + } else { + [self.topBar insertSubview:self.progressView belowSubview:self.topBar.textLabel]; + } + + // calculate progressView frame + CGRect frame = self.topBar.bounds; + CGFloat height = MIN(frame.size.height,MAX(0.5, self.activeStyle.progressBarHeight)); + if (height == 20.0 && frame.size.height > height) height = frame.size.height; + frame.size.height = height; + frame.size.width = round((frame.size.width - 2 * self.activeStyle.progressBarHorizontalInsets) * progress); + frame.origin.x = self.activeStyle.progressBarHorizontalInsets; + + // apply y-position from active style + CGFloat barHeight = self.topBar.bounds.size.height; + if (self.activeStyle.progressBarPosition == JDStatusBarProgressBarPositionBottom) { + frame.origin.y = barHeight - height; + } else if(self.activeStyle.progressBarPosition == JDStatusBarProgressBarPositionCenter) { + frame.origin.y = round((barHeight - height)/2.0); + } else if(self.activeStyle.progressBarPosition == JDStatusBarProgressBarPositionTop) { + frame.origin.y = 0.0; + } else if(self.activeStyle.progressBarPosition == JDStatusBarProgressBarPositionBelow) { + frame.origin.y = barHeight; + } else if(self.activeStyle.progressBarPosition == JDStatusBarProgressBarPositionNavBar) { + CGFloat navBarHeight = 44.0; + if (([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) && + UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) { + navBarHeight = 32.0; } - - // update superview - if (self.activeStyle.progressBarPosition == JDStatusBarProgressBarPositionBelow || - self.activeStyle.progressBarPosition == JDStatusBarProgressBarPositionNavBar) { - [self.topBar.superview addSubview:self.progressView]; - } else { - [self.topBar insertSubview:self.progressView belowSubview:self.topBar.textLabel]; - } - - // calculate progressView frame - CGRect frame = self.topBar.bounds; - CGFloat height = MIN(frame.size.height,MAX(0.5, self.activeStyle.progressBarHeight)); - if (height == 20.0 && frame.size.height > height) height = frame.size.height; - frame.size.height = height; - frame.size.width = round(frame.size.width * progress); - - // apply y-position from active style - CGFloat barHeight = self.topBar.bounds.size.height; - if (self.activeStyle.progressBarPosition == JDStatusBarProgressBarPositionBottom) { - frame.origin.y = barHeight - height; - } else if(self.activeStyle.progressBarPosition == JDStatusBarProgressBarPositionCenter) { - frame.origin.y = round((barHeight - height)/2.0); - } else if(self.activeStyle.progressBarPosition == JDStatusBarProgressBarPositionTop) { - frame.origin.y = 0.0; - } else if(self.activeStyle.progressBarPosition == JDStatusBarProgressBarPositionBelow) { - frame.origin.y = barHeight; - } else if(self.activeStyle.progressBarPosition == JDStatusBarProgressBarPositionNavBar) { - CGFloat navBarHeight = 44.0; - if (([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) && - UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) { - navBarHeight = 32.0; - } - frame.origin.y = barHeight + navBarHeight; - } - - // apply color from active style - self.progressView.backgroundColor = self.activeStyle.progressBarColor; - - // update progressView frame - BOOL animated = !CGRectEqualToRect(self.progressView.frame, CGRectZero); - [UIView animateWithDuration:animated ? 0.05 : 0.0 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{ - self.progressView.frame = frame; - } completion:nil]; + frame.origin.y = barHeight + navBarHeight; + } + + // apply color from active style + self.progressView.backgroundColor = self.activeStyle.progressBarColor; + + // apply corner radius + self.progressView.layer.cornerRadius = self.activeStyle.progressBarCornerRadius; + + // update progressView frame + BOOL animated = !CGRectEqualToRect(self.progressView.frame, CGRectZero); + [UIView animateWithDuration:animated ? 0.05 : 0.0 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{ + self.progressView.frame = frame; + } completion:nil]; } - (void)showActivityIndicator:(BOOL)show indicatorStyle:(UIActivityIndicatorViewStyle)style; { - if (_topBar == nil) return; - - if (show) { - [self.topBar.activityIndicatorView startAnimating]; - self.topBar.activityIndicatorView.activityIndicatorViewStyle = style; - } else { - [self.topBar.activityIndicatorView stopAnimating]; - } + if (_topBar == nil) return; + + if (show) { + [self.topBar.activityIndicatorView startAnimating]; + self.topBar.activityIndicatorView.activityIndicatorViewStyle = style; + } else { + [self.topBar.activityIndicatorView stopAnimating]; + } } #pragma mark State - (BOOL)isVisible; { - return (_topBar != nil); + return (_topBar != nil); } #pragma mark Lazy views - (UIWindow *)overlayWindow; { - if(_overlayWindow == nil) { - _overlayWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; - _overlayWindow.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - _overlayWindow.backgroundColor = [UIColor clearColor]; - _overlayWindow.userInteractionEnabled = NO; - _overlayWindow.windowLevel = UIWindowLevelStatusBar; - _overlayWindow.rootViewController = [[JDStatusBarNotificationViewController alloc] init]; - _overlayWindow.rootViewController.view.backgroundColor = [UIColor clearColor]; + if(_overlayWindow == nil) { + _overlayWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; + _overlayWindow.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + _overlayWindow.backgroundColor = [UIColor clearColor]; + _overlayWindow.userInteractionEnabled = NO; + _overlayWindow.windowLevel = UIWindowLevelStatusBar; + _overlayWindow.rootViewController = [[JDStatusBarNotificationViewController alloc] init]; + _overlayWindow.rootViewController.view.backgroundColor = [UIColor clearColor]; #if __IPHONE_OS_VERSION_MIN_REQUIRED < 70000 // only when deployment target is < ios7 - _overlayWindow.rootViewController.wantsFullScreenLayout = YES; + _overlayWindow.rootViewController.wantsFullScreenLayout = YES; #endif - [self updateWindowTransform]; - [self updateTopBarFrameWithStatusBarFrame:[[UIApplication sharedApplication] statusBarFrame]]; - } - return _overlayWindow; + [self updateWindowTransform]; + [self updateTopBarFrameWithStatusBarFrame:[[UIApplication sharedApplication] statusBarFrame]]; + } + return _overlayWindow; } - (JDStatusBarView*)topBar; { - if(_topBar == nil) { - _topBar = [[JDStatusBarView alloc] init]; - [self.overlayWindow.rootViewController.view addSubview:_topBar]; - - JDStatusBarStyle *style = self.activeStyle ?: self.defaultStyle; - if (style.animationType != JDStatusBarAnimationTypeFade) { - self.topBar.transform = CGAffineTransformMakeTranslation(0, -self.topBar.frame.size.height); - } else { - self.topBar.alpha = 0.0; - } + if(_topBar == nil) { + _topBar = [[JDStatusBarView alloc] init]; + [self.overlayWindow.rootViewController.view addSubview:_topBar]; + + JDStatusBarStyle *style = self.activeStyle ?: self.defaultStyle; + if (style.animationType != JDStatusBarAnimationTypeFade) { + self.topBar.transform = CGAffineTransformMakeTranslation(0, -self.topBar.frame.size.height); + } else { + self.topBar.alpha = 0.0; } - return _topBar; + } + return _topBar; } - (UIView *)progressView; { - if (_progressView == nil) { - _progressView = [[UIView alloc] initWithFrame:CGRectZero]; - } - return _progressView; + if (_progressView == nil) { + _progressView = [[UIView alloc] initWithFrame:CGRectZero]; + } + return _progressView; } #pragma mark Rotation - (void)updateWindowTransform; { - UIWindow *window = [UIApplication sharedApplication].keyWindow; - if (window == nil && [[[UIApplication sharedApplication] windows] count] > 0) window = [[UIApplication sharedApplication] windows][0]; - - _overlayWindow.transform = window.transform; - _overlayWindow.frame = window.frame; + UIWindow *window = [[UIApplication sharedApplication] + mainApplicationWindowIgnoringWindow:self.overlayWindow]; + _overlayWindow.transform = window.transform; + _overlayWindow.frame = window.frame; } - (void)updateTopBarFrameWithStatusBarFrame:(CGRect)rect; { - CGFloat width = MAX(rect.size.width, rect.size.height); - CGFloat height = MIN(rect.size.width, rect.size.height); + CGFloat width = MAX(rect.size.width, rect.size.height); + CGFloat height = MIN(rect.size.width, rect.size.height); - // on ios7 fix position, if statusBar has double height - CGFloat yPos = 0; - if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0 && height > 20.0) { - yPos = -height/2.0; - } - - _topBar.frame = CGRectMake(0, yPos, width, height); + // on ios7 fix position, if statusBar has double height + CGFloat yPos = 0; + if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0 && height == 40.0) { + yPos = -height/2.0; + } + + // adjust for iPhone X + CGFloat topLayoutMargin = JDStatusBarRootVCLayoutMargin().top; + if (topLayoutMargin > 0) { + height += topLayoutMargin; + } + + _topBar.frame = CGRectMake(0, yPos, width, height); } - (void)willChangeStatusBarFrame:(NSNotification*)notification; { - NSValue *barFrameValue = notification.userInfo[UIApplicationStatusBarFrameUserInfoKey]; - [UIView animateWithDuration:0.5 animations:^{ - [self updateWindowTransform]; - [self updateTopBarFrameWithStatusBarFrame:[barFrameValue CGRectValue]]; - - // update progress - self.progress = self.progress; - }]; + CGRect newBarFrame = [notification.userInfo[UIApplicationStatusBarFrameUserInfoKey] CGRectValue]; + NSTimeInterval duration = [[UIApplication sharedApplication] statusBarOrientationAnimationDuration]; + + // update window & statusbar + void(^updateBlock)(void) = ^{ + [self updateWindowTransform]; + [self updateTopBarFrameWithStatusBarFrame:newBarFrame]; + self.progress = self.progress; // // relayout progress bar + }; + + [UIView animateWithDuration:duration animations:^{ + updateBlock(); + } completion:^(BOOL finished) { + // this hack fixes a broken frame after the rotation (#35) + // but rotation animation is still broken + updateBlock(); + }]; } @end @@ -494,56 +526,82 @@ - (void)willChangeStatusBarFrame:(NSNotification*)notification; // A custom view controller, so the statusBarStyle & rotation behaviour is correct @implementation JDStatusBarNotificationViewController -- (UIViewController*)keyWindowRootViewController { - UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow]; - UIWindow *ourWindow = [[self view] window]; - - // return directly, keywindow isn't our window - if (keyWindow != ourWindow) { - return [keyWindow rootViewController]; - } - - // find another window, if our window is the key window (should fix #24) - for (UIWindow *window in [[UIApplication sharedApplication] windows]) { - if (window != ourWindow) { - return [window rootViewController]; - } - } - - // only our window found - return nil; -} - // rotation -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { - return [[self keyWindowRootViewController] - shouldAutorotateToInterfaceOrientation:toInterfaceOrientation]; +- (UIViewController*)mainController +{ + UIWindow *mainAppWindow = [[UIApplication sharedApplication] mainApplicationWindowIgnoringWindow:self.view.window]; + UIViewController *topController = mainAppWindow.rootViewController; + + while(topController.presentedViewController) { + topController = topController.presentedViewController; + } + + return topController; } +//- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { +// return [[self mainController] shouldAutorotateToInterfaceOrientation:toInterfaceOrientation]; +//} + - (BOOL)shouldAutorotate { - return [[self keyWindowRootViewController] shouldAutorotate]; + return [[self mainController] shouldAutorotate]; } -- (UIInterfaceOrientationMask)supportedInterfaceOrientations { - return UIInterfaceOrientationMaskPortrait; -// return [[self keyWindowRootViewController] supportedInterfaceOrientations]; -} +#if __IPHONE_OS_VERSION_MAX_ALLOWED < 90000 +- (NSUInteger)supportedInterfaceOrientations { +#else + - (UIInterfaceOrientationMask)supportedInterfaceOrientations { +#endif + return [[self mainController] supportedInterfaceOrientations]; + } -- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { - return UIInterfaceOrientationPortrait; -// return [[self keyWindowRootViewController] preferredInterfaceOrientationForPresentation]; -} + - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { + return [[self mainController] preferredInterfaceOrientationForPresentation]; + } + + // statusbar + + static BOOL JDUIViewControllerBasedStatusBarAppearanceEnabled() { + static BOOL enabled = NO; + static dispatch_once_t onceToken; -// statusbar + dispatch_once(&onceToken, ^{ + enabled = [[[[NSBundle mainBundle] infoDictionary] objectForKey:@"UIViewControllerBasedStatusBarAppearance"] boolValue]; + }); + + return enabled; + } + + - (UIStatusBarStyle)preferredStatusBarStyle { + if(JDUIViewControllerBasedStatusBarAppearanceEnabled()) { + return [[self mainController] preferredStatusBarStyle]; + } -- (UIStatusBarStyle)preferredStatusBarStyle { return [[UIApplication sharedApplication] statusBarStyle]; -} + } -- (BOOL)prefersStatusBarHidden { + - (BOOL)prefersStatusBarHidden { return NO; -} + } -@end + - (UIStatusBarAnimation)preferredStatusBarUpdateAnimation { + if(JDUIViewControllerBasedStatusBarAppearanceEnabled()) { + return [[self mainController] preferredStatusBarUpdateAnimation]; + } + return [super preferredStatusBarUpdateAnimation]; + } + @end + + @implementation UIApplication (mainWindow) + // we don't want the keyWindow, since it could be our own window + - (UIWindow*)mainApplicationWindowIgnoringWindow:(UIWindow *)ignoringWindow { + for (UIWindow *window in [[UIApplication sharedApplication] windows]) { + if (!window.hidden && window != ignoringWindow) { + return window; + } + } + return nil; + } + @end diff --git a/Coding_iOS/Vendor/JDStatusBarNotification/JDStatusBarStyle.h b/Coding_iOS/Vendor/JDStatusBarNotification/JDStatusBarStyle.h index 031f0efec..2728589ef 100755 --- a/Coding_iOS/Vendor/JDStatusBarNotification/JDStatusBarStyle.h +++ b/Coding_iOS/Vendor/JDStatusBarNotification/JDStatusBarStyle.h @@ -7,27 +7,43 @@ // #import - -extern NSString *const JDStatusBarStyleError; /// This style has a red background with a white Helvetica label. -extern NSString *const JDStatusBarStyleWarning; /// This style has a yellow background with a gray Helvetica label. -extern NSString *const JDStatusBarStyleSuccess; /// This style has a green background with a white Helvetica label. -extern NSString *const JDStatusBarStyleMatrix; /// This style has a black background with a green bold Courier label. -extern NSString *const JDStatusBarStyleDefault; /// This style has a white background with a gray Helvetica label. -extern NSString *const JDStatusBarStyleDark; /// This style has a nearly black background with a nearly white Helvetica label. +#import + +/// This style has a red background with a white Helvetica label. +extern NSString *const JDStatusBarStyleError; +/// This style has a yellow background with a gray Helvetica label. +extern NSString *const JDStatusBarStyleWarning; +/// This style has a green background with a white Helvetica label. +extern NSString *const JDStatusBarStyleSuccess; +/// This style has a black background with a green bold Courier label. +extern NSString *const JDStatusBarStyleMatrix; +/// This style has a white background with a gray Helvetica label. +extern NSString *const JDStatusBarStyleDefault; +/// This style has a nearly black background with a nearly white Helvetica label. +extern NSString *const JDStatusBarStyleDark; typedef NS_ENUM(NSInteger, JDStatusBarAnimationType) { - JDStatusBarAnimationTypeNone, /// Notification won't animate - JDStatusBarAnimationTypeMove, /// Notification will move in from the top, and move out again to the top - JDStatusBarAnimationTypeBounce, /// Notification will fall down from the top and bounce a little bit - JDStatusBarAnimationTypeFade /// Notification will fade in and fade out + /// Notification won't animate + JDStatusBarAnimationTypeNone, + /// Notification will move in from the top, and move out again to the top + JDStatusBarAnimationTypeMove, + /// Notification will fall down from the top and bounce a little bit + JDStatusBarAnimationTypeBounce, + /// Notification will fade in and fade out + JDStatusBarAnimationTypeFade, }; typedef NS_ENUM(NSInteger, JDStatusBarProgressBarPosition) { - JDStatusBarProgressBarPositionBottom, /// progress bar will be at the bottom of the status bar - JDStatusBarProgressBarPositionCenter, /// progress bar will be at the center of the status bar - JDStatusBarProgressBarPositionTop, /// progress bar will be at the top of the status bar - JDStatusBarProgressBarPositionBelow, /// progress bar will be below the status bar (the prograss bar won't move with the statusbar in this case) - JDStatusBarProgressBarPositionNavBar, /// progress bar will be below the navigation bar (the prograss bar won't move with the statusbar in this case) + /// progress bar will be at the bottom of the status bar + JDStatusBarProgressBarPositionBottom, + /// progress bar will be at the center of the status bar + JDStatusBarProgressBarPositionCenter, + /// progress bar will be at the top of the status bar + JDStatusBarProgressBarPositionTop, + /// progress bar will be below the status bar (the progress bar won't move with the status bar in this case) + JDStatusBarProgressBarPositionBelow, + /// progress bar will be below the navigation bar (the progress bar won't move with the status bar in this case) + JDStatusBarProgressBarPositionNavBar, }; /** @@ -66,5 +82,11 @@ typedef NS_ENUM(NSInteger, JDStatusBarProgressBarPosition) { /// The position of the progress bar. Default is JDStatusBarProgressBarPositionBottom @property (nonatomic, assign) JDStatusBarProgressBarPosition progressBarPosition; +/// The insets of the progress bar. Default is 0.0 +@property (nonatomic, assign) CGFloat progressBarHorizontalInsets; + +/// The corner radius of the progress bar. Default is 0.0 +@property (nonatomic, assign) CGFloat progressBarCornerRadius; + @end diff --git a/Coding_iOS/Vendor/JDStatusBarNotification/JDStatusBarStyle.m b/Coding_iOS/Vendor/JDStatusBarNotification/JDStatusBarStyle.m index 36c1afba2..36b932f1c 100755 --- a/Coding_iOS/Vendor/JDStatusBarNotification/JDStatusBarStyle.m +++ b/Coding_iOS/Vendor/JDStatusBarNotification/JDStatusBarStyle.m @@ -19,88 +19,88 @@ @implementation JDStatusBarStyle - (instancetype)copyWithZone:(NSZone*)zone; { - JDStatusBarStyle *style = [[[self class] allocWithZone:zone] init]; - style.barColor = self.barColor; - style.textColor = self.textColor; - style.textShadow = self.textShadow; - style.font = self.font; - style.textVerticalPositionAdjustment = self.textVerticalPositionAdjustment; - style.animationType = self.animationType; - style.progressBarColor = self.progressBarColor; - style.progressBarHeight = self.progressBarHeight; - style.progressBarPosition = self.progressBarPosition; - return style; + JDStatusBarStyle *style = [[[self class] allocWithZone:zone] init]; + style.barColor = self.barColor; + style.textColor = self.textColor; + style.textShadow = self.textShadow; + style.font = self.font; + style.textVerticalPositionAdjustment = self.textVerticalPositionAdjustment; + style.animationType = self.animationType; + style.progressBarColor = self.progressBarColor; + style.progressBarHeight = self.progressBarHeight; + style.progressBarPosition = self.progressBarPosition; + return style; } + (NSArray*)allDefaultStyleIdentifier; { - return @[JDStatusBarStyleError, JDStatusBarStyleWarning, - JDStatusBarStyleSuccess, JDStatusBarStyleMatrix, - JDStatusBarStyleDark]; + return @[JDStatusBarStyleError, JDStatusBarStyleWarning, + JDStatusBarStyleSuccess, JDStatusBarStyleMatrix, + JDStatusBarStyleDark]; } + (JDStatusBarStyle*)defaultStyleWithName:(NSString*)styleName; { - // setup default style - JDStatusBarStyle *style = [[JDStatusBarStyle alloc] init]; - style.barColor = [UIColor whiteColor]; + // setup default style + JDStatusBarStyle *style = [[JDStatusBarStyle alloc] init]; + style.barColor = [UIColor whiteColor]; + style.progressBarColor = [UIColor greenColor]; + style.progressBarHeight = 1.0; + style.progressBarPosition = JDStatusBarProgressBarPositionBottom; + style.textColor = [UIColor grayColor]; + style.font = [UIFont systemFontOfSize:12.0]; + style.animationType = JDStatusBarAnimationTypeMove; + + // JDStatusBarStyleDefault + if ([styleName isEqualToString:JDStatusBarStyleDefault]) { + return style; + } + + // JDStatusBarStyleError + else if ([styleName isEqualToString:JDStatusBarStyleError]) { + style.barColor = [UIColor colorWithRed:255.0/255.0 green:88.0/255.0 blue:71.0/255.0 alpha:1.000]; + style.textColor = [UIColor whiteColor]; + style.progressBarColor = [UIColor redColor]; + style.progressBarHeight = 2.0; + return style; + } + + // JDStatusBarStyleWarning + else if ([styleName isEqualToString:JDStatusBarStyleWarning]) { + style.barColor = [UIColor colorWithRed:0.900 green:0.734 blue:0.034 alpha:1.000]; + style.textColor = [UIColor darkGrayColor]; + style.progressBarColor = style.textColor; + return style; + } + + // JDStatusBarStyleSuccess + else if ([styleName isEqualToString:JDStatusBarStyleSuccess]) { + style.barColor = [UIColor colorWithRed:59.0/255.0 green:189.0/255.0 blue:121.0/255.0 alpha:1.000]; + style.textColor = [UIColor whiteColor]; + style.progressBarColor = [UIColor colorWithRed:0.106 green:0.594 blue:0.319 alpha:1.000]; + style.progressBarHeight = 1.0+1.0/[[UIScreen mainScreen] scale]; + return style; + } + + // JDStatusBarStyleDark + else if ([styleName isEqualToString:JDStatusBarStyleDark]) { + style.barColor = [UIColor colorWithRed:0.050 green:0.078 blue:0.120 alpha:1.000]; + style.textColor = [UIColor colorWithWhite:0.95 alpha:1.0]; + style.progressBarHeight = 1.0+1.0/[[UIScreen mainScreen] scale]; + return style; + } + + // JDStatusBarStyleMatrix + else if ([styleName isEqualToString:JDStatusBarStyleMatrix]) { + style.barColor = [UIColor blackColor]; + style.textColor = [UIColor greenColor]; + style.font = [UIFont fontWithName:@"Courier-Bold" size:14.0]; style.progressBarColor = [UIColor greenColor]; - style.progressBarHeight = 1.0; - style.progressBarPosition = JDStatusBarProgressBarPositionBottom; - style.textColor = [UIColor grayColor]; - style.font = [UIFont systemFontOfSize:12.0]; - style.animationType = JDStatusBarAnimationTypeMove; - - // JDStatusBarStyleDefault - if ([styleName isEqualToString:JDStatusBarStyleDefault]) { - return style; - } - - // JDStatusBarStyleError - else if ([styleName isEqualToString:JDStatusBarStyleError]) { - style.barColor = [UIColor colorWithRed:255.0/255.0 green:88.0/255.0 blue:71.0/255.0 alpha:1.000]; - style.textColor = [UIColor whiteColor]; - style.progressBarColor = [UIColor redColor]; - style.progressBarHeight = 2.0; - return style; - } - - // JDStatusBarStyleWarning - else if ([styleName isEqualToString:JDStatusBarStyleWarning]) { - style.barColor = [UIColor colorWithRed:0.900 green:0.734 blue:0.034 alpha:1.000]; - style.textColor = [UIColor darkGrayColor]; - style.progressBarColor = style.textColor; - return style; - } - - // JDStatusBarStyleSuccess - else if ([styleName isEqualToString:JDStatusBarStyleSuccess]) { - style.barColor = [UIColor colorWithRed:59.0/255.0 green:189.0/255.0 blue:121.0/255.0 alpha:1.000]; - style.textColor = [UIColor whiteColor]; - style.progressBarColor = [UIColor colorWithRed:0.106 green:0.594 blue:0.319 alpha:1.000]; - style.progressBarHeight = 1.0+1.0/[[UIScreen mainScreen] scale]; - return style; - } - - // JDStatusBarStyleDark - else if ([styleName isEqualToString:JDStatusBarStyleDark]) { - style.barColor = [UIColor colorWithRed:0.050 green:0.078 blue:0.120 alpha:1.000]; - style.textColor = [UIColor colorWithWhite:0.95 alpha:1.0]; - style.progressBarHeight = 1.0+1.0/[[UIScreen mainScreen] scale]; - return style; - } - - // JDStatusBarStyleMatrix - else if ([styleName isEqualToString:JDStatusBarStyleMatrix]) { - style.barColor = [UIColor blackColor]; - style.textColor = [UIColor greenColor]; - style.font = [UIFont fontWithName:@"Courier-Bold" size:14.0]; - style.progressBarColor = [UIColor greenColor]; - style.progressBarHeight = 2.0; - return style; - } - - return nil; + style.progressBarHeight = 2.0; + return style; + } + + return nil; } @end diff --git a/Coding_iOS/Vendor/JDStatusBarNotification/JDStatusBarView.m b/Coding_iOS/Vendor/JDStatusBarNotification/JDStatusBarView.m index c5746a8de..a6313ecd1 100755 --- a/Coding_iOS/Vendor/JDStatusBarNotification/JDStatusBarView.m +++ b/Coding_iOS/Vendor/JDStatusBarNotification/JDStatusBarView.m @@ -7,6 +7,7 @@ // #import "JDStatusBarView.h" +#import "JDStatusBarLayoutMarginHelper.h" @interface JDStatusBarView () @property (nonatomic, strong) UILabel *textLabel; @@ -19,77 +20,80 @@ @implementation JDStatusBarView - (UILabel *)textLabel; { - if (_textLabel == nil) { - _textLabel = [[UILabel alloc] init]; - _textLabel.backgroundColor = [UIColor clearColor]; - _textLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters; - _textLabel.textAlignment = NSTextAlignmentCenter; - _textLabel.adjustsFontSizeToFitWidth = YES; - _textLabel.clipsToBounds = YES; - [self addSubview:_textLabel]; - } - return _textLabel; + if (_textLabel == nil) { + _textLabel = [[UILabel alloc] init]; + _textLabel.backgroundColor = [UIColor clearColor]; + _textLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters; + _textLabel.textAlignment = NSTextAlignmentCenter; + _textLabel.adjustsFontSizeToFitWidth = YES; + _textLabel.clipsToBounds = YES; + [self addSubview:_textLabel]; + } + return _textLabel; } - (UIActivityIndicatorView *)activityIndicatorView; { - if (_activityIndicatorView == nil) { - _activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; - _activityIndicatorView.transform = CGAffineTransformMakeScale(0.7, 0.7); - [self addSubview:_activityIndicatorView]; - } - return _activityIndicatorView; + if (_activityIndicatorView == nil) { + _activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; + _activityIndicatorView.transform = CGAffineTransformMakeScale(0.7, 0.7); + [self addSubview:_activityIndicatorView]; + } + return _activityIndicatorView; } #pragma mark setter - (void)setTextVerticalPositionAdjustment:(CGFloat)textVerticalPositionAdjustment; { - _textVerticalPositionAdjustment = textVerticalPositionAdjustment; - [self setNeedsLayout]; + _textVerticalPositionAdjustment = textVerticalPositionAdjustment; + [self setNeedsLayout]; } #pragma mark layout - (void)layoutSubviews; { - [super layoutSubviews]; - - // label - self.textLabel.frame = CGRectMake(0, 1+self.textVerticalPositionAdjustment, - self.bounds.size.width, self.bounds.size.height-1); - - // activity indicator - if (_activityIndicatorView ) { - CGSize textSize = [self currentTextSize]; - CGRect indicatorFrame = _activityIndicatorView.frame; - indicatorFrame.origin.x = round((self.bounds.size.width - textSize.width)/2.0) - indicatorFrame.size.width - 8.0; - indicatorFrame.origin.y = ceil(1+(self.bounds.size.height - indicatorFrame.size.height)/2.0); - _activityIndicatorView.frame = indicatorFrame; - } + [super layoutSubviews]; + + // label + CGFloat topLayoutMargin = JDStatusBarRootVCLayoutMargin().top; + self.textLabel.frame = CGRectMake(0, + self.textVerticalPositionAdjustment + topLayoutMargin + 1, + self.bounds.size.width, + self.bounds.size.height - topLayoutMargin - 1); + + // activity indicator + if (_activityIndicatorView ) { + CGSize textSize = [self currentTextSize]; + CGRect indicatorFrame = _activityIndicatorView.frame; + indicatorFrame.origin.x = round((self.bounds.size.width - textSize.width)/2.0) - indicatorFrame.size.width - 8.0; + indicatorFrame.origin.y = ceil(1+(self.bounds.size.height - indicatorFrame.size.height + topLayoutMargin)/2.0); + _activityIndicatorView.frame = indicatorFrame; + } } - (CGSize)currentTextSize; { - CGSize textSize = CGSizeZero; - - // use new sizeWithAttributes: if possible - SEL selector = NSSelectorFromString(@"sizeWithAttributes:"); - if ([self.textLabel.text respondsToSelector:selector]) { - #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 - NSDictionary *attributes = @{NSFontAttributeName:self.textLabel.font}; - textSize = [self.textLabel.text sizeWithAttributes:attributes]; - #endif - } - - // otherwise use old sizeWithFont: - else { - #if __IPHONE_OS_VERSION_MIN_REQUIRED < 70000 // only when deployment target is < ios7 - textSize = [self.textLabel.text sizeWithFont:self.textLabel.font]; - #endif - } - - return textSize; + CGSize textSize = CGSizeZero; + + // use new sizeWithAttributes: if possible + SEL selector = NSSelectorFromString(@"sizeWithAttributes:"); + if ([self.textLabel.text respondsToSelector:selector]) { +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 + NSDictionary *attributes = @{NSFontAttributeName:self.textLabel.font}; + textSize = [self.textLabel.text sizeWithAttributes:attributes]; +#endif + } + + // otherwise use old sizeWithFont: + else { +#if __IPHONE_OS_VERSION_MIN_REQUIRED < 70000 // only when deployment target is < ios7 + textSize = [self.textLabel.text sizeWithFont:self.textLabel.font]; +#endif + } + + return textSize; } @end diff --git a/Coding_iOS/Vendor/KxMenu/KxMenu.h b/Coding_iOS/Vendor/KxMenu/KxMenu.h index 439bc787e..83a3308f8 100755 --- a/Coding_iOS/Vendor/KxMenu/KxMenu.h +++ b/Coding_iOS/Vendor/KxMenu/KxMenu.h @@ -75,4 +75,7 @@ + (UIFont *) titleFont; + (void) setTitleFont: (UIFont *) titleFont; +//yOffset 每次视图显示前调用。单次设置有效,视图消失后还原为 0 ++ (CGFloat) yOffset; ++ (void) setYOffset:(CGFloat) yOffset; @end diff --git a/Coding_iOS/Vendor/KxMenu/KxMenu.m b/Coding_iOS/Vendor/KxMenu/KxMenu.m index 6596012c5..fdaa67ecd 100755 --- a/Coding_iOS/Vendor/KxMenu/KxMenu.m +++ b/Coding_iOS/Vendor/KxMenu/KxMenu.m @@ -39,7 +39,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "KxMenu.h" #import -const CGFloat kArrowSize = 8.f; +const CGFloat kArrowSize = 5.f; //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// @@ -326,8 +326,12 @@ - (void)showMenuInView:(UIView *)view [self addSubview:_contentView]; [self setupFrameInView:view fromRect:rect]; - - KxMenuOverlay *overlay = [[KxMenuOverlay alloc] initWithFrame:view.bounds]; + + CGRect overlayFrame = view.bounds; + overlayFrame.origin.y = [KxMenu yOffset]; + overlayFrame.size.height -= [KxMenu yOffset]; + KxMenuOverlay *overlay = [[KxMenuOverlay alloc] initWithFrame:overlayFrame]; + [overlay addSubview:self]; [view addSubview:overlay]; @@ -371,6 +375,7 @@ - (void)dismissMenu:(BOOL) animated if ([self.superview isKindOfClass:[KxMenuOverlay class]]) [self.superview removeFromSuperview]; [self removeFromSuperview]; + [KxMenu setYOffset:0];//yOffset 每次视图消失后,需要还原为 0 }]; } else { @@ -378,6 +383,7 @@ - (void)dismissMenu:(BOOL) animated if ([self.superview isKindOfClass:[KxMenuOverlay class]]) [self.superview removeFromSuperview]; [self removeFromSuperview]; + [KxMenu setYOffset:0];//yOffset 每次视图消失后,需要还原为 0 } } } @@ -400,8 +406,8 @@ - (UIView *) mkContentView if (!_menuItems.count) return nil; - const CGFloat kMinMenuItemHeight = 44.f; - const CGFloat kMinMenuItemWidth = 44.f; + const CGFloat kMinMenuItemHeight = 50.f; + const CGFloat kMinMenuItemWidth = 50.f; const CGFloat kMarginX = 6.f; const CGFloat kMarginY = 0.f; @@ -444,6 +450,7 @@ - (UIView *) mkContentView } maxItemWidth = MAX(maxItemWidth, kMinMenuItemWidth); + maxItemWidth = MAX(maxItemWidth, maxItemWidth * (kScreen_Width/ 375)); maxItemHeight = MAX(maxItemHeight, kMinMenuItemHeight); const CGFloat titleX = kMarginX * 2 + maxImageWidth + titleImagePadding; @@ -537,6 +544,8 @@ - (UIView *) mkContentView } if (itemNum < _menuItems.count - 1) { + [itemView addLineUp:NO andDown:YES andColor:[KxMenu lineColor]]; + itemView.clipsToBounds = YES; itemY += 2; } itemY += maxItemHeight; @@ -663,13 +672,13 @@ - (void)drawBackground:(CGRect)frame UIBezierPath *arrowPath = [UIBezierPath bezierPath]; // fix the issue with gap of arrow's base if on the edge - const CGFloat kEmbedFix = 3.f; - + const CGFloat kEmbedFix = 0.f; + if (_arrowDirection == KxMenuViewArrowDirectionUp) { const CGFloat arrowXM = _arrowPosition; - const CGFloat arrowX0 = arrowXM - kArrowSize; - const CGFloat arrowX1 = arrowXM + kArrowSize; + const CGFloat arrowX0 = arrowXM - kArrowSize - 1; + const CGFloat arrowX1 = arrowXM + kArrowSize + 1; const CGFloat arrowY0 = Y0; const CGFloat arrowY1 = Y0 + kArrowSize + kEmbedFix; @@ -741,7 +750,7 @@ - (void)drawBackground:(CGRect)frame const CGRect bodyFrame = {X0, Y0, X1 - X0, Y1 - Y0}; UIBezierPath *borderPath = [UIBezierPath bezierPathWithRoundedRect:bodyFrame - cornerRadius:2]; + cornerRadius:4]; const CGFloat locations[] = {0, 1}; const CGFloat components[] = { @@ -787,6 +796,7 @@ - (void)drawBackground:(CGRect)frame static KxMenu *gMenu; static UIColor *gTintColor, *gLineColor, *gOverlayColor; static UIFont *gTitleFont; +static CGFloat gYOffset = 0.0; @implementation KxMenu { @@ -921,7 +931,8 @@ + (void) setLineColor: (UIColor *) lineColor + (UIColor *) overlayColor { if (!gOverlayColor) { - gOverlayColor = [UIColor colorWithWhite:0 alpha:0.5]; + gOverlayColor = [UIColor colorWithHexString:@"272C33" andAlpha:.5]; +// [UIColor colorWithWhite:0 alpha:0.5]; } return gOverlayColor; } @@ -945,4 +956,13 @@ + (void) setTitleFont: (UIFont *) titleFont } } ++ (CGFloat) yOffset{ + return gYOffset; +} ++ (void) setYOffset:(CGFloat) yOffset{ + if (yOffset != gYOffset){ + gYOffset = yOffset; + } +} + @end diff --git a/Coding_iOS/Vendor/MJPhotoBrowser/MJPhotoToolbar.m b/Coding_iOS/Vendor/MJPhotoBrowser/MJPhotoToolbar.m index 0909bcd6f..808350edb 100755 --- a/Coding_iOS/Vendor/MJPhotoBrowser/MJPhotoToolbar.m +++ b/Coding_iOS/Vendor/MJPhotoBrowser/MJPhotoToolbar.m @@ -55,16 +55,21 @@ - (void)setPhotos:(NSArray *)photos [self addSubview:_saveImageBtn]; } -- (void)saveImage -{ - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - MJPhoto *photo = _photos[_currentPhotoIndex]; - UIImageWriteToSavedPhotosAlbum(photo.image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); - }); +- (void)saveImage{ + MJPhoto *curP = _photos[_currentPhotoIndex]; + NSString *dataP = [SDWebImageManager.sharedManager.imageCache defaultCachePathForKey:curP.url.absoluteString]; + NSData *imageD = [NSData dataWithContentsOfFile:dataP]; + __weak typeof(self) weakSelf = self; + [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ + [[PHAssetCreationRequest creationRequestForAsset] addResourceWithType:PHAssetResourceTypePhoto data:imageD options:nil]; + } completionHandler:^(BOOL success, NSError * _Nullable error) { + dispatch_async(dispatch_get_main_queue(), ^{ + [weakSelf saveImageHappenedError:error]; + }); + }]; } -- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo -{ +- (void)saveImageHappenedError:(NSError *)error{ if (error) { [MBProgressHUD showSuccess:@"保存失败" toView:nil]; } else { diff --git a/Coding_iOS/Vendor/NSDate+Helper/NSDate+Helper.m b/Coding_iOS/Vendor/NSDate+Helper/NSDate+Helper.m index 2c46a3ac0..91ab097ae 100755 --- a/Coding_iOS/Vendor/NSDate+Helper/NSDate+Helper.m +++ b/Coding_iOS/Vendor/NSDate+Helper/NSDate+Helper.m @@ -43,6 +43,8 @@ static NSString *kNSDateHelperFormatSQLDateWithTime = @"yyyy-MM-dd HH:mm:ss"; @implementation NSDate (Helper) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" static NSCalendar *_calendar = nil; static NSDateFormatter *_displayFormatter = nil; @@ -329,5 +331,5 @@ + (NSString *)timestampFormatString { + (NSString *)dbFormatString { return [NSDate timestampFormatString]; } - +#pragma clang diagnostic pop @end diff --git a/Coding_iOS/Vendor/PopMenu/MenuButton.m b/Coding_iOS/Vendor/PopMenu/MenuButton.m index 3bd88cd42..25c5aea23 100755 --- a/Coding_iOS/Vendor/PopMenu/MenuButton.m +++ b/Coding_iOS/Vendor/PopMenu/MenuButton.m @@ -43,10 +43,10 @@ - (instancetype)initWithFrame:(CGRect)frame menuItem:(MenuItem *)menuItem { self.iconImageView.center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.iconImageView.bounds)); [self addSubview:self.iconImageView]; - self.titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(self.iconImageView.frame), CGRectGetWidth(self.bounds), 35)]; - self.titleLabel.textColor = [UIColor blackColor]; + self.titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(self.iconImageView.frame) + 20, CGRectGetWidth(self.bounds), 20)]; + self.titleLabel.textColor = kColorDark4; self.titleLabel.backgroundColor = [UIColor clearColor]; - self.titleLabel.font = [UIFont systemFontOfSize:14]; + self.titleLabel.font = [UIFont systemFontOfSize:15]; self.titleLabel.textAlignment = NSTextAlignmentCenter; self.titleLabel.text = menuItem.title; CGPoint center = self.titleLabel.center; diff --git a/Coding_iOS/Vendor/PopMenu/PopMenu.m b/Coding_iOS/Vendor/PopMenu/PopMenu.m index 97483e49d..e110ad6da 100755 --- a/Coding_iOS/Vendor/PopMenu/PopMenu.m +++ b/Coding_iOS/Vendor/PopMenu/PopMenu.m @@ -10,7 +10,7 @@ #import "MenuButton.h" #import -#define MenuButtonHeight 110 +#define MenuButtonHeight 135 #define MenuButtonVerticalPadding 10 #define MenuButtonHorizontalMargin 10 #define MenuButtonAnimationTime 0.1 @@ -268,7 +268,7 @@ - (CGRect)getFrameWithItemCount:(NSInteger)itemCount atIndex:(NSInteger)index onPage:(NSInteger)page { - CGFloat insetY = kScreen_Height * 0.1 + 64; + CGFloat insetY = kScreen_Height * 0.12; // NSUInteger rowCount = itemCount / perRowItemCount + (itemCount % perColumItemCount > 0 ? 1 : 0); // CGFloat insetY = (CGRectGetHeight(self.bounds) - (itemHeight + paddingY) * rowCount) / 2.0; diff --git a/Coding_iOS/Vendor/QBImagePickerController/LICENSE b/Coding_iOS/Vendor/QBImagePickerController/LICENSE new file mode 100644 index 000000000..a98aa0927 --- /dev/null +++ b/Coding_iOS/Vendor/QBImagePickerController/LICENSE @@ -0,0 +1,7 @@ +Copyright (c) 2015 Katsuma Tanaka + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionCheckmarkView.h b/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionCheckmarkView.h deleted file mode 100755 index 161379cb4..000000000 --- a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionCheckmarkView.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// QBAssetsCollectionCheckmarkView.h -// QBImagePickerController -// -// Created by Tanaka Katsuma on 2014/01/01. -// Copyright (c) 2014年 Katsuma Tanaka. All rights reserved. -// - -#import - -@interface QBAssetsCollectionCheckmarkView : UIView - -@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionCheckmarkView.m b/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionCheckmarkView.m deleted file mode 100755 index 82ee42d7e..000000000 --- a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionCheckmarkView.m +++ /dev/null @@ -1,53 +0,0 @@ -// -// QBAssetsCollectionCheckmarkView.m -// QBImagePickerController -// -// Created by Tanaka Katsuma on 2014/01/01. -// Copyright (c) 2014年 Katsuma Tanaka. All rights reserved. -// - -#import "QBAssetsCollectionCheckmarkView.h" - -@implementation QBAssetsCollectionCheckmarkView - -- (instancetype)initWithFrame:(CGRect)frame -{ - self = [super initWithFrame:frame]; - - if (self) { - // View settings - self.backgroundColor = [UIColor clearColor]; - } - - return self; -} - -- (CGSize)sizeThatFits:(CGSize)size -{ - return CGSizeMake(24.0, 24.0); -} - -- (void)drawRect:(CGRect)rect -{ - CGContextRef context = UIGraphicsGetCurrentContext(); - - // Border - CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0); - CGContextFillEllipseInRect(context, self.bounds); - - // Body - CGContextSetRGBFillColor(context, 20.0/255.0, 111.0/255.0, 223.0/255.0, 1.0); - CGContextFillEllipseInRect(context, CGRectInset(self.bounds, 1.0, 1.0)); - - // Checkmark - CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0); - CGContextSetLineWidth(context, 1.2); - - CGContextMoveToPoint(context, 6.0, 12.0); - CGContextAddLineToPoint(context, 10.0, 16.0); - CGContextAddLineToPoint(context, 18.0, 8.0); - - CGContextStrokePath(context); -} - -@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionFooterView.h b/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionFooterView.h deleted file mode 100755 index 630307cec..000000000 --- a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionFooterView.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// QBAssetsCollectionFooterView.h -// QBImagePickerController -// -// Created by Tanaka Katsuma on 2013/12/31. -// Copyright (c) 2013年 Katsuma Tanaka. All rights reserved. -// - -#import - -@interface QBAssetsCollectionFooterView : UICollectionReusableView - -@property (nonatomic, strong, readonly) UILabel *textLabel; - -@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionFooterView.m b/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionFooterView.m deleted file mode 100755 index 3d23af88a..000000000 --- a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionFooterView.m +++ /dev/null @@ -1,48 +0,0 @@ -// -// QBAssetsCollectionFooterView.m -// QBImagePickerController -// -// Created by Tanaka Katsuma on 2013/12/31. -// Copyright (c) 2013年 Katsuma Tanaka. All rights reserved. -// - -#import "QBAssetsCollectionFooterView.h" - -@interface QBAssetsCollectionFooterView () - -@property (nonatomic, strong, readwrite) UILabel *textLabel; - -@end - -@implementation QBAssetsCollectionFooterView - -- (instancetype)initWithFrame:(CGRect)frame -{ - self = [super initWithFrame:frame]; - - if (self) { - // Create a label - UILabel *textLabel = [[UILabel alloc] initWithFrame:CGRectZero]; - textLabel.font = [UIFont systemFontOfSize:17]; - textLabel.textColor = [UIColor blackColor]; - textLabel.textAlignment = NSTextAlignmentCenter; - - [self addSubview:textLabel]; - self.textLabel = textLabel; - } - - return self; -} - -- (void)layoutSubviews -{ - [super layoutSubviews]; - - // Layout text label - self.textLabel.frame = CGRectMake(0, - (self.bounds.size.height - 21.0) / 2.0, - self.bounds.size.width, - 21.0); -} - -@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionOverlayView.h b/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionOverlayView.h deleted file mode 100755 index b4b5b3971..000000000 --- a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionOverlayView.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// QBAssetsCollectionOverlayView.h -// QBImagePickerController -// -// Created by Tanaka Katsuma on 2014/01/01. -// Copyright (c) 2014年 Katsuma Tanaka. All rights reserved. -// - -#import - -@interface QBAssetsCollectionOverlayView : UIView - -@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionOverlayView.m b/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionOverlayView.m deleted file mode 100755 index caa7ae670..000000000 --- a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionOverlayView.m +++ /dev/null @@ -1,47 +0,0 @@ -// -// QBAssetsCollectionOverlayView.m -// QBImagePickerController -// -// Created by Tanaka Katsuma on 2014/01/01. -// Copyright (c) 2014年 Katsuma Tanaka. All rights reserved. -// - -#import "QBAssetsCollectionOverlayView.h" -#import - -// Views -#import "QBAssetsCollectionCheckmarkView.h" - -@interface QBAssetsCollectionOverlayView () - -@property (nonatomic, strong) QBAssetsCollectionCheckmarkView *checkmarkView; - -@end - -@implementation QBAssetsCollectionOverlayView - -- (instancetype)initWithFrame:(CGRect)frame -{ - self = [super initWithFrame:frame]; - - if (self) { - // View settings - self.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.4]; - - // Create a checkmark view - QBAssetsCollectionCheckmarkView *checkmarkView = [[QBAssetsCollectionCheckmarkView alloc] initWithFrame:CGRectMake(self.bounds.size.width - (4.0 + 24.0), self.bounds.size.height - (4.0 + 24.0), 24.0, 24.0)]; - checkmarkView.autoresizingMask = UIViewAutoresizingNone; - - checkmarkView.layer.shadowColor = [[UIColor grayColor] CGColor]; - checkmarkView.layer.shadowOffset = CGSizeMake(0, 0); - checkmarkView.layer.shadowOpacity = 0.6; - checkmarkView.layer.shadowRadius = 2.0; - - [self addSubview:checkmarkView]; - self.checkmarkView = checkmarkView; - } - - return self; -} - -@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionVideoIndicatorView.h b/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionVideoIndicatorView.h deleted file mode 100755 index 58a78dc65..000000000 --- a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionVideoIndicatorView.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// QBAssetsCollectionVideoIndicatorView.h -// QBImagePickerControllerDemo -// -// Created by Katsuma Tanaka on 2014/08/07. -// Copyright (c) 2014年 Katsuma Tanaka. All rights reserved. -// - -#import - -@interface QBAssetsCollectionVideoIndicatorView : UIView - -@property (nonatomic, assign) NSTimeInterval duration; - -@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionVideoIndicatorView.m b/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionVideoIndicatorView.m deleted file mode 100755 index 4aba36c01..000000000 --- a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionVideoIndicatorView.m +++ /dev/null @@ -1,107 +0,0 @@ -// -// QBAssetsCollectionVideoIndicatorView.m -// QBImagePickerControllerDemo -// -// Created by Katsuma Tanaka on 2014/08/07. -// Copyright (c) 2014年 Katsuma Tanaka. All rights reserved. -// - -#import "QBAssetsCollectionVideoIndicatorView.h" -#import - -@implementation QBAssetsCollectionVideoIndicatorView - -- (instancetype)initWithFrame:(CGRect)frame -{ - self = [super initWithFrame:frame]; - - if (self) { - self.backgroundColor = [UIColor clearColor]; - self.clipsToBounds = YES; - } - - return self; -} - - -#pragma mark - Accessors - -- (void)setDuration:(NSTimeInterval)duration -{ - _duration = duration; - - [self setNeedsDisplay]; -} - - -#pragma mark - Drawing the View - -- (void)drawRect:(CGRect)rect -{ - // Draw linear gradient - CGContextRef context = UIGraphicsGetCurrentContext(); - - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - CGFloat colors[12] = { - 0.0, 0.0, 0.0, 0.9, - 0.0, 0.0, 0.0, 0.45, - 0.0, 0.0, 0.0, 0.0 - }; - const CGFloat locations[] = { 0.0, 0.55, 1.0 }; - CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, locations, 3); - CGColorSpaceRelease(colorSpace); - - CGPoint startPoint = CGPointMake(0, CGRectGetHeight(self.bounds)); - CGPoint endPoint = CGPointMake(0, 0); - CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation); - - CGGradientRelease(gradient); - - // Draw camera icon - CGSize cameraIconSize = CGSizeMake(14.0, 8.0); - CGRect cameraIconRect = CGRectMake(5.0, (CGRectGetHeight(self.bounds) - cameraIconSize.height) / 2.0, cameraIconSize.width, cameraIconSize.height); - [self drawCameraIconInRect:cameraIconRect]; - - // Draw duration - NSInteger minutes = (NSInteger)(self.duration / 60.0); - NSInteger seconds = (NSInteger)ceil(self.duration - 60.0 * (double)minutes); - NSString *durationString = [NSString stringWithFormat:@"%02ld:%02ld", (long)minutes, (long)seconds]; - - NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; - paragraphStyle.alignment = NSTextAlignmentRight; - - UIFont *durationFont = [UIFont systemFontOfSize:12.0]; - - CGRect durationRect = CGRectMake(CGRectGetMaxX(cameraIconRect), 0, CGRectGetWidth(self.bounds) - CGRectGetMaxX(cameraIconRect), CGRectGetHeight(self.bounds)); - durationRect = CGRectInset(durationRect, 5.0, (CGRectGetHeight(self.bounds) - durationFont.lineHeight) / 2.0); - - [durationString drawInRect:durationRect - withAttributes:@{ - NSParagraphStyleAttributeName: [paragraphStyle copy], - NSFontAttributeName: durationFont, - NSForegroundColorAttributeName: [UIColor whiteColor] - }]; -} - -- (void)drawCameraIconInRect:(CGRect)rect -{ - [[UIColor whiteColor] setFill]; - - // Draw triangle - CGRect triangleRect = CGRectMake(0, CGRectGetMinY(rect), ceil(CGRectGetHeight(rect) / 2.0), CGRectGetHeight(rect)); - triangleRect.origin.x = CGRectGetMinX(rect) + CGRectGetWidth(rect) - CGRectGetWidth(triangleRect); - - UIBezierPath *trianglePath = [UIBezierPath bezierPath]; - [trianglePath moveToPoint:CGPointMake(CGRectGetMinX(triangleRect) + CGRectGetWidth(triangleRect), CGRectGetMinY(triangleRect))]; - [trianglePath addLineToPoint:CGPointMake(CGRectGetMinX(triangleRect) + CGRectGetWidth(triangleRect), CGRectGetMaxY(triangleRect))]; - [trianglePath addLineToPoint:CGPointMake(CGRectGetMinX(triangleRect), CGRectGetMidY(triangleRect))]; - [trianglePath closePath]; - [trianglePath fill]; - - // Draw rounded square - CGRect squareRect = CGRectMake(CGRectGetMinX(rect), CGRectGetMinY(rect), CGRectGetWidth(rect) - CGRectGetWidth(triangleRect) - 1.0, CGRectGetHeight(rect)); - UIBezierPath *squarePath = [UIBezierPath bezierPathWithRoundedRect:squareRect cornerRadius:2.0]; - [squarePath fill]; -} - -@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionViewCell.h b/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionViewCell.h deleted file mode 100755 index caba987e9..000000000 --- a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionViewCell.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// QBAssetsCollectionViewCell.h -// QBImagePickerController -// -// Created by Tanaka Katsuma on 2013/12/31. -// Copyright (c) 2013年 Katsuma Tanaka. All rights reserved. -// - -#import -#import - -@interface QBAssetsCollectionViewCell : UICollectionViewCell - -@property (nonatomic, strong) ALAsset *asset; -@property (nonatomic, assign) BOOL showsOverlayViewWhenSelected; - -@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionViewCell.m b/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionViewCell.m deleted file mode 100755 index 502dc93b1..000000000 --- a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionViewCell.m +++ /dev/null @@ -1,143 +0,0 @@ -// -// QBAssetsCollectionViewCell.m -// QBImagePickerController -// -// Created by Tanaka Katsuma on 2013/12/31. -// Copyright (c) 2013年 Katsuma Tanaka. All rights reserved. -// - -#import "QBAssetsCollectionViewCell.h" - -// Views -#import "QBAssetsCollectionOverlayView.h" -#import "QBAssetsCollectionVideoIndicatorView.h" - -@interface QBAssetsCollectionViewCell () - -@property (nonatomic, strong) UIImageView *imageView; -@property (nonatomic, strong) QBAssetsCollectionOverlayView *overlayView; -@property (nonatomic, strong) QBAssetsCollectionVideoIndicatorView *videoIndicatorView; - -@property (nonatomic, strong) UIImage *blankImage; - -@end - -@implementation QBAssetsCollectionViewCell - -- (instancetype)initWithFrame:(CGRect)frame -{ - self = [super initWithFrame:frame]; - - if (self) { - self.showsOverlayViewWhenSelected = YES; - - // Create a image view - UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.contentView.bounds]; - imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - - [self.contentView addSubview:imageView]; - self.imageView = imageView; - } - - return self; -} - -- (void)setSelected:(BOOL)selected -{ - [super setSelected:selected]; - - // Show/hide overlay view - if (selected && self.showsOverlayViewWhenSelected) { - [self showOverlayView]; - } else { - [self hideOverlayView]; - } -} - - -#pragma mark - Overlay View - -- (void)showOverlayView -{ - [self hideOverlayView]; - - QBAssetsCollectionOverlayView *overlayView = [[QBAssetsCollectionOverlayView alloc] initWithFrame:self.contentView.bounds]; - overlayView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - - [self.contentView addSubview:overlayView]; - self.overlayView = overlayView; -} - -- (void)hideOverlayView -{ - if (self.overlayView) { - [self.overlayView removeFromSuperview]; - self.overlayView = nil; - } -} - - -#pragma mark - Video Indicator View - -- (void)showVideoIndicatorView -{ - CGFloat height = 19.0; - CGRect frame = CGRectMake(0, CGRectGetHeight(self.bounds) - height, CGRectGetWidth(self.bounds), height); - QBAssetsCollectionVideoIndicatorView *videoIndicatorView = [[QBAssetsCollectionVideoIndicatorView alloc] initWithFrame:frame]; - videoIndicatorView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - videoIndicatorView.duration = [[self.asset valueForProperty:ALAssetPropertyDuration] doubleValue]; - - [self.contentView addSubview:videoIndicatorView]; - self.videoIndicatorView = videoIndicatorView; -} - -- (void)hideVideoIndicatorView -{ - if (self.videoIndicatorView) { - [self.videoIndicatorView removeFromSuperview]; - self.videoIndicatorView = nil; - } -} - - -#pragma mark - Accessors - -- (void)setAsset:(ALAsset *)asset -{ - _asset = asset; - - // Update view - CGImageRef thumbnailImageRef = [asset thumbnail]; - - if (thumbnailImageRef) { - self.imageView.image = [UIImage imageWithCGImage:thumbnailImageRef]; - } else { - self.imageView.image = [self blankImage]; - } - - // Show video indicator if the asset is video - if ([[asset valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypeVideo]) { - [self showVideoIndicatorView]; - } else { - [self hideVideoIndicatorView]; - } -} - -- (UIImage *)blankImage -{ - if (_blankImage == nil) { - CGSize size = CGSizeMake(100.0, 100.0); - UIGraphicsBeginImageContextWithOptions(size, NO, 0.0); - - [[UIColor colorWithWhite:(240.0 / 255.0) alpha:1.0] setFill]; - UIRectFill(CGRectMake(0, 0, size.width, size.height)); - - _blankImage = UIGraphicsGetImageFromCurrentImageContext(); - - UIGraphicsEndImageContext(); - } - - return _blankImage; -} - -@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionViewController.h b/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionViewController.h deleted file mode 100755 index 036e7f630..000000000 --- a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionViewController.h +++ /dev/null @@ -1,39 +0,0 @@ -// -// QBAssetsCollectionViewController.h -// QBImagePickerController -// -// Created by Tanaka Katsuma on 2013/12/31. -// Copyright (c) 2013年 Katsuma Tanaka. All rights reserved. -// - -#import -#import - -// ViewControllers -#import "QBImagePickerController.h" - -@class QBAssetsCollectionViewController; - -@protocol QBAssetsCollectionViewControllerDelegate - -@optional -- (void)assetsCollectionViewController:(QBAssetsCollectionViewController *)assetsCollectionViewController didSelectAsset:(ALAsset *)asset; -- (void)assetsCollectionViewController:(QBAssetsCollectionViewController *)assetsCollectionViewController didDeselectAsset:(ALAsset *)asset; -- (void)assetsCollectionViewControllerDidFinishSelection:(QBAssetsCollectionViewController *)assetsCollectionViewController; - -@end - -@interface QBAssetsCollectionViewController : UICollectionViewController - -@property (nonatomic, weak) QBImagePickerController *imagePickerController; - -@property (nonatomic, weak) id delegate; -@property (nonatomic, strong) ALAssetsGroup *assetsGroup; -@property (nonatomic, assign) QBImagePickerControllerFilterType filterType; -@property (nonatomic, assign) BOOL allowsMultipleSelection; -@property (nonatomic, assign) NSUInteger minimumNumberOfSelection; -@property (nonatomic, assign) NSUInteger maximumNumberOfSelection; - -- (void)selectAssetHavingURL:(NSURL *)URL; - -@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionViewController.m b/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionViewController.m deleted file mode 100755 index 58ae05ca8..000000000 --- a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionViewController.m +++ /dev/null @@ -1,339 +0,0 @@ -// -// QBAssetsCollectionViewController.m -// QBImagePickerController -// -// Created by Tanaka Katsuma on 2013/12/31. -// Copyright (c) 2013年 Katsuma Tanaka. All rights reserved. -// - -#import "QBAssetsCollectionViewController.h" - -// Views -#import "QBAssetsCollectionViewCell.h" -#import "QBAssetsCollectionFooterView.h" - -@interface QBAssetsCollectionViewController () - -@property (nonatomic, strong) NSMutableArray *assets; - -@property (nonatomic, assign) NSUInteger numberOfAssets; -@property (nonatomic, assign) NSUInteger numberOfPhotos; -@property (nonatomic, assign) NSUInteger numberOfVideos; - -@property (nonatomic, assign) BOOL disableScrollToBottom, appearToShow; - -@end - -@implementation QBAssetsCollectionViewController - -- (instancetype)initWithCollectionViewLayout:(UICollectionViewLayout *)layout -{ - self = [super initWithCollectionViewLayout:layout]; - - if (self) { - // View settings - self.collectionView.backgroundColor = [UIColor whiteColor]; - - // Register cell class - [self.collectionView registerClass:[QBAssetsCollectionViewCell class] - forCellWithReuseIdentifier:@"AssetsCell"]; - [self.collectionView registerClass:[QBAssetsCollectionFooterView class] - forSupplementaryViewOfKind:UICollectionElementKindSectionFooter - withReuseIdentifier:@"FooterView"]; - } - - return self; -} - -- (void)viewWillAppear:(BOOL)animated -{ - [super viewWillAppear:animated]; - // Validation - if (self.allowsMultipleSelection) { - self.navigationItem.rightBarButtonItem.enabled = [self validateNumberOfSelections:self.imagePickerController.selectedAssetURLs.count]; - } - _appearToShow = YES; -} - -- (void)viewWillDisappear:(BOOL)animated -{ - [super viewWillDisappear:animated]; - - self.disableScrollToBottom = YES; -} - -- (void)viewDidDisappear:(BOOL)animated -{ - [super viewDidDisappear:animated]; - - self.disableScrollToBottom = NO; -} - -- (void)viewDidLayoutSubviews{ - [super viewDidLayoutSubviews]; - if (_appearToShow) { - [self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:self.numberOfAssets-1 inSection:0] atScrollPosition:UICollectionViewScrollPositionTop animated:NO]; - _appearToShow = NO; - } -} - - -#pragma mark - Accessors - -- (void)setFilterType:(QBImagePickerControllerFilterType)filterType -{ - _filterType = filterType; - - // Set assets filter - [self.assetsGroup setAssetsFilter:ALAssetsFilterFromQBImagePickerControllerFilterType(self.filterType)]; -} - -- (void)setAssetsGroup:(ALAssetsGroup *)assetsGroup -{ - _assetsGroup = assetsGroup; - - // Set title - self.title = [self.assetsGroup valueForProperty:ALAssetsGroupPropertyName]; - - // Set assets filter - [self.assetsGroup setAssetsFilter:ALAssetsFilterFromQBImagePickerControllerFilterType(self.filterType)]; - - // Load assets - NSMutableArray *assets = [NSMutableArray array]; - __block NSUInteger numberOfAssets = 0; - __block NSUInteger numberOfPhotos = 0; - __block NSUInteger numberOfVideos = 0; - - [self.assetsGroup enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) { - if (result) { - numberOfAssets++; - - NSString *type = [result valueForProperty:ALAssetPropertyType]; - if ([type isEqualToString:ALAssetTypePhoto]) numberOfPhotos++; - else if ([type isEqualToString:ALAssetTypeVideo]) numberOfVideos++; - - [assets addObject:result]; - } - }]; - - self.assets = assets; - self.numberOfAssets = numberOfAssets; - self.numberOfPhotos = numberOfPhotos; - self.numberOfVideos = numberOfVideos; - - // Update view - [self.collectionView reloadData]; -} - -- (void)setAllowsMultipleSelection:(BOOL)allowsMultipleSelection -{ - self.collectionView.allowsMultipleSelection = allowsMultipleSelection; - - // Show/hide done button - if (allowsMultipleSelection) { - UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(done:)]; - [self.navigationItem setRightBarButtonItem:doneButton animated:NO]; - } else { - [self.navigationItem setRightBarButtonItem:nil animated:NO]; - } -} - -- (BOOL)allowsMultipleSelection -{ - return self.collectionView.allowsMultipleSelection; -} - - -#pragma mark - Actions - -- (void)done:(id)sender -{ - // Delegate - if (self.delegate && [self.delegate respondsToSelector:@selector(assetsCollectionViewControllerDidFinishSelection:)]) { - [self.delegate assetsCollectionViewControllerDidFinishSelection:self]; - } -} - - -#pragma mark - Managing Selection - -- (void)selectAssetHavingURL:(NSURL *)URL -{ - for (NSInteger i = 0; i < self.assets.count; i++) { - ALAsset *asset = self.assets[i]; - NSURL *assetURL = [asset valueForProperty:ALAssetPropertyAssetURL]; - - if ([assetURL isEqual:URL]) { - NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0]; - [self.collectionView selectItemAtIndexPath:indexPath animated:NO scrollPosition:UICollectionViewScrollPositionNone]; - - return; - } - } -} - - -#pragma mark - Validating Selections - -- (BOOL)validateNumberOfSelections:(NSUInteger)numberOfSelections -{ - NSUInteger minimumNumberOfSelection = MAX(1, self.minimumNumberOfSelection); - BOOL qualifiesMinimumNumberOfSelection = (numberOfSelections >= minimumNumberOfSelection); - - BOOL qualifiesMaximumNumberOfSelection = YES; - if (minimumNumberOfSelection <= self.maximumNumberOfSelection) { - qualifiesMaximumNumberOfSelection = (numberOfSelections <= self.maximumNumberOfSelection); - } - - return (qualifiesMinimumNumberOfSelection && qualifiesMaximumNumberOfSelection); -} - -- (BOOL)validateMaximumNumberOfSelections:(NSUInteger)numberOfSelections -{ - NSUInteger minimumNumberOfSelection = MAX(1, self.minimumNumberOfSelection); - - if (minimumNumberOfSelection <= self.maximumNumberOfSelection) { - if (numberOfSelections > self.maximumNumberOfSelection) { - kTipAlert(@"最多只可选择%lu张照片", (unsigned long)self.maximumNumberOfSelection); - } - return (numberOfSelections <= self.maximumNumberOfSelection); - } - - return YES; -} - - -#pragma mark - UICollectionViewDataSource - -- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView -{ - return 1; -} - -- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section -{ - return self.numberOfAssets; -} - -- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath -{ - QBAssetsCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"AssetsCell" forIndexPath:indexPath]; - cell.showsOverlayViewWhenSelected = self.allowsMultipleSelection; - - ALAsset *asset = self.assets[indexPath.row]; - cell.asset = asset; - - return cell; -} - -- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section -{ - return CGSizeMake(collectionView.bounds.size.width, 46.0); -} - -- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath -{ - if (kind == UICollectionElementKindSectionFooter) { - QBAssetsCollectionFooterView *footerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter - withReuseIdentifier:@"FooterView" - forIndexPath:indexPath]; - - switch (self.filterType) { - case QBImagePickerControllerFilterTypeNone:{ - NSString *format; - if (self.numberOfPhotos == 1) { - if (self.numberOfVideos == 1) { - format = @"format_photo_and_video"; - } else { - format = @"format_photo_and_videos"; - } - } else if (self.numberOfVideos == 1) { - format = @"format_photos_and_video"; - } else { - format = @"format_photos_and_videos"; - } - footerView.textLabel.text = [NSString stringWithFormat:NSLocalizedStringFromTable(format, - @"QBImagePickerController", - nil), - self.numberOfPhotos, - self.numberOfVideos - ]; - break; - } - - case QBImagePickerControllerFilterTypePhotos:{ - NSString *format = (self.numberOfPhotos == 1) ? @"format_photo" : @"format_photos"; - footerView.textLabel.text = [NSString stringWithFormat:NSLocalizedStringFromTable(format, - @"QBImagePickerController", - nil), - self.numberOfPhotos - ]; - break; - } - - case QBImagePickerControllerFilterTypeVideos:{ - NSString *format = (self.numberOfVideos == 1) ? @"format_video" : @"format_videos"; - footerView.textLabel.text = [NSString stringWithFormat:NSLocalizedStringFromTable(format, - @"QBImagePickerController", - nil), - self.numberOfVideos - ]; - break; - } - } - - return footerView; - } - - return nil; -} - - -#pragma mark - UICollectionViewDelegateFlowLayout - -- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath -{ - return CGSizeMake(77.5, 77.5); -} - -- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section -{ - return UIEdgeInsetsMake(2, 2, 2, 2); -} - -- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath -{ - return [self validateMaximumNumberOfSelections:(self.imagePickerController.selectedAssetURLs.count + 1)]; -} - -- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath -{ - ALAsset *asset = self.assets[indexPath.row]; - - // Validation - if (self.allowsMultipleSelection) { - self.navigationItem.rightBarButtonItem.enabled = [self validateNumberOfSelections:(self.imagePickerController.selectedAssetURLs.count + 1)]; - } - - // Delegate - if (self.delegate && [self.delegate respondsToSelector:@selector(assetsCollectionViewController:didSelectAsset:)]) { - [self.delegate assetsCollectionViewController:self didSelectAsset:asset]; - } -} - -- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath -{ - ALAsset *asset = self.assets[indexPath.row]; - - // Validation - if (self.allowsMultipleSelection) { - self.navigationItem.rightBarButtonItem.enabled = [self validateNumberOfSelections:(self.imagePickerController.selectedAssetURLs.count - 1)]; - } - - // Delegate - if (self.delegate && [self.delegate respondsToSelector:@selector(assetsCollectionViewController:didDeselectAsset:)]) { - [self.delegate assetsCollectionViewController:self didDeselectAsset:asset]; - } -} - -@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionViewLayout.h b/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionViewLayout.h deleted file mode 100755 index f75811e81..000000000 --- a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionViewLayout.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// QBAssetsCollectionViewLayout.h -// QBImagePickerController -// -// Created by Tanaka Katsuma on 2013/12/31. -// Copyright (c) 2013年 Katsuma Tanaka. All rights reserved. -// - -#import - -@interface QBAssetsCollectionViewLayout : UICollectionViewFlowLayout - -+ (instancetype)layout; - -@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionViewLayout.m b/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionViewLayout.m deleted file mode 100755 index 4d6f4524c..000000000 --- a/Coding_iOS/Vendor/QBImagePickerController/QBAssetsCollectionViewLayout.m +++ /dev/null @@ -1,30 +0,0 @@ -// -// QBAssetsCollectionViewLayout.m -// QBImagePickerController -// -// Created by Tanaka Katsuma on 2013/12/31. -// Copyright (c) 2013年 Katsuma Tanaka. All rights reserved. -// - -#import "QBAssetsCollectionViewLayout.h" - -@implementation QBAssetsCollectionViewLayout - -+ (instancetype)layout -{ - return [[self alloc] init]; -} - -- (instancetype)init -{ - self = [super init]; - - if (self) { - self.minimumLineSpacing = 2.0; - self.minimumInteritemSpacing = 2.0; - } - - return self; -} - -@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBAlbumCell.h b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBAlbumCell.h new file mode 100644 index 000000000..14e5c8871 --- /dev/null +++ b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBAlbumCell.h @@ -0,0 +1,21 @@ +// +// QBAlbumCell.h +// QBImagePicker +// +// Created by Katsuma Tanaka on 2015/04/03. +// Copyright (c) 2015 Katsuma Tanaka. All rights reserved. +// + +#import + +@interface QBAlbumCell : UITableViewCell + +@property (weak, nonatomic) IBOutlet UIImageView *imageView1; +@property (weak, nonatomic) IBOutlet UIImageView *imageView2; +@property (weak, nonatomic) IBOutlet UIImageView *imageView3; +@property (weak, nonatomic) IBOutlet UILabel *titleLabel; +@property (weak, nonatomic) IBOutlet UILabel *countLabel; + +@property (nonatomic, assign) CGFloat borderWidth; + +@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBAlbumCell.m b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBAlbumCell.m new file mode 100644 index 000000000..59750fab8 --- /dev/null +++ b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBAlbumCell.m @@ -0,0 +1,27 @@ +// +// QBAlbumCell.m +// QBImagePicker +// +// Created by Katsuma Tanaka on 2015/04/03. +// Copyright (c) 2015 Katsuma Tanaka. All rights reserved. +// + +#import "QBAlbumCell.h" + +@implementation QBAlbumCell + +- (void)setBorderWidth:(CGFloat)borderWidth +{ + _borderWidth = borderWidth; + + self.imageView1.layer.borderColor = [[UIColor whiteColor] CGColor]; + self.imageView1.layer.borderWidth = borderWidth; + + self.imageView2.layer.borderColor = [[UIColor whiteColor] CGColor]; + self.imageView2.layer.borderWidth = borderWidth; + + self.imageView3.layer.borderColor = [[UIColor whiteColor] CGColor]; + self.imageView3.layer.borderWidth = borderWidth; +} + +@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBAlbumsViewController.h b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBAlbumsViewController.h new file mode 100644 index 000000000..43610b440 --- /dev/null +++ b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBAlbumsViewController.h @@ -0,0 +1,17 @@ +// +// QBAlbumsViewController.h +// QBImagePicker +// +// Created by Katsuma Tanaka on 2015/04/03. +// Copyright (c) 2015 Katsuma Tanaka. All rights reserved. +// + +#import + +@class QBImagePickerController; + +@interface QBAlbumsViewController : UITableViewController + +@property (nonatomic, weak) QBImagePickerController *imagePickerController; + +@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBAlbumsViewController.m b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBAlbumsViewController.m new file mode 100644 index 000000000..413d17e07 --- /dev/null +++ b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBAlbumsViewController.m @@ -0,0 +1,393 @@ +// +// QBAlbumsViewController.m +// QBImagePicker +// +// Created by Katsuma Tanaka on 2015/04/03. +// Copyright (c) 2015 Katsuma Tanaka. All rights reserved. +// + +#import "QBAlbumsViewController.h" +#import + +// Views +#import "QBAlbumCell.h" + +// ViewControllers +#import "QBImagePickerController.h" +#import "QBAssetsViewController.h" + +static CGSize CGSizeScale(CGSize size, CGFloat scale) { + return CGSizeMake(size.width * scale, size.height * scale); +} + +@interface QBImagePickerController (Private) + +@property (nonatomic, strong) NSBundle *assetBundle; + +@end + +@interface QBAlbumsViewController () + +@property (nonatomic, strong) IBOutlet UIBarButtonItem *doneButton; + +@property (nonatomic, copy) NSArray *fetchResults; +@property (nonatomic, copy) NSArray *assetCollections; + +@end + +@implementation QBAlbumsViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + [self setUpToolbarItems]; + + // Fetch user albums and smart albums + PHFetchResult *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAny options:nil]; + PHFetchResult *userAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAny options:nil]; + self.fetchResults = @[smartAlbums, userAlbums]; + + [self updateAssetCollections]; + + // Register observer + [[PHPhotoLibrary sharedPhotoLibrary] registerChangeObserver:self]; +} + +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + + // Configure navigation item + self.navigationItem.title = NSLocalizedStringFromTableInBundle(@"albums.title", @"QBImagePicker", self.imagePickerController.assetBundle, nil); + self.navigationItem.prompt = self.imagePickerController.prompt; + + // Show/hide 'Done' button + if (self.imagePickerController.allowsMultipleSelection) { + [self.navigationItem setRightBarButtonItem:self.doneButton animated:NO]; + } else { + [self.navigationItem setRightBarButtonItem:nil animated:NO]; + } + + [self updateControlState]; + [self updateSelectionInfo]; +} + +- (void)dealloc +{ + // Deregister observer + [[PHPhotoLibrary sharedPhotoLibrary] unregisterChangeObserver:self]; +} + + +#pragma mark - Storyboard + +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender +{ + QBAssetsViewController *assetsViewController = segue.destinationViewController; + assetsViewController.imagePickerController = self.imagePickerController; + assetsViewController.assetCollection = self.assetCollections[self.tableView.indexPathForSelectedRow.row]; +} + + +#pragma mark - Actions + +- (IBAction)cancel:(id)sender +{ + if ([self.imagePickerController.delegate respondsToSelector:@selector(qb_imagePickerControllerDidCancel:)]) { + [self.imagePickerController.delegate qb_imagePickerControllerDidCancel:self.imagePickerController]; + } +} + +- (IBAction)done:(id)sender +{ + if ([self.imagePickerController.delegate respondsToSelector:@selector(qb_imagePickerController:didFinishPickingAssets:)]) { + [self.imagePickerController.delegate qb_imagePickerController:self.imagePickerController + didFinishPickingAssets:self.imagePickerController.selectedAssets.array]; + } +} + + +#pragma mark - Toolbar + +- (void)setUpToolbarItems +{ + // Space + UIBarButtonItem *leftSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:NULL]; + UIBarButtonItem *rightSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:NULL]; + + // Info label + NSDictionary *attributes = @{ NSForegroundColorAttributeName: [UIColor blackColor] }; + UIBarButtonItem *infoButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:NULL]; + infoButtonItem.enabled = NO; + [infoButtonItem setTitleTextAttributes:attributes forState:UIControlStateNormal]; + [infoButtonItem setTitleTextAttributes:attributes forState:UIControlStateDisabled]; + + self.toolbarItems = @[leftSpace, infoButtonItem, rightSpace]; +} + +- (void)updateSelectionInfo +{ + NSMutableOrderedSet *selectedAssets = self.imagePickerController.selectedAssets; + + if (selectedAssets.count > 0) { + NSBundle *bundle = self.imagePickerController.assetBundle; + NSString *format; + if (selectedAssets.count > 1) { + format = NSLocalizedStringFromTableInBundle(@"assets.toolbar.items-selected", @"QBImagePicker", bundle, nil); + } else { + format = NSLocalizedStringFromTableInBundle(@"assets.toolbar.item-selected", @"QBImagePicker", bundle, nil); + } + + NSString *title = [NSString stringWithFormat:format, selectedAssets.count]; + [(UIBarButtonItem *)self.toolbarItems[1] setTitle:title]; + } else { + [(UIBarButtonItem *)self.toolbarItems[1] setTitle:@""]; + } +} + + +#pragma mark - Fetching Asset Collections + +- (void)updateAssetCollections +{ + // Filter albums + NSArray *assetCollectionSubtypes = self.imagePickerController.assetCollectionSubtypes; + NSMutableDictionary *smartAlbums = [NSMutableDictionary dictionaryWithCapacity:assetCollectionSubtypes.count]; + NSMutableArray *userAlbums = [NSMutableArray array]; + + for (PHFetchResult *fetchResult in self.fetchResults) { + [fetchResult enumerateObjectsUsingBlock:^(PHAssetCollection *assetCollection, NSUInteger index, BOOL *stop) { + PHAssetCollectionSubtype subtype = assetCollection.assetCollectionSubtype; + + if (subtype == PHAssetCollectionSubtypeAlbumRegular) { + [userAlbums addObject:assetCollection]; + } else if ([assetCollectionSubtypes containsObject:@(subtype)]) { + if (!smartAlbums[@(subtype)]) { + smartAlbums[@(subtype)] = [NSMutableArray array]; + } + [smartAlbums[@(subtype)] addObject:assetCollection]; + } + }]; + } + + NSMutableArray *assetCollections = [NSMutableArray array]; + + // Fetch smart albums + for (NSNumber *assetCollectionSubtype in assetCollectionSubtypes) { + NSArray *collections = smartAlbums[assetCollectionSubtype]; + + if (collections) { + [assetCollections addObjectsFromArray:collections]; + } + } + + // Fetch user albums + [userAlbums enumerateObjectsUsingBlock:^(PHAssetCollection *assetCollection, NSUInteger index, BOOL *stop) { + [assetCollections addObject:assetCollection]; + }]; + + self.assetCollections = assetCollections; +} + +- (UIImage *)placeholderImageWithSize:(CGSize)size +{ + UIGraphicsBeginImageContext(size); + CGContextRef context = UIGraphicsGetCurrentContext(); + + UIColor *backgroundColor = [UIColor colorWithRed:(239.0 / 255.0) green:(239.0 / 255.0) blue:(244.0 / 255.0) alpha:1.0]; + UIColor *iconColor = [UIColor colorWithRed:(179.0 / 255.0) green:(179.0 / 255.0) blue:(182.0 / 255.0) alpha:1.0]; + + // Background + CGContextSetFillColorWithColor(context, [backgroundColor CGColor]); + CGContextFillRect(context, CGRectMake(0, 0, size.width, size.height)); + + // Icon (back) + CGRect backIconRect = CGRectMake(size.width * (16.0 / 68.0), + size.height * (20.0 / 68.0), + size.width * (32.0 / 68.0), + size.height * (24.0 / 68.0)); + + CGContextSetFillColorWithColor(context, [iconColor CGColor]); + CGContextFillRect(context, backIconRect); + + CGContextSetFillColorWithColor(context, [backgroundColor CGColor]); + CGContextFillRect(context, CGRectInset(backIconRect, 1.0, 1.0)); + + // Icon (front) + CGRect frontIconRect = CGRectMake(size.width * (20.0 / 68.0), + size.height * (24.0 / 68.0), + size.width * (32.0 / 68.0), + size.height * (24.0 / 68.0)); + + CGContextSetFillColorWithColor(context, [backgroundColor CGColor]); + CGContextFillRect(context, CGRectInset(frontIconRect, -1.0, -1.0)); + + CGContextSetFillColorWithColor(context, [iconColor CGColor]); + CGContextFillRect(context, frontIconRect); + + CGContextSetFillColorWithColor(context, [backgroundColor CGColor]); + CGContextFillRect(context, CGRectInset(frontIconRect, 1.0, 1.0)); + + UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + return image; +} + + +#pragma mark - Checking for Selection Limit + +- (BOOL)isMinimumSelectionLimitFulfilled +{ + return (self.imagePickerController.minimumNumberOfSelection <= self.imagePickerController.selectedAssets.count); +} + +- (BOOL)isMaximumSelectionLimitReached +{ + NSUInteger minimumNumberOfSelection = MAX(1, self.imagePickerController.minimumNumberOfSelection); + + if (minimumNumberOfSelection <= self.imagePickerController.maximumNumberOfSelection) { + return (self.imagePickerController.maximumNumberOfSelection <= self.imagePickerController.selectedAssets.count); + } + + return NO; +} + +- (void)updateControlState +{ + self.doneButton.enabled = [self isMinimumSelectionLimitFulfilled]; +} + + +#pragma mark - UITableViewDataSource + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return self.assetCollections.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + QBAlbumCell *cell = [tableView dequeueReusableCellWithIdentifier:@"AlbumCell" forIndexPath:indexPath]; + cell.tag = indexPath.row; + cell.borderWidth = 1.0 / self.traitCollection.displayScale; + + // Thumbnail + PHAssetCollection *assetCollection = self.assetCollections[indexPath.row]; + + PHFetchOptions *options = [PHFetchOptions new]; + + switch (self.imagePickerController.mediaType) { + case QBImagePickerMediaTypeImage: + options.predicate = [NSPredicate predicateWithFormat:@"mediaType == %ld", PHAssetMediaTypeImage]; + break; + + case QBImagePickerMediaTypeVideo: + options.predicate = [NSPredicate predicateWithFormat:@"mediaType == %ld", PHAssetMediaTypeVideo]; + break; + + default: + break; + } + + PHFetchResult *fetchResult = [PHAsset fetchAssetsInAssetCollection:assetCollection options:options]; + PHImageManager *imageManager = [PHImageManager defaultManager]; + + if (fetchResult.count >= 3) { + cell.imageView3.hidden = NO; + + [imageManager requestImageForAsset:fetchResult[fetchResult.count - 3] + targetSize:CGSizeScale(cell.imageView3.frame.size, self.traitCollection.displayScale) + contentMode:PHImageContentModeAspectFill + options:nil + resultHandler:^(UIImage *result, NSDictionary *info) { + if (cell.tag == indexPath.row) { + cell.imageView3.image = result; + } + }]; + } else { + cell.imageView3.hidden = YES; + } + + if (fetchResult.count >= 2) { + cell.imageView2.hidden = NO; + + [imageManager requestImageForAsset:fetchResult[fetchResult.count - 2] + targetSize:CGSizeScale(cell.imageView2.frame.size, self.traitCollection.displayScale) + contentMode:PHImageContentModeAspectFill + options:nil + resultHandler:^(UIImage *result, NSDictionary *info) { + if (cell.tag == indexPath.row) { + cell.imageView2.image = result; + } + }]; + } else { + cell.imageView2.hidden = YES; + } + + if (fetchResult.count >= 1) { + [imageManager requestImageForAsset:fetchResult[fetchResult.count - 1] + targetSize:CGSizeScale(cell.imageView1.frame.size, self.traitCollection.displayScale) + contentMode:PHImageContentModeAspectFill + options:nil + resultHandler:^(UIImage *result, NSDictionary *info) { + if (cell.tag == indexPath.row) { + cell.imageView1.image = result; + } + }]; + } + + if (fetchResult.count == 0) { + cell.imageView3.hidden = NO; + cell.imageView2.hidden = NO; + + // Set placeholder image + UIImage *placeholderImage = [self placeholderImageWithSize:cell.imageView1.frame.size]; + cell.imageView1.image = placeholderImage; + cell.imageView2.image = placeholderImage; + cell.imageView3.image = placeholderImage; + } + + // Album title + cell.titleLabel.text = assetCollection.localizedTitle; + + // Number of photos + cell.countLabel.text = [NSString stringWithFormat:@"%lu", (long)fetchResult.count]; + + return cell; +} + + +#pragma mark - PHPhotoLibraryChangeObserver + +- (void)photoLibraryDidChange:(PHChange *)changeInstance +{ + dispatch_async(dispatch_get_main_queue(), ^{ + // Update fetch results + NSMutableArray *fetchResults = [self.fetchResults mutableCopy]; + + [self.fetchResults enumerateObjectsUsingBlock:^(PHFetchResult *fetchResult, NSUInteger index, BOOL *stop) { + PHFetchResultChangeDetails *changeDetails = [changeInstance changeDetailsForFetchResult:fetchResult]; + + if (changeDetails) { + [fetchResults replaceObjectAtIndex:index withObject:changeDetails.fetchResultAfterChanges]; + } + }]; + + if (![self.fetchResults isEqualToArray:fetchResults]) { + self.fetchResults = fetchResults; + + // Reload albums + [self updateAssetCollections]; + [self.tableView reloadData]; + } + }); +} + +@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBAssetCell.h b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBAssetCell.h new file mode 100644 index 000000000..cd2f4beb3 --- /dev/null +++ b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBAssetCell.h @@ -0,0 +1,20 @@ +// +// QBAssetCell.h +// QBImagePicker +// +// Created by Katsuma Tanaka on 2015/04/03. +// Copyright (c) 2015 Katsuma Tanaka. All rights reserved. +// + +#import + +@class QBVideoIndicatorView; + +@interface QBAssetCell : UICollectionViewCell + +@property (weak, nonatomic) IBOutlet UIImageView *imageView; +@property (weak, nonatomic) IBOutlet QBVideoIndicatorView *videoIndicatorView; + +@property (nonatomic, assign) BOOL showsOverlayViewWhenSelected; + +@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBAssetCell.m b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBAssetCell.m new file mode 100644 index 000000000..c62c5626d --- /dev/null +++ b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBAssetCell.m @@ -0,0 +1,27 @@ +// +// QBAssetCell.m +// QBImagePicker +// +// Created by Katsuma Tanaka on 2015/04/03. +// Copyright (c) 2015 Katsuma Tanaka. All rights reserved. +// + +#import "QBAssetCell.h" + +@interface QBAssetCell () + +@property (weak, nonatomic) IBOutlet UIView *overlayView; + +@end + +@implementation QBAssetCell + +- (void)setSelected:(BOOL)selected +{ + [super setSelected:selected]; + + // Show/hide overlay view + self.overlayView.hidden = !(selected && self.showsOverlayViewWhenSelected); +} + +@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBAssetsViewController.h b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBAssetsViewController.h new file mode 100644 index 000000000..ac1ff742a --- /dev/null +++ b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBAssetsViewController.h @@ -0,0 +1,19 @@ +// +// QBAssetsViewController.h +// QBImagePicker +// +// Created by Katsuma Tanaka on 2015/04/03. +// Copyright (c) 2015 Katsuma Tanaka. All rights reserved. +// + +#import + +@class QBImagePickerController; +@class PHAssetCollection; + +@interface QBAssetsViewController : UICollectionViewController + +@property (nonatomic, weak) QBImagePickerController *imagePickerController; +@property (nonatomic, strong) PHAssetCollection *assetCollection; + +@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBAssetsViewController.m b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBAssetsViewController.m new file mode 100644 index 000000000..f740e424e --- /dev/null +++ b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBAssetsViewController.m @@ -0,0 +1,660 @@ +// +// QBAssetsViewController.m +// QBImagePicker +// +// Created by Katsuma Tanaka on 2015/04/03. +// Copyright (c) 2015 Katsuma Tanaka. All rights reserved. +// + +#import "QBAssetsViewController.h" +#import + +// Views +#import "QBImagePickerController.h" +#import "QBAssetCell.h" +#import "QBVideoIndicatorView.h" + +static CGSize CGSizeScale(CGSize size, CGFloat scale) { + return CGSizeMake(size.width * scale, size.height * scale); +} + +@interface QBImagePickerController (Private) + +@property (nonatomic, strong) NSBundle *assetBundle; + +@end + +@implementation NSIndexSet (Convenience) + +- (NSArray *)qb_indexPathsFromIndexesWithSection:(NSUInteger)section +{ + NSMutableArray *indexPaths = [NSMutableArray arrayWithCapacity:self.count]; + [self enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { + [indexPaths addObject:[NSIndexPath indexPathForItem:idx inSection:section]]; + }]; + return indexPaths; +} + +@end + +@implementation UICollectionView (Convenience) + +- (NSArray *)qb_indexPathsForElementsInRect:(CGRect)rect +{ + NSArray *allLayoutAttributes = [self.collectionViewLayout layoutAttributesForElementsInRect:rect]; + if (allLayoutAttributes.count == 0) { return nil; } + + NSMutableArray *indexPaths = [NSMutableArray arrayWithCapacity:allLayoutAttributes.count]; + for (UICollectionViewLayoutAttributes *layoutAttributes in allLayoutAttributes) { + NSIndexPath *indexPath = layoutAttributes.indexPath; + [indexPaths addObject:indexPath]; + } + return indexPaths; +} + +@end + +@interface QBAssetsViewController () + +@property (nonatomic, strong) IBOutlet UIBarButtonItem *doneButton; + +@property (nonatomic, strong) PHFetchResult *fetchResult; + +@property (nonatomic, strong) PHCachingImageManager *imageManager; +@property (nonatomic, assign) CGRect previousPreheatRect; + +@property (nonatomic, assign) BOOL disableScrollToBottom; +@property (nonatomic, strong) NSIndexPath *lastSelectedItemIndexPath; + +@end + +@implementation QBAssetsViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + [self setUpToolbarItems]; + [self resetCachedAssets]; + + // Register observer + [[PHPhotoLibrary sharedPhotoLibrary] registerChangeObserver:self]; +} + +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + + // Configure navigation item + self.navigationItem.title = self.assetCollection.localizedTitle; + self.navigationItem.prompt = self.imagePickerController.prompt; + + // Configure collection view + self.collectionView.allowsMultipleSelection = self.imagePickerController.allowsMultipleSelection; + + // Show/hide 'Done' button + if (self.imagePickerController.allowsMultipleSelection) { + [self.navigationItem setRightBarButtonItem:self.doneButton animated:NO]; + } else { + [self.navigationItem setRightBarButtonItem:nil animated:NO]; + } + + [self updateDoneButtonState]; + [self updateSelectionInfo]; + [self.collectionView reloadData]; + + // Scroll to bottom + if (self.fetchResult.count > 0 && self.isMovingToParentViewController && !self.disableScrollToBottom) { + NSIndexPath *indexPath = [NSIndexPath indexPathForItem:(self.fetchResult.count - 1) inSection:0]; + [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionTop animated:NO]; + } +} + +- (void)viewWillDisappear:(BOOL)animated +{ + [super viewWillDisappear:animated]; + + self.disableScrollToBottom = YES; +} + +- (void)viewDidAppear:(BOOL)animated +{ + [super viewDidAppear:animated]; + + self.disableScrollToBottom = NO; + + [self updateCachedAssets]; +} + +- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator +{ + // Save indexPath for the last item + NSIndexPath *indexPath = [[self.collectionView indexPathsForVisibleItems] lastObject]; + + // Update layout + [self.collectionViewLayout invalidateLayout]; + + // Restore scroll position + [coordinator animateAlongsideTransition:nil completion:^(id context) { + [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionBottom animated:NO]; + }]; +} + +- (void)dealloc +{ + // Deregister observer + [[PHPhotoLibrary sharedPhotoLibrary] unregisterChangeObserver:self]; +} + + +#pragma mark - Accessors + +- (void)setAssetCollection:(PHAssetCollection *)assetCollection +{ + _assetCollection = assetCollection; + + [self updateFetchRequest]; + [self.collectionView reloadData]; +} + +- (PHCachingImageManager *)imageManager +{ + if (_imageManager == nil) { + _imageManager = [PHCachingImageManager new]; + } + + return _imageManager; +} + +- (BOOL)isAutoDeselectEnabled +{ + return (self.imagePickerController.maximumNumberOfSelection == 1 + && self.imagePickerController.maximumNumberOfSelection >= self.imagePickerController.minimumNumberOfSelection); +} + + +#pragma mark - Actions + +- (IBAction)done:(id)sender +{ + if ([self.imagePickerController.delegate respondsToSelector:@selector(qb_imagePickerController:didFinishPickingAssets:)]) { + [self.imagePickerController.delegate qb_imagePickerController:self.imagePickerController + didFinishPickingAssets:self.imagePickerController.selectedAssets.array]; + } +} + + +#pragma mark - Toolbar + +- (void)setUpToolbarItems +{ + // Space + UIBarButtonItem *leftSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:NULL]; + UIBarButtonItem *rightSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:NULL]; + + // Info label + NSDictionary *attributes = @{ NSForegroundColorAttributeName: [UIColor blackColor] }; + UIBarButtonItem *infoButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:NULL]; + infoButtonItem.enabled = NO; + [infoButtonItem setTitleTextAttributes:attributes forState:UIControlStateNormal]; + [infoButtonItem setTitleTextAttributes:attributes forState:UIControlStateDisabled]; + + self.toolbarItems = @[leftSpace, infoButtonItem, rightSpace]; +} + +- (void)updateSelectionInfo +{ + NSMutableOrderedSet *selectedAssets = self.imagePickerController.selectedAssets; + + if (selectedAssets.count > 0) { + NSBundle *bundle = self.imagePickerController.assetBundle; + NSString *format; + if (selectedAssets.count > 1) { + format = NSLocalizedStringFromTableInBundle(@"assets.toolbar.items-selected", @"QBImagePicker", bundle, nil); + } else { + format = NSLocalizedStringFromTableInBundle(@"assets.toolbar.item-selected", @"QBImagePicker", bundle, nil); + } + + NSString *title = [NSString stringWithFormat:format, selectedAssets.count]; + [(UIBarButtonItem *)self.toolbarItems[1] setTitle:title]; + } else { + [(UIBarButtonItem *)self.toolbarItems[1] setTitle:@""]; + } +} + + +#pragma mark - Fetching Assets + +- (void)updateFetchRequest +{ + if (self.assetCollection) { + PHFetchOptions *options = [PHFetchOptions new]; + + switch (self.imagePickerController.mediaType) { + case QBImagePickerMediaTypeImage: + options.predicate = [NSPredicate predicateWithFormat:@"mediaType == %ld", PHAssetMediaTypeImage]; + break; + + case QBImagePickerMediaTypeVideo: + options.predicate = [NSPredicate predicateWithFormat:@"mediaType == %ld", PHAssetMediaTypeVideo]; + break; + + default: + break; + } + + self.fetchResult = [PHAsset fetchAssetsInAssetCollection:self.assetCollection options:options]; + + if ([self isAutoDeselectEnabled] && self.imagePickerController.selectedAssets.count > 0) { + // Get index of previous selected asset + PHAsset *asset = [self.imagePickerController.selectedAssets firstObject]; + NSInteger assetIndex = [self.fetchResult indexOfObject:asset]; + self.lastSelectedItemIndexPath = [NSIndexPath indexPathForItem:assetIndex inSection:0]; + } + } else { + self.fetchResult = nil; + } +} + + +#pragma mark - Checking for Selection Limit + +- (BOOL)isMinimumSelectionLimitFulfilled +{ + return (self.imagePickerController.minimumNumberOfSelection <= self.imagePickerController.selectedAssets.count); +} + +- (BOOL)isMaximumSelectionLimitReached +{ + NSUInteger minimumNumberOfSelection = MAX(1, self.imagePickerController.minimumNumberOfSelection); + + if (minimumNumberOfSelection <= self.imagePickerController.maximumNumberOfSelection) { + return (self.imagePickerController.maximumNumberOfSelection <= self.imagePickerController.selectedAssets.count); + } + + return NO; +} + +- (void)updateDoneButtonState +{ + self.doneButton.enabled = [self isMinimumSelectionLimitFulfilled]; +} + + +#pragma mark - Asset Caching + +- (void)resetCachedAssets +{ + [self.imageManager stopCachingImagesForAllAssets]; + self.previousPreheatRect = CGRectZero; +} + +- (void)updateCachedAssets +{ + BOOL isViewVisible = [self isViewLoaded] && self.view.window != nil; + if (!isViewVisible) { return; } + + // The preheat window is twice the height of the visible rect + CGRect preheatRect = self.collectionView.bounds; + preheatRect = CGRectInset(preheatRect, 0.0, -0.5 * CGRectGetHeight(preheatRect)); + + // If scrolled by a "reasonable" amount... + CGFloat delta = ABS(CGRectGetMidY(preheatRect) - CGRectGetMidY(self.previousPreheatRect)); + + if (delta > CGRectGetHeight(self.collectionView.bounds) / 3.0) { + // Compute the assets to start caching and to stop caching + NSMutableArray *addedIndexPaths = [NSMutableArray array]; + NSMutableArray *removedIndexPaths = [NSMutableArray array]; + + [self computeDifferenceBetweenRect:self.previousPreheatRect andRect:preheatRect addedHandler:^(CGRect addedRect) { + NSArray *indexPaths = [self.collectionView qb_indexPathsForElementsInRect:addedRect]; + [addedIndexPaths addObjectsFromArray:indexPaths]; + } removedHandler:^(CGRect removedRect) { + NSArray *indexPaths = [self.collectionView qb_indexPathsForElementsInRect:removedRect]; + [removedIndexPaths addObjectsFromArray:indexPaths]; + }]; + + NSArray *assetsToStartCaching = [self assetsAtIndexPaths:addedIndexPaths]; + NSArray *assetsToStopCaching = [self assetsAtIndexPaths:removedIndexPaths]; + + CGSize itemSize = [(UICollectionViewFlowLayout *)self.collectionViewLayout itemSize]; + CGSize targetSize = CGSizeScale(itemSize, self.traitCollection.displayScale); + + [self.imageManager startCachingImagesForAssets:assetsToStartCaching + targetSize:targetSize + contentMode:PHImageContentModeAspectFill + options:nil]; + [self.imageManager stopCachingImagesForAssets:assetsToStopCaching + targetSize:targetSize + contentMode:PHImageContentModeAspectFill + options:nil]; + + self.previousPreheatRect = preheatRect; + } +} + +- (void)computeDifferenceBetweenRect:(CGRect)oldRect andRect:(CGRect)newRect addedHandler:(void (^)(CGRect addedRect))addedHandler removedHandler:(void (^)(CGRect removedRect))removedHandler +{ + if (CGRectIntersectsRect(newRect, oldRect)) { + CGFloat oldMaxY = CGRectGetMaxY(oldRect); + CGFloat oldMinY = CGRectGetMinY(oldRect); + CGFloat newMaxY = CGRectGetMaxY(newRect); + CGFloat newMinY = CGRectGetMinY(newRect); + + if (newMaxY > oldMaxY) { + CGRect rectToAdd = CGRectMake(newRect.origin.x, oldMaxY, newRect.size.width, (newMaxY - oldMaxY)); + addedHandler(rectToAdd); + } + if (oldMinY > newMinY) { + CGRect rectToAdd = CGRectMake(newRect.origin.x, newMinY, newRect.size.width, (oldMinY - newMinY)); + addedHandler(rectToAdd); + } + if (newMaxY < oldMaxY) { + CGRect rectToRemove = CGRectMake(newRect.origin.x, newMaxY, newRect.size.width, (oldMaxY - newMaxY)); + removedHandler(rectToRemove); + } + if (oldMinY < newMinY) { + CGRect rectToRemove = CGRectMake(newRect.origin.x, oldMinY, newRect.size.width, (newMinY - oldMinY)); + removedHandler(rectToRemove); + } + } else { + addedHandler(newRect); + removedHandler(oldRect); + } +} + +- (NSArray *)assetsAtIndexPaths:(NSArray *)indexPaths +{ + if (indexPaths.count == 0) { return nil; } + + NSMutableArray *assets = [NSMutableArray arrayWithCapacity:indexPaths.count]; + for (NSIndexPath *indexPath in indexPaths) { + if (indexPath.item < self.fetchResult.count) { + PHAsset *asset = self.fetchResult[indexPath.item]; + [assets addObject:asset]; + } + } + return assets; +} + + +#pragma mark - PHPhotoLibraryChangeObserver + +- (void)photoLibraryDidChange:(PHChange *)changeInstance +{ + dispatch_async(dispatch_get_main_queue(), ^{ + PHFetchResultChangeDetails *collectionChanges = [changeInstance changeDetailsForFetchResult:self.fetchResult]; + + if (collectionChanges) { + // Get the new fetch result + self.fetchResult = [collectionChanges fetchResultAfterChanges]; + + if (![collectionChanges hasIncrementalChanges] || [collectionChanges hasMoves]) { + // We need to reload all if the incremental diffs are not available + [self.collectionView reloadData]; + } else { + // If we have incremental diffs, tell the collection view to animate insertions and deletions + [self.collectionView performBatchUpdates:^{ + NSIndexSet *removedIndexes = [collectionChanges removedIndexes]; + if ([removedIndexes count]) { + [self.collectionView deleteItemsAtIndexPaths:[removedIndexes qb_indexPathsFromIndexesWithSection:0]]; + } + + NSIndexSet *insertedIndexes = [collectionChanges insertedIndexes]; + if ([insertedIndexes count]) { + [self.collectionView insertItemsAtIndexPaths:[insertedIndexes qb_indexPathsFromIndexesWithSection:0]]; + } + + NSIndexSet *changedIndexes = [collectionChanges changedIndexes]; + if ([changedIndexes count]) { + [self.collectionView reloadItemsAtIndexPaths:[changedIndexes qb_indexPathsFromIndexesWithSection:0]]; + } + } completion:NULL]; + } + + [self resetCachedAssets]; + } + }); +} + + +#pragma mark - UIScrollViewDelegate + +- (void)scrollViewDidScroll:(UIScrollView *)scrollView +{ + [self updateCachedAssets]; +} + + +#pragma mark - UICollectionViewDataSource + +- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView +{ + return 1; +} + +- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section +{ + return self.fetchResult.count; +} + +- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath +{ + QBAssetCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"AssetCell" forIndexPath:indexPath]; + cell.tag = indexPath.item; + cell.showsOverlayViewWhenSelected = self.imagePickerController.allowsMultipleSelection; + + // Image + PHAsset *asset = self.fetchResult[indexPath.item]; + CGSize itemSize = [(UICollectionViewFlowLayout *)collectionView.collectionViewLayout itemSize]; + CGSize targetSize = CGSizeScale(itemSize, self.traitCollection.displayScale); + + [self.imageManager requestImageForAsset:asset + targetSize:targetSize + contentMode:PHImageContentModeAspectFill + options:nil + resultHandler:^(UIImage *result, NSDictionary *info) { + if (cell.tag == indexPath.item) { + cell.imageView.image = result; + } + }]; + + // Video indicator + if (asset.mediaType == PHAssetMediaTypeVideo) { + cell.videoIndicatorView.hidden = NO; + + NSInteger minutes = (NSInteger)(asset.duration / 60.0); + NSInteger seconds = (NSInteger)ceil(asset.duration - 60.0 * (double)minutes); + cell.videoIndicatorView.timeLabel.text = [NSString stringWithFormat:@"%02ld:%02ld", (long)minutes, (long)seconds]; + + if (asset.mediaSubtypes & PHAssetMediaSubtypeVideoHighFrameRate) { + cell.videoIndicatorView.videoIcon.hidden = YES; + cell.videoIndicatorView.slomoIcon.hidden = NO; + } + else { + cell.videoIndicatorView.videoIcon.hidden = NO; + cell.videoIndicatorView.slomoIcon.hidden = YES; + } + } else { + cell.videoIndicatorView.hidden = YES; + } + + // Selection state + if ([self.imagePickerController.selectedAssets containsObject:asset]) { + [cell setSelected:YES]; + [collectionView selectItemAtIndexPath:indexPath animated:NO scrollPosition:UICollectionViewScrollPositionNone]; + } + + return cell; +} + +- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath +{ + if (kind == UICollectionElementKindSectionFooter) { + UICollectionReusableView *footerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter + withReuseIdentifier:@"FooterView" + forIndexPath:indexPath]; + + // Number of assets + UILabel *label = (UILabel *)[footerView viewWithTag:1]; + + NSBundle *bundle = self.imagePickerController.assetBundle; + NSUInteger numberOfPhotos = [self.fetchResult countOfAssetsWithMediaType:PHAssetMediaTypeImage]; + NSUInteger numberOfVideos = [self.fetchResult countOfAssetsWithMediaType:PHAssetMediaTypeVideo]; + + switch (self.imagePickerController.mediaType) { + case QBImagePickerMediaTypeAny: + { + NSString *format; + if (numberOfPhotos == 1) { + if (numberOfVideos == 1) { + format = NSLocalizedStringFromTableInBundle(@"assets.footer.photo-and-video", @"QBImagePicker", bundle, nil); + } else { + format = NSLocalizedStringFromTableInBundle(@"assets.footer.photo-and-videos", @"QBImagePicker", bundle, nil); + } + } else if (numberOfVideos == 1) { + format = NSLocalizedStringFromTableInBundle(@"assets.footer.photos-and-video", @"QBImagePicker", bundle, nil); + } else { + format = NSLocalizedStringFromTableInBundle(@"assets.footer.photos-and-videos", @"QBImagePicker", bundle, nil); + } + + label.text = [NSString stringWithFormat:format, numberOfPhotos, numberOfVideos]; + } + break; + + case QBImagePickerMediaTypeImage: + { + NSString *key = (numberOfPhotos == 1) ? @"assets.footer.photo" : @"assets.footer.photos"; + NSString *format = NSLocalizedStringFromTableInBundle(key, @"QBImagePicker", bundle, nil); + + label.text = [NSString stringWithFormat:format, numberOfPhotos]; + } + break; + + case QBImagePickerMediaTypeVideo: + { + NSString *key = (numberOfVideos == 1) ? @"assets.footer.video" : @"assets.footer.videos"; + NSString *format = NSLocalizedStringFromTableInBundle(key, @"QBImagePicker", bundle, nil); + + label.text = [NSString stringWithFormat:format, numberOfVideos]; + } + break; + } + + return footerView; + } + + return nil; +} + + +#pragma mark - UICollectionViewDelegate + +- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath +{ + if ([self.imagePickerController.delegate respondsToSelector:@selector(qb_imagePickerController:shouldSelectAsset:)]) { + PHAsset *asset = self.fetchResult[indexPath.item]; + return [self.imagePickerController.delegate qb_imagePickerController:self.imagePickerController shouldSelectAsset:asset]; + } + + if ([self isAutoDeselectEnabled]) { + return YES; + } + + return ![self isMaximumSelectionLimitReached]; +} + +- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath +{ + QBImagePickerController *imagePickerController = self.imagePickerController; + NSMutableOrderedSet *selectedAssets = imagePickerController.selectedAssets; + + PHAsset *asset = self.fetchResult[indexPath.item]; + + if (imagePickerController.allowsMultipleSelection) { + if ([self isAutoDeselectEnabled] && selectedAssets.count > 0) { + // Remove previous selected asset from set + [selectedAssets removeObjectAtIndex:0]; + + // Deselect previous selected asset + if (self.lastSelectedItemIndexPath) { + [collectionView deselectItemAtIndexPath:self.lastSelectedItemIndexPath animated:NO]; + } + } + + // Add asset to set + [selectedAssets addObject:asset]; + + self.lastSelectedItemIndexPath = indexPath; + + [self updateDoneButtonState]; + + if (imagePickerController.showsNumberOfSelectedAssets) { + [self updateSelectionInfo]; + + if (selectedAssets.count == 1) { + // Show toolbar + [self.navigationController setToolbarHidden:NO animated:YES]; + } + } + } else { + if ([imagePickerController.delegate respondsToSelector:@selector(qb_imagePickerController:didFinishPickingAssets:)]) { + [imagePickerController.delegate qb_imagePickerController:imagePickerController didFinishPickingAssets:@[asset]]; + } + } + + if ([imagePickerController.delegate respondsToSelector:@selector(qb_imagePickerController:didSelectAsset:)]) { + [imagePickerController.delegate qb_imagePickerController:imagePickerController didSelectAsset:asset]; + } +} + +- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath +{ + if (!self.imagePickerController.allowsMultipleSelection) { + return; + } + + QBImagePickerController *imagePickerController = self.imagePickerController; + NSMutableOrderedSet *selectedAssets = imagePickerController.selectedAssets; + + PHAsset *asset = self.fetchResult[indexPath.item]; + + // Remove asset from set + [selectedAssets removeObject:asset]; + + self.lastSelectedItemIndexPath = nil; + + [self updateDoneButtonState]; + + if (imagePickerController.showsNumberOfSelectedAssets) { + [self updateSelectionInfo]; + + if (selectedAssets.count == 0) { + // Hide toolbar + [self.navigationController setToolbarHidden:YES animated:YES]; + } + } + + if ([imagePickerController.delegate respondsToSelector:@selector(qb_imagePickerController:didDeselectAsset:)]) { + [imagePickerController.delegate qb_imagePickerController:imagePickerController didDeselectAsset:asset]; + } +} + + +#pragma mark - UICollectionViewDelegateFlowLayout + +- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath +{ + NSUInteger numberOfColumns; + if (UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation])) { + numberOfColumns = self.imagePickerController.numberOfColumnsInPortrait; + } else { + numberOfColumns = self.imagePickerController.numberOfColumnsInLandscape; + } + + CGFloat width = (CGRectGetWidth(self.view.frame) - 2.0 * (numberOfColumns - 1)) / numberOfColumns; + + return CGSizeMake(width, width); +} + +@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBCheckmarkView.h b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBCheckmarkView.h new file mode 100644 index 000000000..fd7b745f4 --- /dev/null +++ b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBCheckmarkView.h @@ -0,0 +1,21 @@ +// +// QBCheckmarkView.h +// QBImagePicker +// +// Created by Katsuma Tanaka on 2015/04/03. +// Copyright (c) 2015 Katsuma Tanaka. All rights reserved. +// + +#import + +IB_DESIGNABLE +@interface QBCheckmarkView : UIView + +@property (nonatomic, assign) IBInspectable CGFloat borderWidth; +@property (nonatomic, assign) IBInspectable CGFloat checkmarkLineWidth; + +@property (nonatomic, strong) IBInspectable UIColor *borderColor; +@property (nonatomic, strong) IBInspectable UIColor *bodyColor; +@property (nonatomic, strong) IBInspectable UIColor *checkmarkColor; + +@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBCheckmarkView.m b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBCheckmarkView.m new file mode 100644 index 000000000..aa25ac8c1 --- /dev/null +++ b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBCheckmarkView.m @@ -0,0 +1,54 @@ +// +// QBCheckmarkView.m +// QBImagePicker +// +// Created by Katsuma Tanaka on 2015/04/03. +// Copyright (c) 2015 Katsuma Tanaka. All rights reserved. +// + +#import "QBCheckmarkView.h" + +@implementation QBCheckmarkView + +- (void)awakeFromNib +{ + [super awakeFromNib]; + + // Set default values + self.borderWidth = 1.0; + self.checkmarkLineWidth = 1.2; + + self.borderColor = [UIColor whiteColor]; + self.bodyColor = [UIColor colorWithRed:(20.0 / 255.0) green:(111.0 / 255.0) blue:(223.0 / 255.0) alpha:1.0]; + self.checkmarkColor = [UIColor whiteColor]; + + // Set shadow + self.layer.shadowColor = [[UIColor grayColor] CGColor]; + self.layer.shadowOffset = CGSizeMake(0, 0); + self.layer.shadowOpacity = 0.6; + self.layer.shadowRadius = 2.0; +} + +- (void)drawRect:(CGRect)rect +{ + // Border + [self.borderColor setFill]; + [[UIBezierPath bezierPathWithOvalInRect:self.bounds] fill]; + + // Body + [self.bodyColor setFill]; + [[UIBezierPath bezierPathWithOvalInRect:CGRectInset(self.bounds, self.borderWidth, self.borderWidth)] fill]; + + // Checkmark + UIBezierPath *checkmarkPath = [UIBezierPath bezierPath]; + checkmarkPath.lineWidth = self.checkmarkLineWidth; + + [checkmarkPath moveToPoint:CGPointMake(CGRectGetWidth(self.bounds) * (6.0 / 24.0), CGRectGetHeight(self.bounds) * (12.0 / 24.0))]; + [checkmarkPath addLineToPoint:CGPointMake(CGRectGetWidth(self.bounds) * (10.0 / 24.0), CGRectGetHeight(self.bounds) * (16.0 / 24.0))]; + [checkmarkPath addLineToPoint:CGPointMake(CGRectGetWidth(self.bounds) * (18.0 / 24.0), CGRectGetHeight(self.bounds) * (8.0 / 24.0))]; + + [self.checkmarkColor setStroke]; + [checkmarkPath stroke]; +} + +@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBImagePicker.storyboard b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBImagePicker.storyboard new file mode 100644 index 000000000..e677b6165 --- /dev/null +++ b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBImagePicker.storyboard @@ -0,0 +1,297 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBImagePickerController.h b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBImagePickerController.h new file mode 100644 index 000000000..e7547e597 --- /dev/null +++ b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBImagePickerController.h @@ -0,0 +1,51 @@ +// +// QBImagePickerController.h +// QBImagePicker +// +// Created by Katsuma Tanaka on 2015/04/03. +// Copyright (c) 2015 Katsuma Tanaka. All rights reserved. +// + +#import +#import + +@class QBImagePickerController; + +@protocol QBImagePickerControllerDelegate + +@optional +- (void)qb_imagePickerController:(QBImagePickerController *)imagePickerController didFinishPickingAssets:(NSArray *)assets; +- (void)qb_imagePickerControllerDidCancel:(QBImagePickerController *)imagePickerController; + +- (BOOL)qb_imagePickerController:(QBImagePickerController *)imagePickerController shouldSelectAsset:(PHAsset *)asset; +- (void)qb_imagePickerController:(QBImagePickerController *)imagePickerController didSelectAsset:(PHAsset *)asset; +- (void)qb_imagePickerController:(QBImagePickerController *)imagePickerController didDeselectAsset:(PHAsset *)asset; + +@end + +typedef NS_ENUM(NSUInteger, QBImagePickerMediaType) { + QBImagePickerMediaTypeAny = 0, + QBImagePickerMediaTypeImage, + QBImagePickerMediaTypeVideo +}; + +@interface QBImagePickerController : UIViewController + +@property (nonatomic, weak) id delegate; + +@property (nonatomic, strong, readonly) NSMutableOrderedSet *selectedAssets; + +@property (nonatomic, copy) NSArray *assetCollectionSubtypes; +@property (nonatomic, assign) QBImagePickerMediaType mediaType; + +@property (nonatomic, assign) BOOL allowsMultipleSelection; +@property (nonatomic, assign) NSUInteger minimumNumberOfSelection; +@property (nonatomic, assign) NSUInteger maximumNumberOfSelection; + +@property (nonatomic, copy) NSString *prompt; +@property (nonatomic, assign) BOOL showsNumberOfSelectedAssets; + +@property (nonatomic, assign) NSUInteger numberOfColumnsInPortrait; +@property (nonatomic, assign) NSUInteger numberOfColumnsInLandscape; + +@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBImagePickerController.m b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBImagePickerController.m new file mode 100644 index 000000000..99577c54a --- /dev/null +++ b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBImagePickerController.m @@ -0,0 +1,77 @@ +// +// QBImagePickerController.m +// QBImagePicker +// +// Created by Katsuma Tanaka on 2015/04/03. +// Copyright (c) 2015 Katsuma Tanaka. All rights reserved. +// + +#import "QBImagePickerController.h" +#import + +// ViewControllers +#import "QBAlbumsViewController.h" + +@interface QBImagePickerController () + +@property (nonatomic, strong) UINavigationController *albumsNavigationController; + +@property (nonatomic, strong) NSBundle *assetBundle; + +@end + +@implementation QBImagePickerController + +- (instancetype)init +{ + self = [super init]; + + if (self) { + // Set default values + self.assetCollectionSubtypes = @[ + @(PHAssetCollectionSubtypeSmartAlbumUserLibrary), + @(PHAssetCollectionSubtypeAlbumMyPhotoStream), + @(PHAssetCollectionSubtypeSmartAlbumPanoramas), + @(PHAssetCollectionSubtypeSmartAlbumVideos), + @(PHAssetCollectionSubtypeSmartAlbumBursts) + ]; + self.minimumNumberOfSelection = 1; + self.numberOfColumnsInPortrait = 4; + self.numberOfColumnsInLandscape = 7; + + _selectedAssets = [NSMutableOrderedSet orderedSet]; + + // Get asset bundle + self.assetBundle = [NSBundle bundleForClass:[self class]]; + NSString *bundlePath = [self.assetBundle pathForResource:@"QBImagePicker" ofType:@"bundle"]; + if (bundlePath) { + self.assetBundle = [NSBundle bundleWithPath:bundlePath]; + } + + [self setUpAlbumsViewController]; + + // Set instance + QBAlbumsViewController *albumsViewController = (QBAlbumsViewController *)self.albumsNavigationController.topViewController; + albumsViewController.imagePickerController = self; + } + + return self; +} + +- (void)setUpAlbumsViewController +{ + // Add QBAlbumsViewController as a child + UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"QBImagePicker" bundle:self.assetBundle]; + UINavigationController *navigationController = [storyboard instantiateViewControllerWithIdentifier:@"QBAlbumsNavigationController"]; + + [self addChildViewController:navigationController]; + + navigationController.view.frame = self.view.bounds; + [self.view addSubview:navigationController.view]; + + [navigationController didMoveToParentViewController:self]; + + self.albumsNavigationController = navigationController; +} + +@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBSlomoIconView.h b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBSlomoIconView.h new file mode 100644 index 000000000..55d7ce2d2 --- /dev/null +++ b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBSlomoIconView.h @@ -0,0 +1,16 @@ +// +// QBSlomoIconView.h +// QBImagePicker +// +// Created by Julien Chaumond on 22/04/2015. +// Copyright (c) 2015 Katsuma Tanaka. All rights reserved. +// + +#import + +IB_DESIGNABLE +@interface QBSlomoIconView : UIView + +@property (nonatomic, strong) IBInspectable UIColor *iconColor; + +@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBSlomoIconView.m b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBSlomoIconView.m new file mode 100644 index 000000000..ba6e86706 --- /dev/null +++ b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBSlomoIconView.m @@ -0,0 +1,36 @@ +// +// QBSlomoIconView.m +// QBImagePicker +// +// Created by Julien Chaumond on 22/04/2015. +// Copyright (c) 2015 Katsuma Tanaka. All rights reserved. +// + +#import "QBSlomoIconView.h" + +@implementation QBSlomoIconView + +- (void)awakeFromNib +{ + [super awakeFromNib]; + + // Set default values + self.iconColor = [UIColor whiteColor]; +} + +- (void)drawRect:(CGRect)rect +{ + [self.iconColor setStroke]; + + CGFloat width = 2.2; + CGRect insetRect = CGRectInset(rect, width / 2, width / 2); + + // Draw dashed circle + UIBezierPath* circlePath = [UIBezierPath bezierPathWithOvalInRect:insetRect]; + circlePath.lineWidth = width; + CGFloat ovalPattern[] = {0.75, 0.75}; + [circlePath setLineDash:ovalPattern count:2 phase:0]; + [circlePath stroke]; +} + +@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBVideoIconView.h b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBVideoIconView.h new file mode 100644 index 000000000..d1cf6d45c --- /dev/null +++ b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBVideoIconView.h @@ -0,0 +1,16 @@ +// +// QBVideoIconView.h +// QBImagePicker +// +// Created by Katsuma Tanaka on 2015/04/04. +// Copyright (c) 2015 Katsuma Tanaka. All rights reserved. +// + +#import + +IB_DESIGNABLE +@interface QBVideoIconView : UIView + +@property (nonatomic, strong) IBInspectable UIColor *iconColor; + +@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBVideoIconView.m b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBVideoIconView.m new file mode 100644 index 000000000..898449529 --- /dev/null +++ b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBVideoIconView.m @@ -0,0 +1,38 @@ +// +// QBVideoIconView.m +// QBImagePicker +// +// Created by Katsuma Tanaka on 2015/04/04. +// Copyright (c) 2015 Katsuma Tanaka. All rights reserved. +// + +#import "QBVideoIconView.h" + +@implementation QBVideoIconView + +- (void)awakeFromNib +{ + [super awakeFromNib]; + + // Set default values + self.iconColor = [UIColor whiteColor]; +} + +- (void)drawRect:(CGRect)rect +{ + [self.iconColor setFill]; + + // Draw triangle + UIBezierPath *trianglePath = [UIBezierPath bezierPath]; + [trianglePath moveToPoint:CGPointMake(CGRectGetMaxX(self.bounds), CGRectGetMinY(self.bounds))]; + [trianglePath addLineToPoint:CGPointMake(CGRectGetMaxX(self.bounds), CGRectGetMaxY(self.bounds))]; + [trianglePath addLineToPoint:CGPointMake(CGRectGetMaxX(self.bounds) - CGRectGetMidY(self.bounds), CGRectGetMidY(self.bounds))]; + [trianglePath closePath]; + [trianglePath fill]; + + // Draw rounded square + UIBezierPath *squarePath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(CGRectGetMinX(self.bounds), CGRectGetMinY(self.bounds), CGRectGetWidth(self.bounds) - CGRectGetMidY(self.bounds) - 1.0, CGRectGetHeight(self.bounds)) cornerRadius:2.0]; + [squarePath fill]; +} + +@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBVideoIndicatorView.h b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBVideoIndicatorView.h new file mode 100644 index 000000000..80eeb0948 --- /dev/null +++ b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBVideoIndicatorView.h @@ -0,0 +1,21 @@ +// +// QBVideoIndicatorView.h +// QBImagePicker +// +// Created by Katsuma Tanaka on 2015/04/04. +// Copyright (c) 2015 Katsuma Tanaka. All rights reserved. +// + +#import + +#import "QBVideoIconView.h" +#import "QBSlomoIconView.h" + +@interface QBVideoIndicatorView : UIView + +@property (nonatomic, weak) IBOutlet UILabel *timeLabel; +@property (nonatomic, weak) IBOutlet QBVideoIconView *videoIcon; +@property (nonatomic, weak) IBOutlet QBSlomoIconView *slomoIcon; + + +@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBVideoIndicatorView.m b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBVideoIndicatorView.m new file mode 100644 index 000000000..fcdbf3269 --- /dev/null +++ b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/QBVideoIndicatorView.m @@ -0,0 +1,28 @@ +// +// QBVideoIndicatorView.m +// QBImagePicker +// +// Created by Katsuma Tanaka on 2015/04/04. +// Copyright (c) 2015 Katsuma Tanaka. All rights reserved. +// + +#import "QBVideoIndicatorView.h" + +@implementation QBVideoIndicatorView + +- (void)awakeFromNib +{ + [super awakeFromNib]; + + // Add gradient layer + CAGradientLayer *gradientLayer = [CAGradientLayer layer]; + gradientLayer.frame = self.bounds; + gradientLayer.colors = @[ + (__bridge id)[[UIColor clearColor] CGColor], + (__bridge id)[[UIColor blackColor] CGColor] + ]; + + [self.layer insertSublayer:gradientLayer atIndex:0]; +} + +@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/de.lproj/QBImagePicker.strings b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/de.lproj/QBImagePicker.strings new file mode 100644 index 000000000..97c4944f1 --- /dev/null +++ b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/de.lproj/QBImagePicker.strings @@ -0,0 +1,21 @@ +/* + QBImagePicker.strings + QBImagePicker + + Created by Katsuma Tanaka on 2015/04/03. + Copyright (c) 2015 Katsuma Tanaka. All rights reserved. +*/ + +"albums.title" = "Fotos"; + +"assets.footer.photo" = "%ld Foto"; +"assets.footer.photos" = "%ld Fotos"; +"assets.footer.video" = "%ld Video"; +"assets.footer.videos" = "%ld Videos"; +"assets.footer.photo-and-video" = "%ld Foto, %ld Video"; +"assets.footer.photos-and-video" = "%ld Fotos, %ld Video"; +"assets.footer.photo-and-videos" = "%ld Foto, %ld Videos"; +"assets.footer.photos-and-videos" = "%ld Fotos, %ld Videos"; + +"assets.toolbar.item-selected" = "%ld Element ausgewählt"; +"assets.toolbar.items-selected" = "%ld Elemente ausgewählt"; diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/en.lproj/QBImagePicker.strings b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/en.lproj/QBImagePicker.strings new file mode 100644 index 000000000..a6348ec58 --- /dev/null +++ b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/en.lproj/QBImagePicker.strings @@ -0,0 +1,21 @@ +/* + QBImagePicker.strings + QBImagePicker + + Created by Katsuma Tanaka on 2015/04/03. + Copyright (c) 2015 Katsuma Tanaka. All rights reserved. +*/ + +"albums.title" = "Photos"; + +"assets.footer.photo" = "%ld Photo"; +"assets.footer.photos" = "%ld Photos"; +"assets.footer.video" = "%ld Video"; +"assets.footer.videos" = "%ld Videos"; +"assets.footer.photo-and-video" = "%ld Photo, %ld Video"; +"assets.footer.photos-and-video" = "%ld Photos, %ld Video"; +"assets.footer.photo-and-videos" = "%ld Photo, %ld Videos"; +"assets.footer.photos-and-videos" = "%ld Photos, %ld Videos"; + +"assets.toolbar.item-selected" = "%ld Item Selected"; +"assets.toolbar.items-selected" = "%ld Items Selected"; diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/es.lproj/QBImagePicker.strings b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/es.lproj/QBImagePicker.strings new file mode 100644 index 000000000..40aa0cf56 --- /dev/null +++ b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/es.lproj/QBImagePicker.strings @@ -0,0 +1,21 @@ +/* + QBImagePicker.strings + QBImagePicker + + Created by Katsuma Tanaka on 2015/04/03. + Copyright (c) 2015 Katsuma Tanaka. All rights reserved. +*/ + +"albums.title" = "Fotos"; + +"assets.footer.photo" = "%ld Foto"; +"assets.footer.photos" = "%ld Fotos"; +"assets.footer.video" = "%ld Video"; +"assets.footer.videos" = "%ld Videos"; +"assets.footer.photo-and-video" = "%ld Foto, %ld Video"; +"assets.footer.photos-and-video" = "%ld Fotos, %ld Video"; +"assets.footer.photo-and-videos" = "%ld Foto, %ld Videos"; +"assets.footer.photos-and-videos" = "%ld Fotos, %ld Videos"; + +"assets.toolbar.item-selected" = "%ld items seleccionados"; +"assets.toolbar.items-selected" = "%ld items seleccionados"; diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/ja.lproj/QBImagePicker.strings b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/ja.lproj/QBImagePicker.strings new file mode 100644 index 000000000..642f5aa34 --- /dev/null +++ b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/ja.lproj/QBImagePicker.strings @@ -0,0 +1,21 @@ +/* + QBImagePicker.strings + QBImagePicker + + Created by Katsuma Tanaka on 2015/04/03. + Copyright (c) 2015 Katsuma Tanaka. All rights reserved. +*/ + +"albums.title" = "アルバム"; + +"assets.footer.photo" = "写真: %ld枚"; +"assets.footer.photos" = "写真: %ld枚"; +"assets.footer.video" = "ビデオ: %ld本"; +"assets.footer.videos" = "ビデオ: %ld本"; +"assets.footer.photo-and-video" = "写真: %ld枚、ビデオ%ld本"; +"assets.footer.photos-and-video" = "写真: %ld枚、ビデオ%ld本"; +"assets.footer.photo-and-videos" = "写真: %ld枚、ビデオ%ld本"; +"assets.footer.photos-and-videos" = "写真: %ld枚、ビデオ%ld本"; + +"assets.toolbar.item-selected" = "%ld 項目を選択中"; +"assets.toolbar.items-selected" = "%ld 項目を選択中"; diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/zh-Hans.lproj/QBImagePicker.strings b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/zh-Hans.lproj/QBImagePicker.strings new file mode 100644 index 000000000..c00d6d580 --- /dev/null +++ b/Coding_iOS/Vendor/QBImagePickerController/QBImagePicker/zh-Hans.lproj/QBImagePicker.strings @@ -0,0 +1,21 @@ +/* + QBImagePicker.strings + QBImagePicker + + Created by Katsuma Tanaka on 2015/04/03. + Copyright (c) 2015 Katsuma Tanaka. All rights reserved. +*/ + +"albums.title" = "照片"; + +"assets.footer.photo" = "共%ld张照片"; +"assets.footer.photos" = "共%ld张照片"; +"assets.footer.video" = "共%ld个视频"; +"assets.footer.videos" = "共%ld个视频"; +"assets.footer.photo-and-video" = "共%ld 张照片, %ld 个视频"; +"assets.footer.photos-and-video" = "共%ld 张照片, %ld 个视频"; +"assets.footer.photo-and-videos" = "共%ld 张照片, %ld 个视频"; +"assets.footer.photos-and-videos" = "共%ld 张照片, %ld 个视频"; + +"assets.toolbar.item-selected" = "选择了%ld项"; +"assets.toolbar.items-selected" = "选择了%ld项"; diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePickerController.h b/Coding_iOS/Vendor/QBImagePickerController/QBImagePickerController.h deleted file mode 100755 index 006bf6f95..000000000 --- a/Coding_iOS/Vendor/QBImagePickerController/QBImagePickerController.h +++ /dev/null @@ -1,47 +0,0 @@ -// -// QBImagePickerController.h -// QBImagePickerController -// -// Created by Tanaka Katsuma on 2013/12/30. -// Copyright (c) 2013年 Katsuma Tanaka. All rights reserved. -// - -#import -#import - -typedef NS_ENUM(NSUInteger, QBImagePickerControllerFilterType) { - QBImagePickerControllerFilterTypeNone, - QBImagePickerControllerFilterTypePhotos, - QBImagePickerControllerFilterTypeVideos -}; - -UIKIT_EXTERN ALAssetsFilter * ALAssetsFilterFromQBImagePickerControllerFilterType(QBImagePickerControllerFilterType type); - -@class QBImagePickerController; - -@protocol QBImagePickerControllerDelegate - -@optional -- (void)qb_imagePickerController:(QBImagePickerController *)imagePickerController didSelectAsset:(ALAsset *)asset; -- (void)qb_imagePickerController:(QBImagePickerController *)imagePickerController didSelectAssets:(NSArray *)assets; -- (void)qb_imagePickerControllerDidCancel:(QBImagePickerController *)imagePickerController; - -@end - -@interface QBImagePickerController : UITableViewController - -@property (nonatomic, strong, readonly) ALAssetsLibrary *assetsLibrary; -@property (nonatomic, copy, readonly) NSArray *assetsGroups; -@property (nonatomic, strong, readonly) NSMutableOrderedSet *selectedAssetURLs; - -@property (nonatomic, weak) id delegate; -@property (nonatomic, copy) NSArray *groupTypes; -@property (nonatomic, assign) QBImagePickerControllerFilterType filterType; -@property (nonatomic, assign) BOOL showsCancelButton; -@property (nonatomic, assign) BOOL allowsMultipleSelection; -@property (nonatomic, assign) NSUInteger minimumNumberOfSelection; -@property (nonatomic, assign) NSUInteger maximumNumberOfSelection; - -+ (BOOL)isAccessible; - -@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePickerController.m b/Coding_iOS/Vendor/QBImagePickerController/QBImagePickerController.m deleted file mode 100755 index afb994602..000000000 --- a/Coding_iOS/Vendor/QBImagePickerController/QBImagePickerController.m +++ /dev/null @@ -1,405 +0,0 @@ -// -// QBImagePickerController.m -// QBImagePickerController -// -// Created by Tanaka Katsuma on 2013/12/30. -// Copyright (c) 2013年 Katsuma Tanaka. All rights reserved. -// - -#import "QBImagePickerController.h" -#import - -// Views -#import "QBImagePickerGroupCell.h" -#import "QBAssetsCollectionViewLayout.h" - -// ViewControllers -#import "QBAssetsCollectionViewController.h" - -ALAssetsFilter * ALAssetsFilterFromQBImagePickerControllerFilterType(QBImagePickerControllerFilterType type) { - switch (type) { - case QBImagePickerControllerFilterTypeNone: - return [ALAssetsFilter allAssets]; - break; - - case QBImagePickerControllerFilterTypePhotos: - return [ALAssetsFilter allPhotos]; - break; - - case QBImagePickerControllerFilterTypeVideos: - return [ALAssetsFilter allVideos]; - break; - } -} - -@interface QBImagePickerController () - -@property (nonatomic, strong, readwrite) ALAssetsLibrary *assetsLibrary; -@property (nonatomic, copy, readwrite) NSArray *assetsGroups; -@property (nonatomic, strong, readwrite) NSMutableOrderedSet *selectedAssetURLs; -@property (nonatomic, assign) BOOL firstShow; - -@end - -@implementation QBImagePickerController - -+ (BOOL)isAccessible -{ - return ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary] && - [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeSavedPhotosAlbum]); -} - -- (instancetype)initWithStyle:(UITableViewStyle)style -{ - self = [super initWithStyle:UITableViewStylePlain]; - - if (self) { - [self setUpProperties]; - } - - return self; -} - -- (void)awakeFromNib -{ - [super awakeFromNib]; - - [self setUpProperties]; -} - -- (void)setUpProperties -{ - // Property settings - self.selectedAssetURLs = [NSMutableOrderedSet orderedSet]; - - self.groupTypes = @[ - @(ALAssetsGroupSavedPhotos), - @(ALAssetsGroupPhotoStream), - @(ALAssetsGroupAlbum) - ]; - self.filterType = QBImagePickerControllerFilterTypeNone; - self.showsCancelButton = YES; - - // View settings - self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; - - // Create assets library instance - ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init]; - self.assetsLibrary = assetsLibrary; - - // Register cell classes - [self.tableView registerClass:[QBImagePickerGroupCell class] forCellReuseIdentifier:@"GroupCell"]; -} - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - // View controller settings - self.title = NSLocalizedStringFromTable(@"title", @"QBImagePickerController", nil); - self.firstShow = YES; -} - -- (void)viewWillAppear:(BOOL)animated -{ - [super viewWillAppear:animated]; - - // Load assets groups - [self loadAssetsGroupsWithTypes:self.groupTypes - completion:^(NSArray *assetsGroups) { - self.assetsGroups = assetsGroups; - [self.tableView reloadData]; - if (self.firstShow) { - self.firstShow = NO; -// [self pushToCollectionVCWithIndex:0]; - } - }]; - - // Validation - self.navigationItem.rightBarButtonItem.enabled = [self validateNumberOfSelections:self.selectedAssetURLs.count]; -} - - -#pragma mark - Accessors - -- (void)setShowsCancelButton:(BOOL)showsCancelButton -{ - _showsCancelButton = showsCancelButton; - - // Show/hide cancel button - if (showsCancelButton) { - UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancel:)]; - [self.navigationItem setLeftBarButtonItem:cancelButton animated:NO]; - } else { - [self.navigationItem setLeftBarButtonItem:nil animated:NO]; - } -} - -- (void)setAllowsMultipleSelection:(BOOL)allowsMultipleSelection -{ - _allowsMultipleSelection = allowsMultipleSelection; - - // Show/hide done button - if (allowsMultipleSelection) { - UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(done:)]; - [self.navigationItem setRightBarButtonItem:doneButton animated:NO]; - } else { - [self.navigationItem setRightBarButtonItem:nil animated:NO]; - } -} - - -#pragma mark - Actions - -- (void)done:(id)sender -{ - [self passSelectedAssetsToDelegate]; -} - -- (void)cancel:(id)sender -{ - // Delegate - if (self.delegate && [self.delegate respondsToSelector:@selector(qb_imagePickerControllerDidCancel:)]) { - [self.delegate qb_imagePickerControllerDidCancel:self]; - } -} - - -#pragma mark - Validating Selections - -- (BOOL)validateNumberOfSelections:(NSUInteger)numberOfSelections -{ - // Check the number of selected assets - NSUInteger minimumNumberOfSelection = MAX(1, self.minimumNumberOfSelection); - BOOL qualifiesMinimumNumberOfSelection = (numberOfSelections >= minimumNumberOfSelection); - - BOOL qualifiesMaximumNumberOfSelection = YES; - if (minimumNumberOfSelection <= self.maximumNumberOfSelection) { - qualifiesMaximumNumberOfSelection = (numberOfSelections <= self.maximumNumberOfSelection); - } - - return (qualifiesMinimumNumberOfSelection && qualifiesMaximumNumberOfSelection); -} - - -#pragma mark - Managing Assets - -- (void)loadAssetsGroupsWithTypes:(NSArray *)types completion:(void (^)(NSArray *assetsGroups))completion -{ - __block NSMutableArray *assetsGroups = [NSMutableArray array]; - __block NSUInteger numberOfFinishedTypes = 0; - - for (NSNumber *type in types) { - __weak typeof(self) weakSelf = self; - - [self.assetsLibrary enumerateGroupsWithTypes:[type unsignedIntegerValue] - usingBlock:^(ALAssetsGroup *assetsGroup, BOOL *stop) { - if (assetsGroup) { - // Filter the assets group - [assetsGroup setAssetsFilter:ALAssetsFilterFromQBImagePickerControllerFilterType(weakSelf.filterType)]; - - if (assetsGroup.numberOfAssets > 0) { - // Add assets group - [assetsGroups addObject:assetsGroup]; - } - } else { - numberOfFinishedTypes++; - } - - // Check if the loading finished - if (numberOfFinishedTypes == types.count) { - // Sort assets groups - NSArray *sortedAssetsGroups = [self sortAssetsGroups:(NSArray *)assetsGroups typesOrder:types]; - - // Call completion block - if (completion) { - completion(sortedAssetsGroups); - } - } - } failureBlock:^(NSError *error) { - NSLog(@"Error: %@", [error localizedDescription]); - }]; - } -} - -- (NSArray *)sortAssetsGroups:(NSArray *)assetsGroups typesOrder:(NSArray *)typesOrder -{ - NSMutableArray *sortedAssetsGroups = [NSMutableArray array]; - - for (ALAssetsGroup *assetsGroup in assetsGroups) { - if (sortedAssetsGroups.count == 0) { - [sortedAssetsGroups addObject:assetsGroup]; - continue; - } - - ALAssetsGroupType assetsGroupType = [[assetsGroup valueForProperty:ALAssetsGroupPropertyType] unsignedIntegerValue]; - NSUInteger indexOfAssetsGroupType = [typesOrder indexOfObject:@(assetsGroupType)]; - - for (NSInteger i = 0; i <= sortedAssetsGroups.count; i++) { - if (i == sortedAssetsGroups.count) { - [sortedAssetsGroups addObject:assetsGroup]; - break; - } - - ALAssetsGroup *sortedAssetsGroup = sortedAssetsGroups[i]; - ALAssetsGroupType sortedAssetsGroupType = [[sortedAssetsGroup valueForProperty:ALAssetsGroupPropertyType] unsignedIntegerValue]; - NSUInteger indexOfSortedAssetsGroupType = [typesOrder indexOfObject:@(sortedAssetsGroupType)]; - - if (indexOfAssetsGroupType < indexOfSortedAssetsGroupType) { - [sortedAssetsGroups insertObject:assetsGroup atIndex:i]; - break; - } - } - } - - return [sortedAssetsGroups copy]; -} - -- (void)passSelectedAssetsToDelegate -{ - // Load assets from URLs - __block NSMutableArray *assets = [NSMutableArray array]; - __block NSUInteger tryCount = 0; - - for (NSURL *selectedAssetURL in self.selectedAssetURLs) { - __weak typeof(self) weakSelf = self; - - // Success block - void (^selectAsset)(ALAsset *) = ^(ALAsset *asset) { - if (asset) { - [assets addObject:asset]; - } - // Check if the loading finished - if (tryCount == weakSelf.selectedAssetURLs.count) { - DebugLog(@"照片查找失败张数:%lu", (long)(tryCount - assets.count)); - // Delegate - if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(qb_imagePickerController:didSelectAssets:)]) { - [weakSelf.delegate qb_imagePickerController:weakSelf didSelectAssets:[assets copy]]; - } - } - }; - - [self.assetsLibrary assetForURL:selectedAssetURL resultBlock:^(ALAsset *asset) { - if (asset) { - tryCount++; - selectAsset(asset); - }else{ - // Search in the Photo Stream Album - [weakSelf.assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupPhotoStream usingBlock:^(ALAssetsGroup *group, BOOL *stop) { - [group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stopG) { - if([result.defaultRepresentation.url isEqual:selectedAssetURL]) { - *stopG = YES; - *stop = YES; - tryCount++; - selectAsset(result); - }else if (index == 0){ - NSLog(@"找完了"); - tryCount++;//此处为查找失败 - selectAsset(nil); - } - }]; - } failureBlock:^(NSError *error) { - NSLog(@"Error: %@", [error localizedDescription]); - }]; - } - } failureBlock:^(NSError *error) { - NSLog(@"Error: %@", [error localizedDescription]); - }]; - } -} - - -#pragma mark - UITableViewDataSource - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView -{ - return 1; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section -{ - return self.assetsGroups.count; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath -{ - QBImagePickerGroupCell *cell = [tableView dequeueReusableCellWithIdentifier:@"GroupCell" forIndexPath:indexPath]; - - ALAssetsGroup *assetsGroup = self.assetsGroups[indexPath.row]; - cell.assetsGroup = assetsGroup; - - return cell; -} - - -#pragma mark - UITableViewDelegate - -- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath -{ - return 86.0; -} - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath -{ - [self pushToCollectionVCWithIndex:indexPath.row]; -} - -- (void)pushToCollectionVCWithIndex:(NSInteger)index{ - if (index >= 0 && index < self.assetsGroups.count) { - QBAssetsCollectionViewController *assetsCollectionViewController = [[QBAssetsCollectionViewController alloc] initWithCollectionViewLayout:[QBAssetsCollectionViewLayout layout]]; - assetsCollectionViewController.imagePickerController = self; - assetsCollectionViewController.filterType = self.filterType; - assetsCollectionViewController.allowsMultipleSelection = self.allowsMultipleSelection; - assetsCollectionViewController.minimumNumberOfSelection = self.minimumNumberOfSelection; - assetsCollectionViewController.maximumNumberOfSelection = self.maximumNumberOfSelection; - - ALAssetsGroup *assetsGroup = self.assetsGroups[index]; - assetsCollectionViewController.delegate = self; - assetsCollectionViewController.assetsGroup = assetsGroup; - - for (NSURL *assetURL in self.selectedAssetURLs) { - [assetsCollectionViewController selectAssetHavingURL:assetURL]; - } - - [self.navigationController pushViewController:assetsCollectionViewController animated:YES]; - } -} - - -#pragma mark - QBAssetsCollectionViewControllerDelegate - -- (void)assetsCollectionViewController:(QBAssetsCollectionViewController *)assetsCollectionViewController didSelectAsset:(ALAsset *)asset -{ - if (self.allowsMultipleSelection) { - // Add asset URL - NSURL *assetURL = [asset valueForProperty:ALAssetPropertyAssetURL]; - [self.selectedAssetURLs addObject:assetURL]; - - // Validation - self.navigationItem.rightBarButtonItem.enabled = [self validateNumberOfSelections:self.selectedAssetURLs.count]; - } else { - // Delegate - if (self.delegate && [self.delegate respondsToSelector:@selector(qb_imagePickerController:didSelectAsset:)]) { - [self.delegate qb_imagePickerController:self didSelectAsset:asset]; - } - } -} - -- (void)assetsCollectionViewController:(QBAssetsCollectionViewController *)assetsCollectionViewController didDeselectAsset:(ALAsset *)asset -{ - if (self.allowsMultipleSelection) { - // Remove asset URL - NSURL *assetURL = [asset valueForProperty:ALAssetPropertyAssetURL]; - [self.selectedAssetURLs removeObject:assetURL]; - - // Validation - self.navigationItem.rightBarButtonItem.enabled = [self validateNumberOfSelections:self.selectedAssetURLs.count]; - } -} - -- (void)assetsCollectionViewControllerDidFinishSelection:(QBAssetsCollectionViewController *)assetsCollectionViewController -{ - [self passSelectedAssetsToDelegate]; -} - -@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePickerController.strings b/Coding_iOS/Vendor/QBImagePickerController/QBImagePickerController.strings deleted file mode 100755 index dfc7cce41..000000000 --- a/Coding_iOS/Vendor/QBImagePickerController/QBImagePickerController.strings +++ /dev/null @@ -1,18 +0,0 @@ -/* - QBImagePickerController.strings - QBImagePickerControllerDemo - - Created by Tanaka Katsuma on 2014/01/01. - Copyright (c) 2014年 Katsuma Tanaka. All rights reserved. -*/ - -"title" = "照片"; - -"format_photo" = "共%ld张照片"; -"format_photos" = "共%ld张照片"; -"format_video" = "%共ld个视频"; -"format_videos" = "共%ld个视频"; -"format_photo_and_video" = "%共ld张照片, %ld个视频"; -"format_photos_and_video" = "%共ld张照片, %ld个视频"; -"format_photo_and_videos" = "%共ld张照片, %ld个视频"; -"format_photos_and_videos" = "%共ld张照片, %ld个视频"; diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePickerGroupCell.h b/Coding_iOS/Vendor/QBImagePickerController/QBImagePickerGroupCell.h deleted file mode 100755 index a6480ae4a..000000000 --- a/Coding_iOS/Vendor/QBImagePickerController/QBImagePickerGroupCell.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// QBImagePickerGroupCell.h -// QBImagePickerController -// -// Created by Tanaka Katsuma on 2013/12/30. -// Copyright (c) 2013年 Katsuma Tanaka. All rights reserved. -// - -#import -#import - -@interface QBImagePickerGroupCell : UITableViewCell - -@property (nonatomic, strong) ALAssetsGroup *assetsGroup; - -@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePickerGroupCell.m b/Coding_iOS/Vendor/QBImagePickerController/QBImagePickerGroupCell.m deleted file mode 100755 index c5bdac519..000000000 --- a/Coding_iOS/Vendor/QBImagePickerController/QBImagePickerGroupCell.m +++ /dev/null @@ -1,76 +0,0 @@ -// -// QBImagePickerGroupCell.m -// QBImagePickerController -// -// Created by Tanaka Katsuma on 2013/12/30. -// Copyright (c) 2013年 Katsuma Tanaka. All rights reserved. -// - -#import "QBImagePickerGroupCell.h" - -// Views -#import "QBImagePickerThumbnailView.h" - -@interface QBImagePickerGroupCell () - -@property (nonatomic, strong) QBImagePickerThumbnailView *thumbnailView; -@property (nonatomic, strong) UILabel *nameLabel; -@property (nonatomic, strong) UILabel *countLabel; - -@end - -@implementation QBImagePickerGroupCell - -- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier -{ - self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; - - if (self) { - // Cell settings - self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; - - // Create thumbnail view - QBImagePickerThumbnailView *thumbnailView = [[QBImagePickerThumbnailView alloc] initWithFrame:CGRectMake(8, 4, 70, 74)]; - thumbnailView.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin; - - [self.contentView addSubview:thumbnailView]; - self.thumbnailView = thumbnailView; - - // Create name label - UILabel *nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(8 + 70 + 18, 22, 180, 21)]; - nameLabel.font = [UIFont systemFontOfSize:17]; - nameLabel.textColor = [UIColor blackColor]; - nameLabel.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth; - - [self.contentView addSubview:nameLabel]; - self.nameLabel = nameLabel; - - // Create count label - UILabel *countLabel = [[UILabel alloc] initWithFrame:CGRectMake(8 + 70 + 18, 46, 180, 15)]; - countLabel.font = [UIFont systemFontOfSize:12]; - countLabel.textColor = [UIColor blackColor]; - countLabel.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth; - - [self.contentView addSubview:countLabel]; - self.countLabel = countLabel; - } - - return self; -} - - -#pragma mark - Accessors - -- (void)setAssetsGroup:(ALAssetsGroup *)assetsGroup -{ - _assetsGroup = assetsGroup; - - // Update thumbnail view - self.thumbnailView.assetsGroup = self.assetsGroup; - - // Update label - self.nameLabel.text = [self.assetsGroup valueForProperty:ALAssetsGroupPropertyName]; - self.countLabel.text = [NSString stringWithFormat:@"%ld", (long)self.assetsGroup.numberOfAssets]; -} - -@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePickerThumbnailView.h b/Coding_iOS/Vendor/QBImagePickerController/QBImagePickerThumbnailView.h deleted file mode 100755 index 2b5eeaa6c..000000000 --- a/Coding_iOS/Vendor/QBImagePickerController/QBImagePickerThumbnailView.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// QBImagePickerThumbnailView.h -// QBImagePickerController -// -// Created by Tanaka Katsuma on 2013/12/31. -// Copyright (c) 2013年 Katsuma Tanaka. All rights reserved. -// - -#import -#import - -@interface QBImagePickerThumbnailView : UIView - -@property (nonatomic, strong) ALAssetsGroup *assetsGroup; - -@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/QBImagePickerThumbnailView.m b/Coding_iOS/Vendor/QBImagePickerController/QBImagePickerThumbnailView.m deleted file mode 100755 index ea05a6cb0..000000000 --- a/Coding_iOS/Vendor/QBImagePickerController/QBImagePickerThumbnailView.m +++ /dev/null @@ -1,112 +0,0 @@ -// -// QBImagePickerThumbnailView.m -// QBImagePickerController -// -// Created by Tanaka Katsuma on 2013/12/31. -// Copyright (c) 2013年 Katsuma Tanaka. All rights reserved. -// - -#import "QBImagePickerThumbnailView.h" - -@interface QBImagePickerThumbnailView () - -@property (nonatomic, copy) NSArray *thumbnailImages; -@property (nonatomic, strong) UIImage *blankImage; - -@end - -@implementation QBImagePickerThumbnailView - -- (instancetype)initWithFrame:(CGRect)frame -{ - self = [super initWithFrame:frame]; - - if (self) { - self.backgroundColor = [UIColor clearColor]; - } - - return self; -} - -- (CGSize)sizeThatFits:(CGSize)size -{ - return CGSizeMake(70.0, 74.0); -} - -- (void)drawRect:(CGRect)rect -{ - [super drawRect:rect]; - - CGContextRef context = UIGraphicsGetCurrentContext(); - CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0); - - if (self.thumbnailImages.count == 3) { - UIImage *thumbnailImage = [self.thumbnailImages firstObject]; - - CGRect thumbnailImageRect = CGRectMake(4.0, 0, 62.0, 62.0); - CGContextFillRect(context, thumbnailImageRect); - [thumbnailImage drawInRect:CGRectInset(thumbnailImageRect, 0.5, 0.5)]; - } - if (self.thumbnailImages.count >= 2) { - UIImage *thumbnailImage = self.thumbnailImages[1]; - - CGRect thumbnailImageRect = CGRectMake(2.0, 2.0, 66.0, 66.0); - CGContextFillRect(context, thumbnailImageRect); - [thumbnailImage drawInRect:CGRectInset(thumbnailImageRect, 0.5, 0.5)]; - } - if (self.thumbnailImages.count >= 1) { - UIImage *thumbnailImage = [self.thumbnailImages lastObject]; - - CGRect thumbnailImageRect = CGRectMake(0, 4.0, 70.0, 70.0); - CGContextFillRect(context, thumbnailImageRect); - [thumbnailImage drawInRect:CGRectInset(thumbnailImageRect, 0.5, 0.5)]; - } -} - - -#pragma mark - Accessors - -- (void)setAssetsGroup:(ALAssetsGroup *)assetsGroup -{ - _assetsGroup = assetsGroup; - - // Extract three thumbnail images - NSInteger thumbnailImagesCount = MIN(3, assetsGroup.numberOfAssets); - NSIndexSet *indexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(assetsGroup.numberOfAssets-thumbnailImagesCount, thumbnailImagesCount)]; - NSMutableArray *thumbnailImages = [NSMutableArray array]; - [assetsGroup enumerateAssetsAtIndexes:indexes - options:0 - usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) { - if (result) { - CGImageRef thumbnailImageRef = [result thumbnail]; - - if (thumbnailImageRef) { - [thumbnailImages addObject:[UIImage imageWithCGImage:thumbnailImageRef]]; - } else { - [thumbnailImages addObject:[self blankImage]]; - } - } - }]; - self.thumbnailImages = [thumbnailImages copy]; - - [self setNeedsDisplay]; -} - -- (UIImage *)blankImage -{ - if (_blankImage == nil) { - CGSize size = CGSizeMake(100.0, 100.0); - UIGraphicsBeginImageContextWithOptions(size, NO, 0.0); - - [[UIColor colorWithWhite:(240.0 / 255.0) alpha:1.0] setFill]; - UIRectFill(CGRectMake(0, 0, size.width, size.height)); - - _blankImage = UIGraphicsGetImageFromCurrentImageContext(); - - UIGraphicsEndImageContext(); - } - - return _blankImage; -} - -@end diff --git a/Coding_iOS/Vendor/QBImagePickerController/README.md b/Coding_iOS/Vendor/QBImagePickerController/README.md new file mode 100755 index 000000000..d91d0ebbb --- /dev/null +++ b/Coding_iOS/Vendor/QBImagePickerController/README.md @@ -0,0 +1,175 @@ +# QBImagePicker + +[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) + +A clone of UIImagePickerController with multiple selection support. + +![screenshot01.png](screenshot01.png) +![screenshot02.png](screenshot02.png) + + + +## Features + +- Allows multiple selection of photos and videos +- Fast and memory-efficient scrolling +- Provides similar user interface to the built-in image picker +- Customizable (grid size, navigation message, etc.) +- Supports both portrait mode and landscape mode +- Compatible with iPhone 6/6Plus, and iPad + + + +## Requirements + +- Version `>= 3.0.0` : iOS 8 or later (Using PhotoKit) +- Version `< 3.0.0` : iOS 6 or later (Using AssetsLibrary) + + + +## Example + + QBImagePickerController *imagePickerController = [QBImagePickerController new]; + imagePickerController.delegate = self; + imagePickerController.allowsMultipleSelection = YES; + imagePickerController.maximumNumberOfSelection = 6; + imagePickerController.showsNumberOfSelectedAssets = YES; + + [self presentViewController:imagePickerController animated:YES completion:NULL]; + + + +## Installation + +### CocoaPods + +1. Add `pod "QBImagePickerController"` to Podfile +2. Run `pod install` +3. Add `#import ` to your code + + +### Carthage + +1. Add `github "questbeat/QBImagePicker"` to Cartfile +2. Run `carthage update` +3. Add `#import ` to your code + + + +## Usage + +### Basic + +1. Implement `QBImagePickerControllerDelegate` methods +2. Create `QBImagePickerController` object +3. Set `self` to the `delegate` property +4. Show the picker by using `presentViewController:animated:completion:` + + QBImagePickerController *imagePickerController = [QBImagePickerController new]; + imagePickerController.delegate = self; + + [self presentViewController:imagePickerController animated:YES completion:NULL]; + + +### Delegate Methods + +#### Getting the selected assets + +Implement `qb_imagePickerController:didFinishPickingAssets:` to get the assets selected by the user. +This method will be called when the user finishes picking assets. + + - (void)qb_imagePickerController:(QBImagePickerController *)imagePickerController didFinishPickingAssets:(NSArray *)assets { + for (PHAsset *asset in assets) { + // Do something with the asset + } + + [self dismissViewControllerAnimated:YES completion:NULL]; + } + + +#### Getting notified when the user cancels + +Implement `qb_imagePickerControllerDidCancel:` to get notified when the user hits "Cancel" button. + + - (void)qb_imagePickerControllerDidCancel:(QBImagePickerController *)imagePickerController { + [self dismissViewControllerAnimated:YES completion:NULL]; + } + + +#### Getting notified when the selection is changed + +You can handle the change of user's selection by implementing these methods. + + - (BOOL)qb_imagePickerController:(QBImagePickerController *)imagePickerController shouldSelectAsset:(PHAsset *)asset; + - (void)qb_imagePickerController:(QBImagePickerController *)imagePickerController didSelectAsset:(PHAsset *)asset; + - (void)qb_imagePickerController:(QBImagePickerController *)imagePickerController didDeselectAsset:(PHAsset *)asset; + + +### Customization + +#### Selection mode + +When `allowsMultipleSelection` is `YES`, the user can select multiple photos. +The default value is `NO`. + + imagePickerController.allowsMultipleSelection = YES; + +You can limit the number of selection by using `minimumNumberOfSelection` and `maximumNumberOfSelection` property. +The default value is `0`, which means the number of selection is unlimited. + + imagePickerController.minimumNumberOfSelection = 3; + imagePickerController.maximumNumberOfSelection = 6; + + +#### Specify the albums to be shown + +Use `assetCollectionSubtypes` property to specify the albums to be shown. +The code below shows the default value. + + imagePickerController.assetCollectionSubtypes = @[ + @(PHAssetCollectionSubtypeSmartAlbumUserLibrary), // Camera Roll + @(PHAssetCollectionSubtypeAlbumMyPhotoStream), // My Photo Stream + @(PHAssetCollectionSubtypeSmartAlbumPanoramas), // Panoramas + @(PHAssetCollectionSubtypeSmartAlbumVideos), // Videos + @(PHAssetCollectionSubtypeSmartAlbumBursts) // Bursts + ]; + +The albums will be ordered as you specified. +User's albums are always shown after the smart albums. + + +#### Specify the media type to be shown + +Use `mediaType` to filter the assets to be shown. +The default value is `QBImagePickerMediaTypeAny`. + + imagePickerController.mediaType = QBImagePickerMediaTypeVideo; + + +#### Showing information + +There are some properties to show helpful information. + + imagePickerController.prompt = @"Select the photos you want to upload!"; + imagePickerController.showsNumberOfSelectedAssets = YES; + + +#### Grid size + +Use `numberOfColumnsInPortrait` and `numberOfColumnsInLandscape` to change the grid size. +The code below shows the default value. + + imagePickerController.numberOfColumnsInPortrait = 4; + imagePickerController.numberOfColumnsInLandscape = 7; + + + +## License + +Copyright (c) 2015 Katsuma Tanaka + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Coding_iOS/Vendor/RDVTabBarController/RDVTabBarItem.m b/Coding_iOS/Vendor/RDVTabBarController/RDVTabBarItem.m index ba133f50a..d14aa9d97 100755 --- a/Coding_iOS/Vendor/RDVTabBarController/RDVTabBarItem.m +++ b/Coding_iOS/Vendor/RDVTabBarController/RDVTabBarItem.m @@ -73,17 +73,17 @@ - (void)commonInitialization { }; _selectedTitleAttributes = @{ NSFontAttributeName: [UIFont systemFontOfSize:10], - NSForegroundColorAttributeName: kColorBrandGreen, + NSForegroundColorAttributeName: kColorBrandBlue, }; - _badgeBackgroundColor = [UIColor colorWithHexString:@"0xf75388"]; + _badgeBackgroundColor = [UIColor colorWithHexString:@"0xFF0000"]; _badgeTextColor = [UIColor whiteColor]; if (kDevice_Is_iPhone6 || kDevice_Is_iPhone6Plus) { _badgeTextFont = [UIFont systemFontOfSize:12]; }else{ _badgeTextFont = [UIFont systemFontOfSize:11]; } - _badgePositionAdjustment = UIOffsetMake(-4, 2); + _badgePositionAdjustment = UIOffsetMake(-6, 2); // _badgePositionAdjustment = UIOffsetMake(右移量, 下移量); } diff --git a/Coding_iOS/Vendor/RKSwipeBetweenViewControllers/EasePageViewController.m b/Coding_iOS/Vendor/RKSwipeBetweenViewControllers/EasePageViewController.m index 4fa07395c..97723eb07 100644 --- a/Coding_iOS/Vendor/RKSwipeBetweenViewControllers/EasePageViewController.m +++ b/Coding_iOS/Vendor/RKSwipeBetweenViewControllers/EasePageViewController.m @@ -44,7 +44,7 @@ - (void)viewWillDisappear:(BOOL)animated{ #pragma mark - Orientations - (BOOL)shouldAutorotate{ - return UIInterfaceOrientationIsLandscape(self.interfaceOrientation); + return UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication.statusBarOrientation); } - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { diff --git a/Coding_iOS/Vendor/RRFPSBar/RRFPSBar.m b/Coding_iOS/Vendor/RRFPSBar/RRFPSBar.m index 7a32843cf..569c34f1e 100755 --- a/Coding_iOS/Vendor/RRFPSBar/RRFPSBar.m +++ b/Coding_iOS/Vendor/RRFPSBar/RRFPSBar.m @@ -59,7 +59,12 @@ - (void)dealloc { - (id)init { - if( (self = [super initWithFrame:[[UIApplication sharedApplication] statusBarFrame]]) ){ + CGRect frame = [[UIApplication sharedApplication] statusBarFrame]; + if (frame.size.width < 1.0) { + frame = [UIScreen mainScreen].bounds; + frame.size.height = 20; + } + if( (self = [super initWithFrame:frame]) ){ _maxHistoryDTLength = (NSInteger)CGRectGetWidth(self.bounds); _historyDT = malloc(sizeof(CFTimeInterval) * _maxHistoryDTLength); @@ -102,7 +107,7 @@ - (id)init { // Chart Layer _chartLayer = [CAShapeLayer layer]; [_chartLayer setFrame: self.bounds]; - [_chartLayer setStrokeColor: [UIColor redColor].CGColor]; + [_chartLayer setStrokeColor: [UIColor yellowColor].CGColor]; [_chartLayer setContentsScale: [UIScreen mainScreen].scale]; [self.layer addSublayer:_chartLayer]; diff --git a/Coding_iOS/Vendor/SDWebImage/UIImageView+WebCache.m b/Coding_iOS/Vendor/SDWebImage/UIImageView+WebCache.m index 51663dd47..66b17531c 100755 --- a/Coding_iOS/Vendor/SDWebImage/UIImageView+WebCache.m +++ b/Coding_iOS/Vendor/SDWebImage/UIImageView+WebCache.m @@ -39,6 +39,13 @@ - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder } - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock { + if (!(options & SDWebImageHandleCookies)) { + options |= SDWebImageHandleCookies; + } + if (!(options & SDWebImageRetryFailed)) { + options |= SDWebImageRetryFailed; + } + [self sd_cancelCurrentImageLoad]; objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC); diff --git a/Coding_iOS/Vendor/SVWebViewController/SVWebViewController.m b/Coding_iOS/Vendor/SVWebViewController/SVWebViewController.m index ad7933902..4788151bd 100644 --- a/Coding_iOS/Vendor/SVWebViewController/SVWebViewController.m +++ b/Coding_iOS/Vendor/SVWebViewController/SVWebViewController.m @@ -68,15 +68,15 @@ - (void)viewDidLoad { [self updateToolbarItems]; } -- (void)viewDidUnload { - [super viewDidUnload]; - self.webView = nil; - _backBarButtonItem = nil; - _forwardBarButtonItem = nil; - _refreshBarButtonItem = nil; - _stopBarButtonItem = nil; - _actionBarButtonItem = nil; -} +//- (void)viewDidUnload { +// [super viewDidUnload]; +// self.webView = nil; +// _backBarButtonItem = nil; +// _forwardBarButtonItem = nil; +// _refreshBarButtonItem = nil; +// _stopBarButtonItem = nil; +// _actionBarButtonItem = nil; +//} - (void)viewWillAppear:(BOOL)animated { NSAssert(self.navigationController, @"SVWebViewController needs to be contained in a UINavigationController. If you are presenting SVWebViewController modally, use SVModalWebViewController instead."); @@ -104,11 +104,19 @@ - (void)viewDidDisappear:(BOOL)animated { [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; } -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { - if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) - return YES; - - return toInterfaceOrientation != UIInterfaceOrientationPortraitUpsideDown; +//- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { +// if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) +// return YES; +// +// return toInterfaceOrientation != UIInterfaceOrientationPortraitUpsideDown; +//} + +- (BOOL)shouldAutorotate { + return YES; +} + +- (UIInterfaceOrientationMask)supportedInterfaceOrientations { + return UIInterfaceOrientationMaskAllButUpsideDown; } #pragma mark - Getters @@ -168,10 +176,10 @@ - (UIBarButtonItem *)actionBarButtonItem { #pragma mark - Toolbar - (void)updateToolbarItems { - self.backBarButtonItem.enabled = self.self.webView.canGoBack; - self.forwardBarButtonItem.enabled = self.self.webView.canGoForward; + self.backBarButtonItem.enabled = self.webView.canGoBack; + self.forwardBarButtonItem.enabled = self.webView.canGoForward; - UIBarButtonItem *refreshStopBarButtonItem = self.self.webView.isLoading ? self.stopBarButtonItem : self.refreshBarButtonItem; + UIBarButtonItem *refreshStopBarButtonItem = self.webView.isLoading ? self.stopBarButtonItem : self.refreshBarButtonItem; UIBarButtonItem *fixedSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; @@ -194,7 +202,7 @@ - (void)updateToolbarItems { UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0.0f, 0.0f, toolbarWidth, 44.0f)]; toolbar.items = items; toolbar.barStyle = self.navigationController.navigationBar.barStyle; - toolbar.tintColor = kColorBrandGreen; + toolbar.tintColor = kColorBrandBlue; self.navigationItem.rightBarButtonItems = items.reverseObjectEnumerator.allObjects; } @@ -212,7 +220,7 @@ - (void)updateToolbarItems { nil]; self.navigationController.toolbar.barStyle = self.navigationController.navigationBar.barStyle; - self.navigationController.toolbar.tintColor = kColorBrandGreen; + self.navigationController.toolbar.tintColor = kColorBrandBlue; self.toolbarItems = items; } } diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/common_button_white@2x.png b/Coding_iOS/Vendor/SinaSDK/WeiboSDK.bundle/images/common_button_white@2x.png old mode 100644 new mode 100755 similarity index 100% rename from Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/common_button_white@2x.png rename to Coding_iOS/Vendor/SinaSDK/WeiboSDK.bundle/images/common_button_white@2x.png diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/common_button_white_highlighted@2x.png b/Coding_iOS/Vendor/SinaSDK/WeiboSDK.bundle/images/common_button_white_highlighted@2x.png old mode 100644 new mode 100755 similarity index 100% rename from Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/common_button_white_highlighted@2x.png rename to Coding_iOS/Vendor/SinaSDK/WeiboSDK.bundle/images/common_button_white_highlighted@2x.png diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/empty_failed@2x.png b/Coding_iOS/Vendor/SinaSDK/WeiboSDK.bundle/images/empty_failed@2x.png old mode 100644 new mode 100755 similarity index 100% rename from Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/empty_failed@2x.png rename to Coding_iOS/Vendor/SinaSDK/WeiboSDK.bundle/images/empty_failed@2x.png diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/others/mfp.cer b/Coding_iOS/Vendor/SinaSDK/WeiboSDK.bundle/others/mfp.cer old mode 100644 new mode 100755 similarity index 100% rename from Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/others/mfp.cer rename to Coding_iOS/Vendor/SinaSDK/WeiboSDK.bundle/others/mfp.cer diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/UMSocialSinaSSOHandler.h b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/UMSocialSinaSSOHandler.h deleted file mode 100644 index e375275d2..000000000 --- a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/UMSocialSinaSSOHandler.h +++ /dev/null @@ -1,35 +0,0 @@ -// -// UMSocialSinaSSOHandler.h -// SocialSDK -// -// Created by Gavin Ye on 3/27/15. -// Copyright (c) 2015 Umeng. All rights reserved. -// - -#import - -/** - 使用最新版本的新浪微博官方SDK处理新浪微博SSO授权 - - */ -@interface UMSocialSinaSSOHandler : NSObject - -/** - 设置使用最新新浪微博SDK来处理SSO授权(通过客户端设置appkey进行访问) - - @param appKey 新浪App Key - @param redirectURL 回调URL - - */ - -+(void)openNewSinaSSOWithAppKey:(NSString *)appKey - RedirectURL:(NSString *)redirectURL; -/** - 设置使用最新新浪微博SDK来处理SSO授权 - - @param redirectURL 回调URL - - */ -+(void)openNewSinaSSOWithRedirectURL:(NSString *)redirectURL; - -@end diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WBHttpRequest+WeiboGame.h b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WBHttpRequest+WeiboGame.h deleted file mode 100644 index 98740009a..000000000 --- a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WBHttpRequest+WeiboGame.h +++ /dev/null @@ -1,168 +0,0 @@ -// -// WBHttpRequest+WeiboGame.h -// WeiboSDK -// -// Created by insomnia on 15/3/11. -// Copyright (c) 2015年 SINA iOS Team. All rights reserved. -// - -#import "WBHttpRequest.h" - -@interface WBHttpRequest (WeiboGame) - -/*! - @method - - @abstract - 新增游戏对象。 在http://open.weibo.com/wiki/%E6%B8%B8%E6%88%8F%E6%8E%A5%E5%8F%A3 中有关于该接口的细节说明。 - - @param userID 当前授权用户的uid - - @param accessToken 当前授权用户的accessToken - - @param otherProperties 一个NSDictionary字典,承载任意想额外添加到请求中的参数。 - - @param queue 指定发送请求的NSOperationQueue,如果这个参数为nil,则请求会发送在MainQueue( [NSOperationQueue mainQueue] )中。 - - @param handler 完成请求后会回调handler,处理完成请求后的逻辑。 - */ -+ (WBHttpRequest *)addGameObject:(NSString*)userID - withAccessToken:(NSString*)accessToken - andOtherProperties:(NSDictionary*)otherProperties - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; - -/*! - @method - - @abstract - 游戏成就对象入库/更新。 在http://open.weibo.com/wiki/%E6%B8%B8%E6%88%8F%E6%8E%A5%E5%8F%A3 中有关于该接口的细节说明。 - - @param userID 当前授权用户的uid - - @param accessToken 当前授权用户的accessToken - - @param otherProperties 一个NSDictionary字典,承载任意想额外添加到请求中的参数。 - - @param queue 指定发送请求的NSOperationQueue,如果这个参数为nil,则请求会发送在MainQueue( [NSOperationQueue mainQueue] )中。 - - @param handler 完成请求后会回调handler,处理完成请求后的逻辑。 - */ -+ (WBHttpRequest *)addGameAchievementObject:(NSString*)userID - withAccessToken:(NSString*)accessToken - andOtherProperties:(NSDictionary*)otherProperties - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; - -/*! - @method - - @abstract - 用户获得游戏成就关系入库/更新。 在http://open.weibo.com/wiki/%E6%B8%B8%E6%88%8F%E6%8E%A5%E5%8F%A3 中有关于该接口的细节说明。 - - @param userID 当前授权用户的uid - - @param accessToken 当前授权用户的accessToken - - @param otherProperties 一个NSDictionary字典,承载任意想额外添加到请求中的参数。 - - @param queue 指定发送请求的NSOperationQueue,如果这个参数为nil,则请求会发送在MainQueue( [NSOperationQueue mainQueue] )中。 - - @param handler 完成请求后会回调handler,处理完成请求后的逻辑。 - */ -+ (WBHttpRequest *)addGameAchievementGain:(NSString*)userID - withAccessToken:(NSString*)accessToken - andOtherProperties:(NSDictionary*)otherProperties - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; - -/*! - @method - - @abstract - 用户游戏得分关系入库/更新。 在http://open.weibo.com/wiki/%E6%B8%B8%E6%88%8F%E6%8E%A5%E5%8F%A3 中有关于该接口的细节说明。 - - @param userID 当前授权用户的uid - - @param accessToken 当前授权用户的accessToken - - @param otherProperties 一个NSDictionary字典,承载任意想额外添加到请求中的参数。 - - @param queue 指定发送请求的NSOperationQueue,如果这个参数为nil,则请求会发送在MainQueue( [NSOperationQueue mainQueue] )中。 - - @param handler 完成请求后会回调handler,处理完成请求后的逻辑。 - */ -+ (WBHttpRequest *)addGameScoreGain:(NSString*)userID - withAccessToken:(NSString*)accessToken - andOtherProperties:(NSDictionary*)otherProperties - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; - - -/*! - @method - - @abstract - 读取玩家游戏分数。 在http://open.weibo.com/wiki/%E6%B8%B8%E6%88%8F%E6%8E%A5%E5%8F%A3 中有关于该接口的细节说明。 - - @param userID 当前授权用户的uid - - @param accessToken 当前授权用户的accessToken - - @param otherProperties 一个NSDictionary字典,承载任意想额外添加到请求中的参数。 - - @param queue 指定发送请求的NSOperationQueue,如果这个参数为nil,则请求会发送在MainQueue( [NSOperationQueue mainQueue] )中。 - - @param handler 完成请求后会回调handler,处理完成请求后的逻辑。 - */ -+ (WBHttpRequest *)requestForGameScore:(NSString*)userID - withAccessToken:(NSString*)accessToken - andOtherProperties:(NSDictionary*)otherProperties - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; - -/*! - @method - - @abstract - 读取玩家互粉好友游戏分数。 在http://open.weibo.com/wiki/%E6%B8%B8%E6%88%8F%E6%8E%A5%E5%8F%A3 中有关于该接口的细节说明。 - - @param userID 当前授权用户的uid - - @param accessToken 当前授权用户的accessToken - - @param otherProperties 一个NSDictionary字典,承载任意想额外添加到请求中的参数。 - - @param queue 指定发送请求的NSOperationQueue,如果这个参数为nil,则请求会发送在MainQueue( [NSOperationQueue mainQueue] )中。 - - @param handler 完成请求后会回调handler,处理完成请求后的逻辑。 - */ -+ (WBHttpRequest *)requestForFriendsGameScore:(NSString*)userID - withAccessToken:(NSString*)accessToken - andOtherProperties:(NSDictionary*)otherProperties - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; - -/*! - @method - - @abstract - 读取玩家获取成就列表。 在http://open.weibo.com/wiki/%E6%B8%B8%E6%88%8F%E6%8E%A5%E5%8F%A3 中有关于该接口的细节说明。 - - @param userID 当前授权用户的uid - - @param accessToken 当前授权用户的accessToken - - @param otherProperties 一个NSDictionary字典,承载任意想额外添加到请求中的参数。 - - @param queue 指定发送请求的NSOperationQueue,如果这个参数为nil,则请求会发送在MainQueue( [NSOperationQueue mainQueue] )中。 - - @param handler 完成请求后会回调handler,处理完成请求后的逻辑。 - */ -+ (WBHttpRequest *)requestForGameAchievementGain:(NSString*)userID - withAccessToken:(NSString*)accessToken - andOtherProperties:(NSDictionary*)otherProperties - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; - -@end diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WBHttpRequest+WeiboShare.h b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WBHttpRequest+WeiboShare.h deleted file mode 100644 index e0c0b136c..000000000 --- a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WBHttpRequest+WeiboShare.h +++ /dev/null @@ -1,93 +0,0 @@ -// -// WBHttpRequest+WeiboShare.h -// WeiboSDK -// -// Created by DannionQiu on 14/10/31. -// Copyright (c) 2014年 SINA iOS Team. All rights reserved. -// - -#import "WBHttpRequest.h" - -@class WBImageObject; - -@interface WBHttpRequest (WeiboShare) - -/*! - @method - - @abstract - 获得当前授权用户的微博id列表。 - - @param userID 当前授权用户的uid - - @param accessToken 当前授权用户的accessToken - - @param otherProperties 一个NSDictionary字典,承载任意想额外添加到请求中的参数。 - - @param queue 指定发送请求的NSOperationQueue,如果这个参数为nil,则请求会发送在MainQueue( [NSOperationQueue mainQueue] )中。 - - @param handler 完成请求后会回调handler,处理完成请求后的逻辑。 -*/ -+ (WBHttpRequest *)requestForStatusIDsFromCurrentUser:(NSString*)userID - withAccessToken:(NSString*)accessToken - andOtherProperties:(NSDictionary*)otherProperties - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; - -/*! - @method - - @abstract - 转发微博。转发微博id所对应的微博。 - - @param statusID 微博id,微博的唯一标识符。 - - @param text 添加的转发文本,内容不超过140个汉字,不填则默认为“转发微博”。 - - @param accessToken 当前授权用户的accessToken - - @param otherProperties 一个NSDictionary字典,承载任意想额外添加到请求中的参数。 - - @param queue 指定发送请求的NSOperationQueue,如果这个参数为nil,则请求会发送在MainQueue( [NSOperationQueue mainQueue] )中。 - - @param handler 完成请求后会回调handler,处理完成请求后的逻辑。 - */ -+ (WBHttpRequest *)requestForRepostAStatus:(NSString*)statusID - repostText:(NSString*)text - withAccessToken:(NSString*)accessToken - andOtherProperties:(NSDictionary*)otherProperties - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; - -/*! - @method - - @abstract - 发表一个微博(无图或者带一张图片的微博)。 - - @param statusText 要发布的微博文本内容,内容不超过140个汉字。 - - @param imageObject 要上传的图片,仅支持JPEG、GIF、PNG格式,图片大小小于5M。这个参数可为nil。由于只能传一张图片,若imageObject和url都有值,请看@caution。 - - @param url 图片的URL地址,必须以http开头。这个参数可为nil,由于只能传一张图片,若imageObject和url都有值,请看@caution。 - - @param accessToken 当前授权用户的accessToken - - @param otherProperties 一个NSDictionary字典,承载任意想额外添加到请求中的参数。 - - @param queue 指定发送请求的NSOperationQueue,如果这个参数为nil,则请求会发送在MainQueue( [NSOperationQueue mainQueue] )中。 - - @param handler 完成请求后会回调handler,处理完成请求后的逻辑。 - - @caution 注意,如果参数imageObject和url都有值,则发布带有imageObject所对应的图片,忽略url所对应的图片。 - */ -+ (WBHttpRequest *)requestForShareAStatus:(NSString*)statusText - contatinsAPicture:(WBImageObject*)imageObject - orPictureUrl:(NSString*)url - withAccessToken:(NSString*)accessToken - andOtherProperties:(NSDictionary*)otherProperties - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; - - -@end diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WBHttpRequest+WeiboToken.h b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WBHttpRequest+WeiboToken.h deleted file mode 100644 index 2457efed4..000000000 --- a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WBHttpRequest+WeiboToken.h +++ /dev/null @@ -1,30 +0,0 @@ -// -// WBHttpRequest+WeiboToken.h -// WeiboSDK -// -// Created by DannionQiu on 14/11/6. -// Copyright (c) 2014年 SINA iOS Team. All rights reserved. -// - -#import "WBHttpRequest.h" - -@interface WBHttpRequest (WeiboToken) -/*! - @method - - @abstract - 使用RefreshToken去换取新的身份凭证AccessToken. - - @discussion - 在SSO授权登录后,服务器会下发有效期为7天的refreshToken以及有效期为1天的AccessToken。 - 当有效期为1天的AccessToken过期时,可以调用该接口带着refreshToken信息区换取新的AccessToken。 - @param refreshToken refreshToken - - @param queue 指定发送请求的NSOperationQueue,如果这个参数为nil,则请求会发送在MainQueue( [NSOperationQueue mainQueue] )中。 - - @param handler 完成请求后会回调handler,处理完成请求后的逻辑。 - */ -+ (WBHttpRequest *)requestForRenewAccessTokenWithRefreshToken:(NSString*)refreshToken - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; -@end diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WBHttpRequest+WeiboUser.h b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WBHttpRequest+WeiboUser.h deleted file mode 100644 index 47657a426..000000000 --- a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WBHttpRequest+WeiboUser.h +++ /dev/null @@ -1,439 +0,0 @@ -// -// WBHttpRequest+WeiboUser.h -// WeiboSDK -// -// Created by DannionQiu on 14-9-23. -// Copyright (c) 2014年 SINA iOS Team. All rights reserved. -// - -#import "WBHttpRequest.h" - -@interface WBHttpRequest (WeiboUser) - -/*! - @method - - @abstract - Creates a request representing a Open API call to the "friendships/friends". - - @discussion - Simplifies preparing a request and sending request to retrieve the user's friends. - - A successful Open API call will return an NSDictionary of objects which contanis an array of objects representing the - user's friends. - - You can see more details about this API in http://open.weibo.com/wiki/2/friendships/friends/en - - @param currentUserID should be the current User's UserID which has been authorized. - - @param accessToken The token string. - - @param otherProperties Any additional properties for the Open API Request. - - @param queue specify the queue that you want to send request on, if this param is nil, the request will be start on MainQueue( [NSOperationQueue mainQueue] ). - - @param handler the comletion block which will be executed after received response from Open API server. - */ -+ (WBHttpRequest *)requestForFriendsListOfUser:(NSString*)currentUserID - withAccessToken:(NSString*)accessToken - andOtherProperties:(NSDictionary*)otherProperties - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; - -/*! - @method - - @abstract - Creates a request representing a Open API call to the "friendships/friends/ids". - - @discussion - Simplifies preparing a request and sending request to retrieve the user's friends' UserID. - - A successful Open API call will return an NSDictionary of objects which contanis an array of NSString representing the - user's friends' UserID. - - You can see more details about this API in http://open.weibo.com/wiki/2/friendships/friends/ids/en - - @param currentUserID should be the current User's UserID which has been authorized. - - @param accessToken The token string. - - @param otherProperties Any additional properties for the Open API Request. - - @param queue specify the queue that you want to send request on, if this param is nil, the request will be start on MainQueue( [NSOperationQueue mainQueue] ). - - @param handler the comletion block which will be executed after received response from Open API server. - */ -+ (WBHttpRequest *)requestForFriendsUserIDListOfUser:(NSString*)currentUserID - withAccessToken:(NSString*)accessToken - andOtherProperties:(NSDictionary*)otherProperties - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; - - -/*! - @method - - @abstract - Creates a request representing a Open API call to the "friendships/friends/in_common". - - @discussion - Simplifies preparing a request and sending request to retrieve the common friends list between two users.. - - A successful Open API call will return an NSDictionary of objects which contanis an array of objects representing the - user's friends. - - You can see more details about this API in http://open.weibo.com/wiki/2/friendships/friends/in_common/en - - @param currentUserID should be the current User's UserID which has been authorized. - - @param accessToken The token string. - - @param otherProperties Any additional properties for the Open API Request. - - @param queue specify the queue that you want to send request on, if this param is nil, the request will be start on MainQueue( [NSOperationQueue mainQueue] ). - - @param handler the comletion block which will be executed after received response from Open API server. - */ -+ (WBHttpRequest *)requestForCommonFriendsListBetweenUser:(NSString*)currentUserID - andUser:(NSString*)anotherUserID - withAccessToken:(NSString*)accessToken - andOtherProperties:(NSDictionary*)otherProperties - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; - -/*! - @method - - @abstract - Creates a request representing a Open API call to the "friendships/friends/bilateral". - - @discussion - Simplifies preparing a request and sending request to retrieve the list of the users that are following the specified user and are being followed by the specified user. - - A successful Open API call will return an NSDictionary of objects which contanis an array of objects representing the - users that are following the specified user and are being followed by the specified user. - - You can see more details about this API in http://open.weibo.com/wiki/2/friendships/friends/bilateral/en - - @param currentUserID should be the current User's UserID which has been authorized. - - @param accessToken The token string. - - @param otherProperties Any additional properties for the Open API Request. - - @param queue specify the queue that you want to send request on, if this param is nil, the request will be start on MainQueue( [NSOperationQueue mainQueue] ). - - @param handler the comletion block which will be executed after received response from Open API server. - */ -+ (WBHttpRequest *)requestForBilateralFriendsListOfUser:(NSString*)currentUserID - withAccessToken:(NSString*)accessToken - andOtherProperties:(NSDictionary*)otherProperties - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; - -/*! - @method - - @abstract - Creates a request representing a Open API call to the "friendships/followers". - - @discussion - Simplifies preparing a request and sending request to retrieve the user's followers. - - A successful Open API call will return an NSDictionary of objects which contanis an array of objects representing the - user's followers. - - You can see more details about this API in http://open.weibo.com/wiki/2/friendships/followers/en - - @param currentUserID should be the current User's UserID which has been authorized. - - @param accessToken The token string. - - @param otherProperties Any additional properties for the Open API Request. - - @param queue specify the queue that you want to send request on, if this param is nil, the request will be start on MainQueue( [NSOperationQueue mainQueue] ). - - @param handler the comletion block which will be executed after received response from Open API server. - */ -+ (WBHttpRequest *)requestForFollowersListOfUser:(NSString*)currentUserID - withAccessToken:(NSString*)accessToken - andOtherProperties:(NSDictionary*)otherProperties - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; - -/*! - @method - - @abstract - Creates a request representing a Open API call to the "friendships/followers/ids". - - @discussion - Simplifies preparing a request and sending request to retrieve the user's followers' UserID. - - A successful Open API call will return an NSDictionary of objects which contanis an array of NSString representing the - user's followers' UserID. - - You can see more details about this API in http://open.weibo.com/wiki/2/friendships/followers/ids/en - - @param currentUserID should be the current User's UserID which has been authorized. - - @param accessToken The token string. - - @param otherProperties Any additional properties for the Open API Request. - - @param queue specify the queue that you want to send request on, if this param is nil, the request will be start on MainQueue( [NSOperationQueue mainQueue] ). - - @param handler the comletion block which will be executed after received response from Open API server. - */ -+ (WBHttpRequest *)requestForFollowersUserIDListOfUser:(NSString*)currentUserID - withAccessToken:(NSString*)accessToken - andOtherProperties:(NSDictionary*)otherProperties - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; - -/*! - @method - - @abstract - Creates a request representing a Open API call to the "friendships/followers/active". - - @discussion - Simplifies preparing a request and sending request to retrieve the active(high quality) followers list of a user. - - A successful Open API call will return an NSDictionary of objects which contanis an array of objects representing the active(high quality) followers list of a user. - - You can see more details about this API in http://open.weibo.com/wiki/2/friendships/followers/active/en - - @param currentUserID should be the current User's UserID which has been authorized. - - @param accessToken The token string. - - @param otherProperties Any additional properties for the Open API Request. - - @param queue specify the queue that you want to send request on, if this param is nil, the request will be start on MainQueue( [NSOperationQueue mainQueue] ). - - @param handler the comletion block which will be executed after received response from Open API server. - */ -+ (WBHttpRequest *)requestForActiveFollowersListOfUser:(NSString*)currentUserID - withAccessToken:(NSString*)accessToken - andOtherProperties:(NSDictionary*)otherProperties - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; - -/*! - @method - - @abstract - Creates a request representing a Open API call to the "friendships/friends_chain/followers". - - @discussion - Simplifies preparing a request and sending request to retrieve the users that are being followed by the authenticating user and are following the specified user. - - A successful Open API call will return an NSDictionary of objects which contanis an array of objects representing the users that are being followed by the authenticating user and are following the specified user. - - You can see more details about this API in http://open.weibo.com/wiki/2/friendships/friends_chain/followers/en - - @param currentUserID should be the current User's UserID which has been authorized. - - @param accessToken The token string. - - @param otherProperties Any additional properties for the Open API Request. - - @param queue specify the queue that you want to send request on, if this param is nil, the request will be start on MainQueue( [NSOperationQueue mainQueue] ). - - @param handler the comletion block which will be executed after received response from Open API server. - */ -+ (WBHttpRequest *)requestForBilateralFollowersListOfUser:(NSString*)currentUserID - withAccessToken:(NSString*)accessToken - andOtherProperties:(NSDictionary*)otherProperties - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; - -/*! - @method - - @abstract - Creates a request representing a Open API call to the "friendships/show". - - @discussion - Simplifies preparing a request and sending request to retrieve the relationship of two users. - - A successful Open API call will return an NSDictionary of objects which contanis the relationship of two users. - - You can see more details about this API in http://open.weibo.com/wiki/2/friendships/show - - @param targetUserID a User ID - - @param sourceUserID a User ID - - @param accessToken The token string. - - @param otherProperties Any additional properties for the Open API Request. - - @param queue specify the queue that you want to send request on, if this param is nil, the request will be start on MainQueue( [NSOperationQueue mainQueue] ). - - @param handler the comletion block which will be executed after received response from Open API server. - */ -+ (WBHttpRequest *)requestForFriendshipDetailBetweenTargetUser:(NSString*)targetUserID - andSourceUser:(NSString*)sourceUserID - withAccessToken:(NSString*)accessToken - andOtherProperties:(NSDictionary*)otherProperties - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; - -/*! - @method - - @abstract - Creates a request representing a Open API call to the "friendships/create". - - @discussion - Simplifies preparing a request and sending request to Follow a user. - - A successful Open API call will return an object representing the user to be followed. - - You can see more details about this API in http://open.weibo.com/wiki/2/friendships/create/en - - @param theUserToBeFollowed the userID of the user which you want to follow. - - @param accessToken The token string. - - @param otherProperties Any additional properties for the Open API Request. - - @param queue specify the queue that you want to send request on, if this param is nil, the request will be start on MainQueue( [NSOperationQueue mainQueue] ). - - @param handler the comletion block which will be executed after received response from Open API server. - */ -+ (WBHttpRequest *)requestForFollowAUser:(NSString*)theUserToBeFollowed - withAccessToken:(NSString*)accessToken - andOtherProperties:(NSDictionary*)otherProperties - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; - -/*! - @method - - @abstract - Creates a request representing a Open API call to the "friendships/destroy". - - @discussion - Simplifies preparing a request and sending request to cancel following a user. - - A successful Open API call will return an object representing the user to be followed. - - You can see more details about this API in http://open.weibo.com/wiki/2/friendships/destroy/en - - @param theUserThatYouDontLike the userID of the user which you want to cancel following. - - @param accessToken The token string. - - @param otherProperties Any additional properties for the Open API Request. - - @param queue specify the queue that you want to send request on, if this param is nil, the request will be start on MainQueue( [NSOperationQueue mainQueue] ). - - @param handler the comletion block which will be executed after received response from Open API server. - */ -+ (WBHttpRequest *)requestForCancelFollowAUser:(NSString*)theUserThatYouDontLike - withAccessToken:(NSString*)accessToken - andOtherProperties:(NSDictionary*)otherProperties - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; - -/*! - @method - - @abstract - Creates a request representing a Open API call to the "friendships/followers/destroy". - - @discussion - Simplifies preparing a request and sending request to remove a follower of the authenticating user. - - A successful Open API call will return an object representing the user to be followed. - - this API requires advanced level authorization. You can see more details about advanced level authorization in http://open.weibo.com/wiki/%E6%8E%88%E6%9D%83%E6%9C%BA%E5%88%B6%E8%AF%B4%E6%98%8E#scope - - You can see more details about this API in http://open.weibo.com/wiki/2/friendships/followers/destroy/en - - @param theUserThatYouDontLike the userID of the follower which you want to remove. - - @param accessToken The token string. - - @param otherProperties Any additional properties for the Open API Request. - - @param queue specify the queue that you want to send request on, if this param is nil, the request will be start on MainQueue( [NSOperationQueue mainQueue] ). - - @param handler the comletion block which will be executed after received response from Open API server. - */ -+ (WBHttpRequest *)requestForRemoveFollowerUser:(NSString*)theUserThatYouDontLike - withAccessToken:(NSString*)accessToken - andOtherProperties:(NSDictionary*)otherProperties - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; - -/*! - @method - - @abstract - Creates a request representing a Open API call to the "messages/invite". - - @discussion - Simplifies preparing a request and sending request to send invitation to a bilateral friend of the authenticating user. - - A successful Open API call will return an NSDictionary of objects which contanis objects representing sender and receiver and other invitation details. - - You can see more details about this API in http://open.weibo.com/wiki/2/messages/invite - - @param theUserThatShouldBeYourBilateralFriend the userID of the follower which you want to remove. - - @param accessToken The token string. - - @param text The text content in your invitation message. should not be nil. - - @param url The url in your invitation message. can be nil. - - @param logoUrl The logoUrl in your invitation message. can be nil. - - @param queue specify the queue that you want to send request on, if this param is nil, the request will be start on MainQueue( [NSOperationQueue mainQueue] ). - - @param handler the comletion block which will be executed after received response from Open API server. - */ -+ (WBHttpRequest *)requestForInviteBilateralFriend:(NSString*)theUserThatShouldBeYourBilateralFriend - withAccessToken:(NSString*)accessToken - inviteText:(NSString*)text - inviteUrl:(NSString*)url - inviteLogoUrl:(NSString*)logoUrl - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; - - -/*! - @method - - @abstract - Creates a request representing a Open API call to the "users/show". - - @discussion - Simplifies preparing a request and sending request to retrieve user profile by user ID.. - - A successful Open API call will return a object representing the user profile by user ID. - - You can see more details about this API in http://open.weibo.com/wiki/2/users/show/en - - @param aUserID a User ID. - - @param accessToken The token string. - - @param otherProperties Any additional properties for the Open API Request. - - @param queue specify the queue that you want to send request on, if this param is nil, the request will be start on MainQueue( [NSOperationQueue mainQueue] ). - - @param handler the comletion block which will be executed after received response from Open API server. - */ -+ (WBHttpRequest *)requestForUserProfile:(NSString*)aUserID - withAccessToken:(NSString*)accessToken - andOtherProperties:(NSDictionary*)otherProperties - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; - -@end diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WBHttpRequest.h b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WBHttpRequest.h deleted file mode 100644 index dcd532514..000000000 --- a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WBHttpRequest.h +++ /dev/null @@ -1,182 +0,0 @@ -// -// WBHttpRequest.h -// WeiboSDK -// -// Created by DannionQiu on 14-9-18. -// Copyright (c) 2014年 SINA iOS Team. All rights reserved. -// - -#import -#import - -#pragma mark - WBHttpRequest and WBHttpRequestDelegate -@class WBHttpRequest; - -/** - 接收并处理来自微博sdk对于网络请求接口的调用响应 以及openAPI - 如inviteFriend、logOutWithToken的请求 - */ -@protocol WBHttpRequestDelegate - -/** - 收到一个来自微博Http请求的响应 - - @param response 具体的响应对象 - */ -@optional -- (void)request:(WBHttpRequest *)request didReceiveResponse:(NSURLResponse *)response; - -/** - 收到一个来自微博Http请求失败的响应 - - @param error 错误信息 - */ -@optional -- (void)request:(WBHttpRequest *)request didFailWithError:(NSError *)error; - -/** - 收到一个来自微博Http请求的网络返回 - - @param result 请求返回结果 - */ -@optional -- (void)request:(WBHttpRequest *)request didFinishLoadingWithResult:(NSString *)result; - -/** - 收到一个来自微博Http请求的网络返回 - - @param data 请求返回结果 - */ -@optional -- (void)request:(WBHttpRequest *)request didFinishLoadingWithDataResult:(NSData *)data; - -/** - 收到快速SSO授权的重定向 - - @param URI - */ -@optional -- (void)request:(WBHttpRequest *)request didReciveRedirectResponseWithURI:(NSURL *)redirectUrl; - -@end - - -/** - 微博封装Http请求的消息结构 - - */ -@interface WBHttpRequest : NSObject -{ - NSURLConnection *connection; - NSMutableData *responseData; -} - -/** - 用户自定义请求地址URL - */ -@property (nonatomic, strong) NSString *url; - -/** - 用户自定义请求方式 - - 支持"GET" "POST" - */ -@property (nonatomic, strong) NSString *httpMethod; - -/** - 用户自定义请求参数字典 - */ -@property (nonatomic, strong) NSDictionary *params; - -/** - WBHttpRequestDelegate对象,用于接收微博SDK对于发起的接口请求的请求的响应 - */ -@property (nonatomic, weak) id delegate; - -/** - 用户自定义TAG - - 用于区分回调Request - */ -@property (nonatomic, strong) NSString* tag; - -/** - 统一HTTP请求接口 - 调用此接口后,将发送一个HTTP网络请求 - @param url 请求url地址 - @param httpMethod 支持"GET" "POST" - @param params 向接口传递的参数结构 - @param delegate WBHttpRequestDelegate对象,用于接收微博SDK对于发起的接口请求的请求的响应 - @param tag 用户自定义TAG,将通过回调WBHttpRequest实例的tag属性返回 - */ -+ (WBHttpRequest *)requestWithURL:(NSString *)url - httpMethod:(NSString *)httpMethod - params:(NSDictionary *)params - delegate:(id)delegate - withTag:(NSString *)tag; - -/** - 统一微博Open API HTTP请求接口 - 调用此接口后,将发送一个HTTP网络请求(用于访问微博open api) - @param accessToken 应用获取到的accessToken,用于身份验证 - @param url 请求url地址 - @param httpMethod 支持"GET" "POST" - @param params 向接口传递的参数结构 - @param delegate WBHttpRequestDelegate对象,用于接收微博SDK对于发起的接口请求的请求的响应 - @param tag 用户自定义TAG,将通过回调WBHttpRequest实例的tag属性返回 - */ -+ (WBHttpRequest *)requestWithAccessToken:(NSString *)accessToken - url:(NSString *)url - httpMethod:(NSString *)httpMethod - params:(NSDictionary *)params - delegate:(id)delegate - withTag:(NSString *)tag; - - - -/** - 取消网络请求接口 - 调用此接口后,将取消当前网络请求,建议同时[WBHttpRequest setDelegate:nil]; - 注意:该方法只对使用delegate的request方法有效。无法取消任何使用block的request的网络请求接口。 - */ -- (void)disconnect; - -#pragma mark - block extension - -typedef void (^WBRequestHandler)(WBHttpRequest *httpRequest, - id result, - NSError *error); - -/** - 统一微博Open API HTTP请求接口 - 调用此接口后,将发送一个HTTP网络请求(用于访问微博open api) - @param url 请求url地址 - @param httpMethod 支持"GET" "POST" - @param params 向接口传递的参数结构 - @param queue 发起请求的NSOperationQueue对象,如queue为nil,则在主线程([NSOperationQueue mainQueue])发起请求。 - @param handler 接口请求返回调用的block方法 - */ -+ (WBHttpRequest *)requestWithURL:(NSString *)url - httpMethod:(NSString *)httpMethod - params:(NSDictionary *)params - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; - - -/** - 统一HTTP请求接口 - 调用此接口后,将发送一个HTTP网络请求 - @param url 请求url地址 - @param httpMethod 支持"GET" "POST" - @param params 向接口传递的参数结构 - @param queue 发起请求的NSOperationQueue对象,如queue为nil,则在主线程([NSOperationQueue mainQueue])发起请求。 - @param handler 接口请求返回调用的block方法 - */ -+ (WBHttpRequest *)requestWithAccessToken:(NSString *)accessToken - url:(NSString *)url - httpMethod:(NSString *)httpMethod - params:(NSDictionary *)params - queue:(NSOperationQueue*)queue - withCompletionHandler:(WBRequestHandler)handler; - -@end diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WBSDKBasicButton.h b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WBSDKBasicButton.h deleted file mode 100644 index 8f92123da..000000000 --- a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WBSDKBasicButton.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// WBSDKBasicButton.h -// WeiboSDK -// -// Created by DannionQiu on 14/10/24. -// Copyright (c) 2014年 SINA iOS Team. All rights reserved. -// - -#import - -@class WBSDKBasicButton; -typedef void (^WBSDKButtonHandler)(WBSDKBasicButton *button, - BOOL isSuccess, - NSDictionary *resultDict); - -@interface WBSDKBasicButton : UIButton - -@end diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WBSDKCommentButton.h b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WBSDKCommentButton.h deleted file mode 100644 index dfd7f67dc..000000000 --- a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WBSDKCommentButton.h +++ /dev/null @@ -1,34 +0,0 @@ -// -// WBSDKCommentButton.h -// WeiboSDK -// -// Created by DannionQiu on 14/10/26. -// Copyright (c) 2014年 SINA iOS Team. All rights reserved. -// - -#import "WBSDKBasicButton.h" - -@interface WBSDKCommentButton : WBSDKBasicButton - -/** - 初始化一个社会化评论按钮 - @param frame 按钮的frame值 - @param accessToken 用户授权后获取的Token - @param keyWord 社会化评论的热点词 - @param urlString 社会化评论链接,可传空 - @param category 领域ID, 此参数为必选参数。 - @param handler 回调函数,当用户点击按钮,进行完与社会化评论组件相关的交互之后,回调的函数。 - */ -- (id)initWithFrame:(CGRect)frame - accessToken:(NSString*)accessToken - keyword:(NSString*)keyWord - urlString:(NSString*)urlString - category:(NSString*)category - completionHandler:(WBSDKButtonHandler)handler; - -@property (nonatomic, strong)NSString* keyWord; -@property (nonatomic, strong)NSString* accessToken; -@property (nonatomic, strong)NSString* urlString; -@property (nonatomic, strong)NSString* category; - -@end diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WBSDKRelationshipButton.h b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WBSDKRelationshipButton.h deleted file mode 100644 index 8abe1890d..000000000 --- a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WBSDKRelationshipButton.h +++ /dev/null @@ -1,50 +0,0 @@ -// -// WBSDKRelationshipButton.h -// WeiboSDK -// -// Created by DannionQiu on 14/10/26. -// Copyright (c) 2014年 SINA iOS Team. All rights reserved. -// - -#import "WBSDKBasicButton.h" - -enum -{ - WBSDKRelationshipButtonStateFollow, - WBSDKRelationshipButtonStateUnfollow -}; -typedef NSUInteger WBSDKRelationshipButtonState; - - - -@interface WBSDKRelationshipButton : WBSDKBasicButton - -/** - 初始化一个关注组件按钮 - @param frame 按钮的frame值 - @param accessToken 用户授权后获取的Token - @param currentUserID 当前用户的uid值 - @param followerUserID 希望当前用户加关注的用户uid值 - @param handler 回调函数,当用户点击按钮,进行完关注组件相关的交互之后,回调的函数。 - */ -- (id)initWithFrame:(CGRect)frame - accessToken:(NSString*)accessToken - currentUser:(NSString*)currentUserID - followUser:(NSString*)followerUserID - completionHandler:(WBSDKButtonHandler)handler; - -@property (nonatomic, strong)NSString* accessToken; -@property (nonatomic, strong)NSString* currentUserID; -@property (nonatomic, strong)NSString* followUserID; - - -@property (nonatomic, assign)WBSDKRelationshipButtonState currentRelationShip; - - -/** - 获取最新的关注状态 - 该方法会调用OpenApi,获取当前用户与目标用户之间的关注状态,并将按钮的状态改变为正确的状态。 - */ -- (void)checkCurrentRelationship; - -@end diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/alert_error_icon@2x.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/alert_error_icon@2x.png deleted file mode 100644 index d1b90649e..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/alert_error_icon@2x.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/alert_success_icon@2x.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/alert_success_icon@2x.png deleted file mode 100644 index bd75226b8..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/alert_success_icon@2x.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/close.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/close.png deleted file mode 100644 index 1fd28aca3..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/close.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/close@2x.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/close@2x.png deleted file mode 100644 index 78eaa115c..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/close@2x.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/common_button_big_blue@2x.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/common_button_big_blue@2x.png deleted file mode 100644 index 1652d54c8..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/common_button_big_blue@2x.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/common_button_big_blue_disable@2x.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/common_button_big_blue_disable@2x.png deleted file mode 100644 index 3779ce959..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/common_button_big_blue_disable@2x.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/common_button_big_blue_highlighted@2x.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/common_button_big_blue_highlighted@2x.png deleted file mode 100644 index 3404f948a..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/common_button_big_blue_highlighted@2x.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/common_button_white.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/common_button_white.png deleted file mode 100644 index 732cc9425..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/common_button_white.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/common_button_white_highlighted.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/common_button_white_highlighted.png deleted file mode 100644 index 5ef5cf3aa..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/common_button_white_highlighted.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/common_icon_arrow@2x.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/common_icon_arrow@2x.png deleted file mode 100644 index 2891f5046..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/common_icon_arrow@2x.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/compose_keyboardbutton_background.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/compose_keyboardbutton_background.png deleted file mode 100644 index dcfc0ea1b..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/compose_keyboardbutton_background.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/compose_keyboardbutton_background@2x.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/compose_keyboardbutton_background@2x.png deleted file mode 100644 index 8879d32cc..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/compose_keyboardbutton_background@2x.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/compose_toolbar_background.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/compose_toolbar_background.png deleted file mode 100644 index c582e4cba..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/compose_toolbar_background.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/compose_toolbar_background@2x.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/compose_toolbar_background@2x.png deleted file mode 100644 index d2ed22214..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/compose_toolbar_background@2x.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/empty_failed.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/empty_failed.png deleted file mode 100644 index 4da51e03e..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/empty_failed.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/login_background@2x.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/login_background@2x.png deleted file mode 100644 index 8fe6aa9c7..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/login_background@2x.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/login_country_background@2x.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/login_country_background@2x.png deleted file mode 100644 index db8e5b642..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/login_country_background@2x.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/login_country_background_highlighted@2x.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/login_country_background_highlighted@2x.png deleted file mode 100644 index 1b1143d7a..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/login_country_background_highlighted@2x.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/navigationbar_background.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/navigationbar_background.png deleted file mode 100644 index 4eeec6026..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/navigationbar_background.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/navigationbar_background@2x.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/navigationbar_background@2x.png deleted file mode 100644 index 00cb3d948..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/navigationbar_background@2x.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/navigationbar_background_os7.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/navigationbar_background_os7.png deleted file mode 100644 index 0a9e7c3c1..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/navigationbar_background_os7.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/navigationbar_background_os7@2x.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/navigationbar_background_os7@2x.png deleted file mode 100644 index 9e46e44e2..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/navigationbar_background_os7@2x.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/progresshud_background@2x.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/progresshud_background@2x.png deleted file mode 100644 index 40676050b..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/progresshud_background@2x.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/sdk_weibo_logo.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/sdk_weibo_logo.png deleted file mode 100644 index c656b5e2d..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/sdk_weibo_logo.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/sdk_weibo_logo@2x.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/sdk_weibo_logo@2x.png deleted file mode 100644 index 7e0f11cbc..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/sdk_weibo_logo@2x.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/sdk_weibo_logo@3x.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/sdk_weibo_logo@3x.png deleted file mode 100644 index 0d044208f..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/sdk_weibo_logo@3x.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/timeline_relationship_icon_addattention.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/timeline_relationship_icon_addattention.png deleted file mode 100644 index ee95e72ff..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/timeline_relationship_icon_addattention.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/timeline_relationship_icon_addattention@2x.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/timeline_relationship_icon_addattention@2x.png deleted file mode 100644 index 70b222e0b..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/timeline_relationship_icon_addattention@2x.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/timeline_relationship_icon_addattention@3x.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/timeline_relationship_icon_addattention@3x.png deleted file mode 100644 index 02cf0df42..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/timeline_relationship_icon_addattention@3x.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/timeline_relationship_icon_attention.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/timeline_relationship_icon_attention.png deleted file mode 100644 index e5b80110e..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/timeline_relationship_icon_attention.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/timeline_relationship_icon_attention@2x.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/timeline_relationship_icon_attention@2x.png deleted file mode 100644 index b5cb58474..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/timeline_relationship_icon_attention@2x.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/timeline_relationship_icon_attention@3x.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/timeline_relationship_icon_attention@3x.png deleted file mode 100644 index 6ef6f80fa..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/timeline_relationship_icon_attention@3x.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/verify_code_button@2x.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/verify_code_button@2x.png deleted file mode 100644 index ab80b1b6c..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/verify_code_button@2x.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/verify_code_button@3x.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/verify_code_button@3x.png deleted file mode 100644 index 5886944f7..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/verify_code_button@3x.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/verify_code_button_highlighted@2x.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/verify_code_button_highlighted@2x.png deleted file mode 100644 index bf472dafc..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/verify_code_button_highlighted@2x.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/verify_code_button_highlighted@3x.png b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/verify_code_button_highlighted@3x.png deleted file mode 100644 index 1fd16b5ce..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/images/verify_code_button_highlighted@3x.png and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/others/countryList b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/others/countryList deleted file mode 100644 index 86e85d9b5..000000000 --- a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.bundle/others/countryList +++ /dev/null @@ -1 +0,0 @@ -{"香港地区":{"code":"00852","rule":{"mcc":["454"]}},"台湾地区":{"code":"00886","rule":{"mcc":["466"]}},"澳门地区":{"code":"00853","rule":{"mcc":["455"]}},"日本":{"code":"0081","rule":{"mcc":["440","441"]}},"韩国":{"code":"0082","rule":{"mcc":["450"]}},"新加坡":{"code":"0065","rule":{"mcc":["525"]}},"马来西亚":{"code":"0060","rule":{"mcc":["502"]}},"美国":{"code":"001","rule":{"mcc":["310","311","316"]}},"加拿大":{"code":"001","rule":{"mcc":["302"]}},"澳大利亚":{"code":"0061","rule":{"mcc":["505"]}},"英国":{"code":"0044","rule":{"mcc":["234"]}},"法国":{"code":"0033","rule":{"mcc":["208"]}},"俄罗斯":{"code":"007","rule":{"mcc":["250"]}},"印度":{"code":"0091","rule":{"mcc":["404"]}},"泰国":{"code":"0066","rule":{"mcc":["520"]}},"德国":{"code":"0049","rule":{"mcc":["262"]}}} \ No newline at end of file diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.h b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.h deleted file mode 100644 index f04b789b6..000000000 --- a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboSDK.h +++ /dev/null @@ -1,755 +0,0 @@ -// -// WeiboSDKHeaders.h -// WeiboSDKDemo -// -// Created by Wade Cheng on 4/3/13. -// Copyright (c) 2013 SINA iOS Team. All rights reserved. -// - -#import -#import - -#import "WBHttpRequest.h" -#import "WBHttpRequest+WeiboUser.h" -#import "WBHttpRequest+WeiboShare.h" -#import "WBHttpRequest+WeiboToken.h" -#import "WBHttpRequest+WeiboGame.h" -#import "WBSDKRelationshipButton.h" -#import "WBSDKCommentButton.h" - - -typedef NS_ENUM(NSInteger, WeiboSDKResponseStatusCode) -{ - WeiboSDKResponseStatusCodeSuccess = 0,//成功 - WeiboSDKResponseStatusCodeUserCancel = -1,//用户取消发送 - WeiboSDKResponseStatusCodeSentFail = -2,//发送失败 - WeiboSDKResponseStatusCodeAuthDeny = -3,//授权失败 - WeiboSDKResponseStatusCodeUserCancelInstall = -4,//用户取消安装微博客户端 - WeiboSDKResponseStatusCodePayFail = -5,//支付失败 - WeiboSDKResponseStatusCodeShareInSDKFailed = -8,//分享失败 详情见response UserInfo - WeiboSDKResponseStatusCodeUnsupport = -99,//不支持的请求 - WeiboSDKResponseStatusCodeUnknown = -100, -}; - -@protocol WeiboSDKDelegate; -@protocol WBHttpRequestDelegate; -@class WBBaseRequest; -@class WBBaseResponse; -@class WBMessageObject; -@class WBImageObject; -@class WBBaseMediaObject; -@class WBHttpRequest; -@class WBOrderObject; -/** - 微博SDK接口类 - */ -@interface WeiboSDK : NSObject - -/** - 检查用户是否安装了微博客户端程序 - @return 已安装返回YES,未安装返回NO - */ -+ (BOOL)isWeiboAppInstalled; - -/** - 检查用户是否可以通过微博客户端进行分享 - @return 可以使用返回YES,不可以使用返回NO - */ -+ (BOOL)isCanShareInWeiboAPP; - -/** - 检查用户是否可以使用微博客户端进行SSO授权 - @return 可以使用返回YES,不可以使用返回NO - */ -+ (BOOL)isCanSSOInWeiboApp; - -/** - 打开微博客户端程序 - @return 成功打开返回YES,失败返回NO - */ -+ (BOOL)openWeiboApp; - -/** - 获取微博客户端程序的itunes安装地址 - @return 微博客户端程序的itunes安装地址 - */ -+ (NSString *)getWeiboAppInstallUrl; - -/** - 获取当前微博客户端程序所支持的SDK最高版本 - @return 当前微博客户端程序所支持的SDK最高版本号,返回 nil 表示未安装微博客户端 - */ -+ (NSString *)getWeiboAppSupportMaxSDKVersion __attribute__((deprecated)); - -/** - 获取当前微博SDK的版本号 - @return 当前微博SDK的版本号 - */ -+ (NSString *)getSDKVersion; - - -extern NSString * const WeiboSDKGetAidSucessNotification; -extern NSString * const WeiboSDKGetAidFailNotification; -/** - 获取当前微博SDK的aid - 返回的aid值可能为 nil ,当值为 nil 时会尝试获取 aid 值。 - 当获取成功( aid 值变为有效值)时,SDK会发出名为 WeiboSDKGetAidSucessNotification 的通知,通知中带有 aid 值。 - 当获取失败时,SDK会发出名为 WeiboSDKGetAidFailNotification 的通知,通知中带有 NSError 对象。 - @return aid 用于广告的与设备信息相关的标识符 - */ -+ (NSString *)getWeiboAid; - -/** - 向微博客户端程序注册第三方应用 - @param appKey 微博开放平台第三方应用appKey - @return 注册成功返回YES,失败返回NO - */ -+ (BOOL)registerApp:(NSString *)appKey; - -/** - 处理微博客户端程序通过URL启动第三方应用时传递的数据 - - 需要在 application:openURL:sourceApplication:annotation:或者application:handleOpenURL中调用 - @param url 启动第三方应用的URL - @param delegate WeiboSDKDelegate对象,用于接收微博触发的消息 - @see WeiboSDKDelegate - */ -+ (BOOL)handleOpenURL:(NSURL *)url delegate:(id)delegate; - -/** - 发送请求给微博客户端程序,并切换到微博 - - 请求发送给微博客户端程序之后,微博客户端程序会进行相关的处理,处理完成之后一定会调用 [WeiboSDKDelegate didReceiveWeiboResponse:] 方法将处理结果返回给第三方应用 - - @param request 具体的发送请求 - - @see [WeiboSDKDelegate didReceiveWeiboResponse:] - @see WBBaseResponse - */ -+ (BOOL)sendRequest:(WBBaseRequest *)request; - -/** - 收到微博客户端程序的请求后,发送对应的应答给微博客户端端程序,并切换到微博 - - 第三方应用收到微博的请求后,异步处理该请求,完成后必须调用该函数将应答返回给微博 - - @param response 具体的应答内容 - @see WBBaseRequest - */ -+ (BOOL)sendResponse:(WBBaseResponse *)response; - -/** - 设置WeiboSDK的调试模式 - - 当开启调试模式时,WeiboSDK会在控制台输出详细的日志信息,开发者可以据此调试自己的程序。默认为 NO - @param enabled 开启或关闭WeiboSDK的调试模式 - */ -+ (void)enableDebugMode:(BOOL)enabled; - -/** - 取消授权,登出接口 - 调用此接口后,token将失效 - @param token 第三方应用之前申请的Token - @param delegate WBHttpRequestDelegate对象,用于接收微博SDK对于发起的接口请求的请求的响应 - @param tag 用户自定义TAG,将通过回调WBHttpRequest实例的tag属性返回 - - */ -+ (void)logOutWithToken:(NSString *)token delegate:(id)delegate withTag:(NSString*)tag; - -/** - 邀请好友使用应用 - 调用此接口后,将发送私信至好友,成功将返回微博标准私信结构 - @param data 邀请数据。必须为json字串的形式,必须做URLEncode,采用UTF-8编码。 - data参数支持的参数: - 参数名称 值的类型 是否必填 说明描述 - text string true 要回复的私信文本内容。文本大小必须小于300个汉字。 - url string false 邀请点击后跳转链接。默认为当前应用地址。 - invite_logo string false 邀请Card展示时的图标地址,大小必须为80px X 80px,仅支持PNG、JPG格式。默认为当前应用logo地址。 - @param uid 被邀请人,需为当前用户互粉好友。 - @param access_token 第三方应用之前申请的Token - @param delegate WBHttpRequestDelegate对象,用于接收微博SDK对于发起的接口请求的请求的响应 - @param tag 用户自定义TAG,将通过回调WBHttpRequest实例的tag属性返回 - - */ -+ (void)inviteFriend:(NSString* )data withUid:(NSString *)uid withToken:(NSString *)access_token delegate:(id)delegate withTag:(NSString*)tag; - -/* - 第三方调用微博短信注册或者登陆 - @param navTitle 为登陆页navigationBar的title,如果为空的话,默认为“验证码登陆” -*/ -+ (void)messageRegister:(NSString *)navTitle; -@end - -/** - 接收并处理来至微博客户端程序的事件消息 - */ -@protocol WeiboSDKDelegate - -/** - 收到一个来自微博客户端程序的请求 - - 收到微博的请求后,第三方应用应该按照请求类型进行处理,处理完后必须通过 [WeiboSDK sendResponse:] 将结果回传给微博 - @param request 具体的请求对象 - */ -- (void)didReceiveWeiboRequest:(WBBaseRequest *)request; - -/** - 收到一个来自微博客户端程序的响应 - - 收到微博的响应后,第三方应用可以通过响应类型、响应的数据和 WBBaseResponse.userInfo 中的数据完成自己的功能 - @param response 具体的响应对象 - */ -- (void)didReceiveWeiboResponse:(WBBaseResponse *)response; - -@end - - -#pragma mark - DataTransferObject and Base Request/Response - -/** - 微博客户端程序和第三方应用之间传输数据信息的基类 - */ -@interface WBDataTransferObject : NSObject - -/** - 自定义信息字典,用于数据传输过程中存储相关的上下文环境数据 - - 第三方应用给微博客户端程序发送 request 时,可以在 userInfo 中存储请求相关的信息。 - - @warning userInfo中的数据必须是实现了 `NSCoding` 协议的对象,必须保证能序列化和反序列化 - @warning 序列化后的数据不能大于10M - */ -@property (nonatomic, strong) NSDictionary *userInfo; - - -/** - 发送该数据对象的SDK版本号 - - 如果数据对象是自己生成的,则sdkVersion为当前SDK的版本号;如果是接收到的数据对象,则sdkVersion为数据发送方SDK版本号 - */ -@property (strong, nonatomic, readonly) NSString *sdkVersion; - - -/** - 当用户没有安装微博客户端程序时是否提示用户打开微博安装页面 - - 如果设置为YES,当用户未安装微博时会弹出Alert询问用户是否要打开微博App的安装页面。默认为YES - */ -@property (nonatomic, assign) BOOL shouldOpenWeiboAppInstallPageIfNotInstalled; - - -@end - - -/** - 微博SDK所有请求类的基类 - */ -@interface WBBaseRequest : WBDataTransferObject - -/** - 返回一个 WBBaseRequest 对象 - - @return 返回一个*自动释放的*WBBaseRequest对象 - */ -+ (id)request; - -@end - - -/** - 微博SDK所有响应类的基类 - */ -@interface WBBaseResponse : WBDataTransferObject - -/** - 对应的 request 中的自定义信息字典 - - 如果当前 response 是由微博客户端响应给第三方应用的,则 requestUserInfo 中会包含原 request.userInfo 中的所有数据 - - @see WBBaseRequest.userInfo - */ -@property (strong, nonatomic, readonly) NSDictionary *requestUserInfo; - -/** - 响应状态码 - - 第三方应用可以通过statusCode判断请求的处理结果 - */ -@property (nonatomic, assign) WeiboSDKResponseStatusCode statusCode; - -/** - 返回一个 WBBaseResponse 对象 - - @return 返回一个*自动释放的*WBBaseResponse对象 - */ -+ (id)response; - -@end - -#pragma mark - Authorize Request/Response - -/** - 第三方应用向微博客户端请求认证的消息结构 - - 第三方应用向微博客户端申请认证时,需要调用 [WeiboSDK sendRequest:] 函数, 向微博客户端发送一个 WBAuthorizeRequest 的消息结构。 - 微博客户端处理完后会向第三方应用发送一个结构为 WBAuthorizeResponse 的处理结果。 - */ -@interface WBAuthorizeRequest : WBBaseRequest - -/** - 微博开放平台第三方应用授权回调页地址,默认为`http://` - - 参考 http://open.weibo.com/wiki/%E6%8E%88%E6%9D%83%E6%9C%BA%E5%88%B6%E8%AF%B4%E6%98%8E#.E5.AE.A2.E6.88.B7.E7.AB.AF.E9.BB.98.E8.AE.A4.E5.9B.9E.E8.B0.83.E9.A1.B5 - - @warning 必须保证和在微博开放平台应用管理界面配置的“授权回调页”地址一致,如未进行配置则默认为`http://` - @warning 不能为空,长度小于1K - */ -@property (nonatomic, strong) NSString *redirectURI; - -/** - 微博开放平台第三方应用scope,多个scrope用逗号分隔 - - 参考 http://open.weibo.com/wiki/%E6%8E%88%E6%9D%83%E6%9C%BA%E5%88%B6%E8%AF%B4%E6%98%8E#scope - - @warning 长度小于1K - */ -@property (nonatomic, strong) NSString *scope; - -/** - 当用户没有安装微博客户端或微博客户端过低无法支持SSO的时候是否弹出SDK自带的Webview进行授权 - - 如果设置为YES,当用户没有安装微博客户端或微博客户端过低无法支持SSO的时候会自动弹出SDK自带的Webview进行授权。 - - 如果设置为NO,会根据 shouldOpenWeiboAppInstallPageIfNotInstalled 属性判断是否弹出安装/更新微博的对话框 - - 默认为YES - */ -@property (nonatomic, assign) BOOL shouldShowWebViewForAuthIfCannotSSO; - -@end - - -/** - 微博客户端处理完第三方应用的认证申请后向第三方应用回送的处理结果 - - WBAuthorizeResponse 结构中仅包含常用的 userID 、accessToken 和 expirationDate 信息,其他的认证信息(比如部分应用可以获取的 refresh_token 信息)会统一存放到 userInfo 中 - */ -@interface WBAuthorizeResponse : WBBaseResponse - -/** - 用户ID - */ -@property (nonatomic, strong) NSString *userID; - -/** - 认证口令 - */ -@property (nonatomic, strong) NSString *accessToken; - -/** - 认证过期时间 - */ -@property (nonatomic, strong) NSDate *expirationDate; - -/** - 当认证口令过期时用于换取认证口令的更新口令 - */ -@property (nonatomic, strong) NSString *refreshToken; - -@end - -#pragma mark - ProvideMessageForWeibo Request/Response - -/** - 微博客户端向第三方程序请求提供内容的消息结构 - */ -@interface WBProvideMessageForWeiboRequest : WBBaseRequest - -@end - -/** - 微博客户端向第三方应用请求提供内容,第三方应用向微博客户端返回的消息结构 - */ -@interface WBProvideMessageForWeiboResponse : WBBaseResponse - -/** - 提供给微博客户端的消息 - */ -@property (nonatomic, strong) WBMessageObject *message; - -/** - 返回一个 WBProvideMessageForWeiboResponse 对象 - @param message 需要回送给微博客户端程序的消息对象 - @return 返回一个*自动释放的*WBProvideMessageForWeiboResponse对象 - */ -+ (id)responseWithMessage:(WBMessageObject *)message; - -@end - -#pragma mark - SendMessageToWeibo Request/Response - -/** - 第三方应用发送消息至微博客户端程序的消息结构体 - */ -@interface WBSendMessageToWeiboRequest : WBBaseRequest - -/** - 发送给微博客户端的消息 - */ -@property (nonatomic, strong) WBMessageObject *message; - -/** - 返回一个 WBSendMessageToWeiboRequest 对象 - 此方法生成对象被[WeiboSDK sendRequest:]会唤起微博客户端的发布器进行分享,如果未安装微博客户端或客户端版本太低 - 会根据 shouldOpenWeiboAppInstallPageIfNotInstalled 属性判断是否弹出安装/更新微博的对话框 - @param message 需要发送给微博客户端的消息对象 - @return 返回一个*自动释放的*WBSendMessageToWeiboRequest对象 - */ -+ (id)requestWithMessage:(WBMessageObject *)message; - -/** - 返回一个 WBSendMessageToWeiboRequest 对象 - - 当用户安装了可以支持微博客户端內分享的微博客户端时,会自动唤起微博并分享 - 当用户没有安装微博客户端或微博客户端过低无法支持通过客户端內分享的时候会自动唤起SDK內微博发布器 - - @param message 需要发送给微博的消息对象 - @param authRequest 授权相关信息,与access_token二者至少有一个不为空,当access_token为空并且需要弹出SDK內发布器时会通过此信息先进行授权后再分享 - @param access_token 第三方应用之前申请的Token,当此值不为空并且无法通过客户端分享的时候,会使用此token进行分享。 - @return 返回一个*自动释放的*WBSendMessageToWeiboRequest对象 - */ -+ (id)requestWithMessage:(WBMessageObject *)message - authInfo:(WBAuthorizeRequest *)authRequest - access_token:(NSString *)access_token; - -@end - -/** - WBSendMessageToWeiboResponse - */ -@interface WBSendMessageToWeiboResponse : WBBaseResponse - -/** - 可能在分享过程中用户进行了授权操作,当此值不为空时,为用户相应授权信息 - */ -@property (nonatomic,strong) WBAuthorizeResponse *authResponse; -@end - -#pragma mark - AppRecomend Request/Response - -/** - 第三方应用私信好友推荐app的请求 - */ -@interface WBSDKAppRecommendRequest : WBBaseRequest -/** - 返回一个 WBSDKAppRecommendRequest 对象 - - @param uids 为推荐的好友列表,为空时跳转到用户自选的页面 - @param access_token 第三方应用之前申请的Token,当此值不为空并且无法通过客户端分享的时候,会使用此token私信。 - @return 返回一个*自动释放的*WBSDKAppRecommendRequest对象 - */ -+ (id)requestWithUIDs:(NSArray *)uids access_token:(NSString *)access_token; - -/** - 私信对象列表 - */ -@property (nonatomic, strong) NSArray* uids; -/** - 用于认证的Token - */ -@property (nonatomic, strong) NSString *access_token; -@end - -/** - 第三方应用私信好友推荐app的响应 - - WBSDKAppRecommendResponse 结构中仅包含常用的 userID 、accessToken 和 expirationDate 信息,其他的认证信息(比如部分应用可以获取的 refresh_token 信息)会统一存放到 userInfo 中 - */ -@interface WBSDKAppRecommendResponse : WBBaseResponse -@property (nonatomic,strong) WBAuthorizeResponse *authResponse; -/** - 用户ID - */ -@property (nonatomic, strong) NSString *userID; - -/** - 认证口令 - */ -@property (nonatomic, strong) NSString *accessToken; - -/** - 认证过期时间 - */ -@property (nonatomic, strong) NSDate *expirationDate; - -/** - 当认证口令过期时用于换取认证口令的更新口令 - */ -@property (nonatomic, strong) NSString *refreshToken; -@end - -#pragma mark - Payment Request/Response - -/** - 第三方应用发送消息至微博客户端程序的消息结构体 - */ -@interface WBPaymentRequest : WBBaseRequest - -/** - 发送给微博客户端的订单 - */ -@property (nonatomic, strong) WBOrderObject *order; - -/** - 返回一个 WBPaymentRequest 对象 - @param message 需要发送给微博客户端程序的消息对象 - @return 返回一个*自动释放的*WBSendMessageToWeiboRequest对象 - */ -+ (id)requestWithOrder:(WBOrderObject *)order; - -@end - -/** - WBPaymentResponse - */ -@interface WBPaymentResponse : WBBaseResponse - -/** - 支付返回状态码 - */ -@property (nonatomic, strong) NSString *payStatusCode; - -/** - 支付返回状态信息 - */ -@property (nonatomic, strong) NSString *payStatusMessage; - -@end - -#pragma mark - MessageObject / ImageObject - -/** - 微博客户端程序和第三方应用之间传递的消息结构 - - 一个消息结构由三部分组成:文字、图片和多媒体数据。三部分内容中至少有一项不为空,图片和多媒体数据不能共存。 - */ -@interface WBMessageObject : NSObject - -/** - 消息的文本内容 - - @warning 长度小于140个汉字 - */ -@property (nonatomic, strong) NSString *text; - -/** - 消息的图片内容 - - @see WBImageObject - */ -@property (nonatomic, strong) WBImageObject *imageObject; - -/** - 消息的多媒体内容 - - @see WBBaseMediaObject - */ -@property (nonatomic, strong) WBBaseMediaObject *mediaObject; - -/** - 返回一个 WBMessageObject 对象 - - @return 返回一个*自动释放的*WBMessageObject对象 - */ -+ (id)message; - -@end - -/** - 消息中包含的图片数据对象 - */ -@interface WBImageObject : NSObject - -/** - 图片真实数据内容 - - @warning 大小不能超过10M - */ -@property (nonatomic, strong) NSData *imageData; - -/** - 返回一个 WBImageObject 对象 - - @return 返回一个*自动释放的*WBImageObject对象 - */ -+ (id)object; - -/** - 返回一个 UIImage 对象 - - @return 返回一个*自动释放的*UIImage对象 - */ -- (UIImage *)image; - -@end - -#pragma mark - Message Media Objects - -/** - 消息中包含的多媒体数据对象基类 - */ -@interface WBBaseMediaObject : NSObject - -/** - 对象唯一ID,用于唯一标识一个多媒体内容 - - 当第三方应用分享多媒体内容到微博时,应该将此参数设置为被分享的内容在自己的系统中的唯一标识 - @warning 不能为空,长度小于255 - */ -@property (nonatomic, strong) NSString *objectID; - -/** - 多媒体内容标题 - @warning 不能为空且长度小于1k - */ -@property (nonatomic, strong) NSString *title; - -/** - 多媒体内容描述 - @warning 长度小于1k - */ -@property (nonatomic, strong) NSString *description; - -/** - 多媒体内容缩略图 - @warning 大小小于32k - */ -@property (nonatomic, strong) NSData *thumbnailData; - -/** - 点击多媒体内容之后呼起第三方应用特定页面的scheme - @warning 长度小于255 - */ -@property (nonatomic, strong) NSString *scheme; - -/** - 返回一个 WBBaseMediaObject 对象 - - @return 返回一个*自动释放的*WBBaseMediaObject对象 - */ -+ (id)object; - -@end - -#pragma mark - Message Video Objects - -/** - 消息中包含的视频数据对象 - */ -@interface WBVideoObject : WBBaseMediaObject - -/** - 视频网页的url - - @warning 不能为空且长度不能超过255 - */ -@property (nonatomic, strong) NSString *videoUrl; - -/** - 视频lowband网页的url - - @warning 长度不能超过255 - */ -@property (nonatomic, strong) NSString *videoLowBandUrl; - -/** - 视频数据流url - - @warning 长度不能超过255 - */ -@property (nonatomic, strong) NSString *videoStreamUrl; - -/** - 视频lowband数据流url - - @warning 长度不能超过255 - */ -@property (nonatomic, strong) NSString *videoLowBandStreamUrl; - -@end - -#pragma mark - Message Music Objects - -/** - 消息中包含的音乐数据对象 - */ -@interface WBMusicObject : WBBaseMediaObject - -/** - 音乐网页url地址 - - @warning 不能为空且长度不能超过255 - */ -@property (nonatomic, strong) NSString *musicUrl; - -/** - 音乐lowband网页url地址 - - @warning 长度不能超过255 - */ -@property (nonatomic, strong) NSString *musicLowBandUrl; - -/** - 音乐数据流url - - @warning 长度不能超过255 - */ -@property (nonatomic, strong) NSString *musicStreamUrl; - - -/** - 音乐lowband数据流url - - @warning 长度不能超过255 - */ -@property (nonatomic, strong) NSString *musicLowBandStreamUrl; - -@end - -#pragma mark - Message WebPage Objects - -/** - 消息中包含的网页数据对象 - */ -@interface WBWebpageObject : WBBaseMediaObject - -/** - 网页的url地址 - - @warning 不能为空且长度不能超过255 - */ -@property (nonatomic, strong) NSString *webpageUrl; - -@end - -#pragma mark - OrderObject - -/** - 微博客户端程序和第三方应用之间传递的订单结构 - */ -@interface WBOrderObject : NSObject - -/** - 订单编号 - */ -@property (nonatomic, strong) NSString *orderString; - - -/** - 返回一个 WBOrderObject 对象 - - @return 返回一个*自动释放的*WBOrderObject对象 - */ -+ (id)order; - -@end \ No newline at end of file diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboUser.h b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboUser.h deleted file mode 100644 index 8c356c6ad..000000000 --- a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/WeiboUser.h +++ /dev/null @@ -1,77 +0,0 @@ -// -// WeiboUser.h -// WeiboSDK -// -// Created by DannionQiu on 14-9-23. -// Copyright (c) 2014年 SINA iOS Team. All rights reserved. -// - -#import - -/*@ - You can get the latest WeiboUser field description on http://open.weibo.com/wiki/2/friendships/friends/en . -*/ -@interface WeiboUser : NSObject - -- (instancetype)initWithDictionary:(NSDictionary*)paraDict; -+ (instancetype)userWithDictionary:(NSDictionary*)paraDict; - -// Validate the dictionary to be converted. -+ (BOOL)isValidForDictionary:(NSDictionary *)dict; - -- (BOOL)updateWithDictionary:(NSDictionary*)paraDict; - - -@property(readwrite, strong, nonatomic) NSString* userID; -@property(readwrite, strong, nonatomic) NSString* userClass; -@property(readwrite, strong, nonatomic) NSString* screenName; -@property(readwrite, strong, nonatomic) NSString* name; -@property(readwrite, strong, nonatomic) NSString* province; -@property(readwrite, strong, nonatomic) NSString* city; -@property(readwrite, strong, nonatomic) NSString* location; -@property(readwrite, strong, nonatomic) NSString* userDescription; -@property(readwrite, strong, nonatomic) NSString* url; -@property(readwrite, strong, nonatomic) NSString* profileImageUrl; -@property(readwrite, strong, nonatomic) NSString* coverImageUrl; -@property(readwrite, strong, nonatomic) NSString* coverImageForPhoneUrl; -@property(readwrite, strong, nonatomic) NSString* profileUrl; -@property(readwrite, strong, nonatomic) NSString* userDomain; -@property(readwrite, strong, nonatomic) NSString* weihao; -@property(readwrite, strong, nonatomic) NSString* gender; -@property(readwrite, strong, nonatomic) NSString* followersCount; -@property(readwrite, strong, nonatomic) NSString* friendsCount; -@property(readwrite, strong, nonatomic) NSString* pageFriendsCount; -@property(readwrite, strong, nonatomic) NSString* statusesCount; -@property(readwrite, strong, nonatomic) NSString* favouritesCount; -@property(readwrite, strong, nonatomic) NSString* createdTime; -@property(readwrite, assign, nonatomic) BOOL isFollowingMe; -@property(readwrite, assign, nonatomic) BOOL isFollowingByMe; -@property(readwrite, assign, nonatomic) BOOL isAllowAllActMsg; -@property(readwrite, assign, nonatomic) BOOL isAllowAllComment; -@property(readwrite, assign, nonatomic) BOOL isGeoEnabled; -@property(readwrite, assign, nonatomic) BOOL isVerified; -@property(readwrite, strong, nonatomic) NSString* verifiedType; -@property(readwrite, strong, nonatomic) NSString* remark; -@property(readwrite, strong, nonatomic) NSString* statusID; -@property(readwrite, strong, nonatomic) NSString* ptype; -@property(readwrite, strong, nonatomic) NSString* avatarLargeUrl; -@property(readwrite, strong, nonatomic) NSString* avatarHDUrl; -@property(readwrite, strong, nonatomic) NSString* verifiedReason; -@property(readwrite, strong, nonatomic) NSString* verifiedTrade; -@property(readwrite, strong, nonatomic) NSString* verifiedReasonUrl; -@property(readwrite, strong, nonatomic) NSString* verifiedSource; -@property(readwrite, strong, nonatomic) NSString* verifiedSourceUrl; -@property(readwrite, strong, nonatomic) NSString* verifiedState; -@property(readwrite, strong, nonatomic) NSString* verifiedLevel; -@property(readwrite, strong, nonatomic) NSString* onlineStatus; -@property(readwrite, strong, nonatomic) NSString* biFollowersCount; -@property(readwrite, strong, nonatomic) NSString* language; -@property(readwrite, strong, nonatomic) NSString* star; -@property(readwrite, strong, nonatomic) NSString* mbtype; -@property(readwrite, strong, nonatomic) NSString* mbrank; -@property(readwrite, strong, nonatomic) NSString* block_word; -@property(readwrite, strong, nonatomic) NSString* block_app; -@property(readwrite, strong, nonatomic) NSString* credit_score; -@property(readwrite, strong, nonatomic) NSDictionary* originParaDict; - -@end diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/libSocialSinaSSO.a b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/libSocialSinaSSO.a deleted file mode 100644 index 0e58e3e07..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/libSocialSinaSSO.a and /dev/null differ diff --git a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/libWeiboSDK.a b/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/libWeiboSDK.a deleted file mode 100644 index 12fc34396..000000000 Binary files a/Coding_iOS/Vendor/UMSocial_Sdk_4.3.0_Extra/SinaSSO/libWeiboSDK.a and /dev/null differ diff --git a/Coding_iOS/Vendor/XHRealTimeBlur/XHRealTimeBlur.m b/Coding_iOS/Vendor/XHRealTimeBlur/XHRealTimeBlur.m index abce2f3ec..0a41fdec5 100644 --- a/Coding_iOS/Vendor/XHRealTimeBlur/XHRealTimeBlur.m +++ b/Coding_iOS/Vendor/XHRealTimeBlur/XHRealTimeBlur.m @@ -301,4 +301,4 @@ - (void)disMissRealTimeBlur { [[self realTimeBlur] disMiss]; } -@end \ No newline at end of file +@end diff --git a/Coding_iOS/Vendor/XTSegmentControl/XTSegmentControl.m b/Coding_iOS/Vendor/XTSegmentControl/XTSegmentControl.m index 5b1f27fce..8f425f311 100755 --- a/Coding_iOS/Vendor/XTSegmentControl/XTSegmentControl.m +++ b/Coding_iOS/Vendor/XTSegmentControl/XTSegmentControl.m @@ -12,9 +12,9 @@ #define XTSegmentControlItemFont (15) -#define XTSegmentControlHspace (0) +#define XTSegmentControlHspace ([self p_Hspace]) -#define XTSegmentControlLineHeight (2) +#define XTSegmentControlLineHeight ([self p_LineHeight]) #define XTSegmentControlAnimationTime (0.3) @@ -22,6 +22,9 @@ #define XTSegmentControlIconSpace (4) +#define XTSegmentControl_SelectedColor kColorLightBlue + + typedef NS_ENUM(NSInteger, XTSegmentControlItemType) { XTSegmentControlItemTypeTitle = 0, @@ -48,7 +51,7 @@ - (id)initWithFrame:(CGRect)frame title:(NSString *)title type:(XTSegmentControl switch (_type) { case XTSegmentControlItemTypeIconUrl: { - _titleIconView = [[UIImageView alloc] initWithFrame:CGRectMake((CGRectGetWidth(self.bounds)-40)/2, (CGRectGetHeight(self.bounds)-40)/2, 40, 40)]; + _titleIconView = [[YLImageView alloc] initWithFrame:CGRectMake((CGRectGetWidth(self.bounds)-40)/2, (CGRectGetHeight(self.bounds)-40)/2, 40, 40)]; [_titleIconView doCircleFrame]; if (title) { [_titleIconView sd_setImageWithURL:[title urlImageWithCodePathResizeToView:_titleIconView] placeholderImage:kPlaceholderMonkeyRoundView(_titleIconView)]; @@ -90,7 +93,8 @@ - (id)initWithFrame:(CGRect)frame title:(NSString *)title type:(XTSegmentControl default: { _titleLabel = ({ - UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(XTSegmentControlHspace, 0, CGRectGetWidth(self.bounds) - 2 * XTSegmentControlHspace, CGRectGetHeight(self.bounds))]; +// UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(XTSegmentControlHspace, 0, CGRectGetWidth(self.bounds) - 2 * XTSegmentControlHspace, CGRectGetHeight(self.bounds))]; + UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds))]; label.font = [UIFont systemFontOfSize:XTSegmentControlItemFont]; label.textAlignment = NSTextAlignmentCenter; label.text = title; @@ -99,7 +103,6 @@ - (id)initWithFrame:(CGRect)frame title:(NSString *)title type:(XTSegmentControl label; }); - [self addSubview:_titleLabel]; } break; @@ -118,7 +121,7 @@ - (void)setSelected:(BOOL)selected case XTSegmentControlItemTypeTitleAndIcon: { if (_titleLabel) { - [_titleLabel setTextColor:(selected ? kColorBrandGreen:kColor222)]; + [_titleLabel setTextColor:(selected ? XTSegmentControl_SelectedColor:kColor222)]; } if (_titleIconView) { [_titleIconView setImage:[UIImage imageNamed: selected ? @"tag_list_down" : @"tag_list_up"]]; @@ -128,7 +131,7 @@ - (void)setSelected:(BOOL)selected default: { if (_titleLabel) { - [_titleLabel setTextColor:(selected ? kColorBrandGreen:kColor222)]; + [_titleLabel setTextColor:(selected ? XTSegmentControl_SelectedColor:kColor222)]; } } break; @@ -199,7 +202,7 @@ - (void)setupUI_IsIcon:(BOOL)isIcon Items:(NSArray *)titleItem { _contentView = ({ UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.bounds]; - scrollView.backgroundColor = kColorTableBG; + scrollView.backgroundColor = [UIColor clearColor]; scrollView.delegate = self; scrollView.showsHorizontalScrollIndicator = NO; scrollView.scrollsToTop = NO; @@ -210,6 +213,7 @@ - (void)setupUI_IsIcon:(BOOL)isIcon Items:(NSArray *)titleItem [tapGes requireGestureRecognizerToFail:scrollView.panGestureRecognizer]; scrollView; }); + self.backgroundColor = kColorTableBG; [self initItemsWithTitleArray:titleItem withIcon:isIcon]; } @@ -277,7 +281,6 @@ - (void)initItemsWithTitleArray:(NSArray *)titleArray withIcon:(BOOL)isIcon _items = @[].mutableCopy; float y = 0; float height = CGRectGetHeight(self.bounds); - NSObject *obj = [titleArray firstObject]; if ([obj isKindOfClass:[NSString class]]) { for (int i = 0; i < titleArray.count; i++) { @@ -286,7 +289,27 @@ - (void)initItemsWithTitleArray:(NSArray *)titleArray withIcon:(BOOL)isIcon CGRect rect = CGRectMake(x, y, width, height); [_itemFrames addObject:[NSValue valueWithCGRect:rect]]; } - + if (!isIcon) { + BOOL needResize = NO; + for (int i = 0; i < titleArray.count; i++) { + CGRect rect = [_itemFrames[i] CGRectValue]; + NSString *title = titleArray[i]; + if ([title getWidthWithFont:[UIFont systemFontOfSize:XTSegmentControlItemFont] constrainedToSize:CGSizeMake(CGFLOAT_MAX, 20)] > rect.size.width) { + needResize = YES; + break; + } + } + if (needResize) { + [_itemFrames removeAllObjects]; + for (int i = 0; i < titleArray.count; i++) { + NSString *title = titleArray[i]; + float width = [title getWidthWithFont:[UIFont systemFontOfSize:XTSegmentControlItemFont] constrainedToSize:CGSizeMake(CGFLOAT_MAX, 20)] + 25; + float x = i > 0 ? CGRectGetMaxX([_itemFrames[i-1] CGRectValue]) : 0; + CGRect rect = CGRectMake(x, y, width, height); + [_itemFrames addObject:[NSValue valueWithCGRect:rect]]; + } + } + } for (int i = 0; i < titleArray.count; i++) { CGRect rect = [_itemFrames[i] CGRectValue]; NSString *title = titleArray[i]; @@ -343,7 +366,7 @@ - (void)initItemsWithTitleArray:(NSArray *)titleArray withIcon:(BOOL)isIcon (CGRectGetHeight(rect) - 14) * 0.5, 1, 14)]; - lineView.backgroundColor = kColorDDD; + lineView.backgroundColor = kColorD8DDE4; [self addSubview:lineView]; } } @@ -353,20 +376,43 @@ - (void)addRedLine { if (!_lineView) { CGRect rect = [_itemFrames[0] CGRectValue]; - _lineView = [[UIView alloc] initWithFrame:CGRectMake( - CGRectGetMinX(rect), - CGRectGetHeight(rect) - XTSegmentControlLineHeight, - CGRectGetWidth(rect) - 2 * XTSegmentControlHspace, - XTSegmentControlLineHeight)]; - _lineView.backgroundColor = kColorBrandGreen; + + CGRect lineRect = CGRectMake(CGRectGetMinX(rect) + XTSegmentControlHspace, + CGRectGetHeight(rect) - XTSegmentControlLineHeight - .5, + CGRectGetWidth(rect) - 2 * XTSegmentControlHspace, + XTSegmentControlLineHeight); + _lineView = [[UIView alloc] initWithFrame:lineRect]; + _lineView.backgroundColor = XTSegmentControl_SelectedColor; + _lineView.layer.cornerRadius = 1.5; + _lineView.layer.masksToBounds = YES; [_contentView addSubview:_lineView]; UIView *bottomLineView = [[UIView alloc] initWithFrame:CGRectMake(0, CGRectGetHeight(rect)-0.5, CGRectGetWidth(self.bounds), 0.5)]; - bottomLineView.backgroundColor = kColorDDD; + bottomLineView.backgroundColor = kColorD8DDE4; [self addSubview:bottomLineView]; } } +- (CGFloat)p_Hspace{ + CGFloat value = 0; + CGRect rect = [_itemFrames.firstObject CGRectValue]; + value = MAX(0, (rect.size.width - 20) / 2); +// XTSegmentControlItem *item = _items.firstObject; +// if (item.type == XTSegmentControlItemTypeIconUrl) { +// value = 15; +// } + return value; +} + +- (CGFloat)p_LineHeight{ + CGFloat value = 3; +// XTSegmentControlItem *item = _items.firstObject; +// if (item.type == XTSegmentControlItemTypeIconUrl) { +// value = 2; +// } + return value; +} + - (void)setTitle:(NSString *)title withIndex:(NSInteger)index { XTSegmentControlItem *curItem = [_items objectAtIndex:index]; @@ -388,7 +434,7 @@ - (void)selectIndex:(NSInteger)index if (index != _currentIndex) { XTSegmentControlItem *curItem = [_items objectAtIndex:index]; CGRect rect = [_itemFrames[index] CGRectValue]; - CGRect lineRect = CGRectMake(CGRectGetMinX(rect) + XTSegmentControlHspace, CGRectGetHeight(rect) - XTSegmentControlLineHeight, CGRectGetWidth(rect) - 2 * XTSegmentControlHspace, XTSegmentControlLineHeight); + CGRect lineRect = CGRectMake(CGRectGetMinX(rect) + XTSegmentControlHspace, CGRectGetHeight(rect) - XTSegmentControlLineHeight - .5, CGRectGetWidth(rect) - 2 * XTSegmentControlHspace, XTSegmentControlLineHeight); if (_currentIndex < 0) { _lineView.frame = lineRect; [curItem setSelected:YES]; @@ -417,7 +463,7 @@ - (void)moveIndexWithProgress:(float)progress CGRect origionRect = [_itemFrames[_currentIndex] CGRectValue];; - CGRect origionLineRect = CGRectMake(CGRectGetMinX(origionRect) + XTSegmentControlHspace, CGRectGetHeight(origionRect) - XTSegmentControlLineHeight, CGRectGetWidth(origionRect) - 2 * XTSegmentControlHspace, XTSegmentControlLineHeight); + CGRect origionLineRect = CGRectMake(CGRectGetMinX(origionRect) + XTSegmentControlHspace, CGRectGetHeight(origionRect) - XTSegmentControlLineHeight - .5, CGRectGetWidth(origionRect) - 2 * XTSegmentControlHspace, XTSegmentControlLineHeight); CGRect rect; @@ -427,7 +473,7 @@ - (void)moveIndexWithProgress:(float)progress self.currentIndex += floorf(delta); delta -= floorf(delta); origionRect = [_itemFrames[_currentIndex] CGRectValue];; - origionLineRect = CGRectMake(CGRectGetMinX(origionRect) + XTSegmentControlHspace, CGRectGetHeight(origionRect) - XTSegmentControlLineHeight, CGRectGetWidth(origionRect) - 2 * XTSegmentControlHspace, XTSegmentControlLineHeight); + origionLineRect = CGRectMake(CGRectGetMinX(origionRect) + XTSegmentControlHspace, CGRectGetHeight(origionRect) - XTSegmentControlLineHeight - .5, CGRectGetWidth(origionRect) - 2 * XTSegmentControlHspace, XTSegmentControlLineHeight); } @@ -438,7 +484,7 @@ - (void)moveIndexWithProgress:(float)progress rect = [_itemFrames[_currentIndex + 1] CGRectValue]; - CGRect lineRect = CGRectMake(CGRectGetMinX(rect) + XTSegmentControlHspace, CGRectGetHeight(rect) - XTSegmentControlLineHeight, CGRectGetWidth(rect) - 2 * XTSegmentControlHspace, XTSegmentControlLineHeight); + CGRect lineRect = CGRectMake(CGRectGetMinX(rect) + XTSegmentControlHspace, CGRectGetHeight(rect) - XTSegmentControlLineHeight - .5, CGRectGetWidth(rect) - 2 * XTSegmentControlHspace, XTSegmentControlLineHeight); CGRect moveRect = CGRectZero; @@ -451,7 +497,7 @@ - (void)moveIndexWithProgress:(float)progress return; } rect = [_itemFrames[_currentIndex - 1] CGRectValue]; - CGRect lineRect = CGRectMake(CGRectGetMinX(rect) + XTSegmentControlHspace, CGRectGetHeight(rect) - XTSegmentControlLineHeight, CGRectGetWidth(rect) - 2 * XTSegmentControlHspace, XTSegmentControlLineHeight); + CGRect lineRect = CGRectMake(CGRectGetMinX(rect) + XTSegmentControlHspace, CGRectGetHeight(rect) - XTSegmentControlLineHeight - .5, CGRectGetWidth(rect) - 2 * XTSegmentControlHspace, XTSegmentControlLineHeight); CGRect moveRect = CGRectZero; moveRect.size = CGSizeMake(CGRectGetWidth(origionLineRect) - delta * (CGRectGetWidth(lineRect) - CGRectGetWidth(origionLineRect)), CGRectGetHeight(lineRect)); moveRect.origin = CGPointMake(CGRectGetMidX(origionLineRect) - delta * (CGRectGetMidX(lineRect) - CGRectGetMidX(origionLineRect)) - CGRectGetMidX(moveRect), CGRectGetMidY(origionLineRect) - CGRectGetMidY(moveRect)); diff --git a/Coding_iOS/Vendor/YLGIFImage/YLGIFImage.h b/Coding_iOS/Vendor/YLGIFImage/YLGIFImage.h index 897ea9b26..3605542fd 100644 --- a/Coding_iOS/Vendor/YLGIFImage/YLGIFImage.h +++ b/Coding_iOS/Vendor/YLGIFImage/YLGIFImage.h @@ -29,7 +29,7 @@ /** Number of loops the image can do before it stops */ -@property (nonatomic, readonly) NSUInteger loopCount; +@property (nonatomic, readwrite) NSUInteger loopCount;//easeeeeeeeee 由 readonly 权限改为 readwrite - (UIImage*)getFrameWithIndex:(NSUInteger)idx; diff --git a/Coding_iOS/Vendor/YLGIFImage/YLGIFImage.m b/Coding_iOS/Vendor/YLGIFImage/YLGIFImage.m index ff3b432e6..c2de1f6bb 100644 --- a/Coding_iOS/Vendor/YLGIFImage/YLGIFImage.m +++ b/Coding_iOS/Vendor/YLGIFImage/YLGIFImage.m @@ -65,7 +65,7 @@ @interface YLGIFImage () @property (nonatomic, readwrite) NSMutableArray *images; @property (nonatomic, readwrite) NSTimeInterval *frameDurations; @property (nonatomic, readwrite) NSTimeInterval totalDuration; -@property (nonatomic, readwrite) NSUInteger loopCount; +//@property (nonatomic, readwrite) NSUInteger loopCount; @property (nonatomic, readwrite) CGImageSourceRef incrementalSource; @end @@ -291,4 +291,4 @@ - (void)dealloc { } } -@end \ No newline at end of file +@end diff --git a/Coding_iOS/Views/ActivityMonScrollView.h b/Coding_iOS/Views/ActivityMonScrollView.h new file mode 100644 index 000000000..7f552e567 --- /dev/null +++ b/Coding_iOS/Views/ActivityMonScrollView.h @@ -0,0 +1,17 @@ +// +// ActivityMonScrollView.h +// Coding_iOS +// +// Created by 张达棣 on 16/11/29. +// Copyright © 2016年 Coding. All rights reserved. +// + +#import +#import "ActivenessModel.h" + + +@interface ActivityMonScrollView : UIScrollView +@property (nonatomic, strong) NSArray *dailyActiveness; +@property (nonatomic, assign) NSInteger startMon; //开始的月份 + +@end diff --git a/Coding_iOS/Views/ActivityMonScrollView.m b/Coding_iOS/Views/ActivityMonScrollView.m new file mode 100644 index 000000000..3e652978f --- /dev/null +++ b/Coding_iOS/Views/ActivityMonScrollView.m @@ -0,0 +1,108 @@ +// +// ActivityMonScrollView.m +// Coding_iOS +// +// Created by 张达棣 on 16/11/29. +// Copyright © 2016年 Coding. All rights reserved. +// + +#import "ActivityMonScrollView.h" +#import "ActivityView.h" + +#define KMon 12 + +@interface ActivityMonScrollView () +@property (nonatomic, strong) ActivityView *activityView; +@property (nonatomic, strong) NSMutableArray *monLabelArray; +@end + +@implementation ActivityMonScrollView + +#pragma mark - 生命周期方法 + +- (void)awakeFromNib { + [super awakeFromNib]; + [self creatView]; + +} + +- (instancetype)init { + self = [super init]; + if (self) { + [self creatView]; + } + return self; +} + +#pragma mark - 外部方法 + +#pragma makr - 消息 + +#pragma mark - 系统委托 + +#pragma mark - 自定义委托 + +#pragma mark - 响应方法 + +#pragma mark - 私有方法 + +- (void)creatView { + self.showsHorizontalScrollIndicator = NO; + _activityView = [[ActivityView alloc] init]; + [self addSubview:_activityView]; + [self setupAutoContentSizeWithRightView:_activityView rightMargin:15]; + + self.monLabelArray = [NSMutableArray arrayWithCapacity:KMon]; + for (int i = 0; i < KMon; i++) { + UILabel *label = [[UILabel alloc] init]; + label.textColor = [UIColor colorWithRGBHex:0x666666]; + label.font = [UIFont systemFontOfSize:12]; + [self addSubview:label]; + label.sd_layout.leftSpaceToView(self, 22 + i * 48).topSpaceToView(self, 0).heightIs(17).widthIs(24); + [_monLabelArray addObject:label]; + } +} + +#pragma mark - get/set方法 + +- (void)setDailyActiveness:(NSArray *)dailyActiveness { + _dailyActiveness = dailyActiveness; + + NSMutableArray *colorArray = [NSMutableArray array]; + for (DailyActiveness *item in dailyActiveness) { + UIColor *color; + if (item.count.integerValue == 0) { + color = [UIColor colorWithRGBHex:0xeeeeee]; + } else if (1 <= item.count.integerValue && item.count.integerValue <= 24) { + color = [UIColor colorWithRGBHex:0xd6e685]; + } else if (25 <= item.count.integerValue && item.count.integerValue <= 49) { + color = [UIColor colorWithRGBHex:0x8cc665]; + } else if (50 <= item.count.integerValue && item.count.integerValue <= 74) { + color = [UIColor colorWithRGBHex:0x44a340]; + } else if (75 <= item.count.integerValue) { + color = [UIColor colorWithRGBHex:0x1e6923]; + } + [colorArray addObject:color]; + } + _activityView.colorArray = colorArray; + NSInteger row = colorArray.count / 7; + if (colorArray.count % 7 != 0) { + row++; + } + _activityView.sd_layout.leftSpaceToView(self, 0).topSpaceToView(self, 22).heightIs(77).widthIs(row * 11); + +} + +- (void)setStartMon:(NSInteger)startMon { + _startMon = startMon; + + NSArray *monArray = @[@"Dec", @"Jan", @"Feb", @"Mar", @"Apr", @"May", @"Jun", @"Jul", @"Aug", @"Sep", @"Oct", @"Nov"]; + for (NSInteger i = _startMon; i < _startMon + KMon; i++) { + NSString *mon = monArray[(i + 1) % KMon];//UI 元素的位置是下个月开始的位置,所以月份也显示成下个月 + UILabel *label = _monLabelArray[i - _startMon]; + label.text = mon; + } +} + + +@end diff --git a/Coding_iOS/Views/ActivityView.h b/Coding_iOS/Views/ActivityView.h new file mode 100644 index 000000000..245ca939c --- /dev/null +++ b/Coding_iOS/Views/ActivityView.h @@ -0,0 +1,14 @@ +// +// ActivityView.h +// Coding_iOS +// +// Created by 张达棣 on 16/11/29. +// Copyright © 2016年 Coding. All rights reserved. +// + +#import + +@interface ActivityView : UIView +@property (nonatomic, strong) NSArray *colorArray; + +@end diff --git a/Coding_iOS/Views/ActivityView.m b/Coding_iOS/Views/ActivityView.m new file mode 100644 index 000000000..3631e4f41 --- /dev/null +++ b/Coding_iOS/Views/ActivityView.m @@ -0,0 +1,58 @@ +// +// ActivityView.m +// Coding_iOS +// +// Created by 张达棣 on 16/11/29. +// Copyright © 2016年 Coding. All rights reserved. +// + +#import "ActivityView.h" + +@interface ActivityView () +@property (nonatomic, strong) NSArray *typeColorArray; +@end + +@implementation ActivityView + +- (void)awakeFromNib { + [super awakeFromNib]; + [self creatView]; + +} + +- (instancetype)init { + self = [super init]; + if (self) { + [self creatView]; + } + return self; +} + +- (void)drawRect:(CGRect)rect { + [super drawRect:rect]; + + CGContextRef ctx = UIGraphicsGetCurrentContext(); + + for (int i = 0; i < _colorArray.count; ++i) { + NSInteger line = i /7; + NSInteger row = i % 7; + CGContextAddRect(ctx, CGRectMake(line * 11, row * 11, 10, 10)); + UIColor *color = _colorArray[i]; + [color set]; + CGContextFillPath(ctx); + } + +} + +- (void)creatView { + self.backgroundColor = [UIColor whiteColor]; +} + +- (void)setColorArray:(NSArray *)colorArray { + _colorArray = colorArray; + [self setNeedsDisplay]; + + +} + +@end diff --git a/Coding_iOS/Views/CCell/MessageMediaItemCCell.m b/Coding_iOS/Views/CCell/MessageMediaItemCCell.m index 8cb041ff3..ba8dda11b 100755 --- a/Coding_iOS/Views/CCell/MessageMediaItemCCell.m +++ b/Coding_iOS/Views/CCell/MessageMediaItemCCell.m @@ -72,7 +72,7 @@ - (void)setCurObj:(NSObject *)curObj{ } +(CGSize)ccellSizeWithObj:(NSObject *)obj{ - CGSize itemSize; + CGSize itemSize = CGSizeZero; if ([obj isKindOfClass:[UIImage class]]) { itemSize = [[ImageSizeManager shareManager] sizeWithImage:(UIImage *)obj originalWidth:kMessageCell_ContentWidth maxHeight:kScreen_Height/2]; }else if ([obj isKindOfClass:[VoiceMedia class]]) { diff --git a/Coding_iOS/Views/CCell/ShopGoodsCCell.h b/Coding_iOS/Views/CCell/ShopGoodsCCell.h index 81e0ac989..11f868190 100644 --- a/Coding_iOS/Views/CCell/ShopGoodsCCell.h +++ b/Coding_iOS/Views/CCell/ShopGoodsCCell.h @@ -14,6 +14,7 @@ UILabel *_priceLabel; UILabel *_titleLabel; + UILabel *_countLabel; UIButton *_codingCoinView; UIImageView *_exchangeIconView; diff --git a/Coding_iOS/Views/CCell/ShopGoodsCCell.m b/Coding_iOS/Views/CCell/ShopGoodsCCell.m index 1d953e15a..301c1602b 100644 --- a/Coding_iOS/Views/CCell/ShopGoodsCCell.m +++ b/Coding_iOS/Views/CCell/ShopGoodsCCell.m @@ -17,105 +17,85 @@ - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { - + self.clipsToBounds = YES; + self.backgroundColor = [UIColor whiteColor]; [self setUpContentView]; - } return self; } -- (void)setUpContentView -{ -// self.contentView.backgroundColor = [UIColor whiteColor]; -// self.contentView.layer.borderColor = [UIColor lightGrayColor].CGColor; -// self.contentView.layer.borderWidth = 0.5; - - //float height = self.frame.size.width*((466.0/600.0)); - // float height = (UIWidth - 30)/2; +- (void)setUpContentView{ UIView *superView = self.contentView; - _coverView = [[UIImageView alloc] initWithFrame:CGRectZero]; + _coverView = [[YLImageView alloc] initWithFrame:CGRectZero]; _coverView.backgroundColor = [UIColor colorWithHexString:@"0xe5e5e5"]; _coverView.contentMode = UIViewContentModeScaleAspectFill; _coverView.layer.masksToBounds =YES; [superView addSubview:_coverView]; -// _priceLabel = [[UILabel alloc] initWithFrame:CGRectZero]; -// _priceLabel.font = FONT(12); -// _priceLabel.backgroundColor = [UIColor clearColor]; -// _priceLabel.textColor = [UIColor colorWithHexString:@""]; -// [superView addSubview:_priceLabel]; - _titleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; _titleLabel.font = FONT(14); _titleLabel.backgroundColor = [UIColor clearColor]; - _titleLabel.textAlignment = NSTextAlignmentCenter; _titleLabel.textColor = kColor222; [superView addSubview:_titleLabel]; - UIView *_coinView = [UIView new]; - [superView addSubview: _coinView]; - - _codingCoinView = [UIButton buttonWithType:UIButtonTypeCustom]; + _codingCoinView = [UIButton buttonWithType:UIButtonTypeCustom]; + _codingCoinView.userInteractionEnabled = NO; + _codingCoinView.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; [_codingCoinView setImage:[UIImage imageNamed:@"shop_coding_coin_icon"] forState:UIControlStateNormal]; [_codingCoinView setTitle:@" 码币 " forState:UIControlStateNormal]; - [_codingCoinView setTitleColor:kColor222 forState:UIControlStateNormal]; - [_codingCoinView.titleLabel setFont:[UIFont boldSystemFontOfSize:12.0]]; - [_coinView addSubview:_codingCoinView]; + [_codingCoinView setTitleColor:kColorDark7 forState:UIControlStateNormal]; + [_codingCoinView.titleLabel setFont:[UIFont systemFontOfSize:14]]; + [superView addSubview:_codingCoinView]; _exchangeIconView = [UIImageView new]; + _exchangeIconView.contentMode = UIViewContentModeScaleAspectFill; + _exchangeIconView.clipsToBounds = YES; _exchangeIconView.backgroundColor = [UIColor clearColor]; - [_coinView addSubview:_exchangeIconView]; + _exchangeIconView.image = [UIImage imageNamed:@"shop_exchange_icon"]; + + [superView addSubview:_exchangeIconView]; + + _priceLabel = [UILabel labelWithFont:[UIFont systemFontOfSize:18] textColor:kColorBrandOrange]; + [superView addSubview:_priceLabel]; + _countLabel = [UILabel labelWithFont:[UIFont systemFontOfSize:12] textColor:kColorDark7]; + [superView addSubview:_countLabel]; float _coverViewHeight = self.frame.size.width * (176.0/284.0); NSLog(@"_coverViewHeight %lf",_coverViewHeight); [_coverView mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.left.right.equalTo(superView); - make.height.offset(_coverViewHeight); + make.left.offset(kPaddingLeftWidth); + make.centerY.equalTo(superView); + make.size.mas_equalTo(CGSizeMake(80, 80)); }]; [_titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(_coverView.mas_bottom).offset(10); - make.left.equalTo(superView.mas_left).offset(10); - make.right.equalTo(superView.mas_right).offset(-10); + make.top.equalTo(_coverView); + make.left.equalTo(_coverView.mas_right).offset(20); + make.right.equalTo(superView.mas_right).offset(-kPaddingLeftWidth); }]; [_codingCoinView mas_makeConstraints:^(MASConstraintMaker *make) { - make.centerY.equalTo(_coinView.mas_centerY); - make.left.equalTo(_coinView.mas_left); + make.left.equalTo(_titleLabel); + make.centerY.equalTo(_coverView); }]; [_exchangeIconView mas_makeConstraints:^(MASConstraintMaker *make) { - make.centerY.equalTo(_coinView.mas_centerY); - make.left.equalTo(_codingCoinView.mas_right).offset(10); + make.right.equalTo(superView).offset(-kPaddingLeftWidth); + make.centerY.equalTo(_countLabel); }]; - [_coinView mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.equalTo(_codingCoinView.mas_left); - make.right.equalTo(_exchangeIconView.mas_right); - make.top.equalTo(_titleLabel.mas_bottom).offset(5); - make.height.equalTo(@20); - make.centerX.equalTo(_coverView.mas_centerX); + [_priceLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(_titleLabel); + make.bottom.equalTo(_coverView); + }]; + [_countLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(_priceLabel.mas_right).offset(10); + make.bottom.equalTo(_priceLabel); }]; - - - -// -// [_priceLabel mas_makeConstraints:^(MASConstraintMaker *make) { -// make.top.equalTo(_titleLabel.bottom).offset(5); -// make.centerX.equalTo(_coverView.centerX); -// }]; -// -// -// [_timeStampLabel mas_makeConstraints:^(MASConstraintMaker *make) { -// make.left.equalTo(superView.left); -// make.right.equalTo(superView.right); -// make.bottom.equalTo(superView.bottom).offset(-5); -// }]; - } @@ -123,10 +103,18 @@ - (void)configViewWithModel:(ShopGoods *)model { [super configViewWithModel:model]; - _titleLabel.text = model.name; - NSString *points_cost = [NSString stringWithFormat:@" %@ 码币",[model.points_cost stringValue]]; + _titleLabel.text = [model.name componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"¥¥"]].firstObject; + NSString *points_cost = [NSString stringWithFormat:@" %@ 码币", model.points_cost]; [_codingCoinView setTitle:points_cost forState:UIControlStateNormal]; + CGFloat price = model.points_cost.floatValue * 50; + if (price - ((int)price) < .1) { + _priceLabel.text = [NSString stringWithFormat:@"¥%.0f", price]; + }else{ + _priceLabel.text = [NSString stringWithFormat:@"¥%.1f", price]; + } + _countLabel.text = [NSString stringWithFormat:@"销量:%@", model.count]; + [self showExchangeIcon:model.exchangeable]; [_coverView sd_setImageWithURL:[model.image urlImageWithCodePathResize:kScreen_Width] placeholderImage:nil]; @@ -134,14 +122,16 @@ - (void)configViewWithModel:(ShopGoods *)model - (void)showExchangeIcon:(BOOL)_isCanExchangeIcon { - if (_isCanExchangeIcon) { - UIImage *image = [UIImage imageNamed:@"shop_exchange_icon"]; - _exchangeIconView.image = image; - }else - { - UIImage *image = [UIImage imageNamed:@"shop_unexchange_icon"]; - _exchangeIconView.image =image; - } + _exchangeIconView.hidden = !_isCanExchangeIcon; + +// if (_isCanExchangeIcon) { +// UIImage *image = [UIImage imageNamed:@"shop_exchange_icon"]; +// _exchangeIconView.image = image; +// }else +// { +// UIImage *image = [UIImage imageNamed:@"shop_unexchange_icon"]; +// _exchangeIconView.image =image; +// } } diff --git a/Coding_iOS/Views/CCell/SkillCCell.h b/Coding_iOS/Views/CCell/SkillCCell.h new file mode 100644 index 000000000..4fb953e43 --- /dev/null +++ b/Coding_iOS/Views/CCell/SkillCCell.h @@ -0,0 +1,19 @@ +// +// SkillCCell.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2017/12/25. +// Copyright © 2017年 Coding. All rights reserved. +// +#define kCCellIdentifier_SkillCCell @"SkillCCell" + +#import +#import "CodingSkill.h" + +@interface SkillCCell : UICollectionViewCell + +@property (strong, nonatomic) CodingSkill *curSkill; +@property (copy, nonatomic) void(^deleteBlock)(CodingSkill *deletedSkill); + ++ (CGSize)ccellSizeWithObj:(id)obj; +@end diff --git a/Coding_iOS/Views/CCell/SkillCCell.m b/Coding_iOS/Views/CCell/SkillCCell.m new file mode 100644 index 000000000..1db398dd4 --- /dev/null +++ b/Coding_iOS/Views/CCell/SkillCCell.m @@ -0,0 +1,63 @@ +// +// SkillCCell.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2017/12/25. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "SkillCCell.h" + +@interface SkillCCell () + +@property (strong, nonatomic) UILabel *contentLabel; +@property (strong, nonatomic) UIButton *deleteB; + +@end + +@implementation SkillCCell + +- (void)setCurSkill:(CodingSkill *)curSkill{ + _curSkill = curSkill; + if (!_curSkill) { + return; + } + if (!_contentLabel) { + self.contentView.backgroundColor = kColorBrandBlue; + self.contentView.layer.cornerRadius = 2.0; + self.layer.cornerRadius = 2.0; + _contentLabel = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorWhite]; + _contentLabel.minimumScaleFactor = 0.5; + _contentLabel.adjustsFontSizeToFitWidth = YES; + [self.contentView addSubview:_contentLabel]; + _deleteB = [UIButton new]; + [_deleteB setImage:[UIImage imageNamed:@"skill_delete"] forState:UIControlStateNormal]; + __weak typeof(self) weakSelf = self; + [_deleteB bk_addEventHandler:^(id sender) { + if (weakSelf.deleteBlock) { + weakSelf.deleteBlock(weakSelf.curSkill); + } + } forControlEvents:UIControlEventTouchUpInside]; + [self.contentView addSubview:_deleteB]; + [_deleteB mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.bottom.right.equalTo(self.contentView); + make.width.mas_equalTo(30); + }]; + [_contentLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.contentView); + make.left.equalTo(self.contentView).offset(10); + make.right.equalTo(_deleteB.mas_left).offset(-5); + }]; + } + _contentLabel.text = _curSkill.skill_str; +} + ++ (CGSize)ccellSizeWithObj:(id)obj{ + CGSize ccellSize = CGSizeZero; + if ([obj isKindOfClass:[CodingSkill class]]) { + ccellSize = CGSizeMake((kScreen_Width - 30 - 10)/ 2, 30); + } + return ccellSize; +} + +@end diff --git a/Coding_iOS/Views/CCell/TagCCell.m b/Coding_iOS/Views/CCell/TagCCell.m index 48177c6aa..cebf621a7 100755 --- a/Coding_iOS/Views/CCell/TagCCell.m +++ b/Coding_iOS/Views/CCell/TagCCell.m @@ -41,10 +41,10 @@ - (void)setCurTag:(Tag *)curTag{ - (void)setHasBeenSelected:(BOOL)hasBeenSelected{ _hasBeenSelected = hasBeenSelected; if (_hasBeenSelected) { - self.backgroundColor = kColorBrandGreen; + self.backgroundColor = kColorBrandBlue; _contentLabel.textColor = [UIColor whiteColor]; }else{ - self.backgroundColor = kColorTableSectionBg; + self.backgroundColor = [UIColor whiteColor]; _contentLabel.textColor = [UIColor blackColor]; } } diff --git a/Coding_iOS/Views/CCell/TweetLikeUserCCell.h b/Coding_iOS/Views/CCell/TweetLikeUserCCell.h index 5ac817a24..dccb92f06 100755 --- a/Coding_iOS/Views/CCell/TweetLikeUserCCell.h +++ b/Coding_iOS/Views/CCell/TweetLikeUserCCell.h @@ -15,4 +15,5 @@ - (void)configWithUser:(User *)user rewarded:(BOOL)rewarded; ++(CGSize)ccellSize; @end diff --git a/Coding_iOS/Views/CCell/TweetLikeUserCCell.m b/Coding_iOS/Views/CCell/TweetLikeUserCCell.m index b384c996a..0c6b667c6 100755 --- a/Coding_iOS/Views/CCell/TweetLikeUserCCell.m +++ b/Coding_iOS/Views/CCell/TweetLikeUserCCell.m @@ -6,7 +6,7 @@ // Copyright (c) 2014年 Coding. All rights reserved. // -#define kTweetCell_LikeUserCCell_Height 25.0 +#define kTweetCell_LikeUserCCell_Height 30.0 #import "TweetLikeUserCCell.h" @@ -19,7 +19,7 @@ @interface TweetLikeUserCCell () @implementation TweetLikeUserCCell - (void)configWithUser:(User *)user rewarded:(BOOL)rewarded{ if (!self.imgView) { - self.imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, kTweetCell_LikeUserCCell_Height, kTweetCell_LikeUserCCell_Height)]; + self.imgView = [[YLImageView alloc] initWithFrame:CGRectMake(0, 0, kTweetCell_LikeUserCCell_Height, kTweetCell_LikeUserCCell_Height)]; self.imgView.layer.masksToBounds = YES; self.imgView.layer.cornerRadius = kTweetCell_LikeUserCCell_Height/2; self.imgView.layer.borderColor = [UIColor colorWithHexString:@"0xFFAE03"].CGColor; @@ -32,7 +32,7 @@ - (void)configWithUser:(User *)user rewarded:(BOOL)rewarded{ } }else{ [self.imgView sd_setImageWithURL:nil]; - [self.imgView setImage:[UIImage imageWithColor:[UIColor colorWithHexString:@"0xdadada"]]]; + [self.imgView setImage:[UIImage imageWithColor:[UIColor colorWithHexString:@"0xD8DDE4"]]]; if (!_likesLabel) { _likesLabel = [[UILabel alloc] initWithFrame:_imgView.bounds]; _likesLabel.backgroundColor = [UIColor clearColor]; @@ -50,4 +50,9 @@ - (void)configWithUser:(User *)user rewarded:(BOOL)rewarded{ - (void)layoutSubviews{ [super layoutSubviews]; } + ++(CGSize)ccellSize{ + CGSize itemSize = CGSizeMake(kTweetCell_LikeUserCCell_Height, kTweetCell_LikeUserCCell_Height); + return itemSize; +} @end diff --git a/Coding_iOS/Views/CCell/TweetMediaItemCCell.m b/Coding_iOS/Views/CCell/TweetMediaItemCCell.m index e0bd87161..ee1ed35df 100755 --- a/Coding_iOS/Views/CCell/TweetMediaItemCCell.m +++ b/Coding_iOS/Views/CCell/TweetMediaItemCCell.m @@ -67,7 +67,7 @@ - (void)layoutSubviews{ [super layoutSubviews]; } +(CGSize)ccellSizeWithObj:(id)obj{ - CGSize itemSize; + CGSize itemSize = CGSizeZero; if ([obj isKindOfClass:[HtmlMediaItem class]]) { itemSize = CGSizeMake(kTweetMediaItemCCell_Width, kTweetMediaItemCCell_Width); } diff --git a/Coding_iOS/Views/CCell/TweetMediaItemSingleCCell.m b/Coding_iOS/Views/CCell/TweetMediaItemSingleCCell.m index 669b0c023..01610594d 100755 --- a/Coding_iOS/Views/CCell/TweetMediaItemSingleCCell.m +++ b/Coding_iOS/Views/CCell/TweetMediaItemSingleCCell.m @@ -82,7 +82,7 @@ - (void)setCurMediaItem:(HtmlMediaItem *)curMediaItem{ } +(CGSize)ccellSizeWithObj:(id)obj{ - CGSize itemSize; + CGSize itemSize = CGSizeZero; if ([obj isKindOfClass:[HtmlMediaItem class]]) { HtmlMediaItem *curMediaItem = (HtmlMediaItem *)obj; if (curMediaItem.type == HtmlMediaItemType_EmotionMonkey) { diff --git a/Coding_iOS/Views/CCell/TweetSendImageCCell.h b/Coding_iOS/Views/CCell/TweetSendImageCCell.h index a217bb3ed..de70808ad 100755 --- a/Coding_iOS/Views/CCell/TweetSendImageCCell.h +++ b/Coding_iOS/Views/CCell/TweetSendImageCCell.h @@ -12,6 +12,7 @@ #import "Tweets.h" @interface TweetSendImageCCell : UICollectionViewCell +@property (strong, nonatomic) UIActivityIndicatorView *activityIndicator; @property (strong, nonatomic) UIImageView *imgView; @property (strong, nonatomic) UIButton *deleteBtn; @property (strong, nonatomic) TweetImage *curTweetImg; diff --git a/Coding_iOS/Views/CCell/TweetSendImageCCell.m b/Coding_iOS/Views/CCell/TweetSendImageCCell.m index 45d6c3551..bc9d35ccb 100755 --- a/Coding_iOS/Views/CCell/TweetSendImageCCell.m +++ b/Coding_iOS/Views/CCell/TweetSendImageCCell.m @@ -50,7 +50,23 @@ - (void)setCurTweetImg:(TweetImage *)curTweetImg{ [_deleteBtn addTarget:self action:@selector(deleteBtnClicked:) forControlEvents:UIControlEventTouchUpInside]; [self.contentView addSubview:_deleteBtn]; } + if (!_activityIndicator) { + _activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; + _activityIndicator.hidesWhenStopped = YES; + [self.contentView addSubview:_activityIndicator]; + [_activityIndicator mas_makeConstraints:^(MASConstraintMaker *make) { + make.center.equalTo(self.contentView); + }]; + } RAC(self.imgView, image) = [RACObserve(self.curTweetImg, thumbnailImage) takeUntil:self.rac_prepareForReuseSignal]; + __weak typeof(self) weakSelf = self; + [[RACObserve(self.curTweetImg, downloadState) takeUntil:self.rac_prepareForReuseSignal] subscribeNext:^(NSNumber *x) { + if (x.integerValue == TweetImageDownloadStateIng) { + [weakSelf.activityIndicator startAnimating]; + }else{ + [weakSelf.activityIndicator stopAnimating]; + } + }]; _deleteBtn.hidden = NO; }else{ _imgView.image = [UIImage imageNamed:@"addPictureBgImage"]; diff --git a/Coding_iOS/Views/Cell/AddCommentCell.m b/Coding_iOS/Views/Cell/AddCommentCell.m index 9b94960ce..14030fcf0 100644 --- a/Coding_iOS/Views/Cell/AddCommentCell.m +++ b/Coding_iOS/Views/Cell/AddCommentCell.m @@ -26,13 +26,13 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus } if (!_contentL) { _contentL = [UILabel new]; - _contentL.font = [UIFont systemFontOfSize:15]; - _contentL.textColor = kColor222; + _contentL.font = [UIFont systemFontOfSize:14]; + _contentL.textColor = kColorDark7; _contentL.text = @"添加评论"; [self.contentView addSubview:_contentL]; } [_iconView mas_makeConstraints:^(MASConstraintMaker *make) { - make.size.mas_equalTo(CGSizeMake(20, 20)); + make.size.mas_equalTo(CGSizeMake(22, 22)); make.centerY.equalTo(self.contentView); make.centerX.equalTo(self.contentView).offset(-50); }]; diff --git a/Coding_iOS/Views/Cell/CodingTipCell.m b/Coding_iOS/Views/Cell/CodingTipCell.m index 169c9eaaa..7bdf796ac 100755 --- a/Coding_iOS/Views/Cell/CodingTipCell.m +++ b/Coding_iOS/Views/Cell/CodingTipCell.m @@ -122,7 +122,7 @@ - (void)setCurTip:(CodingTip *)curTip{ // NSString *username_first = pinyin.length > 0? [[pinyin substringToIndex:1] uppercaseString]: @"C"; // _ownerL.text = username_first; //owner姓名 - [self.ownerNameBtn setTitleColor:[UIColor colorWithHexString:curTip.user_item.type != HtmlMediaItemType_CustomLink? @"0x3bbd79": @"0x222222"] forState:UIControlStateNormal]; + [self.ownerNameBtn setTitleColor:[UIColor colorWithHexString:curTip.user_item.type != HtmlMediaItemType_CustomLink? @"0x136BFB": @"0x222222"] forState:UIControlStateNormal]; [self.ownerNameBtn setUserTitle:userName font:[UIFont systemFontOfSize:17] maxWidth:(kCodingTipCell_WidthContent -80)]; //时间 // _timeLabel.text = _curTip.target_type; diff --git a/Coding_iOS/Views/Cell/CommitContentCell.m b/Coding_iOS/Views/Cell/CommitContentCell.m index 335a7ec85..29ac2ef67 100644 --- a/Coding_iOS/Views/Cell/CommitContentCell.m +++ b/Coding_iOS/Views/Cell/CommitContentCell.m @@ -24,7 +24,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus self.selectionStyle = UITableViewCellSelectionStyleNone; self.backgroundColor = kColorTableBG; if (!_userIconView) { - _userIconView = [[UIImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 0, 20, 20)]; + _userIconView = [[YLImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 0, 20, 20)]; [_userIconView doCircleFrame]; [self.contentView addSubview:_userIconView]; } diff --git a/Coding_iOS/Views/Cell/CommitListCell.m b/Coding_iOS/Views/Cell/CommitListCell.m index 178a913e6..67420b225 100644 --- a/Coding_iOS/Views/Cell/CommitListCell.m +++ b/Coding_iOS/Views/Cell/CommitListCell.m @@ -24,7 +24,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; self.backgroundColor = kColorTableBG; if (!_imgView) { - _imgView = [UIImageView new]; + _imgView = [YLImageView new]; [_imgView doBorderWidth:0.5 color:kColorDDD cornerRadius:kCommitListCell_UserWidth/2]; [self.contentView addSubview:_imgView]; [_imgView mas_makeConstraints:^(MASConstraintMaker *make) { @@ -39,7 +39,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus [_titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(_imgView.mas_right).offset(12); make.right.equalTo(self.contentView); - make.top.equalTo(self.contentView).offset(15); + make.top.equalTo(self.contentView).offset(10); make.height.mas_equalTo(30); }]; } diff --git a/Coding_iOS/Views/Cell/ConversationCell.m b/Coding_iOS/Views/Cell/ConversationCell.m index d55cc92e1..bc42aa306 100755 --- a/Coding_iOS/Views/Cell/ConversationCell.m +++ b/Coding_iOS/Views/Cell/ConversationCell.m @@ -22,21 +22,21 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (self) { // Initialization code if (!_userIconView) { - _userIconView = [[UIImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, ([ConversationCell cellHeight]-48)/2, 48, 48)]; + _userIconView = [[YLImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, ([ConversationCell cellHeight]-48)/2, 48, 48)]; [_userIconView doCircleFrame]; [self.contentView addSubview:_userIconView]; } if (!_name) { _name = [[UILabel alloc] initWithFrame:CGRectMake(75, 8, 150, 25)]; _name.font = [UIFont systemFontOfSize:17]; - _name.textColor = kColor222; + _name.textColor = kColorDark3; _name.backgroundColor = [UIColor clearColor]; [self.contentView addSubview:_name]; } if (!_time) { _time = [[UILabel alloc] initWithFrame:CGRectMake(kScreen_Width - 100-kPaddingLeftWidth, 8, 100, 25)]; _time.font = [UIFont systemFontOfSize:12]; - _time.textColor = kColor999; + _time.textColor = kColorDark7; _time.textAlignment = NSTextAlignmentRight; _time.backgroundColor = [UIColor clearColor]; [self.contentView addSubview:_time]; @@ -45,7 +45,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus _msg = [[UILabel alloc] initWithFrame:CGRectMake(75, 30, kScreen_Width-75-30 -kPaddingLeftWidth, 25)]; _msg.font = [UIFont systemFontOfSize:15]; _msg.backgroundColor = [UIColor clearColor]; - _msg.textColor = kColor999; + _msg.textColor = kColorDark7; [self.contentView addSubview:_msg]; } } @@ -62,7 +62,7 @@ - (void)layoutSubviews{ _name.text = _curPriMsg.friend.name; _time.text = [_curPriMsg.created_at stringDisplay_MMdd]; - _msg.textColor = kColor999; + _msg.textColor = kColorDark7; NSMutableString *textMsg = [[NSMutableString alloc] initWithString:_curPriMsg.content]; if (_curPriMsg.hasMedia) { [textMsg appendString:@"[图片]"]; @@ -70,7 +70,7 @@ - (void)layoutSubviews{ if ([_curPriMsg isVoice]) { [textMsg setString:@"[语音]"]; if (_curPriMsg.played.intValue == 0) { - _msg.textColor = kColorBrandGreen; + _msg.textColor = kColorBrandBlue; } } _msg.text = textMsg; diff --git a/Coding_iOS/Views/Cell/CountryCodeCell.m b/Coding_iOS/Views/Cell/CountryCodeCell.m index 3fe7293e4..38f057d1f 100644 --- a/Coding_iOS/Views/Cell/CountryCodeCell.m +++ b/Coding_iOS/Views/Cell/CountryCodeCell.m @@ -22,7 +22,7 @@ - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSStr _leftL = ({ UILabel *label = [UILabel new]; label.font = [UIFont systemFontOfSize:15]; - label.textColor = kColor222; + label.textColor = kColorDark2; [self.contentView addSubview:label]; [label mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.contentView).offset(kPaddingLeftWidth); @@ -33,7 +33,7 @@ - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSStr _rightL = ({ UILabel *label = [UILabel new]; label.font = [UIFont systemFontOfSize:15]; - label.textColor = kColor999; + label.textColor = [UIColor colorWithHexString:@"0x136BFB"]; [self.contentView addSubview:label]; [label mas_makeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.contentView).offset(-kPaddingLeftWidth); diff --git a/Coding_iOS/Views/Cell/EACodeBranchListCell.h b/Coding_iOS/Views/Cell/EACodeBranchListCell.h new file mode 100644 index 000000000..ee54e166d --- /dev/null +++ b/Coding_iOS/Views/Cell/EACodeBranchListCell.h @@ -0,0 +1,15 @@ +// +// EACodeBranchListCell.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/22. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import +#import "CodeBranchOrTag.h" +#import "SWTableViewCell.h" + +@interface EACodeBranchListCell : SWTableViewCell +@property (strong, nonatomic) CodeBranchOrTag *curBranch; +@end diff --git a/Coding_iOS/Views/Cell/EACodeBranchListCell.m b/Coding_iOS/Views/Cell/EACodeBranchListCell.m new file mode 100644 index 000000000..80bd740d7 --- /dev/null +++ b/Coding_iOS/Views/Cell/EACodeBranchListCell.m @@ -0,0 +1,54 @@ +// +// EACodeBranchListCell.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/22. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "EACodeBranchListCell.h" + +@interface EACodeBranchListCell () +@property (weak, nonatomic) IBOutlet UILabel *nameL; +@property (weak, nonatomic) IBOutlet UILabel *commitTimeL; +@property (weak, nonatomic) IBOutlet UIImageView *is_protectedV; +@property (weak, nonatomic) IBOutlet UIView *metricV; +@property (weak, nonatomic) IBOutlet NSLayoutConstraint *metric_leadingC; +@property (weak, nonatomic) IBOutlet NSLayoutConstraint *metric_trailingC; +@property (weak, nonatomic) IBOutlet UILabel *aheadL; +@property (weak, nonatomic) IBOutlet UILabel *behindL; + +@end + +@implementation EACodeBranchListCell + +- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + // Initialization code + + } + return self; +} + +- (void)setCurBranch:(CodeBranchOrTag *)curBranch{ + _curBranch = curBranch; + _nameL.text = [NSString stringWithFormat:@" %@ ", _curBranch.name]; + _nameL.textColor = _curBranch.is_default_branch.boolValue? kColorWhite: kColorDark7; + _nameL.backgroundColor = _curBranch.is_default_branch.boolValue? kColorDark3: kColorD8DDE4; + _commitTimeL.text = [NSString stringWithFormat:@"更新于 %@", [_curBranch.last_commit.commitTime stringTimesAgo]]; + _is_protectedV.hidden = !_curBranch.is_protected.boolValue; + _metricV.hidden = _curBranch.is_default_branch.boolValue; + + _metric_leadingC.constant = -MIN(_curBranch.branch_metric.ahead.floatValue, 40); + _metric_trailingC.constant = MIN(_curBranch.branch_metric.behind.floatValue, 40); + _aheadL.text = [NSString stringWithFormat:@"%ld", (long)_curBranch.branch_metric.ahead.integerValue]; + _behindL.text = [NSString stringWithFormat:@"%ld", (long)_curBranch.branch_metric.behind.integerValue]; + + NSMutableArray *rightUtilityButtons = [NSMutableArray new]; + [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:@"0xF66262"] icon:[UIImage imageNamed:@"icon_file_cell_delete"]]; + [self setRightUtilityButtons:rightUtilityButtons WithButtonWidth:80]; +} + +@end + diff --git a/Coding_iOS/Views/Cell/EACodeBranchListCell.xib b/Coding_iOS/Views/Cell/EACodeBranchListCell.xib new file mode 100644 index 000000000..0b686319d --- /dev/null +++ b/Coding_iOS/Views/Cell/EACodeBranchListCell.xib @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Coding_iOS/Views/Cell/EACodeReleaseAttachmentsOrReferencesCell.h b/Coding_iOS/Views/Cell/EACodeReleaseAttachmentsOrReferencesCell.h new file mode 100644 index 000000000..b7d99da01 --- /dev/null +++ b/Coding_iOS/Views/Cell/EACodeReleaseAttachmentsOrReferencesCell.h @@ -0,0 +1,25 @@ +// +// EACodeReleaseAttachmentsOrReferencesCell.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/23. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import +#import "EACodeRelease.h" + +typedef NS_ENUM(NSUInteger, EACodeReleaseAttachmentsOrReferencesCellType) { + EACodeReleaseAttachmentsOrReferencesCellTypeAttachments = 0, + EACodeReleaseAttachmentsOrReferencesCellTypeReferences, +}; + +@interface EACodeReleaseAttachmentsOrReferencesCell : UITableViewCell + +@property (copy, nonatomic) void(^itemClickedBlock)(id item); + +- (void)setupCodeRelease:(EACodeRelease *)curR type:(EACodeReleaseAttachmentsOrReferencesCellType)type; + ++ (CGFloat)cellHeightWithObj:(EACodeRelease *)obj type:(EACodeReleaseAttachmentsOrReferencesCellType)type; + +@end diff --git a/Coding_iOS/Views/Cell/EACodeReleaseAttachmentsOrReferencesCell.m b/Coding_iOS/Views/Cell/EACodeReleaseAttachmentsOrReferencesCell.m new file mode 100644 index 000000000..fef4a5e36 --- /dev/null +++ b/Coding_iOS/Views/Cell/EACodeReleaseAttachmentsOrReferencesCell.m @@ -0,0 +1,142 @@ +// +// EACodeReleaseAttachmentsOrReferencesCell.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/23. +// Copyright © 2018年 Coding. All rights reserved. +// + +#define kEACodeReleaseAttachmentsOrReferencesCell_ItemHeight 36.0 + +#import "EACodeReleaseAttachmentsOrReferencesCell.h" + +@interface EACodeReleaseAttachmentsOrReferencesCell () +@property (strong, nonatomic) EACodeRelease *curR; +@property (assign, nonatomic) EACodeReleaseAttachmentsOrReferencesCellType type; + +@end + + +@implementation EACodeReleaseAttachmentsOrReferencesCell + +- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + // Initialization code + self.selectionStyle = UITableViewCellSelectionStyleNone; + } + return self; +} + +- (void)setupCodeRelease:(EACodeRelease *)curR type:(EACodeReleaseAttachmentsOrReferencesCellType)type{ + _type = type; + _curR = curR; + [self.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; + if (_type == EACodeReleaseAttachmentsOrReferencesCellTypeAttachments) { + [self p_addHeaderV]; + [self p_addItemWithIndex:0]; + [self p_addItemWithIndex:1]; + for (NSInteger index = 0; index < _curR.attachments.count; index++) { + [self p_addItemWithIndex:index + 2]; + } + }else if (_curR.resource_references.count > 0){ + [self p_addHeaderV]; + for (NSInteger index = 0; index < _curR.resource_references.count; index++) { + [self p_addItemWithIndex:index]; + } + } +} + +- (void)p_addHeaderV{ + UIView *headerV = [[UIView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 0, kScreen_Width - 2* kPaddingLeftWidth, kEACodeReleaseAttachmentsOrReferencesCell_ItemHeight + 2)]; + headerV.backgroundColor = kColorTableSectionBg; + headerV.borderColor = kColorD8DDE4; + headerV.borderWidth = 1.0; + headerV.cornerRadius = 2.0; + headerV.masksToBounds = YES; + UILabel *titleL = [UILabel labelWithFont:[UIFont systemFontOfSize:13] textColor:kColorDark4]; + titleL.text = _type == EACodeReleaseAttachmentsOrReferencesCellTypeAttachments? @"下载": @"关联资源"; + [headerV addSubview:titleL]; + [titleL mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.offset(10); + make.centerY.offset(-1.0); + }]; + [self.contentView addSubview:headerV]; +} + +- (void)p_addItemWithIndex:(NSInteger)index{ + UIView *itemV = [[UIView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, kEACodeReleaseAttachmentsOrReferencesCell_ItemHeight * (index + 1), kScreen_Width - 2* kPaddingLeftWidth, kEACodeReleaseAttachmentsOrReferencesCell_ItemHeight + 1)]; + itemV.backgroundColor = kColorWhite; + itemV.borderColor = kColorD8DDE4; + itemV.borderWidth = 1.0; + __weak typeof(self) weakSelf = self; + [itemV bk_whenTapped:^{ + [weakSelf p_handleTappedIndex:index]; + }]; + UIImageView *iconV = [UIImageView new]; + UILabel *nameL = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDark4]; + nameL.lineBreakMode = NSLineBreakByTruncatingMiddle; + UILabel *sizeL = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDark4]; + [itemV addSubview:iconV]; + [itemV addSubview:nameL]; + [itemV addSubview:sizeL]; + [iconV mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.offset(10); + make.centerY.equalTo(itemV); + make.size.mas_equalTo(CGSizeMake(18, 18)); + }]; + [nameL mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(iconV.mas_right).offset(5); + make.centerY.equalTo(itemV); + make.right.lessThanOrEqualTo(sizeL.mas_left); + }]; + [sizeL mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.offset(-10); + make.centerY.equalTo(itemV); + }]; + [sizeL setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; + [sizeL setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; + if (_type == EACodeReleaseAttachmentsOrReferencesCellTypeAttachments) { + if (index < 2) { + iconV.image = [UIImage imageNamed:@"code_release_resource_Zip"]; + nameL.text = index == 0? @"Source code (zip)": @"Source code (tar.gz)"; + }else{ + EACodeReleaseAttachment *item = _curR.attachments[index - 2]; + iconV.image = [UIImage imageNamed:@"code_release_resource_Default"]; + nameL.text = item.name; + sizeL.text = [NSString sizeDisplayWithByte:item.size.floatValue]; + } + }else{ + ResourceReferenceItem *item = _curR.resource_references[index]; + iconV.image = [UIImage imageNamed:[NSString stringWithFormat:@"code_release_resource_%@", item.target_type]] ?: [UIImage imageNamed:@"code_release_resource_Default"]; + nameL.text = [NSString stringWithFormat:@"#%@ %@", item.code, item.title]; + } + [self.contentView addSubview:itemV]; +} + +- (void)p_handleTappedIndex:(NSInteger)index{ + if (_type == EACodeReleaseAttachmentsOrReferencesCellTypeAttachments) { + if (index < 2) { + [NSObject showHudTipStr:@"暂不支持下载"]; + }else if (_itemClickedBlock){ + _itemClickedBlock(_curR.attachments[index - 2]); + } + }else{ + if (_itemClickedBlock) { + _itemClickedBlock(_curR.resource_references[index]); + } + } +} + + ++ (CGFloat)cellHeightWithObj:(EACodeRelease *)obj type:(EACodeReleaseAttachmentsOrReferencesCellType)type{ + CGFloat cellHeight = 0; + if (type == EACodeReleaseAttachmentsOrReferencesCellTypeAttachments) { + cellHeight = kEACodeReleaseAttachmentsOrReferencesCell_ItemHeight * (3 + obj.attachments.count) + 15; + }else{ + cellHeight = obj.resource_references.count > 0? kEACodeReleaseAttachmentsOrReferencesCell_ItemHeight * (1 + obj.resource_references.count) + 15: 0; + } + return cellHeight; +} + +@end diff --git a/Coding_iOS/Views/Cell/EACodeReleaseBodyCell.h b/Coding_iOS/Views/Cell/EACodeReleaseBodyCell.h new file mode 100644 index 000000000..c59f4bf2e --- /dev/null +++ b/Coding_iOS/Views/Cell/EACodeReleaseBodyCell.h @@ -0,0 +1,19 @@ +// +// EACodeReleaseBodyCell.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/23. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import +#import "EACodeRelease.h" + +@interface EACodeReleaseBodyCell : UITableViewCell +@property (strong, nonatomic) EACodeRelease *curR; + +@property (nonatomic, copy) void (^cellHeightChangedBlock)(); +@property (nonatomic, copy) void (^loadRequestBlock)(NSURLRequest *curRequest); + ++ (CGFloat)cellHeightWithObj:(EACodeRelease *)obj; +@end diff --git a/Coding_iOS/Views/Cell/EACodeReleaseBodyCell.m b/Coding_iOS/Views/Cell/EACodeReleaseBodyCell.m new file mode 100644 index 000000000..c6874bc37 --- /dev/null +++ b/Coding_iOS/Views/Cell/EACodeReleaseBodyCell.m @@ -0,0 +1,113 @@ +// +// EACodeReleaseBodyCell.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/23. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "EACodeReleaseBodyCell.h" +#import "WebContentManager.h" + +@interface EACodeReleaseBodyCell () +@property (strong, nonatomic) UIWebView *webContentView; +@property (strong, nonatomic) UIActivityIndicatorView *activityIndicator; + +@end + + +@implementation EACodeReleaseBodyCell + +- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + // Initialization code + self.selectionStyle = UITableViewCellSelectionStyleNone; + CGFloat curWidth = kScreen_Width - 2 * kPaddingLeftWidth; + if (!self.webContentView) { + self.webContentView = [[UIWebView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 0, curWidth, 1)]; + self.webContentView.delegate = self; + self.webContentView.scrollView.scrollEnabled = NO; + self.webContentView.scrollView.scrollsToTop = NO; + self.webContentView.scrollView.bounces = NO; + self.webContentView.backgroundColor = [UIColor clearColor]; + self.webContentView.opaque = NO; + [self.contentView addSubview:self.webContentView]; + } + if (!_activityIndicator) { + _activityIndicator = [[UIActivityIndicatorView alloc] + initWithActivityIndicatorStyle: + UIActivityIndicatorViewStyleGray]; + _activityIndicator.hidesWhenStopped = YES; + [self.contentView addSubview:_activityIndicator]; + [_activityIndicator mas_makeConstraints:^(MASConstraintMaker *make) { + make.center.equalTo(self.contentView); + }]; + } + } + return self; +} + +- (void)setCurR:(EACodeRelease *)curR{ + _curR = curR; + [self.webContentView setHeight:_curR.contentHeight]; + if (!_webContentView.isLoading) { + [_activityIndicator startAnimating]; + [self.webContentView loadHTMLString:[WebContentManager markdownPatternedWithContent:_curR.markdownBody] baseURL:nil]; + } +} + ++ (CGFloat)cellHeightWithObj:(EACodeRelease *)obj{ + return obj.contentHeight; +} + +#pragma mark UIWebViewDelegate +- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType +{ + NSString *strLink = request.URL.absoluteString; + DebugLog(@"strLink=[%@]", strLink); + if ([strLink rangeOfString:@"about:blank"].location != NSNotFound) { + return YES; + } else { + if (_loadRequestBlock) { + _loadRequestBlock(request); + } + return NO; + } +} +- (void)webViewDidStartLoad:(UIWebView *)webView +{ + [_activityIndicator startAnimating]; +} +- (void)webViewDidFinishLoad:(UIWebView *)webView +{ + [self refreshwebContentView]; + [_activityIndicator stopAnimating]; + CGFloat scrollHeight = MIN(webView.scrollView.contentSize.height, 20 * kScreen_Height); + if (ABS(scrollHeight - _curR.contentHeight) > 5) { + NSLog(@"scrollHeight: %.2f, contentHeight: %.2f, (scrollHeight - contentHeight): %.2f", scrollHeight, _curR.contentHeight, (scrollHeight - _curR.contentHeight)); + webView.scalesPageToFit = YES; + _curR.contentHeight = scrollHeight; + if (_cellHeightChangedBlock) { + _cellHeightChangedBlock(); + } + } +} +- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error +{ + [_activityIndicator stopAnimating]; + if([error code] == NSURLErrorCancelled) + return; + else + DebugLog(@"%@", error.description); +} + +- (void)refreshwebContentView +{ + if (_webContentView) { + //修改服务器页面的meta的值 + NSString *meta = [NSString stringWithFormat:@"document.getElementsByName(\"viewport\")[0].content = \"width=%f, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no\"", CGRectGetWidth(_webContentView.frame)]; + [_webContentView stringByEvaluatingJavaScriptFromString:meta]; + } +} +@end diff --git a/Coding_iOS/Views/Cell/EACodeReleaseListCell.h b/Coding_iOS/Views/Cell/EACodeReleaseListCell.h new file mode 100644 index 000000000..d63a7adbd --- /dev/null +++ b/Coding_iOS/Views/Cell/EACodeReleaseListCell.h @@ -0,0 +1,15 @@ +// +// EACodeReleaseListCell.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/22. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import +#import "EACodeRelease.h" +#import "SWTableViewCell.h" + +@interface EACodeReleaseListCell : SWTableViewCell +@property (strong, nonatomic) EACodeRelease *curCodeRelease; +@end diff --git a/Coding_iOS/Views/Cell/EACodeReleaseListCell.m b/Coding_iOS/Views/Cell/EACodeReleaseListCell.m new file mode 100644 index 000000000..1bf909566 --- /dev/null +++ b/Coding_iOS/Views/Cell/EACodeReleaseListCell.m @@ -0,0 +1,46 @@ +// +// EACodeReleaseListCell.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/22. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "EACodeReleaseListCell.h" + +@interface EACodeReleaseListCell () +@property (weak, nonatomic) IBOutlet UILabel *titleL; +@property (weak, nonatomic) IBOutlet UILabel *tag_nameL; +@property (weak, nonatomic) IBOutlet UILabel *authorL; +@property (weak, nonatomic) IBOutlet UILabel *created_atL; +@property (weak, nonatomic) IBOutlet UIView *preV; +@property (weak, nonatomic) IBOutlet NSLayoutConstraint *created_atLeftC; + +@end + +@implementation EACodeReleaseListCell + +- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + // Initialization code + + } + return self; +} + +- (void)setCurCodeRelease:(EACodeRelease *)curCodeRelease{ + _curCodeRelease = curCodeRelease; + + _titleL.text = _curCodeRelease.title.length > 0? _curCodeRelease.title: _curCodeRelease.tag_name; + _tag_nameL.text = _curCodeRelease.tag_name; + _authorL.text = _curCodeRelease.author.name; + _created_atL.text = [_curCodeRelease.created_at stringTimesAgo]; + _preV.hidden = !_curCodeRelease.pre.boolValue; + _created_atLeftC.constant = _preV.hidden? 15: 60+ 15; + + NSMutableArray *rightUtilityButtons = [NSMutableArray new]; + [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:@"0xF66262"] icon:[UIImage imageNamed:@"icon_file_cell_delete"]]; + [self setRightUtilityButtons:rightUtilityButtons WithButtonWidth:65]; +} +@end diff --git a/Coding_iOS/Views/Cell/EACodeReleaseListCell.xib b/Coding_iOS/Views/Cell/EACodeReleaseListCell.xib new file mode 100644 index 000000000..e3351f5af --- /dev/null +++ b/Coding_iOS/Views/Cell/EACodeReleaseListCell.xib @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Coding_iOS/Views/Cell/EACodeReleaseTopCell.h b/Coding_iOS/Views/Cell/EACodeReleaseTopCell.h new file mode 100644 index 000000000..a926e359a --- /dev/null +++ b/Coding_iOS/Views/Cell/EACodeReleaseTopCell.h @@ -0,0 +1,18 @@ +// +// EACodeReleaseTopCell.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/23. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import +#import "EACodeRelease.h" + +@interface EACodeReleaseTopCell : UITableViewCell +@property (strong, nonatomic) EACodeRelease *curR; + +@property (copy, nonatomic) void(^tagClickedBlock)(EACodeRelease *curR); + ++ (CGFloat)cellHeightWithObj:(EACodeRelease *)obj; +@end diff --git a/Coding_iOS/Views/Cell/EACodeReleaseTopCell.m b/Coding_iOS/Views/Cell/EACodeReleaseTopCell.m new file mode 100644 index 000000000..d19170729 --- /dev/null +++ b/Coding_iOS/Views/Cell/EACodeReleaseTopCell.m @@ -0,0 +1,49 @@ +// +// EACodeReleaseTopCell.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/23. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "EACodeReleaseTopCell.h" + +@interface EACodeReleaseTopCell () + +@property (weak, nonatomic) IBOutlet UILabel *titleL; +@property (weak, nonatomic) IBOutlet UILabel *tag_nameL; +@property (weak, nonatomic) IBOutlet UILabel *authorL; +@property (weak, nonatomic) IBOutlet UILabel *created_atL; +@property (weak, nonatomic) IBOutlet UIView *preV; +@property (weak, nonatomic) IBOutlet NSLayoutConstraint *created_atLeftC; + +@end + +@implementation EACodeReleaseTopCell + +- (void)setCurR:(EACodeRelease *)curR{ + _curR = curR; + + _titleL.text = _curR.title; + _tag_nameL.text = _curR.tag_name; + _authorL.text = _curR.author.name; + _created_atL.text = [_curR.created_at stringTimesAgo]; +// _preV.hidden = !_curR.pre.boolValue; + _preV.hidden = YES; + _created_atLeftC.constant = _preV.hidden? 15: 60+ 15; +} + +- (IBAction)tagButtonClicked:(id)sender { + if (_tagClickedBlock) { + _tagClickedBlock(_curR); + } +} + + ++ (CGFloat)cellHeightWithObj:(EACodeRelease *)obj{ + CGFloat cellHeight = 15 + [obj.title getHeightWithFont:[UIFont systemFontOfSize:17 weight:UIFontWeightMedium] constrainedToSize:CGSizeMake(kScreen_Width - 2* kPaddingLeftWidth, CGFLOAT_MAX)] + 10 + 20 + 15; + + return cellHeight; +} + +@end diff --git a/Coding_iOS/Views/Cell/EACodeReleaseTopCell.xib b/Coding_iOS/Views/Cell/EACodeReleaseTopCell.xib new file mode 100644 index 000000000..0b4fe891c --- /dev/null +++ b/Coding_iOS/Views/Cell/EACodeReleaseTopCell.xib @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Coding_iOS/Views/Cell/EALocalCodeListCell.h b/Coding_iOS/Views/Cell/EALocalCodeListCell.h new file mode 100644 index 000000000..205121d55 --- /dev/null +++ b/Coding_iOS/Views/Cell/EALocalCodeListCell.h @@ -0,0 +1,15 @@ +// +// EALocalCodeListCell.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/28. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import + +@interface EALocalCodeListCell : UITableViewCell + +@property (strong, nonatomic) NSURL *curURL; +@property (strong, nonatomic) NSString *searchText; +@end diff --git a/Coding_iOS/Views/Cell/EALocalCodeListCell.m b/Coding_iOS/Views/Cell/EALocalCodeListCell.m new file mode 100644 index 000000000..501a83013 --- /dev/null +++ b/Coding_iOS/Views/Cell/EALocalCodeListCell.m @@ -0,0 +1,64 @@ +// +// EALocalCodeListCell.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/3/28. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "EALocalCodeListCell.h" + +@interface EALocalCodeListCell () + +@property (strong, nonatomic) UIImageView *leftIconView; +@property (strong, nonatomic) UILabel *fileNameL; + +@end + +@implementation EALocalCodeListCell + +- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + // Initialization code + self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + if (!_leftIconView) { + _leftIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"icon_code_file"]]; + [self.contentView addSubview:_leftIconView]; + } + if (!_fileNameL) { + _fileNameL = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColor222]; + _fileNameL.lineBreakMode = NSLineBreakByTruncatingMiddle; + [self.contentView addSubview:_fileNameL]; + } + [_leftIconView mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.contentView); + make.left.equalTo(self.contentView).offset(kPaddingLeftWidth); + }]; + [_fileNameL mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.contentView); + make.left.equalTo(_leftIconView.mas_right).offset(10); + make.right.lessThanOrEqualTo(self.contentView).offset(-kPaddingLeftWidth); + }]; + } + return self; +} + +- (void)layoutSubviews{ + [super layoutSubviews]; + NSDictionary *attributes = [_curURL resourceValuesForKeys:@[NSURLIsDirectoryKey, NSURLTypeIdentifierKey] error:nil]; + BOOL isDir = [attributes[NSURLIsDirectoryKey] boolValue]; + NSString *itemUTI = attributes[NSURLTypeIdentifierKey] ?: @"unknown"; + _leftIconView.image = [UIImage imageNamed:isDir? @"icon_code_tree": [[NSURL ea_imageUTIList] containsObject:itemUTI]? @"icon_code_image": @"icon_code_file"]; + self.fileNameL.attributedText = [self attrPath]; +} + +- (NSAttributedString *)attrPath{ + NSString *shortPath = _curURL.lastPathComponent; + NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:shortPath]; + [attrString addAttributes:@{NSBackgroundColorAttributeName: [UIColor colorWithHexString:@"0xFFEFBD"]} + range:[shortPath rangeOfString:_searchText options:NSCaseInsensitiveSearch]]; + return attrString; +} + +@end diff --git a/Coding_iOS/Views/Cell/EATaskBoardListTaskCell.h b/Coding_iOS/Views/Cell/EATaskBoardListTaskCell.h new file mode 100644 index 000000000..c5fc6b97b --- /dev/null +++ b/Coding_iOS/Views/Cell/EATaskBoardListTaskCell.h @@ -0,0 +1,20 @@ +// +// EATaskBoardListTaskCell.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/4/27. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import +#import "Task.h" + +@interface EATaskBoardListTaskCell : UITableViewCell + +@property (strong, nonatomic) Task *task; + +@property (copy, nonatomic) void(^taskStatusChangedBlock)(Task *task); + ++ (CGFloat)cellHeightWithObj:(Task *)obj; + +@end diff --git a/Coding_iOS/Views/Cell/EATaskBoardListTaskCell.m b/Coding_iOS/Views/Cell/EATaskBoardListTaskCell.m new file mode 100644 index 000000000..15587e5b2 --- /dev/null +++ b/Coding_iOS/Views/Cell/EATaskBoardListTaskCell.m @@ -0,0 +1,192 @@ +// +// EATaskBoardListTaskCell.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/4/27. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "EATaskBoardListTaskCell.h" +#import "Coding_NetAPIManager.h" + +@interface EATaskBoardListTaskCell () + +@property (strong, nonatomic) UIView *innerContentView; + +@property (strong, nonatomic) UIImageView *taskPriorityView; +@property (strong, nonatomic) UITapImageView *checkView; +@property (strong, nonatomic) UILabel *contentLabel, *timeLabel; +@property (strong, nonatomic) UIView *tagsView; + +@end + +@implementation EATaskBoardListTaskCell + + +- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier +{ + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + // Initialization code + self.selectionStyle = UITableViewCellSelectionStyleNone; + self.backgroundColor = self.contentView.backgroundColor = [UIColor clearColor]; + if (!_innerContentView) { + _innerContentView = [UIView new]; + _innerContentView.backgroundColor = kColorWhite; + _innerContentView.cornerRadius = 2.0; + _innerContentView.masksToBounds = YES; + [self.contentView addSubview:_innerContentView]; + } + if (!_checkView) { + _checkView = [UITapImageView new]; + _checkView.contentMode = UIViewContentModeCenter; + + __weak typeof(self) weakSelf = self; + [_checkView addTapBlock:^(id obj) { + [weakSelf checkViewClicked]; + }]; + [_innerContentView addSubview:_checkView]; + } + if (!_taskPriorityView) { + _taskPriorityView = [UIImageView new]; + _taskPriorityView.contentMode = UIViewContentModeScaleAspectFit; + [_innerContentView addSubview:_taskPriorityView]; + } + if (!_contentLabel) { + _contentLabel = [UILabel new]; + _contentLabel.textColor = kColorDark3; + _contentLabel.font = [UIFont systemFontOfSize:15]; + [_innerContentView addSubview:_contentLabel]; + } + if (!_timeLabel) { + _timeLabel = [UILabel new]; + _timeLabel.font = [UIFont systemFontOfSize:12]; + _timeLabel.textColor = kColorDark7; + [_innerContentView addSubview:_timeLabel]; + } + if (!_tagsView) { + _tagsView = [UIView new]; + _tagsView.clipsToBounds = YES; + [_innerContentView addSubview:_tagsView]; + } + [_innerContentView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.contentView).insets(UIEdgeInsetsMake(0, kPaddingLeftWidth, 10, kPaddingLeftWidth)); + }]; + [_checkView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(_innerContentView).offset(10); + make.centerY.equalTo(_contentLabel); + make.size.mas_equalTo(CGSizeMake(17, 17)); + }]; + [_taskPriorityView mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(_contentLabel); + make.left.equalTo(_checkView.mas_right).offset(10); + make.size.mas_equalTo(CGSizeMake(17, 17)); + }]; + [_contentLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(_innerContentView).offset(15); + make.left.equalTo(self.taskPriorityView.mas_right).offset(10); + make.right.equalTo(_innerContentView).offset(-10); + make.height.mas_equalTo(20); + }]; + [_timeLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.contentLabel); + make.top.equalTo(self.contentLabel.mas_bottom).offset(5); + make.height.mas_equalTo(17); + }]; + [_tagsView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(_contentLabel); + make.right.bottom.equalTo(_innerContentView); + make.height.mas_equalTo(3); + }]; + } + return self; +} + +- (void)setTask:(Task *)task{ + _task = task; + //Top + [_checkView setImage:[UIImage imageNamed:_task.status.integerValue == 1? @"checkbox_unchecked" : @"checkbox_checked"]]; + [_taskPriorityView setImage:[UIImage imageNamed:[NSString stringWithFormat:@"taskPriority%@_small", _task.priority.stringValue]]]; + _contentLabel.textColor = _task.status.integerValue == 1? kColorDark3: kColorDarkA; + _contentLabel.text = [_task.content stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + [self setDate:_task.deadline_date andDone:(_task.status.integerValue != 1)]; + //Tags + [_tagsView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; + for (NSInteger index = 0; index < _task.labels.count; index++) { + [self p_addTag:_task.labels[index] withIndex:index]; + } +} + +- (void)p_addTag:(ProjectTag *)curTag withIndex:(NSInteger)index{ + UIColor *tagColor = curTag.color.length > 1? [UIColor colorWithHexString:[curTag.color stringByReplacingOccurrencesOfString:@"#" withString:@"0x"]]: kColorBrandBlue; + UIView *tagV = [UIView new]; + tagV.backgroundColor = tagColor; + tagV.cornerRadius = 2; + tagV.masksToBounds = YES; + [_tagsView addSubview:tagV]; + [tagV mas_makeConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo(30); + make.top.bottom.equalTo(_tagsView); + make.left.equalTo(_tagsView).offset(index * (30 + 5)); + }]; +} + +- (void)setDate:(NSDate *)deadline_date andDone:(BOOL)done{ + self.timeLabel.hidden = (deadline_date == nil); + + if (deadline_date) { + NSString *textColorStr, *deadlineStr; + NSInteger leftDayCount = [deadline_date leftDayCount]; + switch (leftDayCount) { + case 0: + textColorStr = @"0xF68435"; + deadlineStr = @"今天"; + break; + case 1: + textColorStr = @"0xA1CF64"; + deadlineStr = @"明天"; + break; + default: + textColorStr = leftDayCount > 0? @"0x59A2FF": @"0xF56061"; + deadlineStr = [deadline_date stringWithFormat:@"MM/dd"]; + break; + } + if (done) { + textColorStr = @"0xA9B3BE"; + } + self.timeLabel.textColor = [UIColor colorWithHexString:textColorStr]; + self.timeLabel.text = deadlineStr; + } +} + +- (void)checkViewClicked{ + if (!_task.isRequesting) { + _task.isRequesting = YES; + //用户点击后,直接改变任务状态 + [self.checkView setImage:[UIImage imageNamed:(self.task.status.integerValue != 2? @"checkbox_checked":@"checkbox_unchecked")]]; + //ChangeTaskStatus后,task对象的status属性会直接在请求结束后被修改 + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_ChangeTaskStatus:_task andBlock:^(id data, NSError *error) { + weakSelf.task.isRequesting = NO; + if (data) { + if (weakSelf.taskStatusChangedBlock) { + weakSelf.taskStatusChangedBlock(weakSelf.task); + } + }else{ + [weakSelf.checkView setImage:[UIImage imageNamed:(weakSelf.task.status.integerValue != 2? @"checkbox_checked":@"checkbox_unchecked")]]; + } + }]; + } +} + ++ (CGFloat)cellHeightWithObj:(Task *)obj{ + CGFloat cellHeight = 60; + if (obj.deadline_date) { + cellHeight += 22; + } + if (obj.labels.count > 0) { + cellHeight += 5; + } + return cellHeight; +} +@end diff --git a/Coding_iOS/Views/Cell/EaseUserInfoCell.h b/Coding_iOS/Views/Cell/EaseUserInfoCell.h new file mode 100644 index 000000000..4e7118d0f --- /dev/null +++ b/Coding_iOS/Views/Cell/EaseUserInfoCell.h @@ -0,0 +1,25 @@ +// +// EaseUserInfoCell.h +// Coding_iOS +// +// Created by 张达棣 on 16/11/28. +// Copyright © 2016年 Coding. All rights reserved. +// +#define kCellIdentifier_EaseUserInfoCell @"EaseUserInfoCell" + +#import + + +@interface EaseUserInfoCell : UITableViewCell +@property (nonatomic, strong) User *user; + +@property (nonatomic, copy) void (^userIconClicked)(); +@property (nonatomic, copy) void (^fansCountBtnClicked)(); +@property (nonatomic, copy) void (^followsCountBtnClicked)(); +@property (nonatomic, copy) void (^followBtnClicked)(); +@property (nonatomic, copy) void (^editButtonClicked)(); +@property (nonatomic, copy) void (^messageBtnClicked)(); +@property (nonatomic, copy) void (^detailInfoBtnClicked)(); + + +@end diff --git a/Coding_iOS/Views/Cell/EaseUserInfoCell.m b/Coding_iOS/Views/Cell/EaseUserInfoCell.m new file mode 100644 index 000000000..9211c2eda --- /dev/null +++ b/Coding_iOS/Views/Cell/EaseUserInfoCell.m @@ -0,0 +1,288 @@ +// +// EaseUserInfoCell.m +// Coding_iOS +// +// Created by 张达棣 on 16/11/28. +// Copyright © 2016年 Coding. All rights reserved. +// + +#import "EaseUserInfoCell.h" +#import "UIButton+WebCache.h" +#import "TagsScrollView.h" +#import "Login.h" +#import "UILabel+Common.h" + +@interface EaseUserInfoCell () +@property (nonatomic, strong) UIButton *headIconButton; +@property (strong, nonatomic) UIImageView *vipV; +@property (nonatomic, strong) UIButton *fansButton; //粉丝 +@property (nonatomic, strong) UIButton *followsButton; //关注 +@property (nonatomic, strong) UIButton *addFollowsButton; //添加关注 +@property (nonatomic, strong) UIButton *messageButton; //发送消息 +@property (nonatomic, strong) UILabel *nameLabel; //名字 +@property (nonatomic, strong) UIImageView *sexImageView; //性别 +@property (nonatomic, strong) UIButton *detailsButton;//详情信息 +@property (nonatomic, strong) UIButton *localButton; //地址 +@property (nonatomic, strong) TagsScrollView *tagView; //标签 +@property (nonatomic, strong) UILabel *sloganLabel; //个性签名 +@property (nonatomic, strong) UIButton *editButtonClick; //编辑资料 +@end + +@implementation EaseUserInfoCell + +#pragma mark - 生命周期方法 + +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + [self creatView]; + } + return self; +} + +- (void)awakeFromNib { + [super awakeFromNib]; + [self creatView]; + + // Initialization code +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated { + [super setSelected:selected animated:animated]; + + // Configure the view for the selected state +} + +#pragma mark - 外部方法 + +#pragma makr - 消息 + +#pragma mark - 系统委托 + +#pragma mark - 自定义委托 + +#pragma mark - 响应方法 + +- (void)userIconButtonClicked:(id)sender { + if (_userIconClicked) { + _userIconClicked(); + } +} + +- (void)fansCountButtonClicked:(id)sender { + if (_fansCountBtnClicked) { + _fansCountBtnClicked(); + } +} + +- (void)followsCountButtonClicked:(id)sender { + if (_followsCountBtnClicked) { + _followsCountBtnClicked(); + } +} + +- (void)followButtonClicked:(id)sender { + if (_followBtnClicked) { + _followBtnClicked(); + } +} + +- (void)editButtonClicked:(id)sender { + if (_editButtonClicked) { + _editButtonClicked(); + } +} + +- (void)messageButtonClicked:(id)sender { + if (_messageBtnClicked) { + _messageBtnClicked(); + } +} + +- (void)detailInfoButtonClicked:(id)sender { + if (_detailInfoBtnClicked) { + _detailInfoBtnClicked(); + } +} + +#pragma mark - 私有方法 + +- (void)creatView { + self.selectionStyle = UITableViewCellSelectionStyleNone; + + _headIconButton = [[UIButton alloc] initWithFrame:CGRectMake(15, 20, 77, 77)]; + _headIconButton.cornerRadius = _headIconButton.width / 2; + _headIconButton.masksToBounds = YES; + [_headIconButton addTarget:self action:@selector(userIconButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; + [self.contentView addSubview:_headIconButton]; + + _vipV = [UIImageView new]; + [self.contentView addSubview:_vipV]; + [_vipV mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.bottom.equalTo(_headIconButton); + }]; + + _fansButton = [[UIButton alloc] init]; + _fansButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; + _fansButton.titleLabel.font = [UIFont boldSystemFontOfSize:15]; + [_fansButton setTitleColor:[UIColor colorWithRGBHex:0x4f565f] forState:UIControlStateNormal]; + [_fansButton addTarget:self action:@selector(fansCountButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; + [self.contentView addSubview:_fansButton]; + _fansButton.sd_layout.leftSpaceToView(self.contentView, 112).topSpaceToView(self.contentView, 30).widthIs(100).heightIs(21); + + _followsButton = [[UIButton alloc] init]; + _followsButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; + _followsButton.titleLabel.font = [UIFont boldSystemFontOfSize:15]; + [_followsButton setTitleColor:[UIColor colorWithRGBHex:0x4f565f] forState:UIControlStateNormal]; + [_followsButton addTarget:self action:@selector(followsCountButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; + [self.contentView addSubview:_followsButton]; + _followsButton.sd_layout.leftSpaceToView(_fansButton, 40).topEqualToView(_fansButton).widthIs(100).heightRatioToView(_fansButton, 1); + + _messageButton = [[UIButton alloc] init]; + [_messageButton setImage:[UIImage imageNamed:@"user_info_message"] forState:UIControlStateNormal]; + _messageButton.backgroundColor = [UIColor colorWithRGBHex:0xf2f4f6]; + _messageButton.borderWidth = 1; + _messageButton.borderColor = [UIColor colorWithRGBHex:0xd8dde4]; + _messageButton.cornerRadius = 2; + [_messageButton addTarget:self action:@selector(messageButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; + [self.contentView addSubview:_messageButton]; + _messageButton.sd_layout.rightSpaceToView(self.contentView, 15).topSpaceToView(self.contentView, 59).widthIs(50).heightIs(30); + + + _addFollowsButton = [[UIButton alloc] init]; + [_addFollowsButton setTitleColor:[UIColor colorWithRGBHex:0x0060FF] forState:UIControlStateNormal]; + _addFollowsButton.titleLabel.font = [UIFont systemFontOfSize:13]; + _addFollowsButton.borderWidth = 1; + _addFollowsButton.borderColor = [UIColor colorWithRGBHex:0xd8dde4]; + [_addFollowsButton addTarget:self action:@selector(followButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; + [self.contentView addSubview:_addFollowsButton]; + _addFollowsButton.sd_layout.leftSpaceToView(self.contentView, 112).topEqualToView(_messageButton).rightSpaceToView(_messageButton, 5).heightIs(30); + + + _editButtonClick = [[UIButton alloc] init]; + [_editButtonClick setTitle:@"编辑资料" forState:UIControlStateNormal]; + [_editButtonClick setTitleColor:[UIColor colorWithRGBHex:0x272c33] forState:UIControlStateNormal]; + _editButtonClick.titleLabel.font = [UIFont systemFontOfSize:13]; + _editButtonClick.cornerRadius = 2; + _editButtonClick.masksToBounds = YES; + _editButtonClick.borderWidth = 1; + _editButtonClick.borderColor = [UIColor colorWithRGBHex:0xd8dde4]; + _editButtonClick.backgroundColor = [UIColor colorWithRGBHex:0xf2f4f6]; + [_editButtonClick addTarget:self action:@selector(editButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; + _editButtonClick.hidden = YES; + [self.contentView addSubview:_editButtonClick]; + _editButtonClick.sd_layout.leftSpaceToView(self.contentView, 112).topEqualToView(_messageButton).rightSpaceToView(self.contentView, 15).heightIs(30); + + + _detailsButton = [[UIButton alloc] init]; + _detailsButton.titleLabel.textAlignment = NSTextAlignmentRight; + [_detailsButton setTitle:@"详细信息" forState:UIControlStateNormal]; + [_detailsButton setTitleColor:[UIColor colorWithRGBHex:0x76808E] forState:UIControlStateNormal]; + _detailsButton.titleLabel.font = [UIFont systemFontOfSize:13]; + [_detailsButton setImage:[UIImage imageNamed:@"register_step_un"] forState:UIControlStateNormal]; + [_detailsButton addTarget:self action:@selector(detailInfoButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; + [self.contentView addSubview:_detailsButton]; + _detailsButton.sd_layout.rightSpaceToView(self.contentView, 8).topSpaceToView(_headIconButton, 20).widthIs(80).heightIs(21); + _detailsButton.imageView.sd_layout.rightEqualToView(_detailsButton).centerYEqualToView( _detailsButton).widthIs(13).heightIs(10); + _detailsButton.titleLabel.sd_layout.rightSpaceToView(_detailsButton.imageView, 2).centerYEqualToView( _detailsButton).widthIs(60).heightRatioToView(_detailsButton.imageView, 1); + + + + _nameLabel = [[UILabel alloc] init]; + _nameLabel.textColor = [UIColor colorWithRGBHex:0x323a45]; + _nameLabel.font = [UIFont systemFontOfSize:17]; + [self.contentView addSubview:_nameLabel]; + _nameLabel.sd_layout.leftSpaceToView(self.contentView, 15).topSpaceToView(_headIconButton, 20).heightIs(24); + [_nameLabel setSingleLineAutoResizeWithMaxWidth:kScreen_Width / 2]; + + _sexImageView = [[UIImageView alloc] init]; + [self.contentView addSubview:_sexImageView]; + _sexImageView.sd_layout.leftSpaceToView(_nameLabel, 4).centerYEqualToView(_nameLabel).widthIs(16).heightIs(16); + + _localButton = [[UIButton alloc] init]; + [_localButton setTitleColor:[UIColor colorWithRGBHex:0x4f565f] forState:UIControlStateNormal]; + _localButton.titleLabel.font = [UIFont systemFontOfSize:14]; + _localButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; + [_localButton setImage:[UIImage imageNamed:@"user_info_locus"] forState:UIControlStateNormal]; + [self.contentView addSubview:_localButton]; + _localButton.sd_layout.leftEqualToView(_nameLabel).topSpaceToView(_nameLabel, 15).rightSpaceToView(self.contentView, 15).heightIs(20); + _localButton.imageView.sd_layout.leftSpaceToView(_localButton, 0).centerYEqualToView(_localButton).widthIs(15).heightRatioToView(_localButton, .75); + _localButton.titleLabel.sd_layout.leftSpaceToView(_localButton.imageView, 15).centerYEqualToView(_localButton).heightIs(21).rightSpaceToView(_localButton, 4); + + _tagView = [[TagsScrollView alloc] init]; + _tagView.backgroundColor = [UIColor clearColor]; + [self.contentView addSubview:_tagView]; + + _sloganLabel = [[UILabel alloc] init]; + _sloganLabel.textColor = [UIColor colorWithRGBHex:0x76808e]; + _sloganLabel.font = [UIFont systemFontOfSize:14]; + [self.contentView addSubview:_sloganLabel]; +} + +#pragma mark - get/set方法 + +- (void)setUser:(User *)user { + _user = user; + + if ([Login isLoginUserGlobalKey:user.global_key]) { + _editButtonClick.hidden = NO; + _messageButton.hidden = _addFollowsButton.hidden = _detailsButton.hidden = YES; + } + + [_headIconButton sd_setBackgroundImageWithURL:[user.avatar urlImageWithCodePathResize:2* _headIconButton.width] forState:UIControlStateNormal placeholderImage:kPlaceholderMonkeyRoundWidth(54.0)]; + _vipV.image = [UIImage imageNamed:[NSString stringWithFormat:@"vip_%@_75", _user.vip]]; + + [_fansButton setTitle:[NSString stringWithFormat:@"粉丝 %@", user.fans_count.stringValue] forState:UIControlStateNormal]; + [_fansButton.titleLabel colorTextWithColor:[UIColor colorWithRGBHex:0x76808e] range:NSMakeRange(0, 2)]; + [_fansButton.titleLabel fontTextWithFont:[UIFont systemFontOfSize:12] range:NSMakeRange(0, 2)]; + + [_followsButton setTitle:[NSString stringWithFormat:@"关注 %@", user.follows_count.stringValue] forState:UIControlStateNormal]; + [_followsButton.titleLabel colorTextWithColor:[UIColor colorWithRGBHex:0x76808e] range:NSMakeRange(0, 2)]; + [_followsButton.titleLabel fontTextWithFont:[UIFont systemFontOfSize:12] range:NSMakeRange(0, 2)]; + + NSString *addFollowsButtonImageName, *addFollowsButtonTitle; + if (user.followed.boolValue) { + if (user.follow.boolValue) { + addFollowsButtonImageName = @"user_info_mutualConcern"; //互相关注 + addFollowsButtonTitle = @" 互相关注"; + [_addFollowsButton setTitleColor:[UIColor colorWithRGBHex:0x323a45] forState:UIControlStateNormal]; + }else{ + addFollowsButtonImageName = @"user_info_alreadyConcerned"; //已关注 + addFollowsButtonTitle = @" 已关注"; + [_addFollowsButton setTitleColor:[UIColor colorWithRGBHex:0x323a45] forState:UIControlStateNormal]; + } + }else{ + addFollowsButtonImageName = @"user_info_addAttention"; + addFollowsButtonTitle = @" 关注"; + [_addFollowsButton setTitleColor:[UIColor colorWithRGBHex:0x0060FF] forState:UIControlStateNormal]; + } + [_addFollowsButton setImage:[UIImage imageNamed:addFollowsButtonImageName] forState:UIControlStateNormal]; + [_addFollowsButton setTitle:addFollowsButtonTitle forState:UIControlStateNormal]; + + _nameLabel.text = user.name; + if (user.sex.integerValue == 0) { + _sexImageView.image = [UIImage imageNamed:@"user_info_man"]; + } else if (user.sex.integerValue == 1){ + _sexImageView.image = [UIImage imageNamed:@"user_info_sex"]; + } else { + _sexImageView.image = nil; + } + [_localButton setTitle:user.location forState:UIControlStateNormal]; + _sloganLabel.text = user.slogan; + _tagView.tags = user.tags_str; + + _localButton.hidden = [_user.location isEqualToString:@"未填写"]; + UIView *tempView = !_localButton.hidden ? _localButton : _nameLabel; + _tagView.sd_resetLayout.leftSpaceToView(self.contentView, 15).topSpaceToView(tempView, 14).rightSpaceToView(self.contentView, 15).heightIs(25); + + _tagView.hidden = [_user.tags_str isEqualToString:@"未添加"]; + tempView = !_tagView.hidden ? _tagView : tempView; + _sloganLabel.sd_resetLayout.leftSpaceToView(self.contentView, 15).topSpaceToView(tempView, 10).rightSpaceToView(self.contentView, 15).autoHeightRatio(0); + + _sloganLabel.hidden = [_user.slogan isEqualToString:@"未填写"]; + tempView = !_sloganLabel.hidden ? _sloganLabel : tempView; + [self setupAutoHeightWithBottomView:tempView bottomMargin:20]; + +} + +@end diff --git a/Coding_iOS/Views/Cell/FileActivityCell.m b/Coding_iOS/Views/Cell/FileActivityCell.m index 925574abf..dc411d684 100644 --- a/Coding_iOS/Views/Cell/FileActivityCell.m +++ b/Coding_iOS/Views/Cell/FileActivityCell.m @@ -23,15 +23,19 @@ + (NSAttributedString *)attrContentWithObj:(ProjectActivity *)curActivity{ contentStr = [NSString stringWithFormat:@"%@ 历史版本 V%@ - %@", curActivity.action_msg, curActivity.version, [curActivity.created_at stringDisplay_HHmm]]; }else{ - contentStr = [NSString stringWithFormat:@"%@ 文件 - %@", curActivity.action_msg, [curActivity.created_at stringDisplay_HHmm]]; + if ([curActivity.action isEqualToString:@"rename"]) { + contentStr = [NSString stringWithFormat:@"修改了文件名称 - %@", [curActivity.created_at stringDisplay_HHmm]]; + }else{ + contentStr = [NSString stringWithFormat:@"%@ 文件 - %@", curActivity.action_msg, [curActivity.created_at stringDisplay_HHmm]]; + } } attrContent = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@ %@", userName, contentStr]]; [attrContent addAttributes:@{NSFontAttributeName : [UIFont boldSystemFontOfSize:13], - NSForegroundColorAttributeName : kColor222} + NSForegroundColorAttributeName : kColorDark3} range:NSMakeRange(0, userName.length)]; [attrContent addAttributes:@{NSFontAttributeName : [UIFont systemFontOfSize:13], - NSForegroundColorAttributeName : kColor999} + NSForegroundColorAttributeName : kColorDark7} range:NSMakeRange(userName.length + 1, contentStr.length)]; NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; diff --git a/Coding_iOS/Views/Cell/FileListFileCell.m b/Coding_iOS/Views/Cell/FileListFileCell.m index 09d50b157..c63bfa25c 100755 --- a/Coding_iOS/Views/Cell/FileListFileCell.m +++ b/Coding_iOS/Views/Cell/FileListFileCell.m @@ -73,12 +73,15 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus _progressView.delegate = self; _progressView.font = [UIFont fontWithName:@"Futura-CondensedExtraBold" size:12]; [_progressView setTrackTintColor:[UIColor colorWithHexString:@"0xe6e6e6"]]; - _progressView.popUpViewAnimatedColors = @[kColorBrandGreen]; + _progressView.popUpViewAnimatedColors = @[kColorBrandBlue]; _progressView.hidden = YES; [self.contentView addSubview:self.progressView]; } if (!_stateButton) { - _stateButton = [[UIButton alloc] initWithFrame:CGRectMake((kScreen_Width - 55), ([FileListFileCell cellHeight] - 25)/2, 45, 25)]; + _stateButton = [[UIButton alloc] initWithFrame:CGRectMake((kScreen_Width - 60), ([FileListFileCell cellHeight] - 30)/2, 50, 30)]; + [_stateButton doBorderWidth:1.0 color:kColorD8DDE4 cornerRadius:3]; + _stateButton.titleLabel.font = [UIFont systemFontOfSize:14]; + [_stateButton setTitleColor:kColorDark7 forState:UIControlStateNormal]; [_stateButton addTarget:self action:@selector(clickedByUser) forControlEvents:UIControlEventTouchUpInside]; [self.contentView addSubview:_stateButton]; } @@ -87,28 +90,33 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus } - (void)changeToState:(DownloadState)state{ - NSString *stateImageName; + NSString *stateTitleStr; switch (state) { case DownloadStateDefault: - stateImageName = @"icon_file_state_download"; + stateTitleStr = @"下载"; break; case DownloadStateDownloading: - stateImageName = @"icon_file_state_pause"; + stateTitleStr = @"暂停"; break; case DownloadStatePausing: - stateImageName = @"icon_file_state_goon"; + stateTitleStr = @"继续"; break; case DownloadStateDownloaded: - stateImageName = @"icon_file_state_look"; + stateTitleStr = @"查看"; break; default: - stateImageName = @"icon_file_state_download"; + stateTitleStr = @"下载"; break; } - [self setBackgroundColor:(state == DownloadStateDownloaded)? [UIColor colorWithHexString:@"0xf1fcf6"]:[UIColor whiteColor]]; + [self setBackgroundColor:(state == DownloadStateDownloaded)? [UIColor colorWithHexString:@"0x81BCFF" andAlpha:.1]:[UIColor whiteColor]]; + //addLineforPlainCell: 重置了 backgroundView,要改 layer 才行 + CALayer *bgLayer = self.backgroundView.layer.sublayers.firstObject; + if (bgLayer && [bgLayer isKindOfClass:[CAShapeLayer class]]) { + ((CAShapeLayer *)bgLayer).fillColor = self.backgroundColor.CGColor; + } [self.progressView setHidden:!(state == DownloadStateDownloading || state == DownloadStatePausing)]; - [_stateButton setImage:[UIImage imageNamed:stateImageName] forState:UIControlStateNormal]; + [_stateButton setTitle:stateTitleStr forState:UIControlStateNormal]; } - (void)layoutSubviews{ @@ -142,7 +150,7 @@ - (void)setFile:(ProjectFile *)file{ - (void)clickedByUser{ Coding_FileManager *manager = [Coding_FileManager sharedManager]; - NSURL *fileUrl = [Coding_FileManager diskDownloadUrlForKey:_file.storage_key]; + NSURL *fileUrl = _file.diskFileUrl; if (fileUrl) {//已经下载到本地了 if (_showDiskFileBlock) { _showDiskFileBlock(fileUrl, _file); diff --git a/Coding_iOS/Views/Cell/FileListFolderCell.h b/Coding_iOS/Views/Cell/FileListFolderCell.h index dc8457d53..5df8a87ce 100755 --- a/Coding_iOS/Views/Cell/FileListFolderCell.h +++ b/Coding_iOS/Views/Cell/FileListFolderCell.h @@ -9,10 +9,11 @@ #define kCellIdentifier_FileListFolder @"FileListFolderCell" #import -#import "ProjectFolder.h" +#import "ProjectFile.h" #import "SWTableViewCell.h" @interface FileListFolderCell : SWTableViewCell -@property (strong, nonatomic) ProjectFolder *folder; +@property (strong, nonatomic) ProjectFile *folder; + (CGFloat)cellHeight; @end + diff --git a/Coding_iOS/Views/Cell/FileListFolderCell.m b/Coding_iOS/Views/Cell/FileListFolderCell.m index ceed3ff5a..44623a5ed 100755 --- a/Coding_iOS/Views/Cell/FileListFolderCell.m +++ b/Coding_iOS/Views/Cell/FileListFolderCell.m @@ -51,13 +51,11 @@ - (void)layoutSubviews{ if (!_folder) { return; } - if ([_folder isDefaultFolder]) { - _iconView.image = [UIImage imageNamed:@"icon_file_folder_default"]; - }else{ - _iconView.image = [UIImage imageNamed:@"icon_file_folder_normal"]; - } - _nameLabel.text = [NSString stringWithFormat:@"%@(%ld)", _folder.name, (long)(_folder.count.integerValue)]; - _infoLabel.text = [NSString stringWithFormat:@"%@ 创建于 %@", _folder.owner_name, [_folder.updated_at stringDisplay_HHmm]]; + _iconView.image = [UIImage imageNamed:_folder.isSharedFolder? @"icon_file_folder_share": @"icon_file_folder_normal"]; + // _nameLabel.text = [NSString stringWithFormat:@"%@(%ld)", _folder.name, (long)(_folder.count.integerValue)]; + _nameLabel.text = _folder.isSharedFolder? @"分享中": _folder.name;//count 字段 api 里去掉了 + _infoLabel.text = _folder.isSharedFolder? @"": [NSString stringWithFormat:@"%@ 创建于 %@", _folder.owner_name, [_folder.updated_at stringDisplay_HHmm]]; + _nameLabel.y = _folder.isSharedFolder? (75 - 25)/ 2: kFileListFolderCell_TopPading; } + (CGFloat)cellHeight{ diff --git a/Coding_iOS/Views/Cell/FileListUploadCell.m b/Coding_iOS/Views/Cell/FileListUploadCell.m index 69a17fbbf..fc1b6b3c1 100644 --- a/Coding_iOS/Views/Cell/FileListUploadCell.m +++ b/Coding_iOS/Views/Cell/FileListUploadCell.m @@ -59,7 +59,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus _progressView.delegate = self; _progressView.font = [UIFont fontWithName:@"Futura-CondensedExtraBold" size:12]; [_progressView setTrackTintColor:[UIColor colorWithHexString:@"0xd5d5d5"]]; - _progressView.popUpViewAnimatedColors = @[[UIColor colorWithHexString:@"0x3abd79"]]; + _progressView.popUpViewAnimatedColors = @[kColorLightBlue]; [self.progressView hidePopUpViewAnimated:NO]; [self.contentView addSubview:self.progressView]; } diff --git a/Coding_iOS/Views/Cell/FileSearchCell.m b/Coding_iOS/Views/Cell/FileSearchCell.m index 17ff5edf0..953c43495 100644 --- a/Coding_iOS/Views/Cell/FileSearchCell.m +++ b/Coding_iOS/Views/Cell/FileSearchCell.m @@ -29,7 +29,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (self) { // Initialization code if (!_iconView) { - _iconView = [[UIImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, (kFileSearchCellHeight - kFileListFileCell_IconWidth)/2, kFileListFileCell_IconWidth, kFileListFileCell_IconWidth)]; + _iconView = [[YLImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, (kFileSearchCellHeight - kFileListFileCell_IconWidth)/2, kFileListFileCell_IconWidth, kFileListFileCell_IconWidth)]; _iconView.contentMode=UIViewContentModeScaleAspectFill; _iconView.layer.masksToBounds = YES; _iconView.layer.cornerRadius = 2.0; diff --git a/Coding_iOS/Views/Cell/FileVersionCell.m b/Coding_iOS/Views/Cell/FileVersionCell.m index 837e6b428..0edcaadf3 100644 --- a/Coding_iOS/Views/Cell/FileVersionCell.m +++ b/Coding_iOS/Views/Cell/FileVersionCell.m @@ -63,12 +63,15 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus _progressView.delegate = self; _progressView.font = [UIFont fontWithName:@"Futura-CondensedExtraBold" size:12]; [_progressView setTrackTintColor:[UIColor colorWithHexString:@"0xe6e6e6"]]; - _progressView.popUpViewAnimatedColors = @[kColorBrandGreen]; + _progressView.popUpViewAnimatedColors = @[kColorBrandBlue]; _progressView.hidden = YES; [self.contentView addSubview:self.progressView]; } if (!_stateButton) { - _stateButton = [[UIButton alloc] initWithFrame:CGRectMake((kScreen_Width - 55), ([FileVersionCell cellHeight] - 25)/2, 45, 25)]; + _stateButton = [[UIButton alloc] initWithFrame:CGRectMake((kScreen_Width - 60), ([FileVersionCell cellHeight] - 30)/2, 50, 30)]; + [_stateButton doBorderWidth:1.0 color:kColorD8DDE4 cornerRadius:3]; + _stateButton.titleLabel.font = [UIFont systemFontOfSize:14]; + [_stateButton setTitleColor:kColorDark7 forState:UIControlStateNormal]; [_stateButton addTarget:self action:@selector(clickedByUser) forControlEvents:UIControlEventTouchUpInside]; [self.contentView addSubview:_stateButton]; } @@ -138,33 +141,38 @@ - (void)updateCompleted:(CGFloat)fractionCompleted{ } - (void)changeToState:(DownloadState)state{ - NSString *stateImageName; + NSString *stateTitleStr; switch (state) { case DownloadStateDefault: - stateImageName = @"icon_file_state_download"; + stateTitleStr = @"下载"; break; case DownloadStateDownloading: - stateImageName = @"icon_file_state_pause"; + stateTitleStr = @"暂停"; break; case DownloadStatePausing: - stateImageName = @"icon_file_state_goon"; + stateTitleStr = @"继续"; break; case DownloadStateDownloaded: - stateImageName = @"icon_file_state_look"; + stateTitleStr = @"查看"; break; default: - stateImageName = @"icon_file_state_download"; + stateTitleStr = @"下载"; break; } - [self setBackgroundColor:(state == DownloadStateDownloaded)? [UIColor colorWithHexString:@"0xf1fcf6"]:[UIColor clearColor]]; + [self setBackgroundColor:(state == DownloadStateDownloaded)? [UIColor colorWithHexString:@"0x81BCFF" andAlpha:.1]:[UIColor whiteColor]]; + //addLineforPlainCell: 重置了 backgroundView,要改 layer 才行 + CALayer *bgLayer = self.backgroundView.layer.sublayers.firstObject; + if (bgLayer && [bgLayer isKindOfClass:[CAShapeLayer class]]) { + ((CAShapeLayer *)bgLayer).fillColor = self.backgroundColor.CGColor; + } [self.progressView setHidden:!(state == DownloadStateDownloading || state == DownloadStatePausing)]; - [_stateButton setImage:[UIImage imageNamed:stateImageName] forState:UIControlStateNormal]; + [_stateButton setTitle:stateTitleStr forState:UIControlStateNormal]; } - (void)clickedByUser{ Coding_FileManager *manager = [Coding_FileManager sharedManager]; - NSURL *fileUrl = [Coding_FileManager diskDownloadUrlForKey:_curVersion.storage_key]; + NSURL *fileUrl = _curVersion.diskFileUrl; if (fileUrl) {//已经下载到本地了 if (_showDiskFileBlock) { _showDiskFileBlock(fileUrl, _curVersion); diff --git a/Coding_iOS/Views/Cell/ForkTreeCell.m b/Coding_iOS/Views/Cell/ForkTreeCell.m index 482f0d18c..a5d2295dd 100644 --- a/Coding_iOS/Views/Cell/ForkTreeCell.m +++ b/Coding_iOS/Views/Cell/ForkTreeCell.m @@ -25,7 +25,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus // Initialization code self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; if (!_forkerIconView) { - _forkerIconView = [UIImageView new]; + _forkerIconView = [YLImageView new]; _forkerIconView.layer.masksToBounds = YES; _forkerIconView.layer.cornerRadius = kForkTreeCell_IconWidth/2; [self.contentView addSubview:_forkerIconView]; diff --git a/Coding_iOS/Views/Cell/InputOnlyTextPlainCell.m b/Coding_iOS/Views/Cell/InputOnlyTextPlainCell.m index 6fedddfd2..615946ba8 100755 --- a/Coding_iOS/Views/Cell/InputOnlyTextPlainCell.m +++ b/Coding_iOS/Views/Cell/InputOnlyTextPlainCell.m @@ -22,13 +22,19 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus // Initialization code self.selectionStyle = UITableViewCellSelectionStyleNone; if (!_textField) { - _textField = [[UITextField alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 7.0, kScreen_Width-kPaddingLeftWidth*2, 30)]; + _textField = [UITextField new]; _textField.backgroundColor = [UIColor clearColor]; _textField.borderStyle = UITextBorderStyleNone; _textField.font = [UIFont systemFontOfSize:16]; [_textField addTarget:self action:@selector(textValueChanged:) forControlEvents:UIControlEventEditingChanged]; _textField.clearButtonMode = UITextFieldViewModeWhileEditing; [self.contentView addSubview:_textField]; + [_textField mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.offset(kPaddingLeftWidth); + make.right.offset(-kPaddingLeftWidth); + make.centerY.equalTo(self.contentView); + make.height.mas_equalTo(30); + }]; } } return self; diff --git a/Coding_iOS/Views/Cell/Input_OnlyText_Cell.h b/Coding_iOS/Views/Cell/Input_OnlyText_Cell.h index 20cf3268c..f5070f2f1 100644 --- a/Coding_iOS/Views/Cell/Input_OnlyText_Cell.h +++ b/Coding_iOS/Views/Cell/Input_OnlyText_Cell.h @@ -10,6 +10,7 @@ #define kCellIdentifier_Input_OnlyText_Cell_Captcha @"Input_OnlyText_Cell_Captcha" #define kCellIdentifier_Input_OnlyText_Cell_Password @"Input_OnlyText_Cell_Password" #define kCellIdentifier_Input_OnlyText_Cell_Phone @"Input_OnlyText_Cell_Phone" +#define kCellIdentifier_Input_OnlyText_Cell_Company @"Input_OnlyText_Cell_Company" #import #import "UITapImageView.h" @@ -20,8 +21,9 @@ @property (strong, nonatomic) UILabel *countryCodeL; @property (strong, nonatomic, readonly) PhoneCodeButton *verify_codeBtn; +@property (strong, nonatomic, readonly) UILabel *companySuffixL; -@property (assign, nonatomic) BOOL isForLoginVC; +@property (assign, nonatomic) BOOL isBottomLineShow; @property (nonatomic,copy) void(^textValueChangedBlock)(NSString *); @property (nonatomic,copy) void(^editDidBeginBlock)(NSString *); diff --git a/Coding_iOS/Views/Cell/Input_OnlyText_Cell.m b/Coding_iOS/Views/Cell/Input_OnlyText_Cell.m index 318232c06..bfee88ce8 100755 --- a/Coding_iOS/Views/Cell/Input_OnlyText_Cell.m +++ b/Coding_iOS/Views/Cell/Input_OnlyText_Cell.m @@ -26,15 +26,21 @@ + (NSString *)randomCellIdentifierOfPhoneCodeType{ return [NSString stringWithFormat:@"%@_%ld", kCellIdentifier_Input_OnlyText_Cell_PhoneCode_Prefix, random()]; } +- (void)setIsBottomLineShow:(BOOL)isBottomLineShow{ + _isBottomLineShow = isBottomLineShow; + _lineView.hidden = !_isBottomLineShow; +} + - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { // Initialization code + self.clipsToBounds = YES; self.selectionStyle = UITableViewCellSelectionStyleNone; if (!_textField) { _textField = [UITextField new]; - [_textField setFont:[UIFont systemFontOfSize:17]]; + [_textField setFont:[UIFont systemFontOfSize:15]]; [_textField addTarget:self action:@selector(editDidBegin:) forControlEvents:UIControlEventEditingDidBegin]; [_textField addTarget:self action:@selector(textValueChanged:) forControlEvents:UIControlEventEditingChanged]; [_textField addTarget:self action:@selector(editDidEnd:) forControlEvents:UIControlEventEditingDidEnd]; @@ -43,7 +49,9 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus make.height.mas_equalTo(20); make.left.equalTo(self.contentView).offset(kLoginPaddingLeftWidth); make.right.equalTo(self.contentView).offset(-kLoginPaddingLeftWidth); - make.centerY.equalTo(self.contentView); + + make.bottom.mas_greaterThanOrEqualTo(self.contentView).offset(-15).priority(MASLayoutPriorityRequired); + make.centerY.equalTo(self.contentView).priority(MASLayoutPriorityDefaultLow); }]; } @@ -59,6 +67,11 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus [weakSelf refreshCaptchaImage]; }]; [self.contentView addSubview:_captchaView]; + [_captchaView mas_makeConstraints:^(MASConstraintMaker *make) { + make.size.mas_equalTo(CGSizeMake(60, 25)); + make.centerY.equalTo(self.textField); + make.right.equalTo(self.contentView).offset(-kLoginPaddingLeftWidth); + }]; } if (!_activityIndicator) { _activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; @@ -82,16 +95,40 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus _verify_codeBtn = [[PhoneCodeButton alloc] initWithFrame:CGRectMake(kScreen_Width - 80 - kLoginPaddingLeftWidth, (44-25)/2, 80, 25)]; [_verify_codeBtn addTarget:self action:@selector(phoneCodeButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; [self.contentView addSubview:_verify_codeBtn]; + [_verify_codeBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.size.mas_equalTo(CGSizeMake(80, 25)); + make.centerY.equalTo(self.textField); + make.right.equalTo(self.contentView).offset(-kLoginPaddingLeftWidth); + }]; + } + }else if ([reuseIdentifier isEqualToString:kCellIdentifier_Input_OnlyText_Cell_Company]){ + if (!_companySuffixL) { + _companySuffixL = [UILabel labelWithFont:[UIFont systemFontOfSize:17] textColor:kColor222]; + [self.contentView addSubview:_companySuffixL]; + [_companySuffixL mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.textField); + make.right.equalTo(self.contentView).offset(-kPaddingLeftWidth); + }]; + { + UIView *splitLineV = [UIView new]; + splitLineV.backgroundColor = kColorDDD; + [self.contentView addSubview:splitLineV]; + [splitLineV mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.textField); + make.size.mas_equalTo(CGSizeMake(1.0/[UIScreen mainScreen].scale, 20)); + make.right.equalTo(self.companySuffixL.mas_left).offset(-10); + }]; + } } }else if ([reuseIdentifier isEqualToString:kCellIdentifier_Input_OnlyText_Cell_Phone]){ _countryCodeL = ({ UILabel *label = [UILabel new]; - label.font = [UIFont systemFontOfSize:17]; - label.textColor = kColorBrandGreen; + label.font = [UIFont systemFontOfSize:15]; + label.textColor = kColorBrandBlue; [self.contentView addSubview:label]; [label mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.contentView).offset(kPaddingLeftWidth); - make.centerY.equalTo(self.contentView); + make.centerY.equalTo(self.textField); }]; label; }); @@ -122,8 +159,10 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus [_textField mas_remakeConstraints:^(MASConstraintMaker *make) { make.height.mas_equalTo(20); make.right.equalTo(self.contentView).offset(-kLoginPaddingLeftWidth); - make.centerY.equalTo(self.contentView); make.left.equalTo(lineV.mas_right).offset(8.0); + + make.bottom.mas_greaterThanOrEqualTo(self.contentView).offset(-15).priority(MASLayoutPriorityRequired); + make.centerY.equalTo(self.contentView).priority(MASLayoutPriorityDefaultLow); }]; } } @@ -131,7 +170,8 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus } - (void)prepareForReuse{ - self.isForLoginVC = NO; + [super prepareForReuse]; + self.isBottomLineShow = NO; if (![self.reuseIdentifier isEqualToString:kCellIdentifier_Input_OnlyText_Cell_Password]) { self.textField.secureTextEntry = NO; } @@ -145,7 +185,7 @@ - (void)prepareForReuse{ } - (void)setPlaceholder:(NSString *)phStr value:(NSString *)valueStr{ - self.textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:phStr? phStr: @"" attributes:@{NSForegroundColorAttributeName: [UIColor colorWithHexString:_isForLoginVC? @"0xffffff": @"0x999999" andAlpha:_isForLoginVC? 0.5: 1.0]}]; + self.textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:phStr? phStr: @"" attributes:@{NSForegroundColorAttributeName: kColorDarkA}]; self.textField.text = valueStr; } @@ -170,36 +210,24 @@ - (void)countryCodeBtnClicked:(id)sender{ - (void)layoutSubviews { [super layoutSubviews]; - if (_isForLoginVC) { - if (!_clearBtn) { - _clearBtn = [UIButton new]; - _clearBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight; - [_clearBtn setImage:[UIImage imageNamed:@"text_clear_btn"] forState:UIControlStateNormal]; - [_clearBtn addTarget:self action:@selector(clearBtnClicked:) forControlEvents:UIControlEventTouchUpInside]; - [self.contentView addSubview:_clearBtn]; - [_clearBtn mas_makeConstraints:^(MASConstraintMaker *make) { - make.size.mas_equalTo(CGSizeMake(30, 30)); - make.right.equalTo(self.contentView).offset(-kLoginPaddingLeftWidth); - make.centerY.equalTo(self.contentView); - }]; - } - if (!_lineView) { - _lineView = [UIView new]; - _lineView.backgroundColor = [UIColor colorWithHexString:@"0xffffff" andAlpha:0.5]; - [self.contentView addSubview:_lineView]; - [_lineView mas_makeConstraints:^(MASConstraintMaker *make) { - make.height.mas_equalTo(0.5); - make.left.equalTo(self.contentView).offset(kLoginPaddingLeftWidth); - make.right.equalTo(self.contentView).offset(-kLoginPaddingLeftWidth); - make.bottom.equalTo(self.contentView); - }]; + if (!_lineView && _isBottomLineShow) { + _lineView = [UIView new]; + if (kTarget_Enterprise) { + _lineView.backgroundColor = [UIColor colorWithHexString:@"0xD8DDE4"]; + }else{ + _lineView.backgroundColor = kColorDarkA; } + [self.contentView addSubview:_lineView]; + [_lineView mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(kLine_MinHeight); + make.left.equalTo(self.contentView).offset(kLoginPaddingLeftWidth); + make.right.equalTo(self.contentView).offset(-kLoginPaddingLeftWidth); + make.bottom.equalTo(self.contentView); + }]; } - - self.backgroundColor = _isForLoginVC? [UIColor clearColor]: [UIColor whiteColor]; - self.textField.clearButtonMode = _isForLoginVC? UITextFieldViewModeNever: UITextFieldViewModeWhileEditing; - self.textField.textColor = _isForLoginVC? [UIColor whiteColor]: kColor222; - self.lineView.hidden = !_isForLoginVC; + self.backgroundColor = [UIColor whiteColor]; + self.textField.clearButtonMode = UITextFieldViewModeWhileEditing; + self.textField.textColor = kColorDark2; self.clearBtn.hidden = YES; UIView *rightElement; @@ -212,18 +240,21 @@ - (void)layoutSubviews { rightElement = _passwordBtn; }else if ([self.reuseIdentifier hasPrefix:kCellIdentifier_Input_OnlyText_Cell_PhoneCode_Prefix]){ rightElement = _verify_codeBtn; + }else if ([self.reuseIdentifier isEqualToString:kCellIdentifier_Input_OnlyText_Cell_Company]){ + rightElement = _companySuffixL; } - + [_clearBtn mas_updateConstraints:^(MASConstraintMaker *make) { CGFloat offset = rightElement? (CGRectGetMinX(rightElement.frame) - kScreen_Width - 10): -kLoginPaddingLeftWidth; make.right.equalTo(self.contentView).offset(offset); }]; - - [_textField mas_updateConstraints:^(MASConstraintMaker *make) { - CGFloat offset = rightElement? (CGRectGetMinX(rightElement.frame) - kScreen_Width - 10): -kLoginPaddingLeftWidth; - offset -= self.isForLoginVC? 30: 0; - make.right.equalTo(self.contentView).offset(offset); - }]; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{//layout 的时候,rightElement 的 frame 还没有固定 + [_textField mas_updateConstraints:^(MASConstraintMaker *make) { + CGFloat offset = rightElement? (CGRectGetMinX(rightElement.frame) - kScreen_Width - 10): -kLoginPaddingLeftWidth; + make.right.equalTo(self.contentView).offset(offset); + }]; + }); + } #pragma password @@ -246,8 +277,11 @@ - (void)refreshCaptchaImage{ #pragma mark TextField - (void)editDidBegin:(id)sender { - self.lineView.backgroundColor = [UIColor whiteColor]; - self.clearBtn.hidden = _isForLoginVC? self.textField.text.length <= 0: YES; + if (kTarget_Enterprise) { + self.lineView.backgroundColor = [UIColor colorWithHexString:@"0x323A45"]; + }else{ + self.lineView.backgroundColor = kColorBrandBlue; + } if (self.editDidBeginBlock) { self.editDidBeginBlock(self.textField.text); @@ -255,17 +289,18 @@ - (void)editDidBegin:(id)sender { } - (void)editDidEnd:(id)sender { - self.lineView.backgroundColor = [UIColor colorWithHexString:@"0xffffff" andAlpha:0.5]; + if (kTarget_Enterprise) { + self.lineView.backgroundColor = [UIColor colorWithHexString:@"0xD8DDE4"]; + }else{ + self.lineView.backgroundColor = kColorDarkA; + } self.clearBtn.hidden = YES; - if (self.editDidEndBlock) { self.editDidEndBlock(self.textField.text); } } - (void)textValueChanged:(id)sender { - self.clearBtn.hidden = _isForLoginVC? self.textField.text.length <= 0: YES; - if (self.textValueChangedBlock) { self.textValueChangedBlock(self.textField.text); } diff --git a/Coding_iOS/Views/Cell/LeftImage_LRTextCell.h b/Coding_iOS/Views/Cell/LeftImage_LRTextCell.h index 57e04fc1e..21e30b787 100755 --- a/Coding_iOS/Views/Cell/LeftImage_LRTextCell.h +++ b/Coding_iOS/Views/Cell/LeftImage_LRTextCell.h @@ -12,6 +12,7 @@ typedef NS_ENUM(NSInteger, LeftImage_LRTextCellType) { LeftImage_LRTextCellTypeTaskProject = 0, LeftImage_LRTextCellTypeTaskOwner, + LeftImage_LRTextCellTypeTaskBoardList, LeftImage_LRTextCellTypeTaskPriority, LeftImage_LRTextCellTypeTaskDeadline, LeftImage_LRTextCellTypeTaskWatchers, diff --git a/Coding_iOS/Views/Cell/LeftImage_LRTextCell.m b/Coding_iOS/Views/Cell/LeftImage_LRTextCell.m index 7b71b7c78..c42aeb054 100755 --- a/Coding_iOS/Views/Cell/LeftImage_LRTextCell.m +++ b/Coding_iOS/Views/Cell/LeftImage_LRTextCell.m @@ -25,20 +25,20 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus // Initialization code self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; if (!_iconView) { - _iconView = [[UIImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 8, 28, 28)]; + _iconView = [[YLImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, ([LeftImage_LRTextCell cellHeight] - 33) / 2, 33, 33)]; [self.contentView addSubview:_iconView]; } if (!_leftLabel) { - _leftLabel = [[UILabel alloc] initWithFrame:CGRectMake(60, 7, 80, 30)]; - _leftLabel.font = [UIFont systemFontOfSize:16]; - _leftLabel.textColor = kColor222; + _leftLabel = [[UILabel alloc] initWithFrame:CGRectMake(60, ([LeftImage_LRTextCell cellHeight] - 30) / 2, 80, 30)]; + _leftLabel.font = [UIFont systemFontOfSize:15]; + _leftLabel.textColor = kColorDark3; _leftLabel.textAlignment = NSTextAlignmentLeft; [self.contentView addSubview:_leftLabel]; } if (!_rightLabel) { - _rightLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(_leftLabel.frame), 7, kScreen_Width - CGRectGetMaxX(_leftLabel.frame) - 35, 30)]; - _rightLabel.font = [UIFont systemFontOfSize:18]; - _rightLabel.textColor = kColor999; + _rightLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(_leftLabel.frame), ([LeftImage_LRTextCell cellHeight] - 30) / 2, kScreen_Width - CGRectGetMaxX(_leftLabel.frame) - 35, 30)]; + _rightLabel.font = [UIFont systemFontOfSize:15]; + _rightLabel.textColor = kColorDark7; _rightLabel.textAlignment = NSTextAlignmentRight; [self.contentView addSubview:_rightLabel]; } @@ -83,6 +83,18 @@ - (void)layoutSubviews{ } } break; + case LeftImage_LRTextCellTypeTaskBoardList: + { + [_iconView doNotCircleFrame]; + [_iconView setImage:[UIImage imageNamed:@"taskBoardList"]]; + _leftLabel.text = @"看板列表"; + if (task.task_board_list) { + _rightLabel.text = task.task_board_list.title; + }else{ + _rightLabel.text = @"未指定"; + } + } + break; case LeftImage_LRTextCellTypeTaskPriority: { [_iconView doNotCircleFrame]; @@ -139,11 +151,17 @@ - (void)layoutSubviews{ default: break; } + if ((_type == LeftImage_LRTextCellTypeTaskProject && task.project.icon.length > 0) || + (_type == LeftImage_LRTextCellTypeTaskOwner && task.owner.avatar.length > 0)) { + _iconView.contentMode = UIViewContentModeScaleAspectFill; + }else{ + _iconView.contentMode = UIViewContentModeCenter; + } } } + (CGFloat)cellHeight{ - return 44; + return 50; } @end diff --git a/Coding_iOS/Views/Cell/LocalFileCell.m b/Coding_iOS/Views/Cell/LocalFileCell.m index 7fe6f76be..275db3daa 100644 --- a/Coding_iOS/Views/Cell/LocalFileCell.m +++ b/Coding_iOS/Views/Cell/LocalFileCell.m @@ -50,7 +50,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus }]; NSMutableArray *rightUtilityButtons = [NSMutableArray new]; - [rightUtilityButtons sw_addUtilityButtonWithColor:kColorBrandRed icon:[UIImage imageNamed:@"icon_file_cell_delete"]]; + [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:@"0xF66262"] icon:[UIImage imageNamed:@"icon_file_cell_delete"]]; [self setRightUtilityButtons:rightUtilityButtons WithButtonWidth:[LocalFileCell cellHeight]]; } return self; diff --git a/Coding_iOS/Views/Cell/LocalFolderCell.m b/Coding_iOS/Views/Cell/LocalFolderCell.m index 15e5db681..ef687654e 100644 --- a/Coding_iOS/Views/Cell/LocalFolderCell.m +++ b/Coding_iOS/Views/Cell/LocalFolderCell.m @@ -43,7 +43,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus make.height.mas_equalTo(30); }]; NSMutableArray *rightUtilityButtons = [NSMutableArray new]; - [rightUtilityButtons sw_addUtilityButtonWithColor:kColorBrandRed icon:[UIImage imageNamed:@"icon_file_cell_delete"]]; + [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:@"0xF66262"] icon:[UIImage imageNamed:@"icon_file_cell_delete"]]; [self setRightUtilityButtons:rightUtilityButtons WithButtonWidth:[LocalFolderCell cellHeight]]; } return self; diff --git a/Coding_iOS/Views/Cell/Login2FATipCell.m b/Coding_iOS/Views/Cell/Login2FATipCell.m index acd38ebeb..b70b47a97 100644 --- a/Coding_iOS/Views/Cell/Login2FATipCell.m +++ b/Coding_iOS/Views/Cell/Login2FATipCell.m @@ -9,6 +9,7 @@ #import "Login2FATipCell.h" @implementation Login2FATipCell + - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; @@ -17,19 +18,16 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus self.backgroundColor = [UIColor clearColor]; self.userInteractionEnabled = NO; if (!_tipLabel) { - _tipLabel = [UILabel new]; - _tipLabel.layer.masksToBounds = YES; - _tipLabel.layer.cornerRadius = 2.0; - - _tipLabel.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.2]; - _tipLabel.font = [UIFont systemFontOfSize:16]; + _tipLabel = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDark2]; _tipLabel.minimumScaleFactor = 0.5; _tipLabel.adjustsFontSizeToFitWidth = YES; - - _tipLabel.textColor = [UIColor whiteColor]; + _tipLabel.text = @"您的账户开启了两步验证,请输入动态验证码登录"; [self.contentView addSubview:_tipLabel]; [_tipLabel mas_makeConstraints:^(MASConstraintMaker *make) { - make.edges.equalTo(self.contentView).insets(UIEdgeInsetsMake(10, kLoginPaddingLeftWidth, 0, kLoginPaddingLeftWidth)); + make.left.offset(kLoginPaddingLeftWidth); + make.right.offset(-kPaddingLeftWidth); + make.top.offset(10); + make.height.mas_equalTo(20); }]; } } diff --git a/Coding_iOS/Views/Cell/MRPRAcceptEditCell.m b/Coding_iOS/Views/Cell/MRPRAcceptEditCell.m index 016d424d4..ce461c608 100644 --- a/Coding_iOS/Views/Cell/MRPRAcceptEditCell.m +++ b/Coding_iOS/Views/Cell/MRPRAcceptEditCell.m @@ -6,7 +6,7 @@ // Copyright (c) 2015年 Coding. All rights reserved. // -#define kMRPRAcceptEditCell_TextViewHeight 80.0 +#define kMRPRAcceptEditCell_TextViewHeight (kScreen_Height/4) #import "MRPRAcceptEditCell.h" @@ -25,7 +25,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus UILabel *titleL = [UILabel new]; titleL.font = [UIFont systemFontOfSize:15]; - titleL.textColor = kColor999; + titleL.textColor = kColorDark7; titleL.text = @"Merge Commit Message"; [self.contentView addSubview:titleL]; @@ -36,7 +36,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus _contentTextView = [UIPlaceHolderTextView new]; _contentTextView.backgroundColor = [UIColor clearColor]; _contentTextView.font = [UIFont systemFontOfSize:15]; - _contentTextView.textColor = kColor222; + _contentTextView.textColor = kColorDark3; _contentTextView.delegate = self; _contentTextView.placeholder = @"输入点什么..."; [self.contentView addSubview:_contentTextView]; diff --git a/Coding_iOS/Views/Cell/MRPRCommentCell.m b/Coding_iOS/Views/Cell/MRPRCommentCell.m index 18266b888..3888b6ac2 100644 --- a/Coding_iOS/Views/Cell/MRPRCommentCell.m +++ b/Coding_iOS/Views/Cell/MRPRCommentCell.m @@ -31,7 +31,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus self.backgroundColor = kColorTableBG; CGFloat curBottomY = 10; if (!_ownerIconView) { - _ownerIconView = [[UIImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, curBottomY, 33, 33)]; + _ownerIconView = [[YLImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, curBottomY, 33, 33)]; [_ownerIconView doCircleFrame]; [self.contentView addSubview:_ownerIconView]; } @@ -65,7 +65,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus } } if (!_detailBtn) { - _detailBtn = [UIButton buttonWithTitle:@"查看详情" titleColor:kColorBrandGreen]; + _detailBtn = [UIButton buttonWithTitle:@"查看详情" titleColor:kColorBrandBlue]; _detailBtn.titleLabel.font = [UIFont systemFontOfSize:12]; [_detailBtn addTarget:self action:@selector(goToDetail) forControlEvents:UIControlEventTouchUpInside]; [self.contentView addSubview:_detailBtn]; @@ -75,6 +75,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus make.centerY.equalTo(_timeLabel); }]; } + _timeLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; } return self; } @@ -117,6 +118,7 @@ - (void)setCurItem:(ProjectLineNote *)curItem{ curBottomY += [MRPRCommentCell imageCollectionViewHeightWithCount:imagesCount]; [_timeLabel setY:curBottomY]; + _timeLabel.width = _detailBtn.hidden? kScreen_Width - 40 - 2*kPaddingLeftWidth: kScreen_Width - 40 - 2*kPaddingLeftWidth - 60; _timeLabel.text = [NSString stringWithFormat:@"%@ %@", _curItem.author.name, [_curItem.created_at stringDisplay_HHmm]]; } diff --git a/Coding_iOS/Views/Cell/MRPRListCell.h b/Coding_iOS/Views/Cell/MRPRListCell.h index eb70cd842..ac91fa4df 100644 --- a/Coding_iOS/Views/Cell/MRPRListCell.h +++ b/Coding_iOS/Views/Cell/MRPRListCell.h @@ -14,5 +14,5 @@ @interface MRPRListCell : UITableViewCell @property (strong, nonatomic) MRPR *curMRPR; -+ (CGFloat)cellHeight; ++ (CGFloat)cellHeightWithObj:(id)obj; @end diff --git a/Coding_iOS/Views/Cell/MRPRListCell.m b/Coding_iOS/Views/Cell/MRPRListCell.m index d032c8423..34270db34 100644 --- a/Coding_iOS/Views/Cell/MRPRListCell.m +++ b/Coding_iOS/Views/Cell/MRPRListCell.m @@ -6,13 +6,13 @@ // Copyright (c) 2015年 Coding. All rights reserved. // -#define kMRPRListCell_UserWidth 33.0 - #import "MRPRListCell.h" @interface MRPRListCell () -@property (strong, nonatomic) UIImageView *imgView; -@property (strong, nonatomic) UILabel *titleLabel, *subTitleLabel; +@property (strong, nonatomic) UIImageView *statusIcon; +@property (strong, nonatomic) UILabel *titleL, *numL, *authorL, *timeL, *commentCountL; +@property (strong, nonatomic) UIImageView *timeIcon, *commentIcon, *arrowIcon; +@property (strong, nonatomic) UILabel *fromL, *toL; @end @implementation MRPRListCell @@ -21,39 +21,77 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { // Initialization code - self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; self.backgroundColor = kColorTableBG; - if (!_imgView) { - _imgView = [UIImageView new]; - _imgView.layer.masksToBounds = YES; - _imgView.layer.cornerRadius = kMRPRListCell_UserWidth/2; - _imgView.layer.borderWidth = 0.5; - _imgView.layer.borderColor = kColorDDD.CGColor; - [self.contentView addSubview:_imgView]; - [_imgView mas_makeConstraints:^(MASConstraintMaker *make) { - make.size.mas_equalTo(CGSizeMake(kMRPRListCell_UserWidth, kMRPRListCell_UserWidth)); - make.left.equalTo(self.contentView).offset(kPaddingLeftWidth); - make.centerY.equalTo(self.contentView); - }]; - } - if (!_titleLabel) { - _titleLabel = [UILabel new]; - [self.contentView addSubview:_titleLabel]; - [_titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.equalTo(_imgView.mas_right).offset(12); - make.right.equalTo(self.contentView); - make.top.equalTo(self.contentView).offset(13); - make.height.mas_equalTo(20); - }]; - } - if (!_subTitleLabel) { - _subTitleLabel = [UILabel new]; - [self.contentView addSubview:_subTitleLabel]; - [_subTitleLabel mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.right.height.equalTo(_titleLabel); - make.bottom.equalTo(self.contentView.mas_bottom).offset(-13); - }]; + _statusIcon = [UIImageView new]; + _titleL = [UILabel labelWithSystemFontSize:15 textColorHexString:@"0x323A45"]; + _numL = [UILabel labelWithSystemFontSize:12 textColorHexString:@"0x76808E"]; + _authorL = [UILabel labelWithSystemFontSize:12 textColorHexString:@"0x76808E"]; + _timeL = [UILabel labelWithSystemFontSize:12 textColorHexString:@"0x76808E"]; + _commentCountL = [UILabel labelWithSystemFontSize:12 textColorHexString:@"0x76808E"]; + _timeIcon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"time_clock_icon"]]; + _commentIcon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"topic_comment_icon"]]; + _arrowIcon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"mrpr_icon_arrow"]]; + _fromL = [UILabel labelWithSystemFontSize:12 textColorHexString:@"0x76808E"]; + _fromL.backgroundColor = [UIColor colorWithHexString:@"0xF2F4F6"]; + _fromL.cornerRadius = 2; + _fromL.masksToBounds = YES; + // [_fromL doBorderWidth:0.5 color:[UIColor colorWithHexString:@"0x76808E"] cornerRadius:2.0]; + _toL = [UILabel labelWithSystemFontSize:12 textColorHexString:@"0x76808E"]; + _toL.backgroundColor = [UIColor colorWithHexString:@"0xD8DDE4"]; + _toL.cornerRadius = 2; + _toL.masksToBounds = YES; + // [_toL doBorderWidth:0.5 color:[UIColor colorWithHexString:@"0x76808E"] cornerRadius:2.0]; + + for (UIView *tempV in @[_statusIcon, _titleL, _numL, _authorL, _timeL, _commentCountL, _timeIcon, _commentIcon, _arrowIcon, _fromL, _toL]) { + [self.contentView addSubview:tempV]; } + [_statusIcon mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.contentView).offset(kPaddingLeftWidth); + make.top.equalTo(self.contentView).offset(15); + make.size.mas_equalTo(CGSizeMake(24, 24)); + }]; + [_titleL mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(_statusIcon); + make.left.equalTo(_statusIcon.mas_right).offset(kPaddingLeftWidth); + make.right.equalTo(self.contentView).offset(-kPaddingLeftWidth); + make.height.mas_equalTo(21); + }]; + [_fromL mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(_titleL.mas_bottom).offset(10); + make.height.mas_equalTo(22); + make.left.equalTo(_titleL); + }]; + [_arrowIcon mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(_fromL.mas_right).offset(10); + make.centerY.equalTo(_fromL); + make.size.mas_equalTo(CGSizeMake(12, 12)); + make.right.lessThanOrEqualTo(self.contentView).offset(-kPaddingLeftWidth); + }]; + [_toL mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(_arrowIcon.mas_right).offset(10); + make.centerY.equalTo(_fromL); + make.height.mas_equalTo(22); + make.right.lessThanOrEqualTo(self.contentView).offset(-kPaddingLeftWidth); + }]; + [_numL mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(_toL.mas_bottom).offset(10); + make.left.equalTo(_titleL); + make.height.mas_equalTo(17); + }]; + [@[_authorL, _timeIcon, _timeL, _commentIcon, _commentCountL] mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(_numL); + }]; + [_authorL mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(_numL.mas_right).offset(10); + make.right.equalTo(_timeIcon.mas_left).offset(-10); + }]; + [_timeL mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(_timeIcon.mas_right).offset(5); + make.right.equalTo(_commentIcon.mas_left).offset(-10); + }]; + [_commentCountL mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(_commentIcon.mas_right).offset(5); + }]; } return self; } @@ -63,39 +101,65 @@ - (void)setCurMRPR:(MRPR *)curMRPR{ if (!_curMRPR) { return; } - [_imgView sd_setImageWithURL:[_curMRPR.author.avatar urlImageWithCodePathResize:2*kMRPRListCell_UserWidth] placeholderImage:kPlaceholderMonkeyRoundWidth(2*kMRPRListCell_UserWidth)]; - _titleLabel.attributedText = [self attributeTitle]; - _subTitleLabel.attributedText = [self attributeTail]; + _statusIcon.image = [UIImage imageNamed:[NSString stringWithFormat:@"mrpr_icon_status_%@", [_curMRPR.merge_status lowercaseString]]]; + _titleL.text = _curMRPR.title; + _numL.text = [NSString stringWithFormat:@"#%@", _curMRPR.iid.stringValue ?: @""]; + _authorL.text = _curMRPR.author.name; + _timeL.text = [_curMRPR.created_at stringDisplay_HHmm]; + _commentCountL.text = _curMRPR.comment_count.stringValue; + _commentCountL.hidden = _commentIcon.hidden = (_curMRPR.comment_count == nil); + + NSString *fromStr, *toStr; + if (_curMRPR.isMR) { + fromStr = [NSString stringWithFormat:@" %@ ", _curMRPR.srcBranch]; + toStr = [NSString stringWithFormat:@" %@ ", _curMRPR.desBranch]; + }else{ + fromStr = [NSString stringWithFormat:@" %@ : %@ ", _curMRPR.src_owner_name ?: @"已删除项目", _curMRPR.srcBranch]; + toStr = [NSString stringWithFormat:@" %@ : %@ ", _curMRPR.des_owner_name ?: @"已删除项目", _curMRPR.desBranch]; + } + NSString *totalStr = [NSString stringWithFormat:@"%@%@", fromStr, toStr]; + if ([totalStr getWidthWithFont:[UIFont systemFontOfSize:12] constrainedToSize:CGSizeMake(CGFLOAT_MAX, 20)] + 40 > kScreen_Width - (24 + 2* kPaddingLeftWidth) - kPaddingLeftWidth) { + [_toL mas_remakeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(_titleL); + make.top.equalTo(_fromL.mas_bottom).offset(15); + make.height.mas_equalTo(22); + make.right.lessThanOrEqualTo(self.contentView).offset(-kPaddingLeftWidth); + }]; + }else{ + [_toL mas_remakeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(_arrowIcon.mas_right).offset(10); + make.centerY.equalTo(_fromL); + make.height.mas_equalTo(22); + make.right.lessThanOrEqualTo(self.contentView).offset(-kPaddingLeftWidth); + }]; + } + _fromL.text = fromStr; + _toL.text = toStr; } -- (NSAttributedString *)attributeTitle{ - NSString *iidStr = [NSString stringWithFormat:@"#%@", _curMRPR.iid.stringValue? _curMRPR.iid.stringValue: @""]; - NSString *titleStr = _curMRPR.title? _curMRPR.title: @""; - NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@ %@", iidStr, titleStr]]; - [attrString addAttributes:@{NSFontAttributeName : [UIFont boldSystemFontOfSize:14], - NSForegroundColorAttributeName : [UIColor colorWithHexString:@"0x4E90BF"]} - range:NSMakeRange(0, iidStr.length)]; - [attrString addAttributes:@{NSFontAttributeName : [UIFont boldSystemFontOfSize:14], - NSForegroundColorAttributeName : kColor222} - range:NSMakeRange(iidStr.length + 1, titleStr.length)]; - return attrString; -} -- (NSAttributedString *)attributeTail{ - NSString *nameStr = _curMRPR.author.name? _curMRPR.author.name: @""; - NSString *timeStr = _curMRPR.created_at? [_curMRPR.created_at stringDisplay_HHmm]: @""; - NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@ %@", nameStr, timeStr]]; - [attrString addAttributes:@{NSFontAttributeName : [UIFont boldSystemFontOfSize:12], - NSForegroundColorAttributeName : kColor222} - range:NSMakeRange(0, nameStr.length)]; - [attrString addAttributes:@{NSFontAttributeName : [UIFont boldSystemFontOfSize:12], - NSForegroundColorAttributeName : kColor999} - range:NSMakeRange(nameStr.length + 1, timeStr.length)]; - return attrString; ++ (CGFloat)cellHeight{ + return 110.0; } - -+ (CGFloat)cellHeight{ - return 70.0; ++ (CGFloat)cellHeightWithObj:(id)obj{ + CGFloat cellHeight = 110.0; + if ([obj isKindOfClass:[MRPR class]]) { + MRPR *curMRPR = (MRPR *)obj; + NSString *fromStr, *toStr; + if (curMRPR.isMR) { + fromStr = [NSString stringWithFormat:@" %@ ", curMRPR.srcBranch]; + toStr = [NSString stringWithFormat:@" %@ ", curMRPR.desBranch]; + }else{ + fromStr = [NSString stringWithFormat:@" %@ : %@ ", curMRPR.src_owner_name ?: @"已删除项目", curMRPR.srcBranch]; + toStr = [NSString stringWithFormat:@" %@ : %@ ", curMRPR.des_owner_name ?: @"已删除项目", curMRPR.desBranch]; + } + NSString *totalStr = [NSString stringWithFormat:@"%@%@", fromStr, toStr]; + if ([totalStr getWidthWithFont:[UIFont systemFontOfSize:12] constrainedToSize:CGSizeMake(CGFLOAT_MAX, 20)] + 40 > kScreen_Width - (24 + 2* kPaddingLeftWidth) - kPaddingLeftWidth) { + cellHeight += 15 + 22; + } + } + return cellHeight; } + @end diff --git a/Coding_iOS/Views/Cell/MRPRTopCell.m b/Coding_iOS/Views/Cell/MRPRTopCell.m index 25e624310..f31c41549 100644 --- a/Coding_iOS/Views/Cell/MRPRTopCell.m +++ b/Coding_iOS/Views/Cell/MRPRTopCell.m @@ -6,14 +6,13 @@ // Copyright (c) 2015年 Coding. All rights reserved. // -#define kMRPRActionView_Height 25.0 -#define kMRPRTopCell_FontTitle [UIFont boldSystemFontOfSize:18] -#define kMRPRTopCell_FontFromTo [UIFont boldSystemFontOfSize:12] +#define kMRPRActionView_Height 35.0 +#define kMRPRTopCell_FontTitle [UIFont boldSystemFontOfSize:15] +#define kMRPRTopCell_FontFromTo [UIFont systemFontOfSize:12] #import "MRPRTopCell.h" @interface MRPRTopCell () -@property (strong, nonatomic) UIImageView *userIconView; @property (strong, nonatomic) UILabel *titleL, *timeL, *statusL; @property (strong, nonatomic) UIView *lineView; @@ -29,21 +28,16 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus // Initialization code self.selectionStyle = UITableViewCellSelectionStyleNone; self.backgroundColor = kColorTableBG; - if (!_userIconView) { - _userIconView = [[UIImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 0, 20, 20)]; - [_userIconView doCircleFrame]; - [self.contentView addSubview:_userIconView]; - } CGFloat curWidth = kScreen_Width - 2 * kPaddingLeftWidth; if (!_titleL) { _titleL = [[UILabel alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 15, curWidth, 30)]; - _titleL.textColor = kColor222; + _titleL.textColor = kColorDark3; _titleL.font = kMRPRTopCell_FontTitle; [self.contentView addSubview:_titleL]; } if (!_timeL) { _timeL = [[UILabel alloc] initWithFrame:CGRectMake(kPaddingLeftWidth +25, 0, curWidth, 20)]; - _timeL.textColor = kColor999; + _timeL.textColor = kColorDark7; _timeL.font = [UIFont systemFontOfSize:12]; [self.contentView addSubview:_timeL]; } @@ -63,9 +57,11 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (!_fromL) { _fromL = [UILabel new]; - [_fromL doBorderWidth:0.5 color:[UIColor colorWithHexString:@"0x4E90BF"] cornerRadius:2.0]; + _fromL.backgroundColor = [UIColor colorWithHexString:@"0xF2F4F6"]; + _fromL.cornerRadius = 2; + _fromL.masksToBounds = YES; _fromL.font = kMRPRTopCell_FontFromTo; - _fromL.textColor = [UIColor colorWithHexString:@"0x4E90BF"]; + _fromL.textColor = [UIColor colorWithHexString:@"0x76808E"]; [self.contentView addSubview:_fromL]; } if (!_arrowIcon) { @@ -75,17 +71,19 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus } if (!_toL) { _toL = [UILabel new]; - [_toL doBorderWidth:0.5 color:[UIColor colorWithHexString:@"0x4E90BF"] cornerRadius:2.0]; + _toL.backgroundColor = [UIColor colorWithHexString:@"0xD8DDE4"]; + _toL.cornerRadius = 2; + _toL.masksToBounds = YES; _toL.font = kMRPRTopCell_FontFromTo; - _toL.textColor = [UIColor colorWithHexString:@"0x4E90BF"]; + _toL.textColor = [UIColor colorWithHexString:@"0x76808E"]; [self.contentView addSubview:_toL]; } { [_timeL mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.equalTo(_userIconView.mas_right).offset(5); - make.centerY.equalTo(_userIconView); - make.height.mas_equalTo(_userIconView.mas_height); + make.left.offset(kPaddingLeftWidth); + make.top.equalTo(_titleL.mas_bottom).offset(15); + make.height.mas_equalTo(17); }]; [_statusL mas_makeConstraints:^(MASConstraintMaker *make) { @@ -95,20 +93,20 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus make.width.mas_equalTo(80); }]; [_lineView mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.equalTo(_userIconView); + make.left.equalTo(_timeL); make.right.equalTo(_statusL); make.height.mas_equalTo(0.5); - make.top.equalTo(_userIconView.mas_bottom).offset(15); + make.top.equalTo(_timeL.mas_bottom).offset(15); }]; [_fromL mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.equalTo(_userIconView); + make.left.equalTo(_timeL); make.top.equalTo(_lineView.mas_bottom).offset(15); make.height.mas_equalTo(20); }]; [_arrowIcon mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(_fromL.mas_right).offset(10); make.centerY.equalTo(_fromL); - make.size.mas_equalTo(CGSizeMake(15, 15)); + make.size.mas_equalTo(CGSizeMake(12, 12)); make.right.lessThanOrEqualTo(self.contentView).offset(-kPaddingLeftWidth); }]; } @@ -122,18 +120,16 @@ - (void)setCurMRPRInfo:(MRPRBaseInfo *)curMRPRInfo{ if (!_curMRPRInfo) { return; } - CGFloat curBottomY = 0; CGFloat curWidth = kScreen_Width -2*kPaddingLeftWidth; [_titleL setLongString:_curMRPRInfo.mrpr.title withFitWidth:curWidth]; - curBottomY += CGRectGetMaxY(_titleL.frame) + 15; - - [_userIconView sd_setImageWithURL:[_curMRPRInfo.mrpr.author.avatar urlImageWithCodePathResizeToView:_userIconView] placeholderImage:kPlaceholderMonkeyRoundView(_userIconView)]; - [_userIconView setY:curBottomY]; - _timeL.attributedText = [self attributeTail]; _statusL.text = _curMRPRInfo.mrpr.statusDisplay; - + _statusL.textColor = [UIColor colorWithHexString:(_curMRPRInfo.mrpr.status == MRPRStatusCanMerge? @"0x666666": + _curMRPRInfo.mrpr.status == MRPRStatusCannotMerge? @"0xB89FDA": + _curMRPRInfo.mrpr.status == MRPRStatusAccepted? @"0x0060FF": + _curMRPRInfo.mrpr.status == MRPRStatusRefused? @"0xF56061": + @"0xF56061")]; NSString *fromStr, *toStr; if (_curMRPRInfo.mrpr.isMR) { fromStr = [NSString stringWithFormat:@" %@ ", _curMRPRInfo.mrpr.srcBranch]; @@ -145,7 +141,7 @@ - (void)setCurMRPRInfo:(MRPRBaseInfo *)curMRPRInfo{ NSString *totalStr = [NSString stringWithFormat:@"%@%@", fromStr, toStr]; if ([totalStr getWidthWithFont:kMRPRTopCell_FontFromTo constrainedToSize:CGSizeMake(CGFLOAT_MAX, 20)] + 40 > kScreen_Width - 2*kPaddingLeftWidth) { [_toL mas_remakeConstraints:^(MASConstraintMaker *make) { - make.left.equalTo(_userIconView); + make.left.equalTo(_timeL); make.top.equalTo(_fromL.mas_bottom).offset(15); make.height.equalTo(_fromL); make.right.lessThanOrEqualTo(self.contentView).offset(-kPaddingLeftWidth); @@ -181,15 +177,8 @@ - (void)setCurMRPRInfo:(MRPRBaseInfo *)curMRPRInfo{ - (NSAttributedString *)attributeTail{ NSString *nameStr = _curMRPRInfo.mrpr.author.name? _curMRPRInfo.mrpr.author.name: @""; - NSString *timeStr = _curMRPRInfo.mrpr.created_at? [_curMRPRInfo.mrpr.created_at stringDisplay_HHmm]: @""; - NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@ %@", nameStr, timeStr]]; - [attrString addAttributes:@{NSFontAttributeName : [UIFont boldSystemFontOfSize:12], - NSForegroundColorAttributeName : kColor222} - range:NSMakeRange(0, nameStr.length)]; - [attrString addAttributes:@{NSFontAttributeName : [UIFont boldSystemFontOfSize:12], - NSForegroundColorAttributeName : kColor999} - range:NSMakeRange(nameStr.length + 1, timeStr.length)]; - return attrString; + NSString *timeStr = _curMRPRInfo.mrpr.created_at? [_curMRPRInfo.mrpr.created_at stringTimesAgo]: @""; + return [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@ 创建 %@", nameStr, timeStr]]; } + (CGFloat)cellHeightWithObj:(id)obj{ @@ -278,7 +267,7 @@ - (void)setStatus:(MRPRStatus)status userName:(NSString *)userName actionDate:(N case MRPRStatusAccepted: imageStr = @"mrpr_icon_accepted"; contentStr = @"合并"; - lineColorStr = @"0x3BBD79"; + lineColorStr = @"0x0060FF"; break; case MRPRStatusRefused: imageStr = @"mrpr_icon_refaused"; @@ -295,13 +284,13 @@ - (void)setStatus:(MRPRStatus)status userName:(NSString *)userName actionDate:(N } _lineView.backgroundColor = [UIColor colorWithHexString:lineColorStr]; [_icon setImage:[UIImage imageNamed:imageStr]]; - contentStr = [NSString stringWithFormat:@"%@ %@ %@了这个请求", userName, [actionDate stringDisplay_HHmm], contentStr]; + contentStr = [NSString stringWithFormat:@"%@ %@ %@了这个请求", userName, [actionDate stringTimesAgo], contentStr]; NSMutableAttributedString *attrContentStr = [[NSMutableAttributedString alloc] initWithString:contentStr]; - [attrContentStr addAttributes:@{NSFontAttributeName : [UIFont boldSystemFontOfSize:12], - NSForegroundColorAttributeName : kColor222} + [attrContentStr addAttributes:@{NSFontAttributeName : [UIFont systemFontOfSize:14], + NSForegroundColorAttributeName : kColorDark3} range:NSMakeRange(0, userName.length)]; - [attrContentStr addAttributes:@{NSFontAttributeName : [UIFont boldSystemFontOfSize:12], - NSForegroundColorAttributeName : kColor999} + [attrContentStr addAttributes:@{NSFontAttributeName : [UIFont systemFontOfSize:14], + NSForegroundColorAttributeName : kColorDark7} range:NSMakeRange(userName.length, attrContentStr.length - userName.length)]; _contentL.attributedText = attrContentStr; } diff --git a/Coding_iOS/Views/Cell/MRReviewerCell.h b/Coding_iOS/Views/Cell/MRReviewerCell.h index 7a76a8dec..a63d963e9 100644 --- a/Coding_iOS/Views/Cell/MRReviewerCell.h +++ b/Coding_iOS/Views/Cell/MRReviewerCell.h @@ -12,6 +12,8 @@ @interface MRReviewerCell: UITableViewCell +@property (copy, nonatomic) void(^rightSideClickedBlock)(); + - (void)setImageStr:(NSString *)imgStr isowner:(BOOL)ower hasLikeMr:(NSNumber *)hasLikeMr; diff --git a/Coding_iOS/Views/Cell/MRReviewerCell.m b/Coding_iOS/Views/Cell/MRReviewerCell.m index ce646aa02..d83feef90 100644 --- a/Coding_iOS/Views/Cell/MRReviewerCell.m +++ b/Coding_iOS/Views/Cell/MRReviewerCell.m @@ -13,7 +13,6 @@ @interface MRReviewerCell () @property (strong, nonatomic) UIImageView *imgView; @property (strong, nonatomic) UILabel *titleLabel; @property (strong, nonatomic) UILabel *rightLabel; -@property (strong, nonatomic) UIImageView *likeImgView; @end @implementation MRReviewerCell @@ -22,7 +21,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { // Initialization code - + self.selectionStyle = UITableViewCellSelectionStyleNone; self.backgroundColor = kColorTableBG; if (!_imgView) { _imgView = [UIImageView new]; @@ -48,28 +47,30 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus self.rightLabel = [UILabel new]; self.rightLabel.text = @"添加"; self.rightLabel.font = [UIFont systemFontOfSize:15]; - //[self.rightLabel setTextColor:kColor999]; [self.contentView addSubview:self.rightLabel]; [self.rightLabel mas_makeConstraints:^(MASConstraintMaker *make) { - //make.left.equalTo(_imgView.mas_right).offset(15); - make.right.equalTo(self.contentView).offset(0); + make.right.equalTo(self.contentView).offset(-kPaddingLeftWidth); make.centerY.height.equalTo(self.contentView); }]; } - if (!self.likeImgView) { - self.likeImgView = [UIImageView new]; - [self.contentView addSubview:self.likeImgView]; - [self.likeImgView mas_makeConstraints:^(MASConstraintMaker *make) { - make.size.mas_equalTo(CGSizeMake(20, 20)); - make.right.equalTo(self.contentView).offset(-40); - make.centerY.equalTo(self.contentView); - }]; - } + UIView *rightSideV = [UIView new]; + [self.contentView addSubview:rightSideV]; + [rightSideV mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.right.bottom.equalTo(self.contentView); + make.width.equalTo(self.contentView).multipliedBy(1.0/4); + }]; + __weak typeof(self) weakSelf = self; + [rightSideV bk_whenTapped:^{ + if (weakSelf.rightSideClickedBlock) { + weakSelf.rightSideClickedBlock(); + } + }]; } return self; } - (void)prepareForReuse{ + [super prepareForReuse]; [self removeTip]; } @@ -101,34 +102,22 @@ - (void)setImageStr:(NSString *)imgStr self.imgView.image = [UIImage imageNamed:imgStr]; self.titleLabel.text = @"评审者"; if(!ower) { - [self.rightLabel mas_makeConstraints:^(MASConstraintMaker *make) { - //make.left.equalTo(_imgView.mas_right).offset(15); - make.right.equalTo(self.contentView).offset(-20); - make.centerY.height.equalTo(self.contentView); - }]; self.selectionStyle = UITableViewCellSelectionStyleNone; if([hasLikeMr isEqual:@1]) { - self.rightLabel.text = @"+1"; - [self.rightLabel setTextColor:kColorBrandGreen]; - [self.likeImgView setHidden:NO]; - self.likeImgView.image = [UIImage imageNamed:@"EPointLikeHead"]; + self.rightLabel.text = @"允许合并"; } else { - [self.rightLabel setTextColor:kColorBrandGreen]; - self.rightLabel.text = @"撤销 +1"; - [self.likeImgView setHidden:YES]; + self.rightLabel.text = @"撤销允许合并"; } + [self.rightLabel setTextColor:kColorLightBlue]; } else { self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; self.rightLabel.text = @"添加"; [self.rightLabel setTextColor:kColor999]; - [self.likeImgView setHidden:YES]; } } -(void) cantReviewer { self.rightLabel.hidden = YES; - self.likeImgView.hidden = YES; - self.selectionStyle = UITableViewCellSelectionStyleNone; self.accessoryType = UITableViewCellAccessoryNone; } diff --git a/Coding_iOS/Views/Cell/MRReviewerListCell.h b/Coding_iOS/Views/Cell/MRReviewerListCell.h index c8a957cee..5008af1ec 100644 --- a/Coding_iOS/Views/Cell/MRReviewerListCell.h +++ b/Coding_iOS/Views/Cell/MRReviewerListCell.h @@ -12,6 +12,7 @@ @interface MRReviewerListCell : UITableViewCell @property (readwrite, nonatomic, strong) NSMutableArray *reviewers; +@property (copy, nonatomic) void(^lastItemClickedBlock)(); - (void)initCellWithReviewers:(NSArray *)reviewers; diff --git a/Coding_iOS/Views/Cell/MRReviewerListCell.m b/Coding_iOS/Views/Cell/MRReviewerListCell.m index 0ecce3d26..224eb5cdc 100644 --- a/Coding_iOS/Views/Cell/MRReviewerListCell.m +++ b/Coding_iOS/Views/Cell/MRReviewerListCell.m @@ -11,10 +11,11 @@ #define kDefaultImageSize 33 #define kDefaultImageCount 8 @interface MRReviewerListCell () -@property (strong, nonatomic) UIImageView *imgView; +//@property (strong, nonatomic) UIImageView *imgView; @property (strong, nonatomic) NSMutableArray *imgViews; @property (strong, nonatomic) NSMutableArray *likeHeadImgViews; @property (strong, nonatomic) UILabel *titleLabel; +@property (strong, nonatomic) NSArray *reviewerList; @end @implementation MRReviewerListCell @@ -24,21 +25,28 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { // Initialization code + self.selectionStyle = UITableViewCellSelectionStyleNone; self.imgViews = [[NSMutableArray alloc] init]; self.likeHeadImgViews = [[NSMutableArray alloc] init]; self.backgroundColor = kColorTableBG; + __weak typeof(self) weakSelf = self; for(int i = 0; i < kDefaultImageCount; i ++) { - UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(40 * (i + 1) + 10, 15, kDefaultImageSize, kDefaultImageSize)]; + UIImageView *imgView = [[YLImageView alloc] initWithFrame:CGRectMake(40 * (i + 1) + 10, 15, kDefaultImageSize, kDefaultImageSize)]; [imgView doCircleFrame]; [imgView setHidden:true]; [self.imgViews addObject:imgView]; [self.contentView addSubview:imgView]; - UIImageView *likeHeadView = [[UIImageView alloc] initWithFrame:CGRectMake(40 * (i + 1) + 23,30, 18, 18)]; + UIImageView *likeHeadView = [[YLImageView alloc] initWithFrame:CGRectMake(40 * (i + 1) + 23,30, 18, 18)]; [likeHeadView doCircleFrame]; [likeHeadView setHidden:true]; [self.likeHeadImgViews addObject:likeHeadView]; [self.contentView addSubview:likeHeadView]; + + imgView.userInteractionEnabled = YES; + [imgView bk_whenTapped:^{ + [weakSelf imgViewClicked:weakSelf.imgViews[i]]; + }]; } } @@ -46,7 +54,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus } - (void)prepareForReuse{ - + [super prepareForReuse]; [self removeTip]; } @@ -89,20 +97,21 @@ - (void)initCellWithReviewers:(NSArray *)reviewerList{ } return result; }]; + _reviewerList = reviewers.copy; int index = 0; for (int i = 0; i < imageCount; i++) { UIImageView *image = self.imgViews[index]; - if(i >= reviewers.count) { + if(i > reviewers.count) { continue; } - Reviewer* reviewer = (Reviewer*)reviewers[i]; - [image setHidden:false]; - if(index >= imageCount-1) { - image.image = [UIImage imageNamed:@"PR_more"]; + if(index >= imageCount-1 || i == reviewers.count) { + image.image = [UIImage imageNamed:i == reviewers.count? @"PR_plus": @"PR_more"]; + image.hidden = NO; index ++; continue; - } + Reviewer* reviewer = (Reviewer*)reviewers[i]; + [image setHidden:false]; [image mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.contentView).offset(15); make.left.equalTo(self.contentView).offset(40 * (index + 1) + 10); @@ -111,16 +120,26 @@ - (void)initCellWithReviewers:(NSArray *)reviewerList{ }]; [image sd_setImageWithURL:[reviewer.reviewer.avatar urlImageWithCodePathResizeToView:image] placeholderImage:kPlaceholderMonkeyRoundView(image)]; if([reviewer.volunteer isEqualToString:@"invitee"]) { - if([reviewer.value isEqual:@100]) { + if([reviewer.value isEqual:@100]) { UIImageView *likeImage = self.likeHeadImgViews[index]; [likeImage setHidden:false]; - likeImage.image = [UIImage imageNamed:@"PointLikeHead"]; - } + likeImage.image = [UIImage imageNamed:@"PointLikeHead"]; + } } index ++; } - - +} + +- (void)imgViewClicked:(UIImageView *)imgView{ + NSUInteger index = [self.imgViews indexOfObject:imgView]; + if (index == NSNotFound) { + return; + } + int imageCount = self.contentView.size.width / 40 - 2; + BOOL isLastV = (index == _reviewerList.count) || (index == imageCount -1); + if (isLastV && _lastItemClickedBlock) { + _lastItemClickedBlock(); + } } + (CGFloat)cellHeight{ @@ -129,3 +148,4 @@ + (CGFloat)cellHeight{ @end + diff --git a/Coding_iOS/Views/Cell/MeRootCompanyCell.h b/Coding_iOS/Views/Cell/MeRootCompanyCell.h new file mode 100644 index 000000000..4d2309374 --- /dev/null +++ b/Coding_iOS/Views/Cell/MeRootCompanyCell.h @@ -0,0 +1,16 @@ +// +// MeRootCompanyCell.h +// Coding_Enterprise_iOS +// +// Created by Ease on 2016/12/30. +// Copyright © 2016年 Coding. All rights reserved. +// +#define kCellIdentifier_MeRootCompanyCell @"MeRootCompanyCell" + +#import +#import "Team.h" + +@interface MeRootCompanyCell : UITableViewCell +@property (strong, nonatomic) Team *curCompany; ++ (CGFloat)cellHeight; +@end diff --git a/Coding_iOS/Views/Cell/MeRootCompanyCell.m b/Coding_iOS/Views/Cell/MeRootCompanyCell.m new file mode 100644 index 000000000..05caa1b0b --- /dev/null +++ b/Coding_iOS/Views/Cell/MeRootCompanyCell.m @@ -0,0 +1,62 @@ +// +// MeRootCompanyCell.m +// Coding_Enterprise_iOS +// +// Created by Ease on 2016/12/30. +// Copyright © 2016年 Coding. All rights reserved. +// + +#import "MeRootCompanyCell.h" + +@interface MeRootCompanyCell () +@property (strong, nonatomic) UIImageView *iconV; +@property (strong, nonatomic) UILabel *nameL, *descriptionL; +@end + +@implementation MeRootCompanyCell +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + if (!_iconV) { + _iconV = [UIImageView new]; + [self.contentView addSubview:_iconV]; + } + if (!_nameL) { + _nameL = [UILabel labelWithSystemFontSize:16 textColorHexString:@"0x1E2D42"]; + [self.contentView addSubview:_nameL]; + } + if (!_descriptionL) { + _descriptionL = [UILabel labelWithFont:[UIFont systemFontOfSize:13] textColor:[UIColor colorWithHexString:@"0x1E2D42" andAlpha:0.6]]; + [self.contentView addSubview:_descriptionL]; + } + [_iconV mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.contentView).offset(kPaddingLeftWidth); + make.size.mas_equalTo(CGSizeMake(22, 22)); + make.centerY.equalTo(self.contentView); + }]; + [_nameL mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.contentView).offset(kPaddingLeftWidth); + make.left.equalTo(_iconV.mas_right).offset(15); + make.right.equalTo(self.contentView).offset(-kPaddingLeftWidth); + }]; + [_descriptionL mas_makeConstraints:^(MASConstraintMaker *make) { + make.bottom.equalTo(self.contentView).offset(-kPaddingLeftWidth); + make.left.right.equalTo(_nameL); + }]; + + } + return self; +} + +- (void)setCurCompany:(Team *)curCompany{ + _curCompany = curCompany; + _iconV.image = [UIImage imageNamed:@"user_info_company"]; + _nameL.text = _curCompany.name; + _descriptionL.text = @"企业账户管理中心"; +} + ++ (CGFloat)cellHeight{ + return 75; +} +@end diff --git a/Coding_iOS/Views/Cell/MeRootServiceCell.m b/Coding_iOS/Views/Cell/MeRootServiceCell.m index 474ccc61a..606ea7480 100644 --- a/Coding_iOS/Views/Cell/MeRootServiceCell.m +++ b/Coding_iOS/Views/Cell/MeRootServiceCell.m @@ -9,7 +9,7 @@ #import "MeRootServiceCell.h" @interface MeRootServiceCell () -@property (strong, nonatomic) UILabel *proL, *proTL, *teamL, *teamTL; +@property (strong, nonatomic) UILabel *leftL, *leftTL, *rightL, *rightTL; @property (strong, nonatomic) UIView *lineV; @property (strong, nonatomic) UIButton *leftBtn, *rightBtn; @end @@ -20,24 +20,24 @@ - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSStr self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { self.selectionStyle = UITableViewCellSelectionStyleNone; - if (!_proL) { - _proL = [UILabel labelWithFont:[UIFont boldSystemFontOfSize:20] textColor:[UIColor colorWithHexString:@"0x4F565F"]]; - [self.contentView addSubview:_proL]; + if (!_leftL) { + _leftL = [UILabel labelWithFont:[UIFont systemFontOfSize:16] textColor:[UIColor colorWithHexString:@"0x323A45"]]; + [self.contentView addSubview:_leftL]; } - if (!_proTL) { - _proTL = [UILabel labelWithSystemFontSize:12 textColorHexString:@"0x76808E"]; - _proTL.text = @"项目"; - [self.contentView addSubview:_proTL]; - } - if (!_teamL) { - _teamL = [UILabel labelWithFont:[UIFont boldSystemFontOfSize:20] textColor:[UIColor colorWithHexString:@"0x4F565F"]]; - [self.contentView addSubview:_teamL]; - } - if (!_teamTL) { - _teamTL = [UILabel labelWithSystemFontSize:12 textColorHexString:@"0x76808E"]; - _teamTL.text = @"团队"; - [self.contentView addSubview:_teamTL]; + if (!_leftTL) { + _leftTL = [UILabel labelWithSystemFontSize:12 textColorHexString:@"0x76808E"]; + _leftTL.text = @"项目数"; + [self.contentView addSubview:_leftTL]; } +// if (!_rightL) { +// _rightL = [UILabel labelWithFont:[UIFont systemFontOfSize:16] textColor:[UIColor colorWithHexString:@"0x323A45"]]; +// [self.contentView addSubview:_rightL]; +// } +// if (!_rightTL) { +// _rightTL = [UILabel labelWithSystemFontSize:12 textColorHexString:@"0x76808E"]; +// _rightTL.text = @"公有"; +// [self.contentView addSubview:_rightTL]; +// } if (!_lineV) { _lineV = [UIView new]; _lineV.backgroundColor = kColorDDD; @@ -53,49 +53,55 @@ - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSStr } forControlEvents:UIControlEventTouchUpInside]; [self.contentView addSubview:_leftBtn]; } - if (!_rightBtn) { - _rightBtn = [UIButton new]; - [_rightBtn bk_addEventHandler:^(id sender) { - if (weakSelf.rightBlock) { - weakSelf.rightBlock(); - } - } forControlEvents:UIControlEventTouchUpInside]; - [self.contentView addSubview:_rightBtn]; - } +// if (!_rightBtn) { +// _rightBtn = [UIButton new]; +// [_rightBtn bk_addEventHandler:^(id sender) { +// if (weakSelf.rightBlock) { +// weakSelf.rightBlock(); +// } +// } forControlEvents:UIControlEventTouchUpInside]; +// [self.contentView addSubview:_rightBtn]; +// } +// [_lineV mas_makeConstraints:^(MASConstraintMaker *make) { +// make.center.equalTo(self.contentView); +// make.size.mas_equalTo(CGSizeMake(0.5, 40)); +// }]; [_lineV mas_makeConstraints:^(MASConstraintMaker *make) { - make.center.equalTo(self.contentView); + make.left.equalTo(self.contentView.mas_right); make.size.mas_equalTo(CGSizeMake(0.5, 40)); }]; [_leftBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.top.bottom.left.equalTo(self.contentView); make.right.equalTo(_lineV.mas_left); }]; - [_rightBtn mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.bottom.right.equalTo(self.contentView); - make.left.equalTo(_lineV.mas_right); - }]; - [_proL mas_makeConstraints:^(MASConstraintMaker *make) { - make.centerY.equalTo(_lineV); - make.baseline.equalTo(@[_proTL, _teamL, _teamTL]); - make.right.equalTo(self.contentView.mas_right).multipliedBy(1.0/4); - }]; - [_proTL mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.equalTo(_proL.mas_right).offset(5); - }]; - [_teamL mas_makeConstraints:^(MASConstraintMaker *make) { - make.right.equalTo(self.contentView.mas_right).multipliedBy(3.0/4); +// [_rightBtn mas_makeConstraints:^(MASConstraintMaker *make) { +// make.top.bottom.right.equalTo(self.contentView); +// make.left.equalTo(_lineV.mas_right); +// }]; + [_leftL mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(_leftBtn); + make.top.equalTo(_leftBtn).offset(15); }]; - [_teamTL mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.mas_equalTo(_teamL.mas_right).offset(5); + [_leftTL mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(_leftBtn); + make.bottom.equalTo(_leftBtn).offset(-15); }]; +// [_rightL mas_makeConstraints:^(MASConstraintMaker *make) { +// make.centerX.equalTo(_rightBtn); +// make.top.equalTo(_rightBtn).offset(15); +// }]; +// [_rightTL mas_makeConstraints:^(MASConstraintMaker *make) { +// make.centerX.equalTo(_rightBtn); +// make.bottom.equalTo(_rightBtn).offset(-15); +// }]; } return self; } - (void)setCurServiceInfo:(UserServiceInfo *)curServiceInfo{ _curServiceInfo = curServiceInfo; - _proL.text = _curServiceInfo? [NSString stringWithFormat:@"%ld", _curServiceInfo.private.integerValue + _curServiceInfo.public.integerValue]: @"--"; - _teamL.text = _curServiceInfo? _curServiceInfo.team.stringValue: @"--"; + _leftL.text = [NSString stringWithFormat:@"%@ / %@", _curServiceInfo.private ?: @"--", _curServiceInfo.private_project_quota ?: @"--"]; + _rightL.text = [NSString stringWithFormat:@"%@ / %@", _curServiceInfo.public ?: @"--", _curServiceInfo.public_project_quota ?: @"--"]; } + (CGFloat)cellHeight{ diff --git a/Coding_iOS/Views/Cell/MeRootUserCell.m b/Coding_iOS/Views/Cell/MeRootUserCell.m index f19154721..480dfd25b 100644 --- a/Coding_iOS/Views/Cell/MeRootUserCell.m +++ b/Coding_iOS/Views/Cell/MeRootUserCell.m @@ -8,6 +8,8 @@ #import "MeRootUserCell.h" +#ifdef Target_Enterprise + @interface MeRootUserCell () @property (strong, nonatomic) UIImageView *userV; @property (strong, nonatomic) UILabel *userL, *gkL; @@ -19,7 +21,7 @@ - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSStr if (self) { self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; if (!_userV) { - _userV = [UIImageView new]; + _userV = [YLImageView new]; [_userV doCircleFrame]; [_userV doBorderWidth:0.5 color:nil cornerRadius:25]; [self.contentView addSubview:_userV]; @@ -58,10 +60,113 @@ - (void)setCurUser:(User *)curUser{ [_userV sd_setImageWithURL:[_curUser.avatar urlImageWithCodePathResize:50* 2]]; _userL.text = _curUser.name; - _gkL.text = [NSString stringWithFormat:@"个性后缀:%@", _curUser.global_key]; + _gkL.text = [NSString stringWithFormat:@"用户名:%@", _curUser.global_key]; +} + ++ (CGFloat)cellHeight{ + return 85; +} +@end + +#else + +@interface MeRootUserCell () +@property (strong, nonatomic) UIImageView *userV, *vipV; +@property (strong, nonatomic) UILabel *userL, *vipL, *expirationL, *gkL; +@end + +@implementation MeRootUserCell +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + if (!_userV) { + _userV = [YLImageView new]; + [_userV doCircleFrame]; + [_userV doBorderWidth:0.5 color:nil cornerRadius:25]; + [self.contentView addSubview:_userV]; + } + if (!_gkL) { + _gkL = [UILabel labelWithFont:[UIFont systemFontOfSize:13] textColor:[UIColor colorWithHexString:@"0x1E2D42" andAlpha:0.6]]; + [self.contentView addSubview:_gkL]; + } + if (!_vipV) { + _vipV = [UIImageView new]; + [self.contentView addSubview:_vipV]; + } + if (!_userL) { + _userL = [UILabel labelWithSystemFontSize:16 textColorHexString:@"0x1E2D42"]; + [self.contentView addSubview:_userL]; + } + if (!_vipL) { + _vipL = [UILabel labelWithFont:[UIFont systemFontOfSize:12] textColor:kColorDark7]; + _vipL.textAlignment = NSTextAlignmentCenter; + _vipL.backgroundColor = kColorD8DDE4; + _vipL.cornerRadius = 2; + _vipL.masksToBounds = YES; + [self.contentView addSubview:_vipL]; + } + if (!_expirationL) { + _expirationL = [UILabel labelWithFont:[UIFont systemFontOfSize:13] textColor:kColorDark7]; + _expirationL.minimumScaleFactor = .5; + _expirationL.adjustsFontSizeToFitWidth = YES; + [self.contentView addSubview:_expirationL]; + } + [_userV mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.contentView).offset(kPaddingLeftWidth); + make.size.mas_equalTo(CGSizeMake(50, 50)); + make.centerY.equalTo(self.contentView); + }]; + [_vipV mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.bottom.equalTo(_userV); + make.size.mas_equalTo(CGSizeMake(18, 18)); + }]; + [_userL mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(_userV); + make.left.equalTo(_userV.mas_right).offset(15); + make.right.equalTo(self.contentView).offset(-kPaddingLeftWidth); + make.height.mas_equalTo(20); + }]; + [_vipL mas_makeConstraints:^(MASConstraintMaker *make) { + make.size.mas_equalTo(CGSizeMake(60, 20)); + make.left.equalTo(_userL); + make.top.equalTo(_userL.mas_bottom).offset(10); + }]; + [_expirationL mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(_vipL); + make.left.equalTo(_vipL.mas_right).offset(8); + make.right.equalTo(_userL); + }]; + [_gkL mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(_userL.mas_bottom).offset(10); + make.left.right.equalTo(_userL); + make.height.mas_equalTo(20); + }]; + } + return self; +} + +- (void)setCurUser:(User *)curUser{ + _curUser = curUser; + + [_userV sd_setImageWithURL:[_curUser.avatar urlImageWithCodePathResize:50* 2]]; + _userL.text = _curUser.name; + _gkL.text = [NSString stringWithFormat:@"用户名:%@", _curUser.global_key]; + _vipL.hidden = _vipV.hidden = _expirationL.hidden = YES; +// _vipV.image = [UIImage imageNamed:[NSString stringWithFormat:@"vip_%@_45", _curUser.vip]]; +// _vipL.text = _curUser.vipName; +// NSString *expirationStr = [_curUser.vip_expired_at string_yyyy_MM_dd]; +// +// if (_curUser.vip.integerValue > 2) { +// [_expirationL setAttrStrWithStr:[NSString stringWithFormat:@"到期时间:%@",expirationStr] diffColorStr:expirationStr diffColor:_curUser.willExpired? [UIColor colorWithHexString:@"0xF23524"]: kColorDark7]; +// }else{ +// _expirationL.hidden = YES; +// } } + (CGFloat)cellHeight{ return 85; } @end + +#endif diff --git a/Coding_iOS/Views/Cell/MemberCell.m b/Coding_iOS/Views/Cell/MemberCell.m index d3b301149..721172e24 100755 --- a/Coding_iOS/Views/Cell/MemberCell.m +++ b/Coding_iOS/Views/Cell/MemberCell.m @@ -24,7 +24,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (self) { // Initialization code if (!_memberIconView) { - _memberIconView = [[UIImageView alloc] initWithFrame:CGRectMake(10, ([MemberCell cellHeight]-40)/2, 40, 40)]; + _memberIconView = [[YLImageView alloc] initWithFrame:CGRectMake(10, ([MemberCell cellHeight]-40)/2, 40, 40)]; [_memberIconView doCircleFrame]; [self.contentView addSubview:_memberIconView]; } @@ -109,19 +109,18 @@ - (void)setCurMember:(ProjectMember *)curMember{ _leftBtn.hidden = YES;//说是不要私信按钮了 }else{ // 自己 - if (_curMember.type.intValue == 100) {//项目创建者不能「退出」 - _leftBtn.hidden = YES; - }else{//「退出」按钮 - [_leftBtn setImage:[UIImage imageNamed:@"btn_project_quit"] forState:UIControlStateNormal]; - [_leftBtn setTitle:@"- 退出项目" forState:UIControlStateNormal]; - _leftBtn.hidden = NO; - } + _leftBtn.hidden = YES;//说是也不要退出按钮了 +// if (_curMember.type.intValue == 100) {//项目创建者不能「退出」 +// _leftBtn.hidden = YES; +// }else{//「退出」按钮 +// [_leftBtn setImage:[UIImage imageNamed:@"btn_project_quit"] forState:UIControlStateNormal]; +// [_leftBtn setTitle:@"- 退出项目" forState:UIControlStateNormal]; +// _leftBtn.hidden = NO; +// } } }else{ _leftBtn.hidden = YES; - } - _leftBtn.hidden = rand()%2; - + } [_memberNameLabel mas_remakeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.memberIconView.mas_right).offset(10); make.height.mas_equalTo(20); @@ -145,6 +144,7 @@ + (CGFloat)cellHeight{ } - (void)prepareForReuse{ + [super prepareForReuse]; [_leftBtn stopQueryAnimate]; } @end diff --git a/Coding_iOS/Views/Cell/MessageCell.m b/Coding_iOS/Views/Cell/MessageCell.m index 6e850ddc6..293258e2d 100755 --- a/Coding_iOS/Views/Cell/MessageCell.m +++ b/Coding_iOS/Views/Cell/MessageCell.m @@ -146,25 +146,18 @@ - (void)setCurPriMsg:(PrivateMessage *)curPriMsg andPrePriMsg:(PrivateMessage *) CGSize bgImgViewSize; CGSize textSize; - if (_curPriMsg.content.length > 0) { - textSize = [_curPriMsg.content getSizeWithFont:kMessageCell_FontContent constrainedToSize:CGSizeMake(kMessageCell_ContentWidth, CGFLOAT_MAX)]; - }else{ - textSize = CGSizeZero; - } - [_contentLabel setWidth:kMessageCell_ContentWidth]; _contentLabel.text = _curPriMsg.content; [_contentLabel sizeToFit]; + textSize = _curPriMsg.content.length > 0? _contentLabel.size: CGSizeZero; + for (HtmlMediaItem *item in _curPriMsg.htmlMedia.mediaItems) { if (item.displayStr.length > 0 && item.href.length > 0) { [self.contentLabel addLinkToTransitInformation:[NSDictionary dictionaryWithObject:item forKey:@"value"] withRange:item.range]; } } - textSize.height = CGRectGetHeight(_contentLabel.frame); - - if (mediaViewHeight > 0) { // 有图片 [_contentLabel setY:2*kMessageCell_PadingHeight + mediaViewHeight]; diff --git a/Coding_iOS/Views/Cell/NProjectItemCell.m b/Coding_iOS/Views/Cell/NProjectItemCell.m index adf499d75..c6f8a3f9c 100644 --- a/Coding_iOS/Views/Cell/NProjectItemCell.m +++ b/Coding_iOS/Views/Cell/NProjectItemCell.m @@ -20,13 +20,13 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { // Initialization code - // self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; self.backgroundColor = kColorTableBG; if (!_imgView) { _imgView = [UIImageView new]; [self.contentView addSubview:_imgView]; [_imgView mas_makeConstraints:^(MASConstraintMaker *make) { - make.size.mas_equalTo(CGSizeMake(20, 20)); + make.size.mas_equalTo(CGSizeMake(22, 22)); make.left.equalTo(self.contentView).offset(kPaddingLeftWidth); make.centerY.equalTo(self.contentView); }]; @@ -56,6 +56,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus } - (void)prepareForReuse{ + [super prepareForReuse]; [self removeTip]; self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; } @@ -98,7 +99,7 @@ - (void)setNorightText { } + (CGFloat)cellHeight{ - return 44.0; + return 50.0; } @end diff --git a/Coding_iOS/Views/Cell/PRMRSearchCell.m b/Coding_iOS/Views/Cell/PRMRSearchCell.m index e340c5b02..63948e2eb 100644 --- a/Coding_iOS/Views/Cell/PRMRSearchCell.m +++ b/Coding_iOS/Views/Cell/PRMRSearchCell.m @@ -30,7 +30,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus // Initialization code self.accessoryType = UITableViewCellAccessoryNone; if (!_imgView) { - _imgView = [UIImageView new]; + _imgView = [YLImageView new]; _imgView.layer.masksToBounds = YES; _imgView.layer.cornerRadius = kMRPRListCell_UserWidth/2; _imgView.layer.borderWidth = 0.5; @@ -111,9 +111,11 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (!_fromL) { _fromL = [UILabel new]; - [_fromL doBorderWidth:0.5 color:[UIColor colorWithHexString:@"0x4E90BF"] cornerRadius:2.0]; + _fromL.backgroundColor = [UIColor colorWithHexString:@"0xF2F4F6"]; + _fromL.cornerRadius = 2; + _fromL.masksToBounds = YES; _fromL.font = [UIFont systemFontOfSize:12]; - _fromL.textColor = [UIColor colorWithHexString:@"0x4E90BF"]; + _fromL.textColor = [UIColor colorWithHexString:@"0x76808E"]; [self.contentView addSubview:_fromL]; } @@ -125,9 +127,11 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (!_toL) { _toL = [UILabel new]; - [_toL doBorderWidth:0.5 color:[UIColor colorWithHexString:@"0x4E90BF"] cornerRadius:2.0]; + _toL.backgroundColor = [UIColor colorWithHexString:@"0xD8DDE4"]; + _toL.cornerRadius = 2; + _toL.masksToBounds = YES; _toL.font = [UIFont systemFontOfSize:12]; - _toL.textColor = [UIColor colorWithHexString:@"0x4E90BF"]; + _toL.textColor = [UIColor colorWithHexString:@"0x76808E"]; [self.contentView addSubview:_toL]; } diff --git a/Coding_iOS/Views/Cell/PointRecordCell.m b/Coding_iOS/Views/Cell/PointRecordCell.m index 7ca6611b6..321c63f76 100644 --- a/Coding_iOS/Views/Cell/PointRecordCell.m +++ b/Coding_iOS/Views/Cell/PointRecordCell.m @@ -31,7 +31,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus [self.contentView addSubview:_pointsLeftL]; } if (!_pointsChangeL) { - _pointsChangeL = [UILabel labelWithFont:[UIFont systemFontOfSize:15] textColor:kColorBrandGreen]; + _pointsChangeL = [UILabel labelWithFont:[UIFont systemFontOfSize:15] textColor:kColorBrandBlue]; [self.contentView addSubview:_pointsChangeL]; } [_usageL mas_makeConstraints:^(MASConstraintMaker *make) { @@ -41,17 +41,17 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus }]; [_timeL mas_makeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.contentView).offset(-kPaddingLeftWidth); - make.centerY.equalTo(_usageL); + make.bottom.equalTo(self.contentView).offset(-10); make.height.mas_equalTo(20); }]; [_pointsLeftL mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.contentView).offset(kPaddingLeftWidth); - make.centerY.equalTo(_pointsChangeL); + make.centerY.equalTo(_timeL); make.height.mas_equalTo(20); }]; [_pointsChangeL mas_makeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.contentView).offset(-kPaddingLeftWidth); - make.bottom.equalTo(self.contentView).offset(-10); + make.centerY.equalTo(_usageL); make.height.mas_equalTo(25); }]; } @@ -63,9 +63,9 @@ - (void)setCurRecord:(PointRecord *)curRecord{ return; } _usageL.text = _curRecord.usage; - _timeL.text = [_curRecord.created_at stringWithFormat:@"yyyy-MM-dd hh:mm:ss"]; + _timeL.text = [_curRecord.created_at stringWithFormat:@"yyyy-MM-dd HH:mm:ss"]; _pointsLeftL.text = [NSString stringWithFormat:@"余额:%.2f", _curRecord.points_left.floatValue]; - _pointsChangeL.textColor = [UIColor colorWithHexString:_curRecord.action.intValue == 1? @"0x3bbd79": @"0xFB8638"]; + _pointsChangeL.textColor = [UIColor colorWithHexString:_curRecord.action.intValue == 1? @"0x0060FF": @"0xFB8638"]; _pointsChangeL.text = [NSString stringWithFormat:@"%@%.2f", _curRecord.action.intValue == 1? @"+": @"-", _curRecord.points_change.floatValue]; } + (CGFloat)cellHeight{ diff --git a/Coding_iOS/Views/Cell/PointShopCell.m b/Coding_iOS/Views/Cell/PointShopCell.m index bfec7fb09..21398b2d9 100644 --- a/Coding_iOS/Views/Cell/PointShopCell.m +++ b/Coding_iOS/Views/Cell/PointShopCell.m @@ -19,6 +19,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (self) { // Initialization code self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + self.clipsToBounds = YES; if (!_iconView) { _iconView = [UIImageView new]; [self.contentView addSubview:_iconView]; @@ -45,6 +46,6 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus return self; } + (CGFloat)cellHeight{ - return 50.0; + return 0.0; } @end diff --git a/Coding_iOS/Views/Cell/PointTopCell.m b/Coding_iOS/Views/Cell/PointTopCell.m index 8bd7880b7..0e3154d13 100644 --- a/Coding_iOS/Views/Cell/PointTopCell.m +++ b/Coding_iOS/Views/Cell/PointTopCell.m @@ -20,7 +20,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus self.selectionStyle = UITableViewCellSelectionStyleNone; if (!_valueL) { _valueL = [UILabel new]; - _valueL.textColor = kColorBrandGreen; + _valueL.textColor = kColorBrandBlue; _valueL.font = [UIFont systemFontOfSize:50]; _valueL.textAlignment = NSTextAlignmentCenter; [self.contentView addSubview:_valueL]; diff --git a/Coding_iOS/Views/Cell/ProjectAboutMeListCell.h b/Coding_iOS/Views/Cell/ProjectAboutMeListCell.h index 3cd1b1a11..8b02a72cb 100644 --- a/Coding_iOS/Views/Cell/ProjectAboutMeListCell.h +++ b/Coding_iOS/Views/Cell/ProjectAboutMeListCell.h @@ -10,7 +10,7 @@ * 全部项目 我创建的 我参与的 cell样式 :(1)支持公开/私有 两种状态,(2)支持侧滑,(3)支持置顶标识 */ -#define kProjectAboutMeListCellHeight 104 +#define kProjectAboutMeListCellHeight 110 #import #import "Projects.h" diff --git a/Coding_iOS/Views/Cell/ProjectAboutMeListCell.m b/Coding_iOS/Views/Cell/ProjectAboutMeListCell.m index ea7cea596..07ed0ec63 100644 --- a/Coding_iOS/Views/Cell/ProjectAboutMeListCell.m +++ b/Coding_iOS/Views/Cell/ProjectAboutMeListCell.m @@ -13,10 +13,12 @@ #import "ProjectAboutMeListCell.h" #import "NSString+Attribute.h" +#import "YLImageView.h" @interface ProjectAboutMeListCell () @property (nonatomic, strong) Project *project; -@property (nonatomic, strong) UIImageView *projectIconView, *privateIconView, *pinIconView; +@property (strong, nonatomic) YLImageView *projectIconView; +@property (nonatomic, strong) UIImageView *privateIconView, *pinIconView; @property (nonatomic, strong) UIButton *setCommonBtn; @property (nonatomic, strong) UILabel *projectTitleLabel; @property (nonatomic, strong) UILabel *ownerTitleLabel; @@ -31,7 +33,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (self) { // Initialization code if (!_projectIconView) { - _projectIconView = [[UIImageView alloc] initWithFrame:CGRectMake(12, 12, kIconSize, kIconSize)]; + _projectIconView = [[YLImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, kPaddingLeftWidth, kIconSize, kIconSize)]; _projectIconView.layer.masksToBounds = YES; _projectIconView.layer.cornerRadius = 2.0; [self.contentView addSubview:_projectIconView]; @@ -39,21 +41,21 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (!_projectTitleLabel) { _projectTitleLabel = [UILabel new]; - _projectTitleLabel.textColor = kColor222; + _projectTitleLabel.textColor = kColorDark3; _projectTitleLabel.font = [UIFont systemFontOfSize:17]; [self.contentView addSubview:_projectTitleLabel]; } if (!_ownerTitleLabel) { _ownerTitleLabel = [UILabel new]; - _ownerTitleLabel.textColor = kColor999; + _ownerTitleLabel.textColor = kColorDarkA; _ownerTitleLabel.font = [UIFont systemFontOfSize:15]; [self.contentView addSubview:_ownerTitleLabel]; } if (!_describeLabel) { _describeLabel = [UILabel new]; - _describeLabel.textColor = kColor666; + _describeLabel.textColor = kColorDark7; _describeLabel.font = [UIFont systemFontOfSize:14]; - _describeLabel.numberOfLines=1; + _describeLabel.numberOfLines = kTarget_Enterprise? 0: 1; [self.contentView addSubview:_describeLabel]; } @@ -115,7 +117,7 @@ - (void)setProject:(Project *)project hasSWButtons:(BOOL)hasSWButtons hasBadgeTi make.top.equalTo(_projectIconView.mas_top); make.height.equalTo(@(20)); make.left.equalTo(_privateIconView.mas_right).offset(_privateIconView.hidden?0:8); - make.right.lessThanOrEqualTo(self.mas_right).offset(-12); + make.right.lessThanOrEqualTo(self.mas_right).offset(-kPaddingLeftWidth); }]; [_ownerTitleLabel mas_updateConstraints:^(MASConstraintMaker *make) { @@ -124,13 +126,21 @@ - (void)setProject:(Project *)project hasSWButtons:(BOOL)hasSWButtons hasBadgeTi make.bottom.equalTo(_projectIconView.mas_bottom); }]; - [_describeLabel mas_updateConstraints:^(MASConstraintMaker *make) { - make.left.equalTo(self.privateIconView); - make.height.equalTo(@(38)); - make.width.equalTo(@(kScreen_Width-kLeftOffset-kIconSize-20)); - make.top.equalTo(_projectTitleLabel.mas_bottom); - }]; - + if (kTarget_Enterprise) { + _privateIconView.hidden = _ownerTitleLabel.hidden = YES; + [_describeLabel mas_updateConstraints:^(MASConstraintMaker *make) { + make.left.right.equalTo(self.projectTitleLabel); + make.bottom.lessThanOrEqualTo(self.projectIconView); + make.top.equalTo(self.projectTitleLabel.mas_bottom).offset(5); + }]; + }else{ + [_describeLabel mas_updateConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.privateIconView); + make.height.equalTo(@(38)); + make.width.equalTo(@(kScreen_Width-kLeftOffset-kIconSize-20)); + make.top.equalTo(_projectTitleLabel.mas_bottom); + }]; + } //Title & UserName & description if (_openKeywords) { @@ -174,9 +184,9 @@ - (void)setProject:(Project *)project hasSWButtons:(BOOL)hasSWButtons hasBadgeTi - (NSArray *)rightButtons{ NSMutableArray *rightUtilityButtons = [NSMutableArray new]; - [rightUtilityButtons sw_addUtilityButtonWithColor:_project.pin.boolValue? kColorTableSectionBg: kColorBrandGreen + [rightUtilityButtons sw_addUtilityButtonWithColor:_project.pin.boolValue? kColorTableSectionBg: kColorBrandBlue title:_project.pin.boolValue?@"取消常用":@"设置常用" - titleColor:_project.pin.boolValue? kColorBrandGreen: [UIColor whiteColor]]; + titleColor:_project.pin.boolValue? kColorBrandBlue: [UIColor whiteColor]]; return rightUtilityButtons; } diff --git a/Coding_iOS/Views/Cell/ProjectAboutOthersListCell.m b/Coding_iOS/Views/Cell/ProjectAboutOthersListCell.m index e203d6013..9cf55f03f 100644 --- a/Coding_iOS/Views/Cell/ProjectAboutOthersListCell.m +++ b/Coding_iOS/Views/Cell/ProjectAboutOthersListCell.m @@ -33,7 +33,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (self) { // Initialization code if (!_projectIconView) { - _projectIconView = [[UIImageView alloc] initWithFrame:CGRectMake(12, 12, kIconSize, kIconSize)]; + _projectIconView = [[YLImageView alloc] initWithFrame:CGRectMake(12, 12, kIconSize, kIconSize)]; _projectIconView.layer.masksToBounds = YES; _projectIconView.layer.cornerRadius = 2.0; [self.contentView addSubview:_projectIconView]; @@ -197,15 +197,9 @@ - (void)setProject:(Project *)project hasSWButtons:(BOOL)hasSWButtons hasBadgeTi - (NSArray *)rightButtons{ NSMutableArray *rightUtilityButtons = [NSMutableArray new]; - // [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:_project.pin.boolValue? @"0xe6e6e6": @"0x3bbd79"] - // icon:[UIImage imageNamed:_project.pin.boolValue? @"icon_project_cell_pin": @"icon_project_cell_nopin"]]; - [rightUtilityButtons sw_addUtilityButtonWithColor:_project.pin.boolValue? kColorTableSectionBg: kColorBrandGreen + [rightUtilityButtons sw_addUtilityButtonWithColor:_project.pin.boolValue? kColorTableSectionBg: kColorBrandBlue title:_project.pin.boolValue?@"取消常用":@"设置常用" - titleColor:_project.pin.boolValue? kColorBrandGreen: [UIColor whiteColor]]; - -// [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:_project.pin.boolValue? @"0xeeeeee": @"0x3bbd79"] -// title:_project.pin.boolValue?@"取消常用":@"设置常用" titleColor:[UIColor colorWithHexString:_project.pin.boolValue?@"0x3bbd79":@"0xffffff"]]; - + titleColor:_project.pin.boolValue? kColorBrandBlue: [UIColor whiteColor]]; return rightUtilityButtons; } diff --git a/Coding_iOS/Views/Cell/ProjectActivityListCell.m b/Coding_iOS/Views/Cell/ProjectActivityListCell.m index d2f2a7f89..0a4fdd3e7 100755 --- a/Coding_iOS/Views/Cell/ProjectActivityListCell.m +++ b/Coding_iOS/Views/Cell/ProjectActivityListCell.m @@ -7,9 +7,9 @@ // #define kProjectActivityListCell_IconHeight 33.0 -#define kProjectActivityListCell_TimeIconWidth 13.0 +#define kProjectActivityListCell_TimeIconWidth 7.0 #define kProjectActivityListCell_TimeLineWidth 2.0 -#define kProjectActivityListCell_LeftPading 85 +#define kProjectActivityListCell_LeftPading 75 #define kProjectActivityListCell_RightPading kPaddingLeftWidth #define kProjectActivityListCell_UpDownPading kScaleFrom_iPhone5_Desgin(10) #define kProjectActivityListCell_TextPading 5.0 @@ -48,15 +48,11 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (self) { // Initialization code if (!_userIconView) { - _userIconView = [[UITapImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, kProjectActivityListCell_UpDownPading, kProjectActivityListCell_IconHeight, kProjectActivityListCell_IconHeight)]; + _userIconView = [[UITapImageView alloc] initWithFrame:CGRectMake(32, kProjectActivityListCell_UpDownPading, kProjectActivityListCell_IconHeight, kProjectActivityListCell_IconHeight)]; [_userIconView doCircleFrame]; [self.contentView addSubview:_userIconView]; } - CGFloat imgRightX = CGRectGetMaxX(_userIconView.frame); - CGFloat timeLineCenterX = imgRightX + (kProjectActivityListCell_LeftPading-imgRightX)/2; - - ; - + CGFloat timeLineCenterX = kPaddingLeftWidth; if (!_timeLineView) { _timeLineView = [[UIImageView alloc] initWithFrame:CGRectMake(timeLineCenterX - kProjectActivityListCell_TimeLineWidth/2, 0, kProjectActivityListCell_TimeLineWidth, 1)]; // _timeLineView.contentMode = UIViewContentModeScaleToFill; @@ -139,12 +135,12 @@ - (void)layoutSubviews{ } } - curBottomY += [_proAct.actionStr getHeightWithFont:kProjectActivityListCell_ActionFont constrainedToSize:CGSizeMake(kProjectActivityListCell_ContentWidth, kProjectActivityListCell_MaxActionHeight)]; + curBottomY += [_proAct.actionStr getHeightWithFont:kProjectActivityListCell_ActionFont constrainedToSize:CGSizeMake(kProjectActivityListCell_ContentWidth - 5, kProjectActivityListCell_MaxActionHeight)]; curBottomY += kProjectActivityListCell_TextPading; // 内容 [_contentLabel setLongString:_proAct.contentStr withFitWidth:kProjectActivityListCell_ContentWidth maxHeight:kProjectActivityListCell_MaxContentHeight]; [_contentLabel setY:curBottomY]; - curBottomY += [_proAct.contentStr getHeightWithFont:kProjectActivityListCell_ContentFont constrainedToSize:CGSizeMake(kProjectActivityListCell_ContentWidth, kProjectActivityListCell_MaxContentHeight)]; + curBottomY += [_proAct.contentStr getHeightWithFont:kProjectActivityListCell_ContentFont constrainedToSize:CGSizeMake(kProjectActivityListCell_ContentWidth - 5, kProjectActivityListCell_MaxContentHeight)]; curBottomY += kProjectActivityListCell_TextPading; // 时间 curBottomY +=5; @@ -160,9 +156,9 @@ + (CGFloat)cellHeightWithObj:(id)obj{ ProjectActivity *proAct = (ProjectActivity *)obj; CGFloat cellHeight = 0; cellHeight += kProjectActivityListCell_UpDownPading *2; - cellHeight += MIN(kProjectActivityListCell_MaxActionHeight, [proAct.actionStr getHeightWithFont:kProjectActivityListCell_ActionFont constrainedToSize:CGSizeMake(kProjectActivityListCell_ContentWidth, kProjectActivityListCell_MaxActionHeight)]); + cellHeight += MIN(kProjectActivityListCell_MaxActionHeight, [proAct.actionStr getHeightWithFont:kProjectActivityListCell_ActionFont constrainedToSize:CGSizeMake(kProjectActivityListCell_ContentWidth - 5, kProjectActivityListCell_MaxActionHeight)]); cellHeight += kProjectActivityListCell_TextPading*2; - cellHeight += MIN(kProjectActivityListCell_MaxContentHeight, [proAct.contentStr getHeightWithFont:kProjectActivityListCell_ContentFont constrainedToSize:CGSizeMake(kProjectActivityListCell_ContentWidth, kProjectActivityListCell_MaxContentHeight)]); + cellHeight += MIN(kProjectActivityListCell_MaxContentHeight, [proAct.contentStr getHeightWithFont:kProjectActivityListCell_ContentFont constrainedToSize:CGSizeMake(kProjectActivityListCell_ContentWidth - 5, kProjectActivityListCell_MaxContentHeight)]); cellHeight += 5+ kProjectActivityListCell_TimeHeight; return cellHeight; diff --git a/Coding_iOS/Views/Cell/ProjectCodeListCell.m b/Coding_iOS/Views/Cell/ProjectCodeListCell.m index 5e3e0f49e..5492df67e 100755 --- a/Coding_iOS/Views/Cell/ProjectCodeListCell.m +++ b/Coding_iOS/Views/Cell/ProjectCodeListCell.m @@ -7,14 +7,14 @@ // -#define kCode_IconViewWidth 25.0 +#define kCode_IconViewWidth 20.0 #define kCode_ContentLeftPading (kPaddingLeftWidth+kCode_IconViewWidth+10) #import "ProjectCodeListCell.h" @interface ProjectCodeListCell () -@property (strong, nonatomic) UIImageView *leftIconView; -@property (strong, nonatomic) UILabel *fileName, *commitTime, *commitInfo, *commitorName; +@property (strong, nonatomic) UIImageView *leftIconView, *commitTimeIcon; +@property (strong, nonatomic) UILabel *fileNameL, *commitorNameL, *commitTimeL; @end @@ -31,18 +31,38 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus _leftIconView = [[UIImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, ([self.class cellHeight] - kCode_IconViewWidth)/2, kCode_IconViewWidth, kCode_IconViewWidth)]; [self.contentView addSubview:_leftIconView]; } - if (!_fileName) { - _fileName = [[UILabel alloc] initWithFrame:CGRectMake(kCode_ContentLeftPading, 10, kScreen_Width-kCode_ContentLeftPading-30, 20)]; - _fileName.font = [UIFont systemFontOfSize:15]; - _fileName.textColor = kColor222; - [self.contentView addSubview:_fileName]; + if (!_fileNameL) { + _fileNameL = [[UILabel alloc] initWithFrame:CGRectMake(kCode_ContentLeftPading, 10, kScreen_Width-kCode_ContentLeftPading-30, 20)]; + _fileNameL.font = [UIFont systemFontOfSize:14]; + _fileNameL.textColor = kColor222; + [self.contentView addSubview:_fileNameL]; } - if (!_commitTime) { - _commitTime = [[UILabel alloc] initWithFrame:CGRectMake(kCode_ContentLeftPading, [self.class cellHeight]-25, kScreen_Width-kCode_ContentLeftPading-30, 20)]; - _commitTime.font = [UIFont systemFontOfSize:12]; - _commitTime.textColor = kColor999; - [self.contentView addSubview:_commitTime]; + + if (!_commitorNameL) { + _commitorNameL = [UILabel labelWithSystemFontSize:12 textColorHexString:@"0x222222"]; + [self.contentView addSubview:_commitorNameL]; } + + if (!_commitTimeIcon) { + _commitTimeIcon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"time_clock_icon"]]; + [self.contentView addSubview:_commitTimeIcon]; + } + + if (!_commitTimeL) { + _commitTimeL = [UILabel labelWithSystemFontSize:12 textColorHexString:@"0x999999"]; + [self.contentView addSubview:_commitTimeL]; + } + [_commitorNameL mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(_fileNameL); + make.bottom.equalTo(self.contentView).offset(-10); + }]; + [@[_commitTimeIcon, _commitTimeL] mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(_commitorNameL); + }]; + [_commitTimeIcon mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(_commitorNameL.mas_right).offset(15); + make.right.equalTo(_commitTimeL.mas_left).offset(-5); + }]; } return self; } @@ -52,27 +72,14 @@ - (void)layoutSubviews{ if (!_file) { return; } - if ([_file.mode isEqualToString:@"tree"]) { - self.leftIconView.image = [UIImage imageNamed:@"icon_code_tree"]; - }else{ + self.leftIconView.image = [UIImage imageNamed:[NSString stringWithFormat:@"icon_code_%@", _file.mode]]; + if (!self.leftIconView.image) { self.leftIconView.image = [UIImage imageNamed:@"icon_code_file"]; } - self.fileName.text = _file.name; - self.commitTime.attributedText = [self subTitleStr]; -// self.commitTime.text = [[self subTitleStr] string]; -} - -- (NSAttributedString *)subTitleStr{ - NSString *nameStr = _file.info.lastCommitter.name? _file.info.lastCommitter.name: @"..."; - NSString *timeStr = _file.info.lastCommitDate? [_file.info.lastCommitDate stringTimesAgo]: @"..."; - NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@ %@", nameStr, timeStr]]; - [attrString addAttributes:@{NSFontAttributeName : [UIFont boldSystemFontOfSize:12], - NSForegroundColorAttributeName : kColor222} - range:NSMakeRange(0, nameStr.length)]; - [attrString addAttributes:@{NSFontAttributeName : [UIFont boldSystemFontOfSize:12], - NSForegroundColorAttributeName : kColor999} - range:NSMakeRange(nameStr.length + 1, timeStr.length)]; - return attrString; + self.fileNameL.text = _file.name; + + self.commitorNameL.text = _file.info.lastCommitter.name ?: @"..."; + self.commitTimeL.text = _file.info.lastCommitDate? [_file.info.lastCommitDate stringTimesAgo]: @"..."; } + (CGFloat)cellHeight{ diff --git a/Coding_iOS/Views/Cell/ProjectCodeListSearchCell.h b/Coding_iOS/Views/Cell/ProjectCodeListSearchCell.h new file mode 100644 index 000000000..8892e4576 --- /dev/null +++ b/Coding_iOS/Views/Cell/ProjectCodeListSearchCell.h @@ -0,0 +1,16 @@ +// +// ProjectCodeListSearchCell.h +// Coding_iOS +// +// Created by Ease on 2017/2/15. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import +#define kCellIdentifier_ProjectCodeListSearchCell @"ProjectCodeListSearchCell" + +@interface ProjectCodeListSearchCell : UITableViewCell +@property (strong, nonatomic) NSString *filePath, *treePath, *searchText; ++ (CGFloat)cellHeight; + +@end diff --git a/Coding_iOS/Views/Cell/ProjectCodeListSearchCell.m b/Coding_iOS/Views/Cell/ProjectCodeListSearchCell.m new file mode 100644 index 000000000..ede7fb440 --- /dev/null +++ b/Coding_iOS/Views/Cell/ProjectCodeListSearchCell.m @@ -0,0 +1,69 @@ +// +// ProjectCodeListSearchCell.m +// Coding_iOS +// +// Created by Ease on 2017/2/15. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "ProjectCodeListSearchCell.h" + +@interface ProjectCodeListSearchCell () +@property (strong, nonatomic) UIImageView *leftIconView; +@property (strong, nonatomic) UILabel *fileNameL; +@end + +@implementation ProjectCodeListSearchCell + +- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier +{ + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + // Initialization code + if (!_leftIconView) { + _leftIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"icon_code_file"]]; + [self.contentView addSubview:_leftIconView]; + } + if (!_fileNameL) { + _fileNameL = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColor222]; + _fileNameL.lineBreakMode = NSLineBreakByTruncatingMiddle; + [self.contentView addSubview:_fileNameL]; + } + [_leftIconView mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.contentView); + make.left.equalTo(self.contentView).offset(kPaddingLeftWidth); + }]; + [_fileNameL mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.contentView); + make.left.equalTo(_leftIconView.mas_right).offset(10); + make.right.lessThanOrEqualTo(self.contentView).offset(-kPaddingLeftWidth); + }]; + } + return self; +} + +- (void)layoutSubviews{ + [super layoutSubviews]; + if (!_filePath) { + return; + } + self.fileNameL.attributedText = [self attrPath]; +} + +- (NSAttributedString *)attrPath{ + NSString *shortPath = _filePath; + if (_treePath.length > 0 && [shortPath hasPrefix:_treePath]) { + shortPath = [shortPath substringFromIndex:_treePath.length + 1];// '/xxxx' + } + NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:shortPath]; + [attrString addAttributes:@{NSBackgroundColorAttributeName: [UIColor colorWithHexString:@"0xFFEFBD"]} + range:[shortPath rangeOfString:_searchText options:NSCaseInsensitiveSearch]]; + return attrString; +} + ++ (CGFloat)cellHeight{ + return 44.0; +} + +@end diff --git a/Coding_iOS/Views/Cell/ProjectInfoCell.m b/Coding_iOS/Views/Cell/ProjectInfoCell.m index 73d6ccf44..751ff60d2 100644 --- a/Coding_iOS/Views/Cell/ProjectInfoCell.m +++ b/Coding_iOS/Views/Cell/ProjectInfoCell.m @@ -28,7 +28,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus self.backgroundColor = kColorTableBG; if (!_proImgView) { - _proImgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, kProjectInfoCell_ProImgViewWidth, kProjectInfoCell_ProImgViewWidth)]; + _proImgView = [[YLImageView alloc] initWithFrame:CGRectMake(0, 0, kProjectInfoCell_ProImgViewWidth, kProjectInfoCell_ProImgViewWidth)]; _proImgView.layer.cornerRadius = 2.0; _proImgView.layer.masksToBounds = YES; [self.contentView addSubview:_proImgView]; @@ -49,7 +49,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus [self.contentView addSubview:_proTitleL]; } if (!_proInfoL) { - _proInfoL = [[UITTTAttributedLabel alloc] init]; + _proInfoL = [[UITTTAttributedLabel alloc] initWithFrame:CGRectZero]; _proInfoL.delegate = self; _proInfoL.linkAttributes = kLinkAttributes; _proInfoL.activeLinkAttributes = kLinkAttributesActive; @@ -95,10 +95,7 @@ - (void)setCurProject:(Project *)curProject{ _proInfoL.text = _curProject.owner_user_name; } _recommendedView.hidden = !(_curProject.recommended.integerValue > 0); - // 如果是自己所属的项目才显示箭头 - if ([self.curProject.owner_id isEqual:[Login curLoginUser].id]) { - self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; - } + self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; } - (void)layoutSubviews{ diff --git a/Coding_iOS/Views/Cell/ProjectItemsCell.m b/Coding_iOS/Views/Cell/ProjectItemsCell.m index 1b4e5696d..64b127e96 100644 --- a/Coding_iOS/Views/Cell/ProjectItemsCell.m +++ b/Coding_iOS/Views/Cell/ProjectItemsCell.m @@ -32,7 +32,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus itemsNumInLine = 3; itemsIconList = @[@"icon-bolt", @"icon-tasks", @"icon-comments", @"icon-folder-open", @"icon-code", @"icon-user"]; - itemsColorList = @[@"0x3bbd79", @"0x25c2d5", @"0x3899d0", @"0xf8b327", @"0xee8c35", @"0xe7683d"]; + itemsColorList = @[@"0x0060FF", @"0x25c2d5", @"0x3899d0", @"0xf8b327", @"0xee8c35", @"0xe7683d"]; itemsTitleList = @[@"动态", @"任务", @"讨论", @"文件", @"代码", @"成员"]; }else if ([reuseIdentifier isEqualToString:kCellIdentifier_ProjectItemsCell_Public]){ @@ -40,7 +40,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus itemsNumInLine = 4; itemsIconList = @[@"icon-bolt", @"icon-comments", @"icon-code", @"icon-user"]; - itemsColorList = @[@"0x3bbd79", @"0x3899d0", @"0xee8c35", @"0xe7683d"]; + itemsColorList = @[@"0x0060FF", @"0x3899d0", @"0xee8c35", @"0xe7683d"]; itemsTitleList = @[@"动态", @"讨论", @"代码", @"成员"]; } @@ -86,8 +86,7 @@ - (UIButton *)itemWithFrame:(CGRect)frame icon:(NSString *)iconStr color:(NSStri UIButton *item = [[UIButton alloc] initWithFrame:frame]; CGFloat iconWidth = kScaleFrom_iPhone5_Desgin(46); - - UIImage *itemImg = [UIImage imageWithIcon:iconStr backgroundColor:[UIColor clearColor] iconColor:[UIColor whiteColor] iconScale:1.0 andSize:CGSizeMake(iconWidth/2.8, iconWidth/2.8)]; + UIImage *itemImg = [UIImage imageWithIcon:iconStr backgroundColor:[UIColor clearColor] iconColor:[UIColor whiteColor] andSize:CGSizeMake(iconWidth/2.8, iconWidth/2.8)]; UIImageView *itemImgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, iconWidth, iconWidth)]; itemImgView.tag = kProjectItemsCell_ItemIconTag; itemImgView.contentMode = UIViewContentModeCenter; diff --git a/Coding_iOS/Views/Cell/ProjectListCell.h b/Coding_iOS/Views/Cell/ProjectListCell.h index 98462167a..427a750b6 100755 --- a/Coding_iOS/Views/Cell/ProjectListCell.h +++ b/Coding_iOS/Views/Cell/ProjectListCell.h @@ -11,9 +11,12 @@ #import #import "Projects.h" #import "SWTableViewCell.h" +#import "ProjectRole.h" @interface ProjectListCell : SWTableViewCell +@property (assign, nonatomic) BOOL hasDeleteBtn; - (void)setProject:(Project *)project hasSWButtons:(BOOL)hasSWButtons hasBadgeTip:(BOOL)hasBadgeTip hasIndicator:(BOOL)hasIndicator; +- (void)setProjectRole:(ProjectRole *)curRole; + (CGFloat)cellHeight; diff --git a/Coding_iOS/Views/Cell/ProjectListCell.m b/Coding_iOS/Views/Cell/ProjectListCell.m index 93c274470..42c59f652 100755 --- a/Coding_iOS/Views/Cell/ProjectListCell.m +++ b/Coding_iOS/Views/Cell/ProjectListCell.m @@ -9,9 +9,150 @@ #define kProjectListCell_IconHeight 55.0 #define kProjectListCell_ContentLeft (kPaddingLeftWidth+kProjectListCell_IconHeight+20) +#import "ProjectListCell.h" +#ifdef Target_Enterprise -#import "ProjectListCell.h" +@interface ProjectListCell () +@property (nonatomic, strong) Project *project; + +@property (nonatomic, strong) UIImageView *projectIconView; +@property (nonatomic, strong) UILabel *projectTitleLabel; +@property (nonatomic, strong) UILabel *rightL; +@property (nonatomic, strong) UIButton *sliderBtn; +@end + +@implementation ProjectListCell +- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier +{ + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + // Initialization code + if (!_projectIconView) { + _projectIconView = [[YLImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 10, kProjectListCell_IconHeight, kProjectListCell_IconHeight)]; + _projectIconView.layer.masksToBounds = YES; + _projectIconView.layer.cornerRadius = 2.0; + [self.contentView addSubview:_projectIconView]; + } + + if (!_projectTitleLabel) { + _projectTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(kProjectListCell_ContentLeft, 10, 180, 25)]; + _projectTitleLabel.textColor = kColor222; + _projectTitleLabel.font = [UIFont systemFontOfSize:17]; + [self.contentView addSubview:_projectTitleLabel]; + } + if (!_rightL) { + _rightL = [UILabel new]; + _rightL.textAlignment = NSTextAlignmentRight; + _rightL.textColor = kColorDark7; + _rightL.font = [UIFont systemFontOfSize:15]; + [self.contentView addSubview:_rightL]; + [_rightL mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(_projectTitleLabel); + make.right.equalTo(self.contentView).offset(-10); + }]; + } + + [_projectTitleLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.contentView); + make.height.mas_equalTo(25); + make.left.equalTo(self.contentView.mas_left).offset(kProjectListCell_ContentLeft); + make.right.lessThanOrEqualTo(self.contentView).offset(0); + }]; + if (!_sliderBtn) { + _sliderBtn = [UIButton new]; + _sliderBtn.hidden = YES; + //for test + [_sliderBtn setImage:[UIImage imageNamed:@"btn_setFrequent"] forState:UIControlStateNormal]; + [self.contentView addSubview:_sliderBtn]; + [_sliderBtn addTarget:self action:@selector(showSliderAction) forControlEvents:UIControlEventTouchUpInside]; + [_sliderBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.size.mas_equalTo(CGSizeMake(40, 40)); + make.right.equalTo(self.contentView); + make.bottom.equalTo(self.contentView).offset(5); + }]; + } + } + return self; +} + +- (void)setProject:(Project *)project hasSWButtons:(BOOL)hasSWButtons hasBadgeTip:(BOOL)hasBadgeTip hasIndicator:(BOOL)hasIndicator{ + _project = project; + if (!_project) { + return; + } + //Icon + [_projectIconView sd_setImageWithURL:[_project.icon urlImageWithCodePathResizeToView:_projectIconView] placeholderImage:kPlaceholderCodingSquareWidth(55.0)]; + //Title & UserName + _projectTitleLabel.text = _project.name; + + //hasSWButtons + [self setRightUtilityButtons:hasSWButtons? [self rightButtons]: nil + WithButtonWidth:[[self class] cellHeight]]; + + //hasBadgeTip + if (hasBadgeTip) { + NSString *badgeTip = @""; + if (_project.un_read_activities_count && _project.un_read_activities_count.integerValue > 0) { + if (_project.un_read_activities_count.integerValue > 99) { + badgeTip = @"99+"; + }else{ + badgeTip = _project.un_read_activities_count.stringValue; + } + } + [self.contentView addBadgeTip:badgeTip withCenterPosition:CGPointMake(10+kProjectListCell_IconHeight, 15)]; + }else{ + [self.contentView removeBadgeTips]; + } + + //hasIndicator + self.accessoryType = hasIndicator? UITableViewCellAccessoryDisclosureIndicator: UITableViewCellAccessoryNone; + _rightL.hidden = YES; +} + +- (void)setProjectRole:(ProjectRole *)curRole{ + [self setProject:curRole.project hasSWButtons:NO hasBadgeTip:NO hasIndicator:YES]; + static NSDictionary *typeDict = nil; + if (!typeDict) { + typeDict = @{@(-1): @"", + @90: @"管理员", + @80: @"普通成员", + @75: @"受限成员"}; + } + _rightL.hidden = NO; + _rightL.text = typeDict[curRole.type]; +} + +- (void)setHasDeleteBtn:(BOOL)hasDeleteBtn{ + _hasDeleteBtn = hasDeleteBtn; + [self setRightUtilityButtons:hasDeleteBtn? [self deleteSWButtons]: nil WithButtonWidth:[[self class] cellHeight]]; + _sliderBtn.hidden = !hasDeleteBtn; +} + +- (NSArray *)deleteSWButtons{ + NSMutableArray *rightUtilityButtons = [NSMutableArray new]; + [rightUtilityButtons sw_addUtilityButtonWithColor:kColorBrandRed icon:[UIImage imageNamed:@"icon_file_cell_delete"]]; + return rightUtilityButtons; +} + +- (NSArray *)rightButtons{ + NSMutableArray *rightUtilityButtons = [NSMutableArray new]; + [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:_project.pin.boolValue? @"0xe6e6e6": @"0x0060FF"] + title:_project.pin.boolValue?@"取消常用":@"设置常用" titleColor:[UIColor colorWithHexString:_project.pin.boolValue?@"0x0060FF":@"0xffffff"]]; + + return rightUtilityButtons; +} + +-(void)showSliderAction{ + [self showRightUtilityButtonsAnimated:YES]; +} + ++ (CGFloat)cellHeight{ + return 75.0; +} +@end + +#else @interface ProjectListCell () @property (nonatomic, strong) Project *project; @@ -29,7 +170,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus // Initialization code self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; if (!_projectIconView) { - _projectIconView = [[UIImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 10, kProjectListCell_IconHeight, kProjectListCell_IconHeight)]; + _projectIconView = [[YLImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 10, kProjectListCell_IconHeight, kProjectListCell_IconHeight)]; _projectIconView.layer.masksToBounds = YES; _projectIconView.layer.cornerRadius = 2.0; [self.contentView addSubview:_projectIconView]; @@ -89,7 +230,7 @@ - (void)setProject:(Project *)project hasSWButtons:(BOOL)hasSWButtons hasBadgeTi //hasSWButtons [self setRightUtilityButtons:hasSWButtons? [self rightButtons]: nil - WithButtonWidth:[[self class] cellHeight]]; + WithButtonWidth:135]; //hasBadgeTip if (hasBadgeTip) { @@ -112,11 +253,11 @@ - (void)setProject:(Project *)project hasSWButtons:(BOOL)hasSWButtons hasBadgeTi - (NSArray *)rightButtons{ NSMutableArray *rightUtilityButtons = [NSMutableArray new]; -// [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:_project.pin.boolValue? @"0xe6e6e6": @"0x3bbd79"] +// [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:_project.pin.boolValue? @"0xe6e6e6": @"0x0060FF"] // icon:[UIImage imageNamed:_project.pin.boolValue? @"icon_project_cell_pin": @"icon_project_cell_nopin"]]; - [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:_project.pin.boolValue? @"0xe6e6e6": @"0x3bbd79"] - title:_project.pin.boolValue?@"取消常用":@"设置常用" titleColor:[UIColor colorWithHexString:_project.pin.boolValue?@"0x3bbd79":@"0xffffff"]]; + [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:_project.pin.boolValue? @"0xe6e6e6": @"0x0060FF"] + title:_project.pin.boolValue?@"取消常用":@"设置常用" titleColor:[UIColor colorWithHexString:_project.pin.boolValue?@"0x0060FF":@"0xffffff"]]; return rightUtilityButtons; } @@ -125,3 +266,5 @@ + (CGFloat)cellHeight{ return 75.0; } @end + +#endif diff --git a/Coding_iOS/Views/Cell/ProjectListTaCell.m b/Coding_iOS/Views/Cell/ProjectListTaCell.m index 6e3a981b7..0087a05eb 100644 --- a/Coding_iOS/Views/Cell/ProjectListTaCell.m +++ b/Coding_iOS/Views/Cell/ProjectListTaCell.m @@ -23,7 +23,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus // Initialization code self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; if (!_iconV) { - _iconV = [[UIImageView alloc] init]; + _iconV = [[YLImageView alloc] init]; _iconV.layer.masksToBounds = YES; _iconV.layer.cornerRadius = 2.0; [self.contentView addSubview:_iconV]; diff --git a/Coding_iOS/Views/Cell/ProjectPublicListCell.m b/Coding_iOS/Views/Cell/ProjectPublicListCell.m index b8ed3f307..1b963c488 100644 --- a/Coding_iOS/Views/Cell/ProjectPublicListCell.m +++ b/Coding_iOS/Views/Cell/ProjectPublicListCell.m @@ -33,7 +33,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (self) { // Initialization code if (!_projectIconView) { - _projectIconView = [[UIImageView alloc] initWithFrame:CGRectMake(12, 12, kIconSize, kIconSize)]; + _projectIconView = [[YLImageView alloc] initWithFrame:CGRectMake(12, 12, kIconSize, kIconSize)]; _projectIconView.layer.masksToBounds = YES; _projectIconView.layer.cornerRadius = 2.0; [self.contentView addSubview:_projectIconView]; @@ -187,7 +187,7 @@ - (void)setProject:(Project *)project hasSWButtons:(BOOL)hasSWButtons hasBadgeTi _forkL.text = _project.fork_count.stringValue; NSString *titleStr=[NSString stringWithFormat:@"%@ 最后更新于 %@",_project.owner_user_name,[_project.updated_at stringDisplay_HHmm]]; - _ownerTitleLabel.attributedText = [NSString getAttributeFromText:titleStr emphasize:_project.owner_user_name emphasizeColor:kColorBrandGreen]; + _ownerTitleLabel.attributedText = [NSString getAttributeFromText:titleStr emphasize:_project.owner_user_name emphasizeColor:kColorLinkBlue]; //hasSWButtons @@ -216,15 +216,9 @@ - (void)setProject:(Project *)project hasSWButtons:(BOOL)hasSWButtons hasBadgeTi - (NSArray *)rightButtons{ NSMutableArray *rightUtilityButtons = [NSMutableArray new]; - // [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:_project.pin.boolValue? @"0xe6e6e6": @"0x3bbd79"] - // icon:[UIImage imageNamed:_project.pin.boolValue? @"icon_project_cell_pin": @"icon_project_cell_nopin"]]; - [rightUtilityButtons sw_addUtilityButtonWithColor:_project.pin.boolValue? kColorTableSectionBg: kColorBrandGreen + [rightUtilityButtons sw_addUtilityButtonWithColor:_project.pin.boolValue? kColorTableSectionBg: kColorBrandBlue title:_project.pin.boolValue?@"取消常用":@"设置常用" - titleColor:_project.pin.boolValue? kColorBrandGreen: [UIColor whiteColor]]; - -// [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:_project.pin.boolValue? @"0xeeeeee": @"0x3bbd79"] -// title:_project.pin.boolValue?@"取消常用":@"设置常用" titleColor:[UIColor colorWithHexString:_project.pin.boolValue?@"0x3bbd79":@"0xffffff"]]; - + titleColor:_project.pin.boolValue? kColorBrandBlue: [UIColor whiteColor]]; return rightUtilityButtons; } diff --git a/Coding_iOS/Views/Cell/ProjectTaskListViewCell.m b/Coding_iOS/Views/Cell/ProjectTaskListViewCell.m index 4f159b589..75a86fb0d 100755 --- a/Coding_iOS/Views/Cell/ProjectTaskListViewCell.m +++ b/Coding_iOS/Views/Cell/ProjectTaskListViewCell.m @@ -8,7 +8,7 @@ #define kProjectTaskListViewCell_LeftPading 93.0 #define kProjectTaskListViewCell_RightPading 10.0 -#define kProjectTaskListViewCell_CheckBoxWidth 20.0 +#define kProjectTaskListViewCell_CheckBoxWidth 17.0 #define kProjectTaskListViewCell_UserIconWidth 33.0 #define kProjectTaskListViewCell_UpDownPading 10.0 #define kProjectTaskListViewCell_MaxContentHeight 20.0 @@ -54,7 +54,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus [self.contentView addSubview:_checkView]; } if (!_userIconView) { - _userIconView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, kProjectTaskListViewCell_UserIconWidth, kProjectTaskListViewCell_UserIconWidth)]; + _userIconView = [[YLImageView alloc] initWithFrame:CGRectMake(0, 0, kProjectTaskListViewCell_UserIconWidth, kProjectTaskListViewCell_UserIconWidth)]; [_userIconView doCircleFrame]; [self.contentView addSubview:_userIconView]; } @@ -65,7 +65,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus } if (!_contentLabel) { _contentLabel = [UILabel new]; - _contentLabel.textColor = kColor222; + _contentLabel.textColor = kColorDark3; _contentLabel.font = kProjectTaskListViewCell_ContentFont; [self.contentView addSubview:_contentLabel]; } @@ -76,13 +76,13 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (!_numLabel) { _numLabel = [UILabel new]; _numLabel.font = [UIFont systemFontOfSize:10]; - _numLabel.textColor = kColor222; + _numLabel.textColor = kColorDark7; [self.contentView addSubview:_numLabel]; } if (!_userNameLabel) { _userNameLabel = [UILabel new]; _userNameLabel.font = [UIFont systemFontOfSize:10]; - _userNameLabel.textColor = kColor666; + _userNameLabel.textColor = kColorDark7; [self.contentView addSubview:_userNameLabel]; } if (!_timeClockIconView) { @@ -93,7 +93,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (!_timeLabel) { _timeLabel = [UILabel new]; _timeLabel.font = [UIFont systemFontOfSize:10]; - _timeLabel.textColor = kColor999; + _timeLabel.textColor = kColorDark7; [self.contentView addSubview:_timeLabel]; } if (!_commentIconView) { @@ -104,7 +104,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (!_commentCountLabel) { _commentCountLabel = [UILabel new]; _commentCountLabel.font = [UIFont systemFontOfSize:10]; - _commentCountLabel.textColor = kColor999; + _commentCountLabel.textColor = kColorDark7; [self.contentView addSubview:_commentCountLabel]; } if (!_mdIconView) { @@ -115,7 +115,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (!_mdLabel) { _mdLabel = [UILabel new]; _mdLabel.font = [UIFont systemFontOfSize:10]; - _mdLabel.textColor = kColor999; + _mdLabel.textColor = kColorDark7; _mdLabel.text = @"描述"; [self.contentView addSubview:_mdLabel]; } @@ -127,13 +127,13 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus kProjectTaskListViewCell_CheckBoxWidth)); }]; [_userIconView mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.equalTo(self.checkView.mas_right).offset(10); + make.left.equalTo(self.checkView.mas_right).offset(15); make.centerY.equalTo(self.contentView); make.size.mas_equalTo(CGSizeMake(kProjectTaskListViewCell_UserIconWidth, kProjectTaskListViewCell_UserIconWidth)); }]; [_taskPriorityView mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(self.contentView).offset(10); + make.top.equalTo(self.contentView).offset(15); make.left.equalTo(self.userIconView.mas_right).offset(10); make.size.mas_equalTo(CGSizeMake(17, 17)); }]; @@ -150,12 +150,12 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus make.right.equalTo(self.contentView).offset(-kPaddingLeftWidth); }]; [_numLabel mas_makeConstraints:^(MASConstraintMaker *make) { - make.bottom.equalTo(self.contentView).offset(-10); + make.bottom.equalTo(self.contentView).offset(-15); make.left.equalTo(self.userIconView.mas_right).offset(10); make.height.mas_equalTo(15); }]; [_userNameLabel mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.equalTo(self.numLabel.mas_right).offset(5); + make.left.equalTo(self.numLabel.mas_right).offset(10); make.centerY.equalTo(self.numLabel); make.height.mas_equalTo(15); }]; @@ -203,7 +203,8 @@ - (void)layoutSubviews{ [_checkView setImage:[UIImage imageNamed:_task.status.integerValue == 1? @"checkbox_unchecked" : @"checkbox_checked"]]; [_userIconView sd_setImageWithURL:[_task.owner.avatar urlImageWithCodePathResize:2*kProjectTaskListViewCell_UserIconWidth] placeholderImage:kPlaceholderMonkeyRoundWidth(kProjectTaskListViewCell_UserIconWidth)]; [_taskPriorityView setImage:[UIImage imageNamed:[NSString stringWithFormat:@"taskPriority%@_small", _task.priority.stringValue]]]; - _contentLabel.textColor = [UIColor colorWithHexString:_task.status.integerValue == 1? @"0x222222" : @"0x999999"]; + _contentLabel.textColor = _task.status.integerValue == 1? kColorDark3: kColorDarkA; +// [UIColor colorWithHexString:_task.status.integerValue == 1? @"0x222222" : @"0x999999"]; _contentLabel.text = [_task.content stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; //Tags if (_task.deadline_date || _task.labels.count > 0) { @@ -228,9 +229,9 @@ + (CGFloat)cellHeightWithObj:(id)obj{ if ([obj isKindOfClass:[Task class]]) { Task *task = (Task *)obj; if (task.deadline_date || task.labels.count > 0) { - cellHeight = 95; + cellHeight = 105; }else{ - cellHeight = 60; + cellHeight = 70; } } return cellHeight; @@ -301,7 +302,7 @@ - (ProjectTagLabel *)p_getLabelWithIndex:(NSInteger)index{ - (void)p_makeMoreStyleWithTagLabel:(ProjectTagLabel *)tagLabel{ tagLabel.layer.backgroundColor = [UIColor clearColor].CGColor; - tagLabel.textColor = kColor999; + tagLabel.textColor = kColorDarkA; tagLabel.text = @"···"; [tagLabel setWidth:15]; } @@ -356,20 +357,20 @@ - (void)setDate:(NSDate *)deadline_date andDone:(BOOL)done{ NSInteger leftDayCount = [deadline_date leftDayCount]; switch (leftDayCount) { case 0: - textColorStr = @"0xF5A523"; + textColorStr = @"0xF68435"; deadlineStr = @"今天"; break; case 1: - textColorStr = @"0x95B763"; + textColorStr = @"0xA1CF64"; deadlineStr = @"明天"; break; default: - textColorStr = leftDayCount > 0? @"0x9AAFC2": @"0xF24B4B"; + textColorStr = leftDayCount > 0? @"0x59A2FF": @"0xF56061"; deadlineStr = [deadline_date stringWithFormat:@"MM/dd"]; break; } if (done) { - textColorStr = @"0xB5B5B5"; + textColorStr = @"0xA9B3BE"; } UIColor *textColor = [UIColor colorWithHexString:textColorStr]; diff --git a/Coding_iOS/Views/Cell/ProjectTopicCell.m b/Coding_iOS/Views/Cell/ProjectTopicCell.m index cfd88a782..10f7f0577 100755 --- a/Coding_iOS/Views/Cell/ProjectTopicCell.m +++ b/Coding_iOS/Views/Cell/ProjectTopicCell.m @@ -35,7 +35,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus // Initialization code self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; if (!_userIconView) { - _userIconView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 12, 33, 33)]; + _userIconView = [[YLImageView alloc] initWithFrame:CGRectMake(10, 12, 33, 33)]; [_userIconView doCircleFrame]; [self.contentView addSubview:_userIconView]; } diff --git a/Coding_iOS/Views/Cell/ScreenCell.h b/Coding_iOS/Views/Cell/ScreenCell.h new file mode 100644 index 000000000..1081f7ec5 --- /dev/null +++ b/Coding_iOS/Views/Cell/ScreenCell.h @@ -0,0 +1,17 @@ +// +// ScreenCell.h +// Coding_iOS +// +// Created by zhangdadi on 2016/12/14. +// Copyright © 2016年 Coding. All rights reserved. +// + +#import +#define kCellIdentifier_ScreenCell @"ScreenCell" + +@interface ScreenCell : UITableViewCell +@property (nonatomic, strong) NSString *title; +@property (nonatomic, strong) NSString *color; +@property (nonatomic, assign) BOOL isSel; + +@end diff --git a/Coding_iOS/Views/Cell/ScreenCell.m b/Coding_iOS/Views/Cell/ScreenCell.m new file mode 100644 index 000000000..61133a82a --- /dev/null +++ b/Coding_iOS/Views/Cell/ScreenCell.m @@ -0,0 +1,79 @@ +// +// ScreenCell.m +// Coding_iOS +// +// Created by zhangdadi on 2016/12/14. +// Copyright © 2016年 Coding. All rights reserved. +// + +#import "ScreenCell.h" + +@interface ScreenCell () +@property (nonatomic, strong) UIButton *tagButton; +@property (nonatomic, strong) UILabel *titleLab; +@property (nonatomic, strong) UIImageView *selImageView; +@end + +@implementation ScreenCell + +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + [self creatView]; + } + return self; +} + +- (void)awakeFromNib { + [super awakeFromNib]; + // Initialization code +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated { + [super setSelected:selected animated:animated]; + + // Configure the view for the selected state +} + +- (void)creatView { + + [self.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; + self.backgroundColor=[UIColor clearColor]; + + _tagButton = [[UIButton alloc] init]; + UIImage *image = [[UIImage imageNamed:@"task_filter_tag"] imageWithRenderingMode:(UIImageRenderingModeAlwaysTemplate)]; + [_tagButton setImage:image forState:UIControlStateNormal]; + [self.contentView addSubview:_tagButton]; + _tagButton.sd_layout.leftSpaceToView(self.contentView, 20).centerYEqualToView(self.contentView).widthIs(15).heightIs(15); + + _selImageView = [[UIImageView alloc] init]; + _selImageView.image = [UIImage imageNamed:@"task_filter_checkIcon"]; + [self.contentView addSubview:_selImageView]; + _selImageView.hidden = YES; + _selImageView.sd_layout.rightSpaceToView(self.contentView, 20).centerYEqualToView(self.contentView).widthIs(20).heightIs(21); + + _titleLab=[[UILabel alloc] init]; + _titleLab.font=[UIFont systemFontOfSize:15]; + [self.contentView addSubview:_titleLab]; + _titleLab.sd_layout.leftSpaceToView(_tagButton, 17).rightSpaceToView(_selImageView, 15).topSpaceToView(self.contentView, 15).bottomSpaceToView(self.contentView, 15); + +} + +- (void)setIsSel:(BOOL)isSel { + _titleLab.textColor=isSel?kColorLightBlue:kColor222; +// _selImageView.hidden = !isSel; + _selImageView.hidden = YES; + self.accessoryType = isSel? UITableViewCellAccessoryCheckmark: UITableViewCellAccessoryNone; +} + +- (void)setTitle:(NSString *)title { + _title = title; + _titleLab.text= title; +} + +- (void)setColor:(NSString *)color { + _color = color; + _tagButton.tintColor = [UIColor colorWithHexString:[NSString stringWithFormat:@"0x%@", [color substringFromIndex:1]]]; +} + +@end diff --git a/Coding_iOS/Views/Cell/ShopMutileValueCell.xib b/Coding_iOS/Views/Cell/ShopMutileValueCell.xib index fdfa1c133..6f38f711e 100644 --- a/Coding_iOS/Views/Cell/ShopMutileValueCell.xib +++ b/Coding_iOS/Views/Cell/ShopMutileValueCell.xib @@ -1,9 +1,13 @@ - - + + + + + - + + @@ -21,7 +25,7 @@ - + @@ -32,7 +36,7 @@ - + @@ -44,7 +48,7 @@ - + @@ -55,7 +59,7 @@ - + @@ -67,12 +71,12 @@ - + - - + + - + diff --git a/Coding_iOS/Views/Cell/ShopOderCell.h b/Coding_iOS/Views/Cell/ShopOderCell.h index 3ec3bc97b..859a328c8 100644 --- a/Coding_iOS/Views/Cell/ShopOderCell.h +++ b/Coding_iOS/Views/Cell/ShopOderCell.h @@ -17,4 +17,7 @@ - (void)configViewWithModel:(BaseModel *)model; +@property (copy, nonatomic) void(^deleteActionBlock)(); +@property (copy, nonatomic) void(^payActionBlock)(); + @end diff --git a/Coding_iOS/Views/Cell/ShopOderCell.m b/Coding_iOS/Views/Cell/ShopOderCell.m index 4a7619f12..b80d0f46b 100644 --- a/Coding_iOS/Views/Cell/ShopOderCell.m +++ b/Coding_iOS/Views/Cell/ShopOderCell.m @@ -14,12 +14,16 @@ @interface ShopOderCell() { + UIView *_superView; + UIImageView *_coverView; UILabel *_priceLabel; UILabel *_titleLabel; UILabel *_descLabel; -// UILabel *_countLabel; + UILabel *_countLabel; + UILabel *_pointLabel; + UILabel *_moneyLabel; UIButton *_codingCoinView; UILabel *_orderNumLabel; @@ -31,6 +35,8 @@ @interface ShopOderCell() UILabel *_sendTimeLabel; UILabel *_expressLabel; + UIButton *_deleteButton; + UIButton *_payButton; } @end @@ -43,8 +49,8 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus self.accessoryType = UITableViewCellAccessoryNone; self.backgroundColor = [UIColor whiteColor]; self.selectionStyle = UITableViewCellSelectionStyleNone; + self.clipsToBounds = YES; [self setUpContentView]; - } return self; } @@ -52,53 +58,41 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus - (void)setUpContentView { - UIView *superView = [UIView new]; - [self.contentView addSubview:superView]; - [superView mas_makeConstraints:^(MASConstraintMaker *make) { + _superView = [UIView new]; + [self.contentView addSubview:_superView]; + [_superView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.contentView); }]; - UILabel *orderLabel = [[UILabel alloc] initWithFrame:CGRectZero]; - orderLabel.font = FONT(14); - orderLabel.backgroundColor = [UIColor clearColor]; - orderLabel.text = @" 订单编号 "; - orderLabel.textAlignment = NSTextAlignmentCenter; - orderLabel.layer.masksToBounds = YES; - orderLabel.layer.cornerRadius = 4; - orderLabel.layer.borderWidth = 0.5; - orderLabel.layer.borderColor = [UIColor colorWithHexString:@"0xB5B5B5"].CGColor; - orderLabel.textColor = kColor222; - [superView addSubview:orderLabel]; - _orderNumLabel = [[UILabel alloc] initWithFrame:CGRectZero]; _orderNumLabel.font = FONT(15); _orderNumLabel.backgroundColor = [UIColor clearColor]; - _orderNumLabel.textColor = [UIColor colorWithHexString:@"0x000000"]; - [superView addSubview:_orderNumLabel]; - - [orderLabel mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.equalTo(superView.mas_left).offset(12); - make.top.equalTo(superView.mas_top).offset(12); -// make.width.offset(132/2); - make.height.offset(20); + _orderNumLabel.textColor = kColorDark4; + [_superView addSubview:_orderNumLabel]; + [_orderNumLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.offset(15); + make.top.offset(15); }]; - [_orderNumLabel mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.equalTo(orderLabel.mas_right).offset(16); - make.centerY.equalTo(orderLabel.mas_centerY); + UIView *lineView1 = [UIView new]; + lineView1.backgroundColor = kColorDDD; + [_superView addSubview:lineView1]; + [lineView1 mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.offset(44); + make.left.equalTo(_orderNumLabel); + make.right.equalTo(_superView); + make.height.mas_equalTo(kLine_MinHeight); }]; UIView *_goodsInfoView = [[UIView alloc] init]; - _goodsInfoView.backgroundColor = kColorTableSectionBg; - [superView addSubview:_goodsInfoView]; + [_superView addSubview:_goodsInfoView]; [_goodsInfoView mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(orderLabel.mas_bottom).offset(15); - make.left.equalTo(superView.mas_left).offset(12); - make.right.equalTo(superView.mas_right).offset(-12); - make.height.offset(108/2); + make.top.equalTo(lineView1.mas_bottom); + make.left.right.equalTo(_superView); + make.height.mas_equalTo(110); }]; - _coverView = [[UIImageView alloc] initWithFrame:CGRectZero]; + _coverView = [[YLImageView alloc] initWithFrame:CGRectZero]; _coverView.backgroundColor = [UIColor clearColor]; _coverView.contentMode = UIViewContentModeScaleAspectFill; _coverView.layer.masksToBounds =YES; @@ -112,95 +106,153 @@ - (void)setUpContentView _titleLabel.textColor = kColor222; [_goodsInfoView addSubview:_titleLabel]; - _remarksLabel = [[UILabel alloc] initWithFrame:CGRectZero]; - _remarksLabel.font = FONT(12); - _remarksLabel.numberOfLines = 0 ; - _remarksLabel.backgroundColor = [UIColor clearColor]; - _remarksLabel.textColor = kColor666; - [_goodsInfoView addSubview:_remarksLabel]; - -// _countLabel = [[UILabel alloc] initWithFrame:CGRectZero]; -// _countLabel.font = FONT(12); -// _countLabel.backgroundColor = [UIColor clearColor]; -// _countLabel.text = @"ⅹ1"; -// _countLabel.textColor = kColorBrandGreen; -// [_goodsInfoView addSubview:_countLabel]; + _countLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + _countLabel.font = FONT(15); + _countLabel.backgroundColor = [UIColor clearColor]; + _countLabel.text = @"ⅹ1"; + _countLabel.textColor = kColorBrandBlue; + [_goodsInfoView addSubview:_countLabel]; _codingCoinView = [UIButton buttonWithType:UIButtonTypeCustom]; [_codingCoinView setImage:[UIImage imageNamed:@"shop_coding_coin_icon"] forState:UIControlStateNormal]; [_codingCoinView setTitle:@" 码币 " forState:UIControlStateNormal]; - [_codingCoinView setTitleColor:kColor222 forState:UIControlStateNormal]; - [_codingCoinView.titleLabel setFont:[UIFont boldSystemFontOfSize:12.0]]; + [_codingCoinView setTitleColor:kColorDark7 forState:UIControlStateNormal]; + [_codingCoinView.titleLabel setFont:[UIFont systemFontOfSize:14.0]]; [_goodsInfoView addSubview:_codingCoinView]; + _priceLabel = [UILabel labelWithFont:[UIFont systemFontOfSize:15] textColor:kColorBrandOrange]; + [_goodsInfoView addSubview:_priceLabel]; [_coverView mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.left.bottom.equalTo(_goodsInfoView); - make.width.offset(90); + make.width.height.mas_equalTo(80); + make.centerY.equalTo(_goodsInfoView); + make.left.offset(15); }]; [_titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(_coverView.mas_top).offset(7); - make.left.equalTo(_coverView.mas_right).offset(12); - make.right.equalTo(superView.mas_right).offset(-(40)); + make.top.equalTo(_coverView); + make.left.equalTo(_coverView.mas_right).offset(20); + make.right.offset(-(40)); }]; -// [_countLabel mas_makeConstraints:^(MASConstraintMaker *make) { -// make.centerY.equalTo(_titleLabel.mas_centerY); -// make.right.equalTo(_goodsInfoView.mas_right).offset(-7); -// make.width.offset(20); -// }]; + [_countLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(_titleLabel); + make.right.offset(-15); + }]; [_codingCoinView mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(_titleLabel.mas_bottom).offset(8); - make.left.equalTo(_titleLabel.mas_left); + make.centerY.equalTo(_coverView); + make.left.equalTo(_titleLabel); }]; - [_remarksLabel mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(_codingCoinView.mas_bottom).offset(7); - make.left.equalTo(_titleLabel.mas_left); + [_priceLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(_titleLabel); + make.bottom.equalTo(_coverView); + }]; + + UIView *lineView2 = [UIView new]; + lineView2.backgroundColor = kColorDDD; + [_superView addSubview:lineView2]; + [lineView2 mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(_goodsInfoView.mas_bottom).offset(88); + make.left.equalTo(_orderNumLabel); + make.right.equalTo(_superView); + make.height.mas_equalTo(kLine_MinHeight); + }]; + + // 码币抵扣 + UILabel *pointLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + pointLabel.font = FONT(14); + pointLabel.backgroundColor = [UIColor clearColor]; + pointLabel.textColor = kColorDark7; + pointLabel.text = @"码币抵扣"; + [_superView addSubview:pointLabel]; + + _pointLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + _pointLabel.textAlignment = NSTextAlignmentRight; + _pointLabel.font = FONT(14); + _pointLabel.backgroundColor = [UIColor clearColor]; + _pointLabel.textColor = kColorDark3; + [_superView addSubview:_pointLabel]; + + [pointLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(_goodsInfoView.mas_bottom).offset(22); + make.left.equalTo(_orderNumLabel); + }]; + + [_pointLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(pointLabel.mas_top); + make.left.equalTo(pointLabel.mas_right); + make.right.equalTo(_goodsInfoView.mas_right).offset(-15); + }]; + + // 商品实付 + UILabel *moneyLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + moneyLabel.font = FONT(14); + moneyLabel.backgroundColor = [UIColor clearColor]; + moneyLabel.textColor = kColorDark7; + moneyLabel.text = @"商品实付"; + [_superView addSubview:moneyLabel]; + + _moneyLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + _moneyLabel.textAlignment = NSTextAlignmentRight; + _moneyLabel.font = FONT(14); + _moneyLabel.backgroundColor = [UIColor clearColor]; + _moneyLabel.textColor = kColorDark3; + [_superView addSubview:_moneyLabel]; + + [moneyLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(_goodsInfoView.mas_bottom).offset(66); + make.left.equalTo(_orderNumLabel); }]; + [_moneyLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(moneyLabel.mas_top); + make.left.equalTo(moneyLabel.mas_right); + make.right.equalTo(_goodsInfoView.mas_right).offset(-15); + }]; + + //基本的送货信息 // 收货人 UILabel *nameLabel = [[UILabel alloc] initWithFrame:CGRectZero]; nameLabel.font = FONT(14); nameLabel.backgroundColor = [UIColor clearColor]; - nameLabel.textColor = kColor666; + nameLabel.textColor = kColorDark7; nameLabel.text = @"收货人:"; - [superView addSubview:nameLabel]; + [_superView addSubview:nameLabel]; _nameLabel = [[UILabel alloc] initWithFrame:CGRectZero]; _nameLabel.font = FONT(14); _nameLabel.backgroundColor = [UIColor clearColor]; - _nameLabel.textColor = kColor666; - [superView addSubview:_nameLabel]; + _nameLabel.textColor = kColorDark3; + [_superView addSubview:_nameLabel]; [nameLabel mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(_goodsInfoView.mas_bottom).offset(12); - make.left.equalTo(_goodsInfoView.mas_left); + make.top.equalTo(lineView2.mas_bottom).offset(15); + make.left.equalTo(_orderNumLabel); }]; [_nameLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(nameLabel.mas_top); make.left.equalTo(nameLabel.mas_right); - make.right.equalTo(_goodsInfoView.mas_right); + make.right.equalTo(_goodsInfoView.mas_right).offset(-15); }]; //联系电话: UILabel *phoneNumLabel = [[UILabel alloc] initWithFrame:CGRectZero]; phoneNumLabel.font = FONT(14); phoneNumLabel.backgroundColor = [UIColor clearColor]; - phoneNumLabel.textColor = kColor666; + phoneNumLabel.textColor = kColorDark7; phoneNumLabel.text = @"联系电话:"; - [superView addSubview:phoneNumLabel]; + [_superView addSubview:phoneNumLabel]; _phoneNumLabel = [[UILabel alloc] initWithFrame:CGRectZero]; _phoneNumLabel.font = FONT(14); _phoneNumLabel.backgroundColor = [UIColor clearColor]; - _phoneNumLabel.textColor = kColor666; - [superView addSubview:_phoneNumLabel]; + _phoneNumLabel.textColor = kColorDark3; + [_superView addSubview:_phoneNumLabel]; [phoneNumLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(nameLabel.mas_bottom).offset(9); @@ -210,7 +262,7 @@ - (void)setUpContentView [_phoneNumLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(phoneNumLabel.mas_top); make.left.equalTo(phoneNumLabel.mas_right); - make.right.equalTo(_goodsInfoView.mas_right); + make.right.equalTo(_goodsInfoView.mas_right).offset(-15); }]; @@ -218,25 +270,25 @@ - (void)setUpContentView UILabel *sendStatusLabel = [[UILabel alloc] initWithFrame:CGRectZero]; sendStatusLabel.font = FONT(14); sendStatusLabel.backgroundColor = [UIColor clearColor]; - sendStatusLabel.textColor = kColor666; - sendStatusLabel.text = @"状态:"; - [superView addSubview:sendStatusLabel]; + sendStatusLabel.textColor = kColorDark7; + sendStatusLabel.text = @"发货状态:"; + [_superView addSubview:sendStatusLabel]; _sendStatusLabel = [[UILabel alloc] initWithFrame:CGRectZero]; _sendStatusLabel.font = FONT(14); _sendStatusLabel.backgroundColor = [UIColor clearColor]; - _sendStatusLabel.textColor = kColor666; - [superView addSubview:_sendStatusLabel]; + _sendStatusLabel.textColor = kColorDark3; + [_superView addSubview:_sendStatusLabel]; [sendStatusLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(phoneNumLabel.mas_bottom).offset(9); - make.left.equalTo(_goodsInfoView.mas_left); + make.left.equalTo(_orderNumLabel); }]; [_sendStatusLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(sendStatusLabel.mas_top); make.left.equalTo(sendStatusLabel.mas_right); - make.right.equalTo(_goodsInfoView.mas_right); + make.right.equalTo(_goodsInfoView.mas_right).offset(-15); }]; @@ -244,26 +296,25 @@ - (void)setUpContentView UILabel *expressLabel = [[UILabel alloc] initWithFrame:CGRectZero]; expressLabel.font = FONT(14); expressLabel.backgroundColor = [UIColor clearColor]; - expressLabel.textColor = kColor666; + expressLabel.textColor = kColorDark7; expressLabel.text = @"快递:"; - [superView addSubview:expressLabel]; + [_superView addSubview:expressLabel]; _expressLabel = [[UILabel alloc] initWithFrame:CGRectZero]; _expressLabel.font = FONT(14); _expressLabel.backgroundColor = [UIColor clearColor]; - _expressLabel.textColor = kColor666; - [superView addSubview:_expressLabel]; + _expressLabel.textColor = kColorDark3; + [_superView addSubview:_expressLabel]; [expressLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(sendStatusLabel.mas_bottom).offset(9); - make.left.equalTo(_goodsInfoView.mas_left); + make.left.equalTo(_orderNumLabel); }]; [_expressLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(expressLabel.mas_top); make.left.equalTo(expressLabel.mas_right); - make.right.equalTo(_goodsInfoView.mas_right); - + make.right.equalTo(_goodsInfoView.mas_right).offset(-15); }]; @@ -271,25 +322,25 @@ - (void)setUpContentView UILabel *sendTimeLabel = [[UILabel alloc] initWithFrame:CGRectZero]; sendTimeLabel.font = FONT(14); sendTimeLabel.backgroundColor = [UIColor clearColor]; - sendTimeLabel.textColor = kColor666; + sendTimeLabel.textColor = kColorDark7; sendTimeLabel.text = @"时间:"; - [superView addSubview:sendTimeLabel]; + [_superView addSubview:sendTimeLabel]; _sendTimeLabel = [[UILabel alloc] initWithFrame:CGRectZero]; _sendTimeLabel.font = FONT(14); _sendTimeLabel.backgroundColor = [UIColor clearColor]; - _sendTimeLabel.textColor = kColor666; - [superView addSubview:_sendTimeLabel]; + _sendTimeLabel.textColor = kColorDark3; + [_superView addSubview:_sendTimeLabel]; [sendTimeLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(expressLabel.mas_bottom).offset(9); - make.left.equalTo(_goodsInfoView.mas_left); + make.left.equalTo(_orderNumLabel); }]; [_sendTimeLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(sendTimeLabel.mas_top); make.left.equalTo(sendTimeLabel.mas_right); - make.right.equalTo(_goodsInfoView.mas_right); + make.right.equalTo(_goodsInfoView.mas_right).offset(-15); }]; @@ -297,26 +348,25 @@ - (void)setUpContentView UILabel *remarkLabel = [[UILabel alloc] initWithFrame:CGRectZero]; remarkLabel.font = FONT(14); remarkLabel.backgroundColor = [UIColor clearColor]; - remarkLabel.textColor = kColor666; + remarkLabel.textColor = kColorDark7; remarkLabel.text = @"备注:"; - [superView addSubview:remarkLabel]; + [_superView addSubview:remarkLabel]; _remarksLabel = [[UILabel alloc] initWithFrame:CGRectZero]; _remarksLabel.font = FONT(14); _remarksLabel.backgroundColor = [UIColor clearColor]; - _remarksLabel.textColor = kColor666; - [superView addSubview:_remarksLabel]; + _remarksLabel.textColor = kColorDark3; + [_superView addSubview:_remarksLabel]; [remarkLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(sendTimeLabel.mas_bottom).offset(9); - make.left.equalTo(_goodsInfoView.mas_left); + make.left.equalTo(_orderNumLabel); }]; [_remarksLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(remarkLabel.mas_top); make.left.equalTo(remarkLabel.mas_right); - make.right.equalTo(_goodsInfoView.mas_right); - + make.right.equalTo(_goodsInfoView.mas_right).offset(-15); }]; @@ -324,48 +374,94 @@ - (void)setUpContentView UILabel *addressLabel = [[UILabel alloc] initWithFrame:CGRectZero]; addressLabel.font = FONT(14); addressLabel.backgroundColor = [UIColor clearColor]; - addressLabel.textColor = kColor666; + addressLabel.textColor = kColorDark7; addressLabel.text = @"收货地址 : "; - [superView addSubview:addressLabel]; + [_superView addSubview:addressLabel]; _addressLabel = [[UILabel alloc] initWithFrame:CGRectZero]; _addressLabel.font = FONT(14); _addressLabel.backgroundColor = [UIColor clearColor]; _addressLabel.numberOfLines = 0; -// _addressLabel.lineBreakMode = NSLineBreakByWordWrapping; - _addressLabel.textColor = kColor666; - [superView addSubview:_addressLabel]; + _addressLabel.textColor = kColorDark3; + [_superView addSubview:_addressLabel]; [addressLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(remarkLabel.mas_bottom).offset(9); - make.left.equalTo(_goodsInfoView.mas_left); -// make.right.equalTo(_addressLabel.mas_left); -// make.width.offset(70); - make.height.offset(15); + make.left.equalTo(_orderNumLabel); }]; [_addressLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(addressLabel.mas_top).offset(-2); make.left.equalTo(addressLabel.mas_right); - make.right.equalTo(_goodsInfoView.mas_right); + make.right.equalTo(_goodsInfoView.mas_right).offset(-15); make.width.equalTo(@(kScreen_Width - 26 - 70)); - make.bottom.equalTo(superView.mas_bottom).offset(-15); }]; - [superView mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(_orderNumLabel.mas_top).offset(-15); - make.bottom.equalTo(_addressLabel.mas_bottom).offset(15); + UIView *lineView3 = [UIView new]; + lineView3.backgroundColor = kColorDDD; + [_superView addSubview:lineView3]; + [lineView3 mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(_addressLabel.mas_bottom).offset(15); + make.left.equalTo(_orderNumLabel); + make.right.equalTo(_superView); + make.height.mas_equalTo(kLine_MinHeight); + }]; + + __weak typeof(self) weakSelf = self; + _deleteButton = ({ + UIButton *button = [UIButton new]; + button.titleLabel.font = FONT(14); + [button setTitleColor:kColorDark7 forState:UIControlStateNormal]; + [button setTitle:@"取消订单" forState:UIControlStateNormal]; + [button doBorderWidth:1 color:kColorDark7 cornerRadius:4]; + [button bk_addEventHandler:^(id sender) { + if (weakSelf.deleteActionBlock) { + weakSelf.deleteActionBlock(); + } + } forControlEvents:UIControlEventTouchUpInside]; + [_superView addSubview:button]; + button; + }); + _payButton = ({ + UIButton *button = [UIButton new]; + button.titleLabel.font = FONT(14); + [button setTitleColor:kColorBrandOrange forState:UIControlStateNormal]; + [button setTitle:@"付款" forState:UIControlStateNormal]; + [button doBorderWidth:1 color:kColorBrandOrange cornerRadius:4]; + [button bk_addEventHandler:^(id sender) { + if (weakSelf.payActionBlock) { + weakSelf.payActionBlock(); + } + } forControlEvents:UIControlEventTouchUpInside]; + [_superView addSubview:button]; + button; + }); + [_payButton mas_makeConstraints:^(MASConstraintMaker *make) { + make.size.mas_equalTo(CGSizeMake(80, 30)); + make.top.equalTo(lineView3.mas_bottom).offset(10); + make.right.offset(-15); + }]; + [_deleteButton mas_makeConstraints:^(MASConstraintMaker *make) { + make.size.mas_equalTo(CGSizeMake(80, 30)); + make.top.equalTo(_payButton); + make.right.equalTo(_payButton.mas_left).offset(-10); }]; } - (void)configViewWithModel:(ShopOrder *)order { - _titleLabel.text = order.giftName; +// _titleLabel.text = order.giftName; + _titleLabel.text = [order.giftName componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"¥¥"]].firstObject; [_coverView sd_setImageWithURL:[order.giftImage urlImageWithCodePathResize:90 * 2]]; NSString *points_cost = [NSString stringWithFormat:@" %@ 码币",[order.pointsCost stringValue]]; [_codingCoinView setTitle:points_cost forState:UIControlStateNormal]; - - _orderNumLabel.text = order.orderNo; + CGFloat price = order.pointsCost.floatValue * 50; + if (price - ((int)price) < .1) { + _priceLabel.text = [NSString stringWithFormat:@"¥%.0f", price]; + }else{ + _priceLabel.text = [NSString stringWithFormat:@"¥%.1f", price]; + } + _orderNumLabel.text = [NSString stringWithFormat:@"订单编号:%@", order.orderNo]; NSString *remarkStr = order.remark ?: @""; if (order.optionName.length > 0) { remarkStr = [remarkStr stringByAppendingFormat:@"(%@)", order.optionName]; @@ -374,34 +470,28 @@ - (void)configViewWithModel:(ShopOrder *)order _nameLabel.text = order.receiverName; _addressLabel.text = order.receiverAddress; _phoneNumLabel.text = order.receiverPhone; - switch (order.status.intValue) { - case 0: - _sendStatusLabel.text = @"未发货"; - - break; - case 1: - _sendStatusLabel.text = @"已发货"; - - break; - default: - break; - } if ([order.createdAt doubleValue] > 0) { - NSDate *date =[NSDate dateWithTimeIntervalSince1970: ((double)(order.createdAt.longLongValue))/1000.0]; if (date) { _sendTimeLabel.text = [date stringWithFormat:@"yyyy年MM月dd日 HH:mm"]; } } + _pointLabel.text = [NSString stringWithFormat:@"%.2f 码币", order.pointDiscount.floatValue]; + _moneyLabel.text = [NSString stringWithFormat:@"¥%.2f", order.paymentAmount.floatValue]; if ([order.expressNo isEmpty]) { _expressLabel.text = @"暂无"; - }else + }else{ _expressLabel.text = order.expressNo; - + } + NSInteger status = order.status.integerValue;//3 待付款, 0 未发货, 1 已发货, 2 已完成 + _sendStatusLabel.text = (status == 1 || status == 2? @"已发货": @"未发货"); + _deleteButton.hidden = _payButton.hidden = (status != 3); + [_superView mas_updateConstraints:^(MASConstraintMaker *make) { + make.bottom.equalTo(_addressLabel.mas_bottom).offset(status == 3? (14 + 50): 14); + }]; CGFloat height = [self systemLayoutSizeFittingSize:UILayoutFittingExpandedSize].height; self.frame = CGRectMake(0, 0, kScreen_Width, height); self.cellHeight = height; - } @end diff --git a/Coding_iOS/Views/Cell/ShopOrderTextFieldCell.h b/Coding_iOS/Views/Cell/ShopOrderTextFieldCell.h index faa883e08..3deb76752 100644 --- a/Coding_iOS/Views/Cell/ShopOrderTextFieldCell.h +++ b/Coding_iOS/Views/Cell/ShopOrderTextFieldCell.h @@ -6,6 +6,8 @@ // Copyright © 2015年 Coding. All rights reserved. // +#define kCellIdentifier_ShopOrderTextFieldCell @"ShopOrderTextFieldCell" + #import @interface ShopOrderTextFieldCell : UITableViewCell diff --git a/Coding_iOS/Views/Cell/ShopOrderTextFieldCell.m b/Coding_iOS/Views/Cell/ShopOrderTextFieldCell.m index 5c995e6a9..fc09c5185 100644 --- a/Coding_iOS/Views/Cell/ShopOrderTextFieldCell.m +++ b/Coding_iOS/Views/Cell/ShopOrderTextFieldCell.m @@ -21,15 +21,15 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus self.selectionStyle = UITableViewCellSelectionStyleNone; if (!_nameLabel) { _nameLabel = [UILabel new]; - _nameLabel.textColor = [UIColor colorWithHexString:@"0x000000"]; + _nameLabel.textColor = kColor222; _nameLabel.font = [UIFont systemFontOfSize:15]; [self.contentView addSubview:_nameLabel]; } if (!_textField) { _textField = [UITextField new]; - _textField.textColor = [UIColor colorWithHexString:@"0x000000"]; - _textField.font = [UIFont systemFontOfSize:14]; + _textField.textColor = kColor222; + _textField.font = [UIFont systemFontOfSize:15]; [self.contentView addSubview:_textField]; } @@ -50,7 +50,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus } + (CGFloat)cellHeight{ - return 596/4.0/2.0; + return 85; } @end diff --git a/Coding_iOS/Views/Cell/ShopSwitchCell.h b/Coding_iOS/Views/Cell/ShopSwitchCell.h new file mode 100644 index 000000000..1eac4da5d --- /dev/null +++ b/Coding_iOS/Views/Cell/ShopSwitchCell.h @@ -0,0 +1,19 @@ +// +// ShopSwitchCell.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2017/9/19. +// Copyright © 2017年 Coding. All rights reserved. +// +#define kCellIdentifier_ShopSwitchCell @"ShopSwitchCell" + +#import + +#import "ShopGoods.h" + +@interface ShopSwitchCell : UITableViewCell + +@property (strong, nonatomic)ShopGoods *shopGoods; +@property (copy, nonatomic) void(^updateBlock)(); + +@end diff --git a/Coding_iOS/Views/Cell/ShopSwitchCell.m b/Coding_iOS/Views/Cell/ShopSwitchCell.m new file mode 100644 index 000000000..484804614 --- /dev/null +++ b/Coding_iOS/Views/Cell/ShopSwitchCell.m @@ -0,0 +1,42 @@ +// +// ShopSwitchCell.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2017/9/19. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "ShopSwitchCell.h" + +@interface ShopSwitchCell () +@property (weak, nonatomic) IBOutlet UILabel *contentL; +@property (weak, nonatomic) IBOutlet UISwitch *mySwitch; + +@end + +@implementation ShopSwitchCell + +- (void)awakeFromNib { + [super awakeFromNib]; + // Initialization code +} + +- (void)setShopGoods:(ShopGoods *)shopGoods{ + _shopGoods = shopGoods; + [_mySwitch setOn:_shopGoods.usePoint]; + [self p_updateContentL]; +} + +- (void)p_updateContentL{ + CGFloat available_points = MIN(_shopGoods.available_points.floatValue, _shopGoods.points_cost.floatValue); + _contentL.text = [NSString stringWithFormat:@"可用 %.2f 码币抵扣 %.2f 元", available_points, available_points* 50]; +} + +- (IBAction)valueChanged:(UISwitch *)sender { + _shopGoods.usePoint = sender.isOn; + [self p_updateContentL]; + if (_updateBlock) { + _updateBlock(); + } +} +@end diff --git a/Coding_iOS/Views/Cell/ShopSwitchCell.xib b/Coding_iOS/Views/Cell/ShopSwitchCell.xib new file mode 100644 index 000000000..2d4fc03db --- /dev/null +++ b/Coding_iOS/Views/Cell/ShopSwitchCell.xib @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Coding_iOS/Views/Cell/TagColorDisplayCell.m b/Coding_iOS/Views/Cell/TagColorDisplayCell.m index 85b615a3e..1a405652a 100644 --- a/Coding_iOS/Views/Cell/TagColorDisplayCell.m +++ b/Coding_iOS/Views/Cell/TagColorDisplayCell.m @@ -14,7 +14,6 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { // Initialization code - self.tintColor = kColorBrandGreen; if (!_colorView) { _colorView = [[UIView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 12, 20, 20)]; _colorView.layer.masksToBounds = YES; diff --git a/Coding_iOS/Views/Cell/TaskActivityCell.m b/Coding_iOS/Views/Cell/TaskActivityCell.m index 6d1fe6f2c..a41681e7a 100644 --- a/Coding_iOS/Views/Cell/TaskActivityCell.m +++ b/Coding_iOS/Views/Cell/TaskActivityCell.m @@ -6,7 +6,9 @@ // Copyright (c) 2015年 Coding. All rights reserved. // -#define kTaskActivityCell_LeftContentPading (kPaddingLeftWidth + 40) +#define kTaskActivityCell_BorderWidth 2.0 +#define kTaskActivityCell_IconWidth 33.0 +#define kTaskActivityCell_LeftContentPading (kPaddingLeftWidth + kTaskActivityCell_IconWidth + 15) #define kTaskActivityCell_ContentWidth (kScreen_Width - kTaskActivityCell_LeftContentPading - kPaddingLeftWidth) #import "TaskActivityCell.h" @@ -31,8 +33,8 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus [self.contentView addSubview:_timeLineView]; } if (!_tipIconView) { - CGFloat borderWidth = 2; - _tipIconView = [[UIImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth - borderWidth, 10, 28 + 2*borderWidth, 28 + 2*borderWidth)]; + CGFloat borderWidth = kTaskActivityCell_BorderWidth; + _tipIconView = [[UIImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth - borderWidth, 6, kTaskActivityCell_IconWidth + 2*borderWidth, kTaskActivityCell_IconWidth + 2*borderWidth)]; _tipIconView.contentMode = UIViewContentModeCenter; _tipIconView.layer.masksToBounds = YES; @@ -41,11 +43,21 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus _tipIconView.layer.borderColor = kColorTableBG.CGColor; [self.contentView addSubview:_tipIconView]; + [_tipIconView mas_makeConstraints:^(MASConstraintMaker *make) { + make.size.mas_equalTo(CGSizeMake(kTaskActivityCell_IconWidth + 2*borderWidth, kTaskActivityCell_IconWidth + 2*borderWidth)); + make.left.equalTo(self.contentView).offset(kPaddingLeftWidth - borderWidth); + make.centerY.equalTo(self.contentView); + }]; } if (!_contentLabel) { _contentLabel = [[UITTTAttributedLabel alloc] initWithFrame:CGRectMake(kTaskActivityCell_LeftContentPading, 13, kTaskActivityCell_ContentWidth, 15)]; _contentLabel.numberOfLines = 0; [self.contentView addSubview:_contentLabel]; + [_contentLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.contentView).offset(kTaskActivityCell_LeftContentPading); + make.centerY.equalTo(self.contentView); + make.width.mas_equalTo(kTaskActivityCell_ContentWidth); + }]; } } return self; @@ -67,8 +79,8 @@ - (void)setCurActivity:(ProjectActivity *)curActivity{ } _tipIconView.image = [UIImage imageNamed:tipIconImageName]; NSAttributedString *attrContent = [[self class] attrContentWithObj:_curActivity]; - CGFloat contentHeight = [attrContent boundingRectWithSize:CGSizeMake(kTaskActivityCell_ContentWidth, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin context:nil].size.height; - [self.contentLabel setHeight:contentHeight]; +// CGFloat contentHeight = [attrContent boundingRectWithSize:CGSizeMake(kTaskActivityCell_ContentWidth, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin context:nil].size.height; +// [self.contentLabel setHeight:contentHeight]; self.contentLabel.attributedText = attrContent; } @@ -124,6 +136,8 @@ + (NSAttributedString *)attrContentWithObj:(ProjectActivity *)curActivity{ contentStr = [NSString stringWithFormat:@"%@「%@」 - %@", curActivity.action_msg, curActivity.watcher.name, [curActivity.created_at stringDisplay_HHmm]]; }else if ([curActivity.action isEqualToString:@"remove_watcher"]){ contentStr = [NSString stringWithFormat:@"%@「%@」 - %@", curActivity.action_msg, curActivity.watcher.name, [curActivity.created_at stringDisplay_HHmm]]; + }else if ([curActivity.action isEqualToString:@"add_milestone"] || [curActivity.action isEqualToString:@"remove_milestone"]){ + contentStr = [NSString stringWithFormat:@"%@「%@」 - %@", curActivity.action_msg, curActivity.milestone.name, [curActivity.created_at stringDisplay_HHmm]]; } }else if ([curActivity.target_type isEqualToString:@"MergeRequestBean"]){ contentStr = [NSString stringWithFormat:@"%@ 合并请求「%@」 - %@", curActivity.action_msg, curActivity.merge_request_title, [curActivity.created_at stringDisplay_HHmm]]; @@ -131,10 +145,10 @@ + (NSAttributedString *)attrContentWithObj:(ProjectActivity *)curActivity{ contentStr = contentStr? contentStr: @"..."; attrContent = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@ %@", userName, contentStr]]; [attrContent addAttributes:@{NSFontAttributeName : [UIFont boldSystemFontOfSize:13], - NSForegroundColorAttributeName : kColor222} + NSForegroundColorAttributeName : kColorDark3} range:NSMakeRange(0, userName.length)]; [attrContent addAttributes:@{NSFontAttributeName : [UIFont systemFontOfSize:13], - NSForegroundColorAttributeName : kColor999} + NSForegroundColorAttributeName : kColorDark7} range:NSMakeRange(userName.length + 1, contentStr.length)]; NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; @@ -152,8 +166,9 @@ + (CGFloat)cellHeightWithObj:(id)obj{ if ([obj isKindOfClass:[ProjectActivity class]]) { NSAttributedString *attrContent = [self attrContentWithObj:obj]; CGFloat contentHeight = [attrContent boundingRectWithSize:CGSizeMake(kTaskActivityCell_ContentWidth, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin context:nil].size.height; - cellHeight = ceilf(contentHeight + 26); - cellHeight = MAX(44, cellHeight); + contentHeight = MAX(contentHeight, kTaskActivityCell_IconWidth); + + cellHeight = contentHeight + 16; } return cellHeight; } diff --git a/Coding_iOS/Views/Cell/TaskCommentCell.m b/Coding_iOS/Views/Cell/TaskCommentCell.m index 9c76698df..a76dcc045 100755 --- a/Coding_iOS/Views/Cell/TaskCommentCell.m +++ b/Coding_iOS/Views/Cell/TaskCommentCell.m @@ -7,9 +7,8 @@ // #define kTaskCommentCell_FontContent [UIFont systemFontOfSize:15] -#define kTaskCommentCell_LeftPading 30.0 -#define kTaskCommentCell_LeftContentPading (kTaskCommentCell_LeftPading + 40) -#define kTaskCommentCell_ContentWidth (kScreen_Width - kTaskCommentCell_LeftContentPading - kTaskCommentCell_LeftPading) +#define kTaskCommentCell_LeftContentPading (30 + 15 * 2 + 15) +#define kTaskCommentCell_ContentWidth (kScreen_Width - kTaskCommentCell_LeftContentPading - 15 * 2) #import "TaskCommentCell.h" #import "UICustomCollectionView.h" @@ -34,7 +33,6 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (self) { // Initialization code self.selectionStyle = UITableViewCellSelectionStyleNone; - CGFloat curBottomY = 15; if (!_contentBGView) { _contentBGView = [UIImageView new]; _contentBGView.image = [[UIImage imageNamed:@"comment_bg"] resizableImageWithCapInsets:UIEdgeInsetsMake(35, 15, 5, 5)]; @@ -49,24 +47,23 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (!_ownerIconView) { CGFloat borderWidth = 2; - UIView *bgView = [[UIView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth - borderWidth, curBottomY, 28+ 2*borderWidth, 28 + 2*borderWidth)]; + UIView *bgView = [[UIView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth - borderWidth, 12, 33+ 2*borderWidth, 33 + 2*borderWidth)]; bgView.backgroundColor = kColorTableBG; - _ownerIconView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 28, 28)]; + _ownerIconView = [[YLImageView alloc] initWithFrame:CGRectMake(0, 0, 33, 33)]; _ownerIconView.layer.masksToBounds = YES; _ownerIconView.layer.cornerRadius = _ownerIconView.frame.size.width/2; [bgView addSubview:_ownerIconView]; [_ownerIconView mas_makeConstraints:^(MASConstraintMaker *make) { - make.width.height.mas_equalTo(28.0); + make.width.height.mas_equalTo(33.0); make.center.equalTo(bgView); }]; - [self.contentView addSubview:bgView]; } if (!_contentLabel) { - _contentLabel = [[UITTTAttributedLabel alloc] initWithFrame:CGRectMake(kTaskCommentCell_LeftContentPading, curBottomY, kTaskCommentCell_ContentWidth, 30)]; - _contentLabel.textColor = kColor222; + _contentLabel = [[UITTTAttributedLabel alloc] initWithFrame:CGRectMake(kTaskCommentCell_LeftContentPading, 7 + 15, kTaskCommentCell_ContentWidth, 30)]; + _contentLabel.textColor = kColorDark4; _contentLabel.font = kTaskCommentCell_FontContent; _contentLabel.linkAttributes = kLinkAttributes; _contentLabel.activeLinkAttributes = kLinkAttributesActive; @@ -75,7 +72,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus } if (!_timeLabel) { _timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(kTaskCommentCell_LeftContentPading, 0, kTaskCommentCell_ContentWidth, 20)]; - _timeLabel.textColor = kColor999; + _timeLabel.textColor = kColorDark7; _timeLabel.font = [UIFont systemFontOfSize:12]; [self.contentView addSubview:_timeLabel]; } @@ -93,19 +90,20 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus } } [_contentBGView mas_makeConstraints:^(MASConstraintMaker *make) { - make.edges.equalTo(self.contentView).insets(UIEdgeInsetsMake(5, 60- 7, 5, 20)); + make.edges.equalTo(self.contentView).insets(UIEdgeInsetsMake(7, 33 + 15* 2 - 9, 7, 15)); }]; if (!_detailBtn) { - _detailBtn = [UIButton buttonWithTitle:@"查看详情" titleColor:kColorBrandGreen]; + _detailBtn = [UIButton buttonWithTitle:@"查看详情" titleColor:kColorBrandBlue]; _detailBtn.titleLabel.font = [UIFont systemFontOfSize:12]; [_detailBtn addTarget:self action:@selector(goToDetail) forControlEvents:UIControlEventTouchUpInside]; [self.contentView addSubview:_detailBtn]; [_detailBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.size.mas_equalTo(CGSizeMake(60, 30)); make.right.equalTo(_contentBGView).offset(-10); - make.bottom.equalTo(_contentBGView).offset(-5); + make.centerY.equalTo(_timeLabel); }]; } + _timeLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; } return self; } @@ -121,7 +119,6 @@ - (void)setCurComment:(TaskComment *)curComment{ return; } _detailBtn.hidden = ![self.curComment.htmlMedia needToShowDetail]; - CGFloat curBottomY = 15; [_ownerIconView sd_setImageWithURL:[_curComment.owner.avatar urlImageWithCodePathResizeToView:_ownerIconView] placeholderImage:kPlaceholderMonkeyRoundWidth(33.0)]; NSString *contentStr = _curComment.content; @@ -133,20 +130,21 @@ - (void)setCurComment:(TaskComment *)curComment{ } } - curBottomY += [contentStr getHeightWithFont:kTaskCommentCell_FontContent constrainedToSize:CGSizeMake(kTaskCommentCell_ContentWidth, CGFLOAT_MAX)] + 5; + CGFloat curBottomY = CGRectGetMinY(_contentLabel.frame) + [contentStr getHeightWithFont:kTaskCommentCell_FontContent constrainedToSize:CGSizeMake(kTaskCommentCell_ContentWidth, CGFLOAT_MAX)]; NSInteger imagesCount = _curComment.htmlMedia.imageItems.count; if (imagesCount > 0) { + curBottomY += 5; self.imageCollectionView.hidden = NO; [self.imageCollectionView setFrame:CGRectMake(kTaskCommentCell_LeftContentPading, curBottomY, kTaskCommentCell_ContentWidth, [TaskCommentCell imageCollectionViewHeightWithCount:imagesCount])]; [self.imageCollectionView reloadData]; + curBottomY += [TaskCommentCell imageCollectionViewHeightWithCount:imagesCount]; }else{ + curBottomY += 10; self.imageCollectionView.hidden = YES; } - - curBottomY += [TaskCommentCell imageCollectionViewHeightWithCount:imagesCount]; - [_timeLabel setY:curBottomY]; + _timeLabel.width = _detailBtn.hidden? kTaskCommentCell_ContentWidth: kTaskCommentCell_ContentWidth - 60; _timeLabel.text = [NSString stringWithFormat:@"%@ 发布于 %@", _curComment.owner.name, [_curComment.created_at stringDisplay_HHmm]]; } @@ -170,9 +168,17 @@ + (CGFloat)cellHeightWithObj:(id)obj{ || [obj isKindOfClass:[FileComment class]]) { TaskComment *curComment = (TaskComment *)obj; NSString *contentStr = curComment.content; - cellHeight += 10 +[contentStr getHeightWithFont:kTaskCommentCell_FontContent constrainedToSize:CGSizeMake(kTaskCommentCell_ContentWidth, CGFLOAT_MAX)] + 5 +20 +10; - cellHeight += [self imageCollectionViewHeightWithCount:curComment.htmlMedia.imageItems.count]; - cellHeight += 10; + cellHeight += 7 + 15 +[contentStr getHeightWithFont:kTaskCommentCell_FontContent constrainedToSize:CGSizeMake(kTaskCommentCell_ContentWidth, CGFLOAT_MAX)]; + if (curComment.htmlMedia.imageItems.count > 0) { + cellHeight += 5 + [self imageCollectionViewHeightWithCount:curComment.htmlMedia.imageItems.count]; + }else{ + cellHeight += 10; + } + cellHeight += 20; + cellHeight += 15 + 7; +// + 5 +20 +10; +// cellHeight += [self imageCollectionViewHeightWithCount:curComment.htmlMedia.imageItems.count]; +// cellHeight += 20; } return cellHeight; } diff --git a/Coding_iOS/Views/Cell/TaskContentCell.m b/Coding_iOS/Views/Cell/TaskContentCell.m index ddbc5b6a7..7b9bfe498 100644 --- a/Coding_iOS/Views/Cell/TaskContentCell.m +++ b/Coding_iOS/Views/Cell/TaskContentCell.m @@ -8,7 +8,7 @@ #define kTaskContentCell_ContentHeightMin kScaleFrom_iPhone5_Desgin(90.0) #define kTextView_Pading 8.0 #define kTaskContentCell_ContentWidth (kScreen_Width-kPaddingLeftWidth-kPaddingLeftWidth + 2*kTextView_Pading) -#define kTaskContentCell_ContentFont [UIFont systemFontOfSize:18] +#define kTaskContentCell_ContentFont [UIFont systemFontOfSize:17] #import "TaskContentCell.h" @@ -21,7 +21,7 @@ @interface TaskContentCell () @property (strong, nonatomic) UITextView *taskContentView; @property (strong, nonatomic) UIButton *deleteBtn; @property (strong, nonatomic) UILabel *creatorLabel, *numLabel; -@property (strong, nonatomic) UIView *downLineView, *upLineView; +//@property (strong, nonatomic) UIView *downLineView, *upLineView; @end @implementation TaskContentCell @@ -32,7 +32,6 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (self) { // Initialization code self.selectionStyle = UITableViewCellSelectionStyleNone; - if (!_tagsView) { _tagsView = [ProjectTagsView viewWithTags:nil]; @weakify(self); @@ -48,83 +47,85 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus }; [self.contentView addSubview:_tagsView]; } - if (!_upLineView) { - _upLineView = [[UIView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 0, kScreen_Width - 2*kPaddingLeftWidth, 0.5)]; - _upLineView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"dot_line"]]; - [self.contentView addSubview:_upLineView]; - } +// if (!_upLineView) { +// _upLineView = [[UIView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 0, kScreen_Width - 2*kPaddingLeftWidth, 0.5)]; +// _upLineView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"dot_line"]]; +// [self.contentView addSubview:_upLineView]; +// } if (!_taskContentView) { _taskContentView = [[UITextView alloc] initWithFrame:CGRectZero]; _taskContentView.backgroundColor = [UIColor clearColor]; _taskContentView.font = kTaskContentCell_ContentFont; _taskContentView.delegate = self; + _taskContentView.textColor = kColorDark3; [self.contentView addSubview:_taskContentView]; } if (!_numLabel) { if (!_numLabel) { _numLabel = [[UILabel alloc] init]; _numLabel.font = [UIFont systemFontOfSize:12]; - _numLabel.textColor = kColor222; + _numLabel.textColor = kColorDark7; [self.contentView addSubview:_numLabel]; } } if (!_creatorLabel) { _creatorLabel = [[UILabel alloc] init]; _creatorLabel.font = [UIFont systemFontOfSize:12]; - _creatorLabel.textColor = kColor999; + _creatorLabel.textColor = kColorDark7; [self.contentView addSubview:_creatorLabel]; } if (!_deleteBtn) { _deleteBtn = ({ UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; - button.titleLabel.font = [UIFont systemFontOfSize:13]; - [button setTitleColor:kColor666 forState:UIControlStateNormal]; + button.titleLabel.font = [UIFont systemFontOfSize:12]; + [button setTitleColor:kColorDark7 forState:UIControlStateNormal]; [button setTitle:@"删除" forState:UIControlStateNormal]; [button addTarget:self action:@selector(deleteBtnClicked:) forControlEvents:UIControlEventTouchUpInside]; [self.contentView addSubview:button]; button; }); } - if (!_downLineView) { - _downLineView = [[UIView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 0, kScreen_Width - 2*kPaddingLeftWidth, 0.5)]; - _downLineView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"dot_line"]]; - [self.contentView addSubview:_downLineView]; - } - [_upLineView mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.equalTo(self.contentView).offset(kPaddingLeftWidth); - make.right.equalTo(self.contentView).offset(-kPaddingLeftWidth); - make.height.mas_equalTo(0.5); - make.bottom.equalTo(_tagsView).offset(5); - }]; +// if (!_downLineView) { +// _downLineView = [[UIView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 0, kScreen_Width - 2*kPaddingLeftWidth, 0.5)]; +// _downLineView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"dot_line"]]; +// [self.contentView addSubview:_downLineView]; +// } +// [_upLineView mas_makeConstraints:^(MASConstraintMaker *make) { +// make.left.equalTo(self.contentView).offset(kPaddingLeftWidth); +// make.right.equalTo(self.contentView).offset(-kPaddingLeftWidth); +// make.height.mas_equalTo(0.5); +// make.bottom.equalTo(_tagsView).offset(7); +// }]; [_taskContentView mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(_upLineView.mas_bottom).offset(5.0); + make.top.equalTo(_tagsView.mas_bottom).offset(7); +// make.top.equalTo(_upLineView.mas_bottom).offset(5.0); make.left.equalTo(self.contentView).offset(kPaddingLeftWidth-kTextView_Pading); make.right.equalTo(self.contentView).offset(-(kPaddingLeftWidth-kTextView_Pading)); make.height.mas_equalTo(kTaskContentCell_ContentHeightMin); }]; [_numLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.contentView.mas_left).offset(kPaddingLeftWidth); - make.bottom.equalTo(self.contentView.mas_bottom).offset(-10); + make.bottom.equalTo(self.contentView.mas_bottom).offset(0); make.height.mas_equalTo(20); }]; [_creatorLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.numLabel.mas_right); make.right.lessThanOrEqualTo(_deleteBtn.mas_left).offset(10); - make.bottom.equalTo(self.contentView.mas_bottom).offset(-10); + make.bottom.equalTo(self.contentView.mas_bottom).offset(0); make.height.mas_equalTo(20); }]; [_deleteBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.size.mas_equalTo(CGSizeMake(44, 20)); - make.bottom.equalTo(self.contentView.mas_bottom).offset(-10); + make.bottom.equalTo(self.contentView.mas_bottom).offset(0); make.right.equalTo(self.contentView.mas_right).offset(-kPaddingLeftWidth); }]; - [_downLineView mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.equalTo(self.contentView).offset(kPaddingLeftWidth); - make.right.equalTo(self.contentView).offset(-kPaddingLeftWidth); - make.height.mas_equalTo(0.5); - make.bottom.equalTo(self.contentView); - }]; +// [_downLineView mas_makeConstraints:^(MASConstraintMaker *make) { +// make.left.equalTo(self.contentView).offset(kPaddingLeftWidth); +// make.right.equalTo(self.contentView).offset(-kPaddingLeftWidth); +// make.height.mas_equalTo(0.5); +// make.bottom.equalTo(self.contentView); +// }]; } return self; } @@ -136,7 +137,7 @@ - (void)layoutSubviews{ } _tagsView.tags = _task.labels; [_tagsView mas_remakeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(self.contentView).offset(10); + make.top.equalTo(self.contentView).offset(15); make.left.right.equalTo(self.contentView); make.height.mas_equalTo([ProjectTagsView getHeightForTags:self.task.labels]); }]; @@ -187,9 +188,9 @@ + (CGFloat)cellHeightWithObj:(id)obj{ CGFloat cellHeight = 0; if ([obj isKindOfClass:[Task class]]) { Task *task = (Task *)obj; - cellHeight += 10; + cellHeight += 15; cellHeight += [ProjectTagsView getHeightForTags:task.labels]; - cellHeight += 10 + kTaskContentCell_ContentHeightMin + 40; + cellHeight += 7+ kTaskContentCell_ContentHeightMin + 7 + 20; } return cellHeight; } diff --git a/Coding_iOS/Views/Cell/TaskDescriptionCell.m b/Coding_iOS/Views/Cell/TaskDescriptionCell.m index 1de25a147..707e7f500 100644 --- a/Coding_iOS/Views/Cell/TaskDescriptionCell.m +++ b/Coding_iOS/Views/Cell/TaskDescriptionCell.m @@ -21,8 +21,8 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus self.selectionStyle = UITableViewCellSelectionStyleNone; if (!_button) { - _button = [[UIButton alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, ([[self class] cellHeight] - 30)/2, kScreen_Width - 2*kPaddingLeftWidth, 30)]; - _button.titleLabel.font = [UIFont systemFontOfSize:16]; + _button = [[UIButton alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, ([[self class] cellHeight] - 36)/2, kScreen_Width - 2*kPaddingLeftWidth, 36)]; + _button.titleLabel.font = [UIFont systemFontOfSize:14]; _button.backgroundColor = kColorTableSectionBg; _button.layer.masksToBounds = YES; _button.layer.cornerRadius = 2.0; @@ -39,8 +39,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus - (void)setTitleStr:(NSString *)title andSpecail:(BOOL)isSpecail{ [_button setTitle:title forState:UIControlStateNormal]; - [_button setTitleColor:[UIColor colorWithHexString:isSpecail? @"0x3bbd79": @"0x222222"] forState:UIControlStateNormal]; - + [_button setTitleColor:isSpecail? kColorBrandBlue: kColorDark4 forState:UIControlStateNormal]; } - (void)buttonClicked:(id)sender{ @@ -50,6 +49,6 @@ - (void)buttonClicked:(id)sender{ } + (CGFloat)cellHeight{ - return 54.0; + return 66.0; } @end diff --git a/Coding_iOS/Views/Cell/TaskResourceReferenceCell.m b/Coding_iOS/Views/Cell/TaskResourceReferenceCell.m index 0ba93c798..118bd1424 100644 --- a/Coding_iOS/Views/Cell/TaskResourceReferenceCell.m +++ b/Coding_iOS/Views/Cell/TaskResourceReferenceCell.m @@ -28,7 +28,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (!_codeL) { _codeL = ({ UILabel *label = [UILabel new]; - label.textColor = kColorBrandGreen; + label.textColor = kColorBrandBlue; label.font = [UIFont systemFontOfSize:15]; label; }); @@ -66,7 +66,7 @@ - (void)setItem:(ResourceReferenceItem *)item{ if (!_item) { return; } - [_imgView setImage:[UIImage imageNamed:[NSString stringWithFormat:@"task_resource_reference_%@", _item.target_type]]]; + [_imgView setImage:[UIImage imageNamed:[NSString stringWithFormat:@"task_resource_reference_%@", _item.target_type]] ?: [UIImage imageNamed:@"task_resource_reference_ProjectFile"]]; _codeL.text = [NSString stringWithFormat:@"# %@ ", _item.code.stringValue]; _titleL.text = _item.title; } diff --git a/Coding_iOS/Views/Cell/TaskSearchCell.m b/Coding_iOS/Views/Cell/TaskSearchCell.m index 7a0835a08..b6dc2b778 100644 --- a/Coding_iOS/Views/Cell/TaskSearchCell.m +++ b/Coding_iOS/Views/Cell/TaskSearchCell.m @@ -40,7 +40,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus // Initialization code self.selectionStyle = UITableViewCellSelectionStyleNone; if (!_userIconView) { - _userIconView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, kProjectTaskListViewCell_UserIconWidth, kProjectTaskListViewCell_UserIconWidth)]; + _userIconView = [[YLImageView alloc] initWithFrame:CGRectMake(0, 0, kProjectTaskListViewCell_UserIconWidth, kProjectTaskListViewCell_UserIconWidth)]; [_userIconView doCircleFrame]; [self.contentView addSubview:_userIconView]; } diff --git a/Coding_iOS/Views/Cell/TaskSelectionCell.h b/Coding_iOS/Views/Cell/TaskSelectionCell.h new file mode 100644 index 000000000..367b4116f --- /dev/null +++ b/Coding_iOS/Views/Cell/TaskSelectionCell.h @@ -0,0 +1,18 @@ +// +// TaskSelectionCell.h +// Coding_iOS +// +// Created by 张达棣 on 16/12/7. +// Copyright © 2016年 Coding. All rights reserved. +// + +#import +#define kCellIdentifier_TaskSelectionCell @"TaskSelectionCell" + +@interface TaskSelectionCell : UITableViewCell +@property (nonatomic, strong) NSString *title; +@property (nonatomic, assign) BOOL isSel; +@property (nonatomic, assign) BOOL isShowLine; +@property (nonatomic, strong) UIImageView *selImageView; + +@end diff --git a/Coding_iOS/Views/Cell/TaskSelectionCell.m b/Coding_iOS/Views/Cell/TaskSelectionCell.m new file mode 100644 index 000000000..4f37654ce --- /dev/null +++ b/Coding_iOS/Views/Cell/TaskSelectionCell.m @@ -0,0 +1,78 @@ +// +// TaskSelectionCell.m +// Coding_iOS +// +// Created by 张达棣 on 16/12/7. +// Copyright © 2016年 Coding. All rights reserved. +// + +#import "TaskSelectionCell.h" + +@interface TaskSelectionCell () +@property (nonatomic, strong) UILabel *titleLab; +@property (nonatomic, strong) UILabel *line; +@end + +@implementation TaskSelectionCell + +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + [self creatView]; + } + return self; +} + +- (void)awakeFromNib { + [super awakeFromNib]; + // Initialization code +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated { + [super setSelected:selected animated:animated]; + + // Configure the view for the selected state +} + +- (void)creatView { + + [self.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; + self.backgroundColor=[UIColor clearColor]; + _titleLab = [[UILabel alloc] initWithFrame:CGRectMake(20, 0, 200, 50)]; + _titleLab.font=[UIFont systemFontOfSize:15]; + [self.contentView addSubview:_titleLab]; + _titleLab.sd_layout.leftSpaceToView(self.contentView, 20).topSpaceToView(self.contentView, 15).bottomSpaceToView(self.contentView, 15).widthIs(200); + + _selImageView = [[UIImageView alloc] init]; + _selImageView.image = [UIImage imageNamed:@"task_filter_checkIcon"]; + [self.contentView addSubview:_selImageView]; + _selImageView.hidden = YES; + _selImageView.sd_layout.rightSpaceToView(self.contentView, 20).centerYEqualToView(self.contentView).widthIs(20).heightIs(21); + + _line = [[UILabel alloc] init]; + _line.backgroundColor = kColorDDD; + [self.contentView addSubview:_line]; + _line.sd_layout.leftSpaceToView(self.contentView, 0).rightSpaceToView(self.contentView, 0).bottomSpaceToView(self.contentView, 0).heightIs(.5); + _line.hidden = YES; + +} + +- (void)setIsSel:(BOOL)isSel { + _titleLab.textColor=isSel?kColorLightBlue:kColor222; +// _selImageView.hidden = !isSel; + _selImageView.hidden = YES; + self.accessoryType = isSel? UITableViewCellAccessoryCheckmark: UITableViewCellAccessoryNone; +} + +- (void)setTitle:(NSString *)title { + _title = title; + _titleLab.text= title; + +} + +- (void)setIsShowLine:(BOOL)isShowLine { + _isShowLine = isShowLine; + _line.hidden = !isShowLine; +} + +@end diff --git a/Coding_iOS/Views/Cell/TeamListCell.m b/Coding_iOS/Views/Cell/TeamListCell.m index b0f876d4e..a1c3f4068 100644 --- a/Coding_iOS/Views/Cell/TeamListCell.m +++ b/Coding_iOS/Views/Cell/TeamListCell.m @@ -19,7 +19,7 @@ - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSStr self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { self.backgroundColor = kColorTableBG; - _iconV = [UIImageView new]; + _iconV = [YLImageView new]; [_iconV doBorderWidth:.5 color:nil cornerRadius:2.0]; _nameL = [UILabel labelWithSystemFontSize:15 textColorHexString:@"0x323A45"]; _proL = [UILabel labelWithSystemFontSize:14 textColorHexString:@"0x4F565F"]; diff --git a/Coding_iOS/Views/Cell/TeamMemberCell.m b/Coding_iOS/Views/Cell/TeamMemberCell.m index 14fa2d7ae..34386fb16 100644 --- a/Coding_iOS/Views/Cell/TeamMemberCell.m +++ b/Coding_iOS/Views/Cell/TeamMemberCell.m @@ -6,11 +6,14 @@ // Copyright © 2016年 Coding. All rights reserved. // +#define kTeamMemberCell_IconWidth 34.0 + #import "TeamMemberCell.h" @interface TeamMemberCell () @property (strong, nonatomic) UIImageView *iconV, *roleV; -@property (strong, nonatomic) UILabel *nameL; +@property (strong, nonatomic) UILabel *nameL, *timeL; +@property (nonatomic, strong) UIButton *sliderBtn; @end @implementation TeamMemberCell @@ -18,26 +21,46 @@ - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSStr self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { self.backgroundColor = kColorTableBG; - _iconV = [UIImageView new]; - [_iconV doBorderWidth:.5 color:nil cornerRadius:20]; + _iconV = [YLImageView new]; + [_iconV doBorderWidth:.5 color:nil cornerRadius:kTeamMemberCell_IconWidth/2]; _roleV = [UIImageView new]; _nameL = [UILabel labelWithSystemFontSize:17 textColorHexString:@"0x222222"]; + _timeL = [UILabel labelWithSystemFontSize:12 textColorHexString:@"0x999999"]; [self.contentView addSubview:_iconV]; [self.contentView addSubview:_roleV]; [self.contentView addSubview:_nameL]; + [self.contentView addSubview:_timeL]; [_iconV mas_makeConstraints:^(MASConstraintMaker *make) { - make.centerY.equalTo(@[self.contentView, _nameL, _roleV]); + make.centerY.equalTo(self.contentView); make.left.equalTo(self.contentView).offset(kPaddingLeftWidth); - make.size.mas_equalTo(CGSizeMake(40, 40)); + make.size.mas_equalTo(CGSizeMake(kTeamMemberCell_IconWidth, kTeamMemberCell_IconWidth)); }]; [_nameL mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.contentView).offset(15); + make.centerY.equalTo(_roleV); make.left.equalTo(_iconV.mas_right).offset(10); make.right.equalTo(_roleV.mas_left).offset(-10); }]; [_roleV mas_makeConstraints:^(MASConstraintMaker *make) { make.right.lessThanOrEqualTo(self.contentView).offset(-kPaddingLeftWidth); }]; + [_timeL mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(_nameL); + make.bottom.equalTo(self.contentView).offset(-15); + }]; + if (!_sliderBtn) { + _sliderBtn = [UIButton new]; + //for test + [_sliderBtn setImage:[UIImage imageNamed:@"btn_setFrequent"] forState:UIControlStateNormal]; + [self.contentView addSubview:_sliderBtn]; + [_sliderBtn addTarget:self action:@selector(showSliderAction) forControlEvents:UIControlEventTouchUpInside]; + [_sliderBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.size.mas_equalTo(CGSizeMake(40, 40)); + make.right.equalTo(self.contentView); + make.bottom.equalTo(self.contentView).offset(5); + }]; + } } return self; } @@ -47,15 +70,21 @@ - (void)setCurMember:(TeamMember *)curMember{ if (!_curMember) { return; } - [_iconV sd_setImageWithURL:[_curMember.user.avatar urlImageWithCodePathResize:40 * 2]]; + [_iconV sd_setImageWithURL:[_curMember.user.avatar urlImageWithCodePathResize:kTeamMemberCell_IconWidth * 2]]; _nameL.text = _curMember.user.name; UIImage *roleImage = [UIImage imageNamed:[NSString stringWithFormat:@"member_type_%@", _curMember.role.stringValue]]; _roleV.image = roleImage; _roleV.hidden = !roleImage; + + _timeL.text = [NSString stringWithFormat:@"加入时间:%@", [_curMember.created_at stringWithFormat:@"yyyy-MM-dd HH:mm"]]; +} + +-(void)showSliderAction{ + [self showRightUtilityButtonsAnimated:YES]; } + (CGFloat)cellHeight{ - return 60; + return 75; } @end diff --git a/Coding_iOS/Views/Cell/TeamPurchaseBillingCell.h b/Coding_iOS/Views/Cell/TeamPurchaseBillingCell.h new file mode 100644 index 000000000..6aa9c8458 --- /dev/null +++ b/Coding_iOS/Views/Cell/TeamPurchaseBillingCell.h @@ -0,0 +1,18 @@ +// +// TeamPurchaseBillingCell.h +// Coding_Enterprise_iOS +// +// Created by Ease on 2017/3/7. +// Copyright © 2017年 Coding. All rights reserved. +// +#define kCellIdentifier_TeamPurchaseBillingCell @"TeamPurchaseBillingCell" + +#import +#import "TeamPurchaseBilling.h" + +@interface TeamPurchaseBillingCell : UITableViewCell +@property (strong, nonatomic) TeamPurchaseBilling *curBilling; +@property (copy, nonatomic) void (^expandBlock)(TeamPurchaseBilling *curBilling); + ++ (CGFloat)cellHeightWithObj:(id)obj; +@end diff --git a/Coding_iOS/Views/Cell/TeamPurchaseBillingCell.m b/Coding_iOS/Views/Cell/TeamPurchaseBillingCell.m new file mode 100644 index 000000000..fe6795690 --- /dev/null +++ b/Coding_iOS/Views/Cell/TeamPurchaseBillingCell.m @@ -0,0 +1,158 @@ +// +// TeamPurchaseBillingCell.m +// Coding_Enterprise_iOS +// +// Created by Ease on 2017/3/7. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "TeamPurchaseBillingCell.h" + +@interface TeamPurchaseBillingCell () +@property (strong, nonatomic) UILabel *createAtL, *statusL; +@property (strong, nonatomic) UILabel *useageT, *priceT, *priceV, *balanceT, *balanceV; +@property (strong, nonatomic) NSMutableArray *detailsL; +@property (strong, nonatomic) UIButton *expandBtn; +@end + +@implementation TeamPurchaseBillingCell + +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + self.selectionStyle = UITableViewCellSelectionStyleNone; + _createAtL = [UILabel labelWithFont:[UIFont systemFontOfSize:15] textColor:kColorDark3]; + _statusL = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDarkA]; + _useageT = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDark7]; + _priceT = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDark7]; + _priceV = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDark3]; + _balanceT = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDark7]; + _balanceV = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDark3]; + _expandBtn = [UIButton new]; + [self.contentView addSubview:_createAtL]; + [self.contentView addSubview:_statusL]; + [self.contentView addSubview:_useageT]; + [self.contentView addSubview:_priceT]; + [self.contentView addSubview:_priceV]; + [self.contentView addSubview:_balanceT]; + [self.contentView addSubview:_balanceV]; + [self.contentView addSubview:_expandBtn]; + UIView *lineV = ({ + UIView *view = [UIView new]; + view.backgroundColor = kColorDarkD; + [self.contentView addSubview:view]; + view; + }); + UIView *bottomV = ({ + UIView *view = [UIView new]; + view.backgroundColor = kColorDarkF; + [self.contentView addSubview:view]; + view; + }); + CGFloat labelW = 240; + CGFloat pointX = kScreen_Width - kPaddingLeftWidth - labelW; + _createAtL.frame = CGRectMake(kPaddingLeftWidth, 10, labelW, 20); + _statusL.frame = CGRectMake(pointX, 10, labelW, 20); + _useageT.frame = CGRectMake(kPaddingLeftWidth, 50, labelW, 20); + lineV.frame = CGRectMake(kPaddingLeftWidth, 40, kScreen_Width, 1.0/[UIScreen mainScreen].scale); + bottomV.frame = CGRectMake(0, 140, kScreen_Width, 10); + [bottomV addLineUp:YES andDown:NO]; + + [bottomV mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.bottom.equalTo(self.contentView); + make.height.mas_equalTo(10); + }]; + [_balanceT mas_makeConstraints:^(MASConstraintMaker *make) { + make.bottom.equalTo(bottomV.mas_top).offset(-10); + make.left.equalTo(self.contentView).offset(kPaddingLeftWidth); + make.height.mas_equalTo(20); + }]; + [_balanceV mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.height.equalTo(_balanceT); + make.right.equalTo(self.contentView).offset(-kPaddingLeftWidth); + }]; + [_priceT mas_makeConstraints:^(MASConstraintMaker *make) { + make.bottom.equalTo(_balanceT.mas_top).offset(-10); + make.left.equalTo(self.contentView).offset(kPaddingLeftWidth); + make.height.mas_equalTo(20); + }]; + [_priceV mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.height.equalTo(_priceT); + make.right.equalTo(self.contentView).offset(-kPaddingLeftWidth); + }]; + [_expandBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.bottom.equalTo(_priceV.mas_top).offset(-10); + make.right.equalTo(self.contentView).offset(-kPaddingLeftWidth); + make.size.mas_equalTo(CGSizeMake(200, 20)); + }]; + + _statusL.textAlignment = NSTextAlignmentRight; + _priceV.textAlignment = NSTextAlignmentRight; + _balanceV.textAlignment = NSTextAlignmentRight; + +// _useageT.text = @"使用情况"; +// _priceT.text = @"结算金额"; +// _balanceT.text = @"剩余金额"; + + _useageT.text = @"当日使用情况"; + _priceT.text = @"扣款时间"; + _balanceT.text = @"扣款金额"; + + _detailsL = @[].mutableCopy; + + [_expandBtn setTitleColor:kColorLightBlue forState:UIControlStateNormal]; + _expandBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight; + _expandBtn.titleLabel.font = [UIFont systemFontOfSize:14]; + [_expandBtn setTitle:@"查看全部" forState:UIControlStateNormal]; + __weak typeof(self) weakSelf = self; + [_expandBtn bk_addEventHandler:^(id sender) { + if (weakSelf.expandBlock) { + weakSelf.expandBlock(weakSelf.curBilling); + } + } forControlEvents:UIControlEventTouchUpInside]; + } + return self; +} + +- (void)setCurBilling:(TeamPurchaseBilling *)curBilling{ + _curBilling = curBilling; + +// _createAtL.text = [_curBilling.created_at stringWithFormat:@"MM 月(结算日:yyyy.MM.dd)"]; +// _statusL.text = @"已结算";//To Dooooooooooo +// _priceV.text = [NSString stringWithFormat:@"¥ %@", _curBilling.price]; +// _balanceV.text = [NSString stringWithFormat:@"¥ %@", _curBilling.balance]; + + _createAtL.text = [_curBilling.billing_date stringWithFormat:@"结算日:yyyy.MM.dd"]; + _statusL.hidden = YES; + _priceV.text = [_curBilling.created_at stringWithFormat:@"yyyy.MM.dd HH:mm"]; + _balanceV.text = [NSString stringWithFormat:@"¥ %@", _curBilling.price]; + + [_detailsL makeObjectsPerformSelector:@selector(removeFromSuperview)]; + [_detailsL removeAllObjects]; + NSInteger detailNum = _curBilling.isExpanded? _curBilling.details_display.count: MIN(_curBilling.details_display.count, 2); + for (NSInteger index = 0; index < detailNum; index++) { + [self addIndex:index detail:_curBilling.details_display[index]]; + } + _expandBtn.hidden = (_curBilling.details_display.count <= detailNum); +} + +- (void)addIndex:(NSInteger)index detail:(NSString *)detail_display{ + UILabel *detailL = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDark3]; + detailL.frame = CGRectMake(kScreen_Width - kPaddingLeftWidth - 200, 50 + (30 * index), 200, 20); + detailL.textAlignment = NSTextAlignmentRight; + detailL.text = detail_display; + [_detailsL addObject:detailL]; + [self.contentView addSubview:detailL]; +} + ++ (CGFloat)cellHeightWithObj:(id)obj{ + if ([obj isKindOfClass:[TeamPurchaseBilling class]]) { + TeamPurchaseBilling *billing = (TeamPurchaseBilling *)obj; + NSInteger detailNum = billing.isExpanded? billing.details_display.count: MIN(billing.details_display.count, 3); + CGFloat cellHeight = 150; + cellHeight += 30 * (detailNum - 1); + return cellHeight; + } + return 0; +} +@end diff --git a/Coding_iOS/Views/Cell/TeamPurchaseOrderCell.h b/Coding_iOS/Views/Cell/TeamPurchaseOrderCell.h new file mode 100644 index 000000000..5328815fa --- /dev/null +++ b/Coding_iOS/Views/Cell/TeamPurchaseOrderCell.h @@ -0,0 +1,17 @@ +// +// TeamPurchaseOrderCell.h +// Coding_Enterprise_iOS +// +// Created by Ease on 2017/3/7. +// Copyright © 2017年 Coding. All rights reserved. +// +#define kCellIdentifier_TeamPurchaseOrderCell @"TeamPurchaseOrderCell" + +#import +#import "TeamPurchaseOrder.h" + +@interface TeamPurchaseOrderCell : UITableViewCell +@property (strong, nonatomic) TeamPurchaseOrder *curOrder; + ++ (CGFloat)cellHeight; +@end diff --git a/Coding_iOS/Views/Cell/TeamPurchaseOrderCell.m b/Coding_iOS/Views/Cell/TeamPurchaseOrderCell.m new file mode 100644 index 000000000..db88af4a4 --- /dev/null +++ b/Coding_iOS/Views/Cell/TeamPurchaseOrderCell.m @@ -0,0 +1,97 @@ +// +// TeamPurchaseOrderCell.m +// Coding_Enterprise_iOS +// +// Created by Ease on 2017/3/7. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "TeamPurchaseOrderCell.h" + +@interface TeamPurchaseOrderCell () +@property (strong, nonatomic) UILabel *priceL, *statusL; +@property (strong, nonatomic) UILabel *numT, *numV, *creatorT, *creatorV, *timeT, *timeV; +@end + +@implementation TeamPurchaseOrderCell + +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + self.selectionStyle = UITableViewCellSelectionStyleNone; + _priceL = [UILabel labelWithFont:[UIFont systemFontOfSize:15] textColor:kColorDark3]; + _statusL = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDarkA]; + _numT = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDark7]; + _numV = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDark3]; + _creatorT = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDark7]; + _creatorV = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDark3]; + _timeT = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDark7]; + _timeV = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDark3]; + [self.contentView addSubview:_priceL]; + [self.contentView addSubview:_statusL]; + [self.contentView addSubview:_numT]; + [self.contentView addSubview:_numV]; + [self.contentView addSubview:_creatorT]; + [self.contentView addSubview:_creatorV]; + [self.contentView addSubview:_timeT]; + [self.contentView addSubview:_timeV]; + UIView *lineV = ({ + UIView *view = [UIView new]; + view.backgroundColor = kColorDarkD; + [self.contentView addSubview:view]; + view; + }); + UIView *bottomV = ({ + UIView *view = [UIView new]; + view.backgroundColor = kColorDarkF; + [self.contentView addSubview:view]; + view; + }); + CGFloat labelW = 200; + CGFloat pointX = kScreen_Width - kPaddingLeftWidth - labelW; + _priceL.frame = CGRectMake(kPaddingLeftWidth, 10, labelW, 20); + _statusL.frame = CGRectMake(pointX, 10, labelW, 20); + _numT.frame = CGRectMake(kPaddingLeftWidth, 50, labelW, 20); + _numV.frame = CGRectMake(pointX, 50, labelW, 20); + _creatorT.frame = CGRectMake(kPaddingLeftWidth, 80, labelW, 20); + _creatorV.frame = CGRectMake(pointX, 80, labelW, 20); + _timeT.frame = CGRectMake(kPaddingLeftWidth, 110, labelW, 20); + _timeV.frame = CGRectMake(pointX, 110, labelW, 20); + lineV.frame = CGRectMake(kPaddingLeftWidth, 40, kScreen_Width, 1.0/[UIScreen mainScreen].scale); + bottomV.frame = CGRectMake(0, 140, kScreen_Width, 10); + + [bottomV addLineUp:YES andDown:NO]; + _statusL.textAlignment = NSTextAlignmentRight; + _numV.textAlignment = NSTextAlignmentRight; + _creatorV.textAlignment = NSTextAlignmentRight; + _timeV.textAlignment = NSTextAlignmentRight; + + _numT.text = @"订单编号"; + _creatorT.text = @"创建者"; + _timeT.text = @"创建时间"; + } + return self; +} + +- (void)setCurOrder:(TeamPurchaseOrder *)curOrder{ + NSDictionary *statusDisplayDict = @{@"pending": @"等待支付", + @"success": @"成功", + @"closed": @"关闭", + }; + NSDictionary *statusColorDict = @{@"pending": @"0xF78636", + @"success": @"0x5BA2FF", + @"closed": @"0xA9B3BE", + }; + _curOrder = curOrder; + _priceL.text = [NSString stringWithFormat:@"充值 %@ 元", _curOrder.price]; + _statusL.textColor = [UIColor colorWithHexString:statusColorDict[_curOrder.status]]; + _statusL.text = statusDisplayDict[_curOrder.status]; + _numV.text = _curOrder.number; + _creatorV.text = _curOrder.creator_name; + _timeV.text = [_curOrder.created_at stringWithFormat:@"yyyy.MM.dd HH:mm"]; +} + ++ (CGFloat)cellHeight{ + return 150; +} +@end diff --git a/Coding_iOS/Views/Cell/TeamPurchaseTopCell.h b/Coding_iOS/Views/Cell/TeamPurchaseTopCell.h new file mode 100644 index 000000000..ab21d93d1 --- /dev/null +++ b/Coding_iOS/Views/Cell/TeamPurchaseTopCell.h @@ -0,0 +1,18 @@ +// +// TeamPurchaseTopCell.h +// Coding_Enterprise_iOS +// +// Created by Ease on 2017/3/7. +// Copyright © 2017年 Coding. All rights reserved. +// +#define kCellIdentifier_TeamPurchaseTopCell @"TeamPurchaseTopCell" + +#import +#import "Team.h" + +@interface TeamPurchaseTopCell : UITableViewCell +@property (strong, nonatomic) Team *curTeam; +@property (copy, nonatomic) void (^closeWebTipBlock)(); + ++ (CGFloat)cellHeightWithObj:(id)obj; +@end diff --git a/Coding_iOS/Views/Cell/TeamPurchaseTopCell.m b/Coding_iOS/Views/Cell/TeamPurchaseTopCell.m new file mode 100644 index 000000000..e495a6b39 --- /dev/null +++ b/Coding_iOS/Views/Cell/TeamPurchaseTopCell.m @@ -0,0 +1,191 @@ +// +// TeamPurchaseTopCell.m +// Coding_Enterprise_iOS +// +// Created by Ease on 2017/3/7. +// Copyright © 2017年 Coding. All rights reserved. +// +#import "TeamPurchaseTopCell.h" + +@interface TeamPurchaseTopCell () +@property (strong, nonatomic) UILabel *tipL, *priceT, *priceV, *leftDayL; + +@property (strong, nonatomic) UIView *toWebV; +@property (strong, nonatomic) UILabel *toWebL; +@property (strong, nonatomic) UIButton *toWebB; +@end + +@implementation TeamPurchaseTopCell + +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + self.selectionStyle = UITableViewCellSelectionStyleNone; + + _tipL = [UILabel labelWithFont:[UIFont systemFontOfSize:15] textColor:kColorActionRed]; + _priceT = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDark3]; + _priceV = [UILabel labelWithFont:[UIFont systemFontOfSize:30 weight:UIFontWeightMedium] textColor:kColorActionRed]; + _leftDayL = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDark7]; + _tipL.adjustsFontSizeToFitWidth = _leftDayL.adjustsFontSizeToFitWidth = YES; + _tipL.minimumScaleFactor = _leftDayL.minimumScaleFactor = 0.5; + [self.contentView addSubview:_tipL]; + [self.contentView addSubview:_priceT]; + [self.contentView addSubview:_priceV]; + [self.contentView addSubview:_leftDayL]; + + [_leftDayL mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.contentView).offset(kPaddingLeftWidth); + make.right.equalTo(self.contentView).offset(-kPaddingLeftWidth); + make.bottom.equalTo(self.contentView).offset(-kPaddingLeftWidth); + make.bottom.equalTo(self.contentView); + }]; + [_priceV mas_makeConstraints:^(MASConstraintMaker *make) { + make.bottom.mas_equalTo(_leftDayL.mas_top).offset(-10); + make.height.mas_equalTo(42); + make.left.equalTo(self.contentView).offset(kPaddingLeftWidth); + }]; + [_priceT mas_makeConstraints:^(MASConstraintMaker *make) { + make.bottom.equalTo(_priceV.mas_top).offset(-10); + make.height.mas_equalTo(20); + make.left.equalTo(self.contentView).offset(kPaddingLeftWidth); + }]; + [_tipL mas_makeConstraints:^(MASConstraintMaker *make) { + make.bottom.equalTo(_priceT.mas_top).offset(-10); + make.height.mas_equalTo(25); + make.left.equalTo(self.contentView).offset(kPaddingLeftWidth); + }]; + _priceT.text = @"账户余额(元)"; + + _toWebV = [UIView new]; + _toWebV.backgroundColor = [UIColor colorWithHexString:@"0xFAF7D4"]; + _toWebL = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:[UIColor colorWithHexString:@"0xAE9651"]]; + _toWebB = [UIButton new]; + [_toWebV addSubview:_toWebL]; + [_toWebV addSubview:_toWebB]; + [self.contentView addSubview:_toWebV]; + + [_toWebV mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.left.right.equalTo(self.contentView); + make.height.mas_equalTo(44); + }]; + [_toWebB mas_makeConstraints:^(MASConstraintMaker *make) { + make.size.mas_equalTo(CGSizeMake(44, 44)); + make.centerY.right.equalTo(_toWebV); + }]; + [_toWebL mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(_toWebV); + make.left.equalTo(_toWebV).offset(kPaddingLeftWidth); + make.right.equalTo(_toWebB.mas_left); + }]; + _toWebL.text = @"APP 暂不支持订购服务,请前往企业版网站订购"; + _toWebL.adjustsFontSizeToFitWidth = YES; + _toWebL.minimumScaleFactor = 0.5; + [_toWebB setImage:[UIImage imageNamed:@"btn_dismiss"] forState:UIControlStateNormal]; + __weak typeof(self) weakSelf = self; + [_toWebB bk_addEventHandler:^(id sender) { + if (weakSelf.closeWebTipBlock) { + weakSelf.closeWebTipBlock(); + } + } forControlEvents:UIControlEventTouchUpInside]; + + _tipL.minimumScaleFactor = 0.5; + _tipL.adjustsFontSizeToFitWidth = YES; + } + return self; +} + +- (void)setCurTeam:(Team *)curTeam{ + _curTeam = curTeam; + + BOOL isToped_up = [_curTeam.info isToped_up];//是否充值过 + BOOL isTrial = _curTeam.info.trial.boolValue; + BOOL isLocked = _curTeam.info.locked.boolValue; + NSInteger remain_days = _curTeam.info.remain_days.integerValue; + + _tipL.textColor = remain_days > kEANeedTipRemainDays && !isLocked? kColorDark4: kColorActionRed; + if (!isToped_up) { + NSInteger trial_left_days = [_curTeam.info trial_left_days]; + if (isLocked || trial_left_days < 0) { + _tipL.text = @"您的试用期已结束,请订购后使用"; + }else{ + _tipL.text = [NSString stringWithFormat:@"您正在试用 CODING 企业版,试用期剩余 %ld 天", (long)trial_left_days]; + if (remain_days > kEANeedTipRemainDays) { + [_tipL setAttrStrWithStr:_tipL.text diffColorStr:@(trial_left_days).stringValue diffColor:[UIColor colorWithHexString:@"0xF78636"]]; + } + } + }else{ + if (isLocked) { + _tipL.text = @"您的服务已过期,请订购后使用"; + }else if (remain_days > kEANeedTipRemainDays) { + _tipL.text = nil; + }else if (remain_days > 0){ + _tipL.text = @"您的账户余额不足,请尽快订购"; + }else{ + _tipL.text = @"您的服务已过期,请订购后使用"; + } + } + + _priceT.hidden = _priceV.hidden = !isToped_up; + _priceV.text = _curTeam.info.balance.stringValue; + _priceV.textColor = (remain_days <= 0)? kColorActionRed: [UIColor colorWithHexString:@"0xF78636"]; + + if (_priceT.hidden) { + [_tipL mas_remakeConstraints:^(MASConstraintMaker *make) { + make.bottom.equalTo(_leftDayL.mas_top).offset(-10); + make.height.mas_equalTo(25); + make.left.equalTo(self.contentView).offset(kPaddingLeftWidth); + }]; + }else{ + [_tipL mas_remakeConstraints:^(MASConstraintMaker *make) { + make.bottom.equalTo(_priceT.mas_top).offset(-10); + make.height.mas_equalTo(25); + make.left.equalTo(self.contentView).offset(kPaddingLeftWidth); + }]; + } + + if (isLocked) { + NSInteger stopped_days = [_curTeam.info stopped_days]; + _leftDayL.text = [NSString stringWithFormat:@"服务已暂停 %ld 天。", (long)stopped_days]; + }else if (isTrial && !isToped_up){ + _leftDayL.text = [NSString stringWithFormat:@"试用期至 %@", [_curTeam.info.estimate_date stringWithFormat:@"yyyy 年 MM 月 dd 日"]]; + }else{ + if (remain_days > 0) { + _leftDayL.text = [NSString stringWithFormat:@"余额预计可使用至 %@,剩余 %ld 天。", [_curTeam.info.estimate_date stringWithFormat:@"yyyy 年 MM 月 dd 日"], (long)remain_days]; + }else{ + NSInteger beyond_days = [_curTeam.info beyond_days]; + _leftDayL.text = [NSString stringWithFormat:@"过期时间 %@,已超时使用 %ld 天。", [_curTeam.info.estimate_date stringWithFormat:@"yyyy 年 MM 月 dd 日"], (long)beyond_days]; + } + } + BOOL needWebTip = (isLocked || + (!isTrial && remain_days <= kEANeedTipRemainDays)); + needWebTip = needWebTip && !_curTeam.hasDismissWebTip; + _toWebV.hidden = !needWebTip; +} + ++ (CGFloat)cellHeightWithObj:(id)obj{ + CGFloat cellHeight = 0; + if ([obj isKindOfClass:[Team class]]) { + Team *curTeam = (Team *)obj; + BOOL isToped_up = [curTeam.info isToped_up];//是否充值过 + BOOL isTrial = curTeam.info.trial.boolValue; + BOOL isLocked = curTeam.info.locked.boolValue; + NSInteger remain_days = curTeam.info.remain_days.integerValue; + + if (!isToped_up) { + cellHeight = 85; + }else{ + BOOL needTipStr = (!isToped_up || remain_days <= kEANeedTipRemainDays || isLocked); + if (needTipStr) { + cellHeight = 165; + }else{ + cellHeight = 132; + } + } + BOOL needWebTip = (isLocked || + (!isTrial && remain_days <= kEANeedTipRemainDays)); + needWebTip = needWebTip && !curTeam.hasDismissWebTip; + cellHeight += needWebTip? 44: 0; + } + return cellHeight; +} +@end diff --git a/Coding_iOS/Views/Cell/TeamSupportCell.h b/Coding_iOS/Views/Cell/TeamSupportCell.h new file mode 100644 index 000000000..7f03d8dd1 --- /dev/null +++ b/Coding_iOS/Views/Cell/TeamSupportCell.h @@ -0,0 +1,17 @@ +// +// TeamSupportCell.h +// Coding_Enterprise_iOS +// +// Created by Easeeeeeeeee on 2018/3/15. +// Copyright © 2018年 Coding. All rights reserved. +// + +#define kCellIdentifier_TeamSupportCell @"TeamSupportCell" + +#import + +@interface TeamSupportCell : UITableViewCell + +@property (strong, nonatomic) UILabel *leftL, *rightL; + +@end diff --git a/Coding_iOS/Views/Cell/TeamSupportCell.m b/Coding_iOS/Views/Cell/TeamSupportCell.m new file mode 100644 index 000000000..2724f82aa --- /dev/null +++ b/Coding_iOS/Views/Cell/TeamSupportCell.m @@ -0,0 +1,33 @@ +// +// TeamSupportCell.m +// Coding_Enterprise_iOS +// +// Created by Easeeeeeeeee on 2018/3/15. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "TeamSupportCell.h" + +@implementation TeamSupportCell + +- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + // Initialization code + _leftL = [UILabel labelWithFont:[UIFont systemFontOfSize:15] textColor:kColorDark2]; + [self.contentView addSubview:_leftL]; + _rightL = [UILabel labelWithFont:[UIFont systemFontOfSize:15] textColor:kColorLightBlue]; + [self.contentView addSubview:_rightL]; + [_leftL mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.offset(kPaddingLeftWidth); + make.centerY.equalTo(self.contentView); + }]; + [_rightL mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.offset(-kPaddingLeftWidth); + make.centerY.equalTo(self.contentView); + }]; + } + return self; +} + +@end diff --git a/Coding_iOS/Views/Cell/TeamTopCell.m b/Coding_iOS/Views/Cell/TeamTopCell.m index 68e4407e3..14c22fccc 100644 --- a/Coding_iOS/Views/Cell/TeamTopCell.m +++ b/Coding_iOS/Views/Cell/TeamTopCell.m @@ -19,30 +19,36 @@ - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSStr self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { self.backgroundColor = kColorTableBG; - self.selectionStyle = UITableViewCellSelectionStyleNone; + self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; _iconV = [UIImageView new]; [_iconV doBorderWidth:0 color:nil cornerRadius:2.0]; _nameL = [UILabel labelWithSystemFontSize:15 textColorHexString:@"0x1E2D42"]; - _introductionL = [UILabel labelWithSystemFontSize:12 textColorHexString:@"0x999999"]; - _introductionL.numberOfLines = 0; + _introductionL = [UILabel labelWithSystemFontSize:14 textColorHexString:@"0x999999"]; + // _introductionL.numberOfLines = 0; for (UIView *subV in @[_iconV, _nameL, _introductionL]) { [self.contentView addSubview:subV]; } [_iconV mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.contentView).offset(kPaddingLeftWidth); - make.size.mas_equalTo(CGSizeMake(80, 80)); + make.size.mas_equalTo(CGSizeMake(22, 22)); make.centerY.equalTo(self.contentView); }]; [_nameL mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(_iconV.mas_right).offset(15); - make.top.equalTo(_iconV).offset(5); + make.top.equalTo(self.contentView).offset(15); }]; [_introductionL mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(_nameL); - make.top.equalTo(_nameL.mas_bottom).offset(10); - make.bottom.equalTo(_iconV.mas_bottom).offset(-5); + make.bottom.equalTo(self.contentView).offset(-15); make.right.equalTo(self.contentView).offset(-kPaddingLeftWidth); }]; + _iconV.image = [UIImage imageNamed:@"team_info_order"]; + _nameL.text = @"订单状态"; + + _introductionL.minimumScaleFactor = 0.5; + _introductionL.adjustsFontSizeToFitWidth = YES; + + self.clipsToBounds = YES; } return self; } @@ -50,12 +56,34 @@ - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSStr - (void)setCurTeam:(Team *)curTeam{ _curTeam = curTeam; - [_iconV sd_setImageWithURL:[_curTeam.avatar urlImageWithCodePathResize:70 * 2]]; - _nameL.text = _curTeam.name; - _introductionL.text = _curTeam.introduction; + BOOL isToped_up = [_curTeam.info isToped_up];//是否充值过 + BOOL isLocked = _curTeam.info.locked.boolValue; + NSInteger remain_days = _curTeam.info.remain_days.integerValue; + + _introductionL.textColor = remain_days > kEANeedTipRemainDays? kColor999: kColorActionRed; + NSString *valueStr = @""; + if (!isToped_up) { + valueStr = [NSString stringWithFormat:@"%ld", (long)[_curTeam.info trial_left_days]]; + if (!isLocked && valueStr.integerValue >= 0) { + [_introductionL setAttrStrWithStr:[NSString stringWithFormat:@"试用期剩余 %@ 天", valueStr] diffColorStr:valueStr diffColor:valueStr.integerValue > kEANeedTipRemainDays? [UIColor colorWithHexString:@"0xF78636"]: kColorActionRed]; + }else{ + _introductionL.text = @"您的试用期已结束,请订购后使用"; + } + }else{ + if (isLocked) { + _introductionL.text = [NSString stringWithFormat:@"您的服务已暂停 %ld 天,请订购后使用", (long)[_curTeam.info stopped_days]]; + }else if (remain_days > kEANeedTipRemainDays) { + valueStr = _curTeam.info.balance.stringValue; + [_introductionL setAttrStrWithStr:[NSString stringWithFormat:@"账户余额:%@ 元", valueStr] diffColorStr:valueStr diffColor:[UIColor colorWithHexString:@"0xF78636"]]; + }else if (remain_days > 0){ + _introductionL.text = @"您的余额不足,请尽快订购"; + }else{ + _introductionL.text = [NSString stringWithFormat:@"您的服务已超时使用 %ld 天,请订购后使用", (long)[_curTeam.info beyond_days]]; + } + } } + (CGFloat)cellHeight{ - return 100; + return 75; } @end diff --git a/Coding_iOS/Views/Cell/TextCheckMarkCell.m b/Coding_iOS/Views/Cell/TextCheckMarkCell.m index 3ac9855e6..703e5f21d 100644 --- a/Coding_iOS/Views/Cell/TextCheckMarkCell.m +++ b/Coding_iOS/Views/Cell/TextCheckMarkCell.m @@ -18,13 +18,12 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { // Initialization code - self.tintColor = kColorBrandGreen; self.backgroundColor = kColorTableBG; if (!_contentL) { _contentL = [UILabel new]; _contentL.font = [UIFont systemFontOfSize:15]; - _contentL.textColor = kColor222; + _contentL.textColor = kColorDark3; [self.contentView addSubview:_contentL]; [_contentL mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.contentView).insets(UIEdgeInsetsMake(10, kPaddingLeftWidth, 10, kPaddingLeftWidth)); diff --git a/Coding_iOS/Views/Cell/TitleRImageMoreCell.h b/Coding_iOS/Views/Cell/TitleRImageMoreCell.h index 2f2191cd2..ae2740580 100755 --- a/Coding_iOS/Views/Cell/TitleRImageMoreCell.h +++ b/Coding_iOS/Views/Cell/TitleRImageMoreCell.h @@ -10,9 +10,10 @@ #import #import "User.h" +#import "Team.h" @interface TitleRImageMoreCell : UITableViewCell @property (strong, nonatomic) User *curUser; - +@property (strong, nonatomic) Team *curTeam; + (CGFloat)cellHeight; @end diff --git a/Coding_iOS/Views/Cell/TitleRImageMoreCell.m b/Coding_iOS/Views/Cell/TitleRImageMoreCell.m index d339cdd2b..af7d9ffd7 100755 --- a/Coding_iOS/Views/Cell/TitleRImageMoreCell.m +++ b/Coding_iOS/Views/Cell/TitleRImageMoreCell.m @@ -31,7 +31,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus [self.contentView addSubview:_titleLabel]; } if (!_userIconView) { - _userIconView = [[UIImageView alloc] initWithFrame:CGRectMake((kScreen_Width- kTitleRImageMoreCell_HeightIcon)- kPaddingLeftWidth- 30, ([TitleRImageMoreCell cellHeight] -kTitleRImageMoreCell_HeightIcon)/2, kTitleRImageMoreCell_HeightIcon, kTitleRImageMoreCell_HeightIcon)]; + _userIconView = [[YLImageView alloc] initWithFrame:CGRectMake((kScreen_Width- kTitleRImageMoreCell_HeightIcon)- kPaddingLeftWidth- 30, ([TitleRImageMoreCell cellHeight] -kTitleRImageMoreCell_HeightIcon)/2, kTitleRImageMoreCell_HeightIcon, kTitleRImageMoreCell_HeightIcon)]; [_userIconView doCircleFrame]; [self.contentView addSubview:_userIconView]; } @@ -39,15 +39,18 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus return self; } -- (void)layoutSubviews{ - [super layoutSubviews]; - if (!_curUser) { - return; - } +- (void)setCurUser:(User *)curUser{ + _curUser = curUser; self.titleLabel.text = @"头像"; [self.userIconView sd_setImageWithURL:[_curUser.avatar urlImageWithCodePathResizeToView:_userIconView] placeholderImage:kPlaceholderMonkeyRoundView(_userIconView)]; } +- (void)setCurTeam:(Team *)curTeam{ + _curTeam = curTeam; + self.titleLabel.text = @"企业头像"; + [self.userIconView sd_setImageWithURL:[_curTeam.avatar urlImageWithCodePathResizeToView:_userIconView] placeholderImage:kPlaceholderMonkeyRoundView(_userIconView)]; +} + + (CGFloat)cellHeight{ return 70.0; } diff --git a/Coding_iOS/Views/Cell/TitleValueMoreCell.m b/Coding_iOS/Views/Cell/TitleValueMoreCell.m index 4a5a76fa8..787dcfd5c 100755 --- a/Coding_iOS/Views/Cell/TitleValueMoreCell.m +++ b/Coding_iOS/Views/Cell/TitleValueMoreCell.m @@ -42,11 +42,11 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus } return self; } -- (void)layoutSubviews{ - [super layoutSubviews]; -} - (void)setTitleStr:(NSString *)title valueStr:(NSString *)value{ + self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + self.selectionStyle = UITableViewCellSelectionStyleDefault; + _titleLabel.text = title; _valueLabel.text = value; } diff --git a/Coding_iOS/Views/Cell/ToMessageCell.h b/Coding_iOS/Views/Cell/ToMessageCell.h index cf5bbdd16..427501734 100755 --- a/Coding_iOS/Views/Cell/ToMessageCell.h +++ b/Coding_iOS/Views/Cell/ToMessageCell.h @@ -13,6 +13,7 @@ typedef NS_ENUM(NSInteger, ToMessageType) { ToMessageTypeAT = 0, ToMessageTypeComment, ToMessageTypeSystemNotification, + ToMessageTypeAllNotification, ToMessageTypeProjectFollows, ToMessageTypeProjectFans, }; diff --git a/Coding_iOS/Views/Cell/ToMessageCell.m b/Coding_iOS/Views/Cell/ToMessageCell.m index fc46c45da..ab1b468f3 100755 --- a/Coding_iOS/Views/Cell/ToMessageCell.m +++ b/Coding_iOS/Views/Cell/ToMessageCell.m @@ -16,7 +16,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (self) { // Initialization code self.textLabel.font = [UIFont systemFontOfSize:17]; - self.textLabel.textColor = kColor222; + self.textLabel.textColor = kColorDark3; } return self; } @@ -37,11 +37,15 @@ - (void)setType:(ToMessageType)type{ imageName = @"messageSystem"; titleStr = @"系统通知"; break; - case ToMessageTypeProjectFollows: + case ToMessageTypeAllNotification: + imageName = @"messageSystem"; + titleStr = @"通知"; + break; + case ToMessageTypeProjectFollows: imageName = @"messageProjectFollows"; titleStr = @"我的关注"; break; - case ToMessageTypeProjectFans: + case ToMessageTypeProjectFans: imageName = @"messageProjectFans"; titleStr = @"我的粉丝"; break; diff --git a/Coding_iOS/Views/Cell/TopicAnswerCell.m b/Coding_iOS/Views/Cell/TopicAnswerCell.m index 79ddbdda8..3f6424a7b 100644 --- a/Coding_iOS/Views/Cell/TopicAnswerCell.m +++ b/Coding_iOS/Views/Cell/TopicAnswerCell.m @@ -44,7 +44,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus [topLineV mas_makeConstraints:^(MASConstraintMaker *make) { make.top.right.equalTo(self.contentView); make.left.equalTo(self.contentView).offset(kPaddingLeftWidth); - make.height.mas_equalTo(1.0/[UIScreen mainScreen].scale); + make.height.mas_equalTo(kLine_MinHeight); }]; } } diff --git a/Coding_iOS/Views/Cell/TopicAnswerCommentMoreCell.m b/Coding_iOS/Views/Cell/TopicAnswerCommentMoreCell.m index 8e7234781..262f4a803 100644 --- a/Coding_iOS/Views/Cell/TopicAnswerCommentMoreCell.m +++ b/Coding_iOS/Views/Cell/TopicAnswerCommentMoreCell.m @@ -19,7 +19,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (self) { // Initialization code if (!_contentLabel) { - _contentLabel = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorBrandGreen]; + _contentLabel = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorBrandBlue]; [self.contentView addSubview:_contentLabel]; } [_contentLabel mas_makeConstraints:^(MASConstraintMaker *make) { diff --git a/Coding_iOS/Views/Cell/TopicCommentCell.m b/Coding_iOS/Views/Cell/TopicCommentCell.m index 0f164e405..73f7792d6 100755 --- a/Coding_iOS/Views/Cell/TopicCommentCell.m +++ b/Coding_iOS/Views/Cell/TopicCommentCell.m @@ -57,7 +57,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus } CGFloat curBottomY = 15; if (!_ownerIconView) { - _ownerIconView = [[UIImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, curBottomY, 33, 33)]; + _ownerIconView = [[YLImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, curBottomY, 33, 33)]; [_ownerIconView doCircleFrame]; [self.contentView addSubview:_ownerIconView]; } @@ -103,7 +103,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus } } if (!_detailBtn) { - _detailBtn = [UIButton buttonWithTitle:@"查看详情" titleColor:kColorBrandGreen]; + _detailBtn = [UIButton buttonWithTitle:@"查看详情" titleColor:kColorBrandBlue]; _detailBtn.titleLabel.font = [UIFont systemFontOfSize:12]; [_detailBtn addTarget:self action:@selector(goToDetail) forControlEvents:UIControlEventTouchUpInside]; [self.contentView addSubview:_detailBtn]; @@ -113,6 +113,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus make.centerY.equalTo(_timeLabel); }]; } + _timeLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; } return self; } @@ -132,7 +133,7 @@ - (void)voteBtnClicked{ } - (void)setVoteCount:(NSNumber *)voteCount isVoted:(BOOL)isVoted{ - [_voteBtn setBackgroundColor:[UIColor colorWithHexString:isVoted? @"0x3BBD79": @"0xFFFFFF"]]; + [_voteBtn setBackgroundColor:[UIColor colorWithHexString:isVoted? @"0x0060FF": @"0xFFFFFF"]]; [_voteBtn setTitleColor:[UIColor colorWithHexString:isVoted? @"0xFFFFFF": @"0x666666"] forState:UIControlStateNormal]; [_voteBtn setTitle:[NSString stringWithFormat:@"+%@", voteCount] forState:UIControlStateNormal]; } @@ -178,6 +179,7 @@ - (void)setToComment:(ProjectTopic *)toComment{ curBottomY += [TopicCommentCell imageCollectionViewHeightWithCount:imagesCount]; [_timeLabel setY:curBottomY]; + _timeLabel.width = _detailBtn.hidden? kScreen_Width - 40 - 2*kPaddingLeftWidth: kScreen_Width - 40 - 2*kPaddingLeftWidth - 60; _timeLabel.text = [NSString stringWithFormat:@"%@ 发布于 %@", _toComment.owner.name, [_toComment.created_at stringDisplay_HHmm]]; } diff --git a/Coding_iOS/Views/Cell/TopicContentCell.m b/Coding_iOS/Views/Cell/TopicContentCell.m index 55151020c..9d5d88ee8 100644 --- a/Coding_iOS/Views/Cell/TopicContentCell.m +++ b/Coding_iOS/Views/Cell/TopicContentCell.m @@ -32,7 +32,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus // Initialization code self.selectionStyle = UITableViewCellSelectionStyleNone; if (!_userIconView) { - _userIconView = [[UIImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 0, 20, 20)]; + _userIconView = [[YLImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 0, 20, 20)]; [_userIconView doCircleFrame]; [self.contentView addSubview:_userIconView]; } diff --git a/Coding_iOS/Views/Cell/TopicPreviewCell.m b/Coding_iOS/Views/Cell/TopicPreviewCell.m index 66cff3370..9bbc74d68 100644 --- a/Coding_iOS/Views/Cell/TopicPreviewCell.m +++ b/Coding_iOS/Views/Cell/TopicPreviewCell.m @@ -36,7 +36,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus // Initialization code self.selectionStyle = UITableViewCellSelectionStyleNone; if (!_userIconView) { - _userIconView = [[UIImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 0, 20, 20)]; + _userIconView = [[YLImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 0, 20, 20)]; [_userIconView doCircleFrame]; [self.contentView addSubview:_userIconView]; } diff --git a/Coding_iOS/Views/Cell/TopicSearchCell.m b/Coding_iOS/Views/Cell/TopicSearchCell.m index 74abedeb9..1ac112d8b 100644 --- a/Coding_iOS/Views/Cell/TopicSearchCell.m +++ b/Coding_iOS/Views/Cell/TopicSearchCell.m @@ -35,7 +35,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus // Initialization code self.accessoryType = UITableViewCellAccessoryNone; if (!_userIconView) { - _userIconView = [[UIImageView alloc] initWithFrame:CGRectMake(15, 18, 40, 40)]; + _userIconView = [[YLImageView alloc] initWithFrame:CGRectMake(15, 18, 40, 40)]; [_userIconView doCircleFrame]; [self.contentView addSubview:_userIconView]; } diff --git a/Coding_iOS/Views/Cell/TweetCell.m b/Coding_iOS/Views/Cell/TweetCell.m index 838b5f5dd..fac31ee52 100755 --- a/Coding_iOS/Views/Cell/TweetCell.m +++ b/Coding_iOS/Views/Cell/TweetCell.m @@ -7,21 +7,21 @@ // #define kTweetCell_PadingLeft kPaddingLeftWidth -#define kTweetCell_PadingTop (65 + 15) +#define kTweetCell_PadingTop (75 + 15) #define kTweetCell_PadingBottom 10.0 #define kTweetCell_ContentWidth (kScreen_Width -kTweetCell_PadingLeft - kPaddingLeftWidth) #define kTweetCell_LikeComment_Height 27.0 #define kTweetCell_LikeComment_Width 50.0 -#define kTweetCell_LikeUserCCell_Height 26.0 -#define kTweetCell_LikeUserCCell_Pading 10.0 +#define kTweetCell_LikeUserCCell_Height 30.0 +#define kTweetCell_LikeUserCCell_Pading 5.0 #define kTweet_ContentFont [UIFont systemFontOfSize:16] #define kTweet_ContentMaxHeight 200.0 #define kTweet_CommentFont [UIFont systemFontOfSize:14] #define kTweet_TimtFont [UIFont systemFontOfSize:12] #define kTweet_LikeUsersLineCount 7.0 -#define kTweetCell_MaxCollectionNum (kDevice_Is_iPhone6Plus? 12: kDevice_Is_iPhone6? 10 : 9) +#define kTweetCell_MaxCollectionNum (kDevice_Is_iPhone6Plus? 10: kDevice_Is_iPhone6? 9 : 8) #import "TweetCell.h" #import "TweetLikeUserCCell.h" @@ -43,6 +43,7 @@ @interface TweetCell () @property (strong, nonatomic) UIView *topView; @property (strong, nonatomic) UITapImageView *ownerImgView; +@property (strong, nonatomic) UIImageView *vipV; @property (strong, nonatomic) UIButton *ownerNameBtn; @property (strong, nonatomic) UITTTAttributedLabel *contentLabel; @property (strong, nonatomic) UILabel *timeLabel, *fromLabel; @@ -69,13 +70,13 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus } if (!self.ownerImgView) { - self.ownerImgView = [[UITapImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 15 + CGRectGetMaxY(_topView.frame), 38, 38)]; + self.ownerImgView = [[UITapImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 15 + CGRectGetMaxY(_topView.frame), 45, 45)]; [self.ownerImgView doCircleFrame]; [self.contentView addSubview:self.ownerImgView]; } if (!self.ownerNameBtn) { self.ownerNameBtn = [UIButton buttonWithUserStyle]; - self.ownerNameBtn.frame = CGRectMake(CGRectGetMaxX(self.ownerImgView.frame) + 10, 23 + CGRectGetMaxY(_topView.frame), 50, 20); + self.ownerNameBtn.frame = CGRectMake(CGRectGetMaxX(self.ownerImgView.frame) + 15, 23 + CGRectGetMaxY(_topView.frame), 50, 24); [self.ownerNameBtn addTarget:self action:@selector(userBtnClicked) forControlEvents:UIControlEventTouchUpInside]; [self.contentView addSubview:self.ownerNameBtn]; } @@ -85,19 +86,20 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus // [self.contentView addSubview:self.timeClockIconView]; // } if (!self.timeLabel) { - self.timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMinX(self.ownerNameBtn.frame), 0, kScreen_Width/2, 12)]; + self.timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMinX(self.ownerNameBtn.frame), 0, kScreen_Width/2, 15)]; // self.timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(kScreen_Width - kPaddingLeftWidth - 55, 23 + CGRectGetMaxY(_topView.frame), 55, 12)]; self.timeLabel.font = kTweet_TimtFont; // self.timeLabel.textAlignment = NSTextAlignmentRight; - self.timeLabel.textColor = kColor999; + self.timeLabel.textColor = kColorDark7; [self.contentView addSubview:self.timeLabel]; } if (!self.contentLabel) { self.contentLabel = [[UITTTAttributedLabel alloc] initWithFrame:CGRectMake(kTweetCell_PadingLeft, kTweetCell_PadingTop, kTweetCell_ContentWidth, 20)]; self.contentLabel.font = kTweet_ContentFont; - self.contentLabel.textColor = kColor222; + self.contentLabel.textColor = kColorDark3; self.contentLabel.numberOfLines = 0; - + self.contentLabel.lineHeightMultiple = 1.2; + self.contentLabel.linkAttributes = kLinkAttributes; self.contentLabel.activeLinkAttributes = kLinkAttributesActive; self.contentLabel.delegate = self; @@ -111,7 +113,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus [self.contentView addSubview:self.likeBtn]; } if (!self.rewardBtn) { - CGRect frame = CGRectMake(kPaddingLeftWidth + kTweetCell_LikeComment_Width + 5, 0, kTweetCell_LikeComment_Width, kTweetCell_LikeComment_Height); + CGRect frame = CGRectMake(kPaddingLeftWidth + kTweetCell_LikeComment_Width + 10, 0, kTweetCell_LikeComment_Width, kTweetCell_LikeComment_Height); self.rewardBtn = [UIButton tweetBtnWithFrame:frame alignmentLeft:YES]; [self.rewardBtn addTarget:self action:@selector(rewardBtnClicked:) forControlEvents:UIControlEventTouchUpInside]; [self.contentView addSubview:self.rewardBtn]; @@ -127,7 +129,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus self.deleteBtn = [UIButton buttonWithType:UIButtonTypeCustom]; self.deleteBtn.frame = CGRectMake(kScreen_Width - kPaddingLeftWidth- 2*kTweetCell_LikeComment_Width -5, 0, kTweetCell_LikeComment_Width, kTweetCell_LikeComment_Height); [self.deleteBtn setTitle:@"删除" forState:UIControlStateNormal]; - [self.deleteBtn setTitleColor:kColorBrandGreen forState:UIControlStateNormal]; + [self.deleteBtn setTitleColor:kColorBrandBlue forState:UIControlStateNormal]; [self.deleteBtn setTitleColor:[UIColor darkGrayColor] forState:UIControlStateHighlighted]; self.deleteBtn.titleLabel.font = [UIFont boldSystemFontOfSize:12]; [self.deleteBtn addTarget:self action:@selector(deleteBtnClicked:) forControlEvents:UIControlEventTouchUpInside]; @@ -141,19 +143,19 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus self.locaitonBtn.frame = CGRectMake(kTweetCell_PadingLeft, 0, kScreen_Width - kTweetCell_PadingLeft - kPaddingLeftWidth, 15); self.locaitonBtn.titleLabel.adjustsFontSizeToFitWidth = NO; self.locaitonBtn.titleLabel.font = [UIFont boldSystemFontOfSize:12]; - [self.locaitonBtn setTitleColor:kColorBrandGreen forState:UIControlStateNormal]; + [self.locaitonBtn setTitleColor:kColorBrandBlue forState:UIControlStateNormal]; [self.locaitonBtn addTarget:self action:@selector(locationBtnClicked:) forControlEvents:UIControlEventTouchUpInside]; [self.contentView addSubview:self.locaitonBtn]; } if (!self.fromPhoneIconView) { - self.fromPhoneIconView = [[UIImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 0, 11, 11)]; + self.fromPhoneIconView = [[UIImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 0, 12, 12)]; self.fromPhoneIconView.image = [UIImage imageNamed:@"little_phone_icon"]; [self.contentView addSubview:self.fromPhoneIconView]; } if (!self.fromLabel) { self.fromLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(self.fromPhoneIconView.frame) + 5, 0, kScreen_Width/2, 15)]; self.fromLabel.font = kTweet_TimtFont; - self.fromLabel.textColor = kColor999; + self.fromLabel.textColor = kColorDark7; [self.contentView addSubview:self.fromLabel]; } @@ -206,6 +208,13 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus _commentOrLikeSplitlineView.image = [UIImage imageNamed:@"splitlineImg"]; [self.contentView addSubview:_commentOrLikeSplitlineView]; } + if (!_vipV) { + _vipV = [UIImageView new]; + [self.contentView addSubview:_vipV]; + [_vipV mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.bottom.equalTo(_ownerImgView); + }]; + } } return self; } @@ -216,10 +225,10 @@ - (void)setTweet:(Tweet *)tweet needTopView:(BOOL)needTopView{ return; } - self.likeBtn.hidden = self.rewardBtn.hidden = [_tweet isProjectTweet]; - + self.likeBtn.hidden = self.rewardBtn.hidden = self.commentBtn.hidden = [_tweet isProjectTweet]; + _like_reward_users = [_tweet like_reward_users]; - BOOL isMineTweet = [_tweet.owner.global_key isEqualToString:[Login curLoginUser].global_key]; + BOOL isMineTweet = [_tweet.owner.global_key isEqualToString:[Login curLoginUser].global_key] || _tweet.project.current_user_role_id.integerValue >= 90; self.topView.hidden = !_needTopView; //owner头像 @@ -227,6 +236,10 @@ - (void)setTweet:(Tweet *)tweet needTopView:(BOOL)needTopView{ [self.ownerImgView setImageWithUrl:[_tweet.owner.avatar urlImageWithCodePathResizeToView:_ownerImgView] placeholderImage:kPlaceholderMonkeyRoundView(_ownerImgView) tapBlock:^(id obj) { [weakSelf userBtnClicked]; }]; + + _vipV.image = [UIImage imageNamed:[NSString stringWithFormat:@"vip_%@_45", _tweet.owner.vip]]; + _vipV.hidden = kTarget_Enterprise; + //owner姓名 [self.ownerNameBtn setUserTitle:_tweet.owner.name font:[UIFont systemFontOfSize:17] maxWidth:(kTweetCell_ContentWidth-85)]; //发出冒泡的时间 @@ -302,8 +315,10 @@ - (void)setTweet:(Tweet *)tweet needTopView:(BOOL)needTopView{ [self.rewardBtn setTitle:_tweet.rewards.stringValue forState:UIControlStateNormal]; [self.commentBtn setTitle:_tweet.comments.stringValue forState:UIControlStateNormal]; - [self.deleteBtn setY:curBottomY]; - self.deleteBtn.hidden = !isMineTweet; + CGFloat deleteBtnX = kScreen_Width - kPaddingLeftWidth - kTweetCell_LikeComment_Width - ([_tweet isProjectTweet]? 0: kTweetCell_LikeComment_Width + 5); + [self.deleteBtn setOrigin:CGPointMake(deleteBtnX, curBottomY)]; + + self.deleteBtn.hidden = !(isMineTweet && !_tweet.isProjectTweet); curBottomY += kTweetCell_LikeComment_Height; curBottomY += [TweetCell likeCommentBtn_BottomPadingWithTweet:_tweet]; @@ -348,6 +363,9 @@ - (void)setTweet:(Tweet *)tweet needTopView:(BOOL)needTopView{ self.commentListView.hidden = YES; } } + if ([_tweet isProjectTweet]) { + _commentListView.hidden = _commentOrLikeSplitlineView.hidden = _likeUsersView.hidden = _commentOrLikeBeginImgView.hidden = YES; + } } + (CGFloat)cellHeightWithObj:(id)obj needTopView:(BOOL)needTopView{ @@ -358,19 +376,35 @@ + (CGFloat)cellHeightWithObj:(id)obj needTopView:(BOOL)needTopView{ cellHeight += [self contentLabelHeightWithTweet:tweet]; cellHeight += [self contentMediaHeightWithTweet:tweet]; cellHeight += [self locationAndDeviceHeightWithTweet:tweet]; - cellHeight += 5+ kTweetCell_LikeComment_Height; - cellHeight += [TweetCell likeCommentBtn_BottomPadingWithTweet:tweet]; - cellHeight += [TweetCell likeUsersHeightWithTweet:tweet]; - cellHeight += [TweetCell commentListViewHeightWithTweet:tweet]; - cellHeight += 15; + if (!tweet.isProjectTweet) { + cellHeight += 5+ kTweetCell_LikeComment_Height; + cellHeight += [TweetCell likeCommentBtn_BottomPadingWithTweet:tweet]; + cellHeight += [TweetCell likeUsersHeightWithTweet:tweet]; + cellHeight += [TweetCell commentListViewHeightWithTweet:tweet]; + cellHeight += 15; + } return ceilf(cellHeight); } + (CGFloat)contentLabelHeightWithTweet:(Tweet *)tweet{ CGFloat height = 0; +// if (tweet.content.length > 0) { +// height += MIN(kTweet_ContentMaxHeight, [tweet.content getHeightWithFont:kTweet_ContentFont constrainedToSize:CGSizeMake(kTweetCell_ContentWidth, CGFLOAT_MAX)]); +// height += 15; +// } + static UITTTAttributedLabel *p_contentLabel = nil; if (tweet.content.length > 0) { - height += MIN(kTweet_ContentMaxHeight, [tweet.content getHeightWithFont:kTweet_ContentFont constrainedToSize:CGSizeMake(kTweetCell_ContentWidth, CGFLOAT_MAX)]); - height += 15; + if (!p_contentLabel) { + p_contentLabel = [[UITTTAttributedLabel alloc] initWithFrame:CGRectMake(kTweetCell_PadingLeft, kTweetCell_PadingTop, kTweetCell_ContentWidth, 20)]; + p_contentLabel.font = kTweet_ContentFont; + p_contentLabel.textColor = kColorDark3; + p_contentLabel.numberOfLines = 0; + p_contentLabel.lineHeightMultiple = 1.2; + p_contentLabel.linkAttributes = kLinkAttributes; + p_contentLabel.activeLinkAttributes = kLinkAttributesActive; + } + [p_contentLabel setLongString:tweet.content withFitWidth:kTweetCell_ContentWidth maxHeight:kTweet_ContentMaxHeight]; + height += p_contentLabel.height + 15; } return height; } @@ -416,7 +450,7 @@ + (CGFloat)locationAndDeviceHeightWithTweet:(Tweet *)tweet{ + (CGFloat)likeUsersHeightWithTweet:(Tweet *)tweet{ CGFloat likeUsersHeight = 0; if ([tweet hasLikesOrRewards]) { - likeUsersHeight = 45; + likeUsersHeight = [TweetLikeUserCCell ccellSize].height + 20; // +30*(ceilf([tweet.like_users count]/kTweet_LikeUsersLineCount)-1); } return likeUsersHeight; @@ -494,7 +528,7 @@ - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollection itemSize = [TweetMediaItemCCell ccellSizeWithObj:_tweet.htmlMedia.imageItems.firstObject]; } }else{ - itemSize = CGSizeMake(kTweetCell_LikeUserCCell_Height, kTweetCell_LikeUserCCell_Height); + itemSize = [TweetLikeUserCCell ccellSize]; } return itemSize; } @@ -508,7 +542,7 @@ - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UIColl insetForSection = UIEdgeInsetsMake(0, 0, 0, 0); } }else{ - insetForSection = UIEdgeInsetsMake(kTweetCell_LikeUserCCell_Pading, 5, kTweetCell_LikeUserCCell_Pading, 5); + insetForSection = UIEdgeInsetsMake(10, kPaddingLeftWidth, 10, kPaddingLeftWidth); } return insetForSection; } diff --git a/Coding_iOS/Views/Cell/TweetCommentCell.m b/Coding_iOS/Views/Cell/TweetCommentCell.m index 1b494a1b2..5ee821b10 100755 --- a/Coding_iOS/Views/Cell/TweetCommentCell.m +++ b/Coding_iOS/Views/Cell/TweetCommentCell.m @@ -11,7 +11,7 @@ #define kTweetCommentCell_LeftOrRightPading 10.0 #define kTweetCommentCell_ContentWidth (kScreen_Width -kPaddingLeftWidth - kPaddingLeftWidth - 2*kTweetCommentCell_LeftOrRightPading) -#define kTweetCommentCell_ContentMaxHeight 105.0 +#define kTweetCommentCell_ContentMaxHeight 150.0 #import "TweetCommentCell.h" @@ -31,11 +31,11 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus // Initialization code self.backgroundView = nil; if (!_commentLabel) { - _commentLabel = [[UITTTAttributedLabel alloc] initWithFrame:CGRectMake(kTweetCommentCell_LeftOrRightPading, kScaleFrom_iPhone5_Desgin(6), kTweetCommentCell_ContentWidth, 20)]; + _commentLabel = [[UITTTAttributedLabel alloc] initWithFrame:CGRectMake(kTweetCommentCell_LeftOrRightPading, 10, kTweetCommentCell_ContentWidth, 20)]; _commentLabel.numberOfLines = 0; _commentLabel.backgroundColor = [UIColor clearColor]; _commentLabel.font = kTweet_CommentFont; - _commentLabel.textColor = kColor222; + _commentLabel.textColor = kColorDark4; _commentLabel.linkAttributes = kLinkAttributes; _commentLabel.activeLinkAttributes = kLinkAttributesActive; [self.contentView addSubview:_commentLabel]; @@ -44,19 +44,20 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (!_userNameLabel) { _userNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(kTweetCommentCell_LeftOrRightPading, 0, 150, 15)]; _userNameLabel.backgroundColor = [UIColor clearColor]; - _userNameLabel.font = [UIFont boldSystemFontOfSize:10]; - _userNameLabel.textColor = kColor666; + _userNameLabel.font = [UIFont systemFontOfSize:12]; + _userNameLabel.textColor = kColorDark7; [self.contentView addSubview:_userNameLabel]; } if (!_timeLabel) { _timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(75, 0, 80, 15)]; _timeLabel.backgroundColor = [UIColor clearColor]; - _timeLabel.font = [UIFont systemFontOfSize:10]; - _timeLabel.textColor = kColor999; + _timeLabel.font = [UIFont systemFontOfSize:12]; + _timeLabel.textColor = kColorDark7; [self.contentView addSubview:_timeLabel]; } if (!_timeClockIconView) { - _timeClockIconView = [[UIImageView alloc] initWithFrame:CGRectMake(60, 0, 12, 12)]; + _timeClockIconView = [[UIImageView alloc] initWithFrame:CGRectMake(60, 0, 15, 15)]; + _timeClockIconView.contentMode = UIViewContentModeCenter; _timeClockIconView.image = [UIImage imageNamed:@"time_clock_icon"]; [self.contentView addSubview:_timeClockIconView]; } @@ -89,7 +90,7 @@ - (void)configWithComment:(Comment *)curComment topLine:(BOOL)has{ [_commentLabel addLinkToTransitInformation:[NSDictionary dictionaryWithObject:item forKey:@"value"] withRange:item.range]; } } - CGFloat curBottomY = CGRectGetMaxY(_commentLabel.frame) +kScaleFrom_iPhone5_Desgin(5); + CGFloat curBottomY = CGRectGetMaxY(_commentLabel.frame) + 10; _userNameLabel.text = curUser.name; _timeLabel.text = [_curComment.created_at stringDisplay_HHmm]; @@ -98,10 +99,10 @@ - (void)configWithComment:(Comment *)curComment topLine:(BOOL)has{ CGRect frame = _timeClockIconView.frame; frame.origin.y = curBottomY; - frame.origin.x = 15+ CGRectGetWidth(_userNameLabel.frame); + frame.origin.x = 10 + CGRectGetMaxX(_userNameLabel.frame); _timeClockIconView.frame = frame; - frame.origin.x += 15; + frame.origin.x += 5 + CGRectGetWidth(_timeClockIconView.frame); frame.size = _timeLabel.frame.size; _timeLabel.frame = frame; [_timeLabel sizeToFit]; @@ -111,7 +112,7 @@ + (CGFloat)cellHeightWithObj:(id)obj{ CGFloat cellHeight = 0; if ([obj isKindOfClass:[Comment class]]) { Comment *curComment = (Comment *)obj; - cellHeight = MIN(kTweetCommentCell_ContentMaxHeight, [curComment.content getHeightWithFont:kTweet_CommentFont constrainedToSize:CGSizeMake(kTweetCommentCell_ContentWidth, CGFLOAT_MAX)]) +15 + kScaleFrom_iPhone5_Desgin(15); + cellHeight = MIN(kTweetCommentCell_ContentMaxHeight, [curComment.content getHeightWithFont:kTweet_CommentFont constrainedToSize:CGSizeMake(kTweetCommentCell_ContentWidth, CGFLOAT_MAX)]) +15 + 10 * 3; } return ceilf(cellHeight); } diff --git a/Coding_iOS/Views/Cell/TweetCommentMoreCell.m b/Coding_iOS/Views/Cell/TweetCommentMoreCell.m index f92097342..3c4d0ab9e 100755 --- a/Coding_iOS/Views/Cell/TweetCommentMoreCell.m +++ b/Coding_iOS/Views/Cell/TweetCommentMoreCell.m @@ -23,15 +23,16 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (self) { // Initialization code if (!_commentIconView) { - _commentIconView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 13, 13)]; + _commentIconView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 20, 20)]; _commentIconView.image = [UIImage imageNamed:@"tweet_more_comment_icon"]; + _commentIconView.contentMode = UIViewContentModeCenter; [self.contentView addSubview:_commentIconView]; } if (!_contentLabel) { - _contentLabel = [[UILabel alloc] initWithFrame:CGRectMake(30, 5, 245, 20)]; + _contentLabel = [[UILabel alloc] initWithFrame:CGRectMake(_commentIconView.maxXOfFrame + 5, 10, 200, 20)]; _contentLabel.backgroundColor = [UIColor clearColor]; _contentLabel.font = kTweet_CommentFont; - _contentLabel.textColor = kColor222; + _contentLabel.textColor = kColorDark4; [self.contentView addSubview:_contentLabel]; } if (!_splitLineView) { @@ -53,6 +54,6 @@ - (void)layoutSubviews{ self.contentLabel.text = [NSString stringWithFormat:@"查看全部%d条评论", _commentNum.intValue]; } +(CGFloat)cellHeight{ - return 12+10*2; + return 20 + 10*2; } @end diff --git a/Coding_iOS/Views/Cell/TweetDetailCell.m b/Coding_iOS/Views/Cell/TweetDetailCell.m index 7f459d13f..562355a9e 100755 --- a/Coding_iOS/Views/Cell/TweetDetailCell.m +++ b/Coding_iOS/Views/Cell/TweetDetailCell.m @@ -11,12 +11,12 @@ #define kTweetDetailCell_LikeComment_Height 27.0 #define kTweetDetailCell_LikeComment_Width 50.0 #define kTweetDetailCell_ContentWidth (kScreen_Width - 2*kPaddingLeftWidth) -#define kTweetDetailCell_PadingTop 55.0 +#define kTweetDetailCell_PadingTop 70.0 #define kTweetDetailCell_PadingBottom 10.0 #define kTweetDetailCell_LikeUserCCell_Height 25.0 -#define kTweetDetailCell_LikeUserCCell_Pading 10.0 +#define kTweetDetailCell_LikeUserCCell_Pading 5.0 -#define kTweetDetailCell_MaxCollectionNum (kDevice_Is_iPhone6Plus? 12: kDevice_Is_iPhone6? 11: 9) +#define kTweetDetailCell_MaxCollectionNum (kDevice_Is_iPhone6Plus? 11: kDevice_Is_iPhone6? 10: 9) @@ -33,6 +33,7 @@ @interface TweetDetailCell () @property (strong, nonatomic) NSArray *like_reward_users; @property (strong, nonatomic) UITapImageView *ownerImgView; +@property (strong, nonatomic) UIImageView *vipV; @property (strong, nonatomic) UIButton *ownerNameBtn; @property (strong, nonatomic) UILabel *timeLabel, *fromLabel; @property (strong, nonatomic) UIButton *likeBtn, *commentBtn, *deleteBtn, *rewardBtn; @@ -54,13 +55,13 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus self.selectionStyle = UITableViewCellSelectionStyleNone; // self.backgroundColor = [UIColor colorWithHexString:@"0xf3f3f3"]; if (!self.ownerImgView) { - self.ownerImgView = [[UITapImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 10, 38, 38)]; + self.ownerImgView = [[UITapImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 10, 45, 45)]; [self.ownerImgView doCircleFrame]; [self.contentView addSubview:self.ownerImgView]; } if (!self.ownerNameBtn) { self.ownerNameBtn = [UIButton buttonWithUserStyle]; - self.ownerNameBtn.frame = CGRectMake(kTweetDetailCell_PadingLeft, CGRectGetMinY(self.ownerImgView.frame), kScreen_Width/2, 20); + self.ownerNameBtn.frame = CGRectMake(CGRectGetMaxX(_ownerImgView.frame) + 15, CGRectGetMinY(self.ownerImgView.frame), kScreen_Width/2, 24); [self.ownerNameBtn addTarget:self action:@selector(userBtnClicked) forControlEvents:UIControlEventTouchUpInside]; [self.contentView addSubview:self.ownerNameBtn]; } @@ -70,11 +71,11 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus // [self.contentView addSubview:self.timeClockIconView]; // } if (!self.timeLabel) { - self.timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMinX(self.ownerNameBtn.frame), CGRectGetMaxY(self.ownerImgView.frame) - 12, kScreen_Width/2, 12)]; + self.timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMinX(self.ownerNameBtn.frame), CGRectGetMaxY(self.ownerImgView.frame) - 17, kScreen_Width/2, 17)]; // self.timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(kScreen_Width - kPaddingLeftWidth - 70, 18, 70, 12)]; self.timeLabel.font = kTweet_TimtFont; // self.timeLabel.textAlignment = NSTextAlignmentRight; - self.timeLabel.textColor = kColor999; + self.timeLabel.textColor = kColorDark7; [self.contentView addSubview:self.timeLabel]; } @@ -101,7 +102,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus self.deleteBtn = [UIButton buttonWithType:UIButtonTypeCustom]; self.deleteBtn.frame = CGRectMake(kScreen_Width - kPaddingLeftWidth- 2*kTweetDetailCell_LikeComment_Width- 5 , 0, kTweetDetailCell_LikeComment_Width, kTweetDetailCell_LikeComment_Height); [self.deleteBtn setTitle:@"删除" forState:UIControlStateNormal]; - [self.deleteBtn setTitleColor:kColorBrandGreen forState:UIControlStateNormal]; + [self.deleteBtn setTitleColor:kColorBrandBlue forState:UIControlStateNormal]; [self.deleteBtn setTitleColor:[UIColor darkGrayColor] forState:UIControlStateHighlighted]; self.deleteBtn.titleLabel.font = [UIFont boldSystemFontOfSize:12]; [self.deleteBtn addTarget:self action:@selector(deleteBtnClicked:) forControlEvents:UIControlEventTouchUpInside]; @@ -116,19 +117,19 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus self.locaitonBtn.frame = CGRectMake(kPaddingLeftWidth, 0, (kScreen_Width - 2*kPaddingLeftWidth), 15); self.locaitonBtn.titleLabel.font = [UIFont boldSystemFontOfSize:12]; - [self.locaitonBtn setTitleColor:kColorBrandGreen forState:UIControlStateNormal]; + [self.locaitonBtn setTitleColor:kColorBrandBlue forState:UIControlStateNormal]; [self.locaitonBtn addTarget:self action:@selector(locationBtnClicked:) forControlEvents:UIControlEventTouchUpInside]; [self.contentView addSubview:self.locaitonBtn]; } if (!self.fromPhoneIconView) { - self.fromPhoneIconView = [[UIImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 0, 11, 11)]; + self.fromPhoneIconView = [[UIImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 0, 12, 12)]; self.fromPhoneIconView.image = [UIImage imageNamed:@"little_phone_icon"]; [self.contentView addSubview:self.fromPhoneIconView]; } if (!self.fromLabel) { self.fromLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(self.fromPhoneIconView.frame) + 5, 0, kScreen_Width/2, 15)]; self.fromLabel.font = kTweet_TimtFont; - self.fromLabel.textColor = kColor999; + self.fromLabel.textColor = kColorDark7; [self.contentView addSubview:self.fromLabel]; } if (!self.likeUsersView) { @@ -161,7 +162,13 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus [_activityIndicator setCenter:CGPointMake(CGRectGetMidX(self.webContentView.frame), kTweetDetailCell_PadingTop+CGRectGetHeight(_activityIndicator.bounds)/2)]; [self.contentView addSubview:_activityIndicator]; } - + if (!_vipV) { + _vipV = [UIImageView new]; + [self.contentView addSubview:_vipV]; + [_vipV mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.bottom.equalTo(_ownerImgView); + }]; + } } return self; } @@ -174,13 +181,17 @@ - (void)setTweet:(Tweet *)tweet{ return; } - self.likeBtn.hidden = self.rewardBtn.hidden = [_tweet isProjectTweet]; - + self.likeBtn.hidden = self.rewardBtn.hidden = self.commentBtn.hidden = [_tweet isProjectTweet]; + //owner头像 __weak __typeof(self)weakSelf = self; [self.ownerImgView setImageWithUrl:[_tweet.owner.avatar urlImageWithCodePathResizeToView:_ownerImgView] placeholderImage:kPlaceholderMonkeyRoundView(_ownerImgView) tapBlock:^(id obj) { [weakSelf userBtnClicked]; }]; + + _vipV.image = [UIImage imageNamed:[NSString stringWithFormat:@"vip_%@_45", _tweet.owner.vip]]; + _vipV.hidden = kTarget_Enterprise; + //owner姓名 // [self.ownerNameBtn setUserTitle:_tweet.owner.name]; [self.ownerNameBtn setUserTitle:_tweet.owner.name font:self.ownerNameBtn.titleLabel.font maxWidth:(kScreen_Width- kTweetDetailCell_PadingLeft - 85)]; @@ -231,9 +242,10 @@ - (void)setTweet:(Tweet *)tweet{ [self.rewardBtn setTitle:_tweet.rewards.stringValue forState:UIControlStateNormal]; [self.commentBtn setTitle:_tweet.comments.stringValue forState:UIControlStateNormal]; - BOOL isMineTweet = [_tweet.owner.global_key isEqualToString:[Login curLoginUser].global_key]; + BOOL isMineTweet = [_tweet.owner.global_key isEqualToString:[Login curLoginUser].global_key] || _tweet.project.current_user_role_id.integerValue >= 90; if (isMineTweet) { - [self.deleteBtn setY:curBottomY]; + CGFloat deleteBtnX = kScreen_Width - kPaddingLeftWidth - kTweetDetailCell_LikeComment_Width - ([_tweet isProjectTweet]? 0: kTweetDetailCell_LikeComment_Width + 5); + [self.deleteBtn setOrigin:CGPointMake(deleteBtnX, curBottomY)]; self.deleteBtn.hidden = NO; }else{ self.deleteBtn.hidden = YES; @@ -267,7 +279,13 @@ + (CGFloat)cellHeightWithObj:(id)obj{ cellHeight += kTweetDetailCell_PadingTop; cellHeight += [[self class] contentHeightWithTweet:tweet]; cellHeight += 10; - cellHeight += 5 + kTweetDetailCell_LikeComment_Height; + if (tweet.isProjectTweet) { + if ([tweet.owner.global_key isEqualToString:[Login curLoginUser].global_key] || tweet.project.current_user_role_id.integerValue >= 90) { + cellHeight += 5 + kTweetDetailCell_LikeComment_Height; + } + }else{ + cellHeight += 5 + kTweetDetailCell_LikeComment_Height; + } cellHeight += [[self class] locationAndDeviceHeightWithTweet:tweet]; cellHeight += [[self class] likeCommentBtn_BottomPadingWithTweet:tweet]; cellHeight += [[self class] likeUsersHeightWithTweet:tweet]; @@ -291,7 +309,7 @@ + (CGFloat)likeCommentBtn_BottomPadingWithTweet:(Tweet *)tweet{ + (CGFloat)likeUsersHeightWithTweet:(Tweet *)tweet{ CGFloat likeUsersHeight = 0; if ([tweet hasLikesOrRewards]) { - likeUsersHeight = 35; + likeUsersHeight = [TweetLikeUserCCell ccellSize].height + 15 + 5; // +30*(ceilf([tweet.like_users count]/kTweet_LikeUsersLineCount)-1); } return likeUsersHeight; @@ -329,7 +347,7 @@ - (void)webViewDidStartLoad:(UIWebView *)webView{ - (void)webViewDidFinishLoad:(UIWebView *)webView{ [self refreshwebContentView]; [_activityIndicator stopAnimating]; - CGFloat scrollHeight = webView.scrollView.contentSize.height; + CGFloat scrollHeight = MAX(webView.scrollView.contentSize.height, _tweet.contentHeight); if (ABS(scrollHeight - _tweet.contentHeight) > 5) { webView.scalesPageToFit = YES; _tweet.contentHeight = scrollHeight; @@ -435,14 +453,12 @@ - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cell return ccell; } - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{ - CGSize itemSize; - itemSize = CGSizeMake(kTweetDetailCell_LikeUserCCell_Height, kTweetDetailCell_LikeUserCCell_Height); + CGSize itemSize = [TweetLikeUserCCell ccellSize]; return itemSize; } - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{ UIEdgeInsets insetForSection; - - insetForSection = UIEdgeInsetsMake(kTweetDetailCell_LikeUserCCell_Pading, kPaddingLeftWidth, kTweetDetailCell_LikeUserCCell_Pading, kPaddingLeftWidth); + insetForSection = UIEdgeInsetsMake(15, kPaddingLeftWidth, 5, kPaddingLeftWidth); return insetForSection; } - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section{ diff --git a/Coding_iOS/Views/Cell/TweetDetailCommentCell.h b/Coding_iOS/Views/Cell/TweetDetailCommentCell.h index e97124937..25092404d 100755 --- a/Coding_iOS/Views/Cell/TweetDetailCommentCell.h +++ b/Coding_iOS/Views/Cell/TweetDetailCommentCell.h @@ -17,7 +17,7 @@ @property (strong, nonatomic) Comment *toComment; @property (nonatomic, copy) void (^commentToCommentBlock)(Comment *, id); @property (strong, nonatomic) UITTTAttributedLabel *contentLabel; -@property (strong, nonatomic) UITapImageView *ownerIconView; +//@property (strong, nonatomic) UITapImageView *ownerIconView; + (CGFloat)cellHeightWithObj:(id)obj; diff --git a/Coding_iOS/Views/Cell/TweetDetailCommentCell.m b/Coding_iOS/Views/Cell/TweetDetailCommentCell.m index a3d2b8eec..5054d7fa2 100755 --- a/Coding_iOS/Views/Cell/TweetDetailCommentCell.m +++ b/Coding_iOS/Views/Cell/TweetDetailCommentCell.m @@ -12,7 +12,11 @@ #import "Login.h" @interface TweetDetailCommentCell () -@property (strong, nonatomic) UILabel *timeLabel; +//@property (strong, nonatomic) UILabel *timeLabel; + +@property (strong, nonatomic) UILabel *userNameLabel, *timeLabel; +@property (strong, nonatomic) UIImageView *timeClockIconView; + @end @implementation TweetDetailCommentCell @@ -22,29 +26,35 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { // Initialization code - CGFloat curBottomY = 10; - if (!_ownerIconView) { - _ownerIconView = [[UITapImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, curBottomY, 33, 33)]; - [_ownerIconView doCircleFrame]; - [self.contentView addSubview:_ownerIconView]; - } - CGFloat curWidth = kScreen_Width - 40 - 2*kPaddingLeftWidth; if (!_contentLabel) { - _contentLabel = [[UITTTAttributedLabel alloc] initWithFrame:CGRectMake(kPaddingLeftWidth + 40, curBottomY, curWidth, 30)]; + _contentLabel = [[UITTTAttributedLabel alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 15, kScreen_Width - 2*kPaddingLeftWidth, 30)]; _contentLabel.numberOfLines = 0; - _contentLabel.textColor = kColor222; + _contentLabel.textColor = kColorDark4; _contentLabel.font = kTweetDetailCommentCell_FontContent; _contentLabel.linkAttributes = kLinkAttributes; _contentLabel.activeLinkAttributes = kLinkAttributesActive; [self.contentView addSubview:_contentLabel]; } - CGFloat commentBtnWidth = 40; + if (!_userNameLabel) { + _userNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 0, 150, 15)]; + _userNameLabel.backgroundColor = [UIColor clearColor]; + _userNameLabel.font = [UIFont systemFontOfSize:12]; + _userNameLabel.textColor = kColorDark7; + [self.contentView addSubview:_userNameLabel]; + } if (!_timeLabel) { - _timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(kPaddingLeftWidth +40, 0, curWidth- commentBtnWidth, 20)]; - _timeLabel.textColor = kColor999; + _timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(75, 0, 80, 15)]; + _timeLabel.backgroundColor = [UIColor clearColor]; _timeLabel.font = [UIFont systemFontOfSize:12]; + _timeLabel.textColor = kColorDark7; [self.contentView addSubview:_timeLabel]; } + if (!_timeClockIconView) { + _timeClockIconView = [[UIImageView alloc] initWithFrame:CGRectMake(60, 0, 15, 15)]; + _timeClockIconView.contentMode = UIViewContentModeCenter; + _timeClockIconView.image = [UIImage imageNamed:@"time_clock_icon"]; + [self.contentView addSubview:_timeClockIconView]; + } } return self; } @@ -62,10 +72,8 @@ - (void)layoutSubviews{ if (!_toComment) { return; } - CGFloat curBottomY = 10; - CGFloat curWidth = kScreen_Width - 40 - 2*kPaddingLeftWidth; - [_ownerIconView sd_setImageWithURL:[_toComment.owner.avatar urlImageWithCodePathResizeToView:_ownerIconView] placeholderImage:kPlaceholderMonkeyRoundView(_ownerIconView)]; - + CGFloat curBottomY = 15; + CGFloat curWidth = kScreen_Width - 2*kPaddingLeftWidth; [_contentLabel setWidth:curWidth]; _contentLabel.text = _toComment.content; [_contentLabel sizeToFit]; @@ -76,9 +84,23 @@ - (void)layoutSubviews{ } } - curBottomY += [_toComment.content getHeightWithFont:kTweetDetailCommentCell_FontContent constrainedToSize:CGSizeMake(curWidth, CGFLOAT_MAX)] + 5; - [_timeLabel setY:curBottomY]; - _timeLabel.text = [NSString stringWithFormat:@"%@ 发布于 %@", _toComment.owner.name, [_toComment.created_at stringDisplay_HHmm]]; + curBottomY += [_toComment.content getHeightWithFont:kTweetDetailCommentCell_FontContent constrainedToSize:CGSizeMake(curWidth, CGFLOAT_MAX)] + 10; + + + _userNameLabel.text = _toComment.owner.name; + _timeLabel.text = [_toComment.created_at stringDisplay_HHmm]; + [_userNameLabel setY:curBottomY]; + [_userNameLabel sizeToFit]; + + CGRect frame = _timeClockIconView.frame; + frame.origin.y = curBottomY; + frame.origin.x = 10 + CGRectGetMaxX(_userNameLabel.frame); + _timeClockIconView.frame = frame; + + frame.origin.x += 5 + CGRectGetWidth(_timeClockIconView.frame); + frame.size = _timeLabel.frame.size; + _timeLabel.frame = frame; + [_timeLabel sizeToFit]; } - (void)commentBtnClicked:(id)sender{ @@ -92,8 +114,8 @@ + (CGFloat)cellHeightWithObj:(id)obj{ CGFloat cellHeight = 0; if ([obj isKindOfClass:[Comment class]]) { Comment *toComment = (Comment *)obj; - CGFloat curWidth = kScreen_Width - 40 - 2*kPaddingLeftWidth; - cellHeight += 10 +[toComment.content getHeightWithFont:kTweetDetailCommentCell_FontContent constrainedToSize:CGSizeMake(curWidth, CGFLOAT_MAX)] + 5 +20 +10; + CGFloat curWidth = kScreen_Width - 2*kPaddingLeftWidth; + cellHeight += 15 +[toComment.content getHeightWithFont:kTweetDetailCommentCell_FontContent constrainedToSize:CGSizeMake(curWidth, CGFLOAT_MAX)] + 10 +15 +15; } return cellHeight; } diff --git a/Coding_iOS/Views/Cell/TweetSendCreateLocationCell.xib b/Coding_iOS/Views/Cell/TweetSendCreateLocationCell.xib index d30cc2e50..c20908ea8 100644 --- a/Coding_iOS/Views/Cell/TweetSendCreateLocationCell.xib +++ b/Coding_iOS/Views/Cell/TweetSendCreateLocationCell.xib @@ -1,8 +1,12 @@ - - + + + + + - + + @@ -11,7 +15,7 @@ - + diff --git a/Coding_iOS/Views/Cell/TweetSendDetailLoctionCell.xib b/Coding_iOS/Views/Cell/TweetSendDetailLoctionCell.xib index f22fad848..e1d387c8f 100644 --- a/Coding_iOS/Views/Cell/TweetSendDetailLoctionCell.xib +++ b/Coding_iOS/Views/Cell/TweetSendDetailLoctionCell.xib @@ -1,9 +1,13 @@ - - + + + + + - + + @@ -15,35 +19,27 @@ - - - - diff --git a/Coding_iOS/Views/Cell/TweetSendLocationCell.m b/Coding_iOS/Views/Cell/TweetSendLocationCell.m index 7ab67fc00..80d12fa91 100644 --- a/Coding_iOS/Views/Cell/TweetSendLocationCell.m +++ b/Coding_iOS/Views/Cell/TweetSendLocationCell.m @@ -53,7 +53,7 @@ - (void)setLocation:(NSString *)locationStr{ if (locationStr.length > 0) { [self.iconImageView setImage:[UIImage imageNamed:@"icon_locationed"]]; self.locationL.text = locationStr; - self.locationL.textColor = kColorBrandGreen; + self.locationL.textColor = kColorBrandBlue; }else{ [self.iconImageView setImage:[UIImage imageNamed:@"icon_not_locationed"]]; self.locationL.text = @"所在位置"; diff --git a/Coding_iOS/Views/Cell/TweetSendTextCell.m b/Coding_iOS/Views/Cell/TweetSendTextCell.m index e1c9a75c8..816b1a3fd 100755 --- a/Coding_iOS/Views/Cell/TweetSendTextCell.m +++ b/Coding_iOS/Views/Cell/TweetSendTextCell.m @@ -121,11 +121,6 @@ - (UIView *)keyboardToolBar{ UIButton *atButton = [self toolButtonWithToolBarFrame:keyboardToolBar.frame index:3 imageStr:@"keyboard_at" andSelecter:@selector(atButtonClicked:)]; [keyboardToolBar addSubview:atButton]; - - - if ([[FunctionTipsManager shareManager] needToTip:kFunctionTipStr_TweetTopic]) { - [topicButton addBadgePoint:4 withPointPosition:CGPointMake(27, 7)]; - } } [_footerToolBar addSubview:keyboardToolBar]; @@ -160,7 +155,7 @@ - (UIButton *)locationButtonWithStr:(NSString *)locationStr{ [_locationButton setWidth:MIN(kScreen_Width - 30, 35+ [titleStr getWidthWithFont:_locationButton.titleLabel.font constrainedToSize:CGSizeMake(CGFLOAT_MAX, 20)])]; - [_locationButton setTitleColor:[UIColor colorWithHexString:locationStr.length > 0? @"0x3bbd79": @"0x999999"] forState:UIControlStateNormal]; + [_locationButton setTitleColor:[UIColor colorWithHexString:locationStr.length > 0? @"0x0060FF": @"0x999999"] forState:UIControlStateNormal]; [_locationButton setImage:[UIImage imageNamed:locationStr.length > 0? @"icon_locationed": @"icon_not_locationed"] forState:UIControlStateNormal]; [_locationButton setTitle:titleStr forState:UIControlStateNormal]; return _locationButton; @@ -198,13 +193,6 @@ - (void)atButtonClicked:(id)sender{ - (void)topicButtonClicked:(id)sender{ [MobClick event:kUmeng_Event_Request_ActionOfLocal label:@"冒泡_添加_话题"]; - - if ([[FunctionTipsManager shareManager] needToTip:kFunctionTipStr_TweetTopic]) { - [[FunctionTipsManager shareManager] markTiped:kFunctionTipStr_TweetTopic]; - UIButton *btnTopic = (UIButton *)sender; - [btnTopic removeBadgePoint]; - } - @weakify(self); [CSTopicCreateVC showATSomeoneWithBlock:^(NSString *topicName) { @strongify(self); @@ -242,7 +230,8 @@ - (void)keyboardChange:(NSNotification*)aNotification{ CGRect keyboardEndFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; [UIView animateWithDuration:animationDuration delay:0.0f options:[UIView animationOptionsForCurve:animationCurve] animations:^{ CGFloat keyboardY = keyboardEndFrame.origin.y; - [self.footerToolBar setY:keyboardY- CGRectGetHeight(self.footerToolBar.frame)]; + CGFloat footerToolBarY = keyboardY- CGRectGetHeight(self.footerToolBar.frame) - ((keyboardY+1 > kScreen_Height)? kSafeArea_Bottom: 0); + [self.footerToolBar setY:footerToolBarY]; } completion:^(BOOL finished) { }]; } @@ -252,9 +241,8 @@ - (void)keyboardChange:(NSNotification*)aNotification{ - (void)emojiKeyBoardView:(AGEmojiKeyboardView *)emojiKeyBoardView didUseEmoji:(NSString *)emoji { NSRange selectedRange = self.tweetContentView.selectedRange; - NSString *emotion_monkey = [emoji emotionMonkeyName]; + NSString *emotion_monkey = [emoji emotionSpecailName]; if (emotion_monkey) { - emotion_monkey = [NSString stringWithFormat:@" :%@: ", emotion_monkey]; self.tweetContentView.text = [self.tweetContentView.text stringByReplacingCharactersInRange:selectedRange withString:emotion_monkey]; self.tweetContentView.selectedRange = NSMakeRange(selectedRange.location +emotion_monkey.length, 0); [self textViewDidChange:self.tweetContentView]; @@ -274,14 +262,10 @@ - (void)emojiKeyBoardViewDidPressSendButton:(AGEmojiKeyboardView *)emojiKeyBoard } - (UIImage *)emojiKeyboardView:(AGEmojiKeyboardView *)emojiKeyboardView imageForSelectedCategory:(AGEmojiKeyboardViewCategoryImage)category { - UIImage *img; - if (category == AGEmojiKeyboardViewCategoryImageEmoji) { - img = [UIImage imageNamed:@"keyboard_emotion_emoji"]; - }else if (category == AGEmojiKeyboardViewCategoryImageMonkey){ - img = [UIImage imageNamed:@"keyboard_emotion_monkey"]; - }else{ - img = [UIImage imageNamed:@"keyboard_emotion_monkey_gif"]; - } + UIImage *img = [UIImage imageNamed:(category == AGEmojiKeyboardViewCategoryImageEmoji? @"keyboard_emotion_emoji": + category == AGEmojiKeyboardViewCategoryImageMonkey? @"keyboard_emotion_monkey": + category == AGEmojiKeyboardViewCategoryImageMonkey_Gif? @"keyboard_emotion_monkey_gif": + @"keyboard_emotion_emoji_code")] ?: [UIImage new]; return img; } diff --git a/Coding_iOS/Views/Cell/UserActiveGraphCell.h b/Coding_iOS/Views/Cell/UserActiveGraphCell.h new file mode 100644 index 000000000..602d1393d --- /dev/null +++ b/Coding_iOS/Views/Cell/UserActiveGraphCell.h @@ -0,0 +1,20 @@ +// +// UserActiveGraphCell.h +// Coding_iOS +// +// Created by 张达棣 on 16/11/28. +// Copyright © 2016年 Coding. All rights reserved. +// + +#import +#import "ActivenessModel.h" + +#define kCellIdentifier_UserActiveGraphCell @"UserActiveGraphCell" + +@interface UserActiveGraphCell : UITableViewCell + +@property (nonatomic, strong) ActivenessModel *activenessModel; + ++ (CGFloat)cellHeight; + +@end diff --git a/Coding_iOS/Views/Cell/UserActiveGraphCell.m b/Coding_iOS/Views/Cell/UserActiveGraphCell.m new file mode 100644 index 000000000..69202e5da --- /dev/null +++ b/Coding_iOS/Views/Cell/UserActiveGraphCell.m @@ -0,0 +1,126 @@ +// +// UserActiveGraphCell.m +// Coding_iOS +// +// Created by 张达棣 on 16/11/28. +// Copyright © 2016年 Coding. All rights reserved. +// + +#import "UserActiveGraphCell.h" +#import "ActivityMonScrollView.h" +#import "UserActiveStatusView.h" + +@interface UserActiveGraphCell () +@property (nonatomic, strong) ActivityMonScrollView *scrollView; +@property (nonatomic, strong) NSArray *userActiveStatusViewArray; +@end + +@implementation UserActiveGraphCell + +#pragma mark - 生命周期方法 + +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + [self creatView]; + } + return self; +} + +- (void)awakeFromNib { + [super awakeFromNib]; + [self creatView]; + + // Initialization code +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated { + [super setSelected:selected animated:animated]; + + // Configure the view for the selected state +} + +#pragma mark - 外部方法 + ++ (CGFloat)cellHeight { + return 202; +} + +#pragma makr - 消息 + +#pragma mark - 系统委托 + +#pragma mark - 自定义委托 + +#pragma mark - 响应方法 + +#pragma mark - 私有方法 + +- (void)creatView { + self.selectionStyle = UITableViewCellSelectionStyleNone; + + NSArray *textArray = @[@"M", @"W", @"F"]; + NSArray *topArray = @[@43, @65, @87]; + for (int i = 0; i < 3; i++) { + UILabel *mondayLabel = [[UILabel alloc] init]; + mondayLabel.text = textArray[i]; + mondayLabel.textColor = [UIColor colorWithRGBHex:0x999999]; + mondayLabel.font = [UIFont systemFontOfSize:12]; + [self.contentView addSubview:mondayLabel]; + mondayLabel.sd_layout.leftSpaceToView(self.contentView, 15).topSpaceToView(self.contentView, [topArray[i] intValue]).widthIs(12).heightIs(17); + } + + _scrollView = [[ActivityMonScrollView alloc] init]; + [self.contentView addSubview:_scrollView]; + _scrollView.sd_layout.leftSpaceToView(self.contentView, 32).topSpaceToView(self.contentView, 15).rightSpaceToView(self.contentView, 0).heightIs(98); + + NSMutableArray *temp = [NSMutableArray array]; + UIView *stateView = [[UIView alloc] init]; + [self.contentView addSubview:stateView]; + stateView.sd_layout.leftSpaceToView(self.contentView, 15).topSpaceToView(_scrollView, 15).rightSpaceToView(self.contentView, 15).heightIs(59); + + for (int i = 0; i < 3; i++) { + UserActiveStatusView *itemView = [[UserActiveStatusView alloc] init]; + itemView.borderWidth = .5; + itemView.borderColor = [UIColor colorWithRGBHex:0xd8dde4]; + [stateView addSubview:itemView]; + itemView.sd_layout.heightIs(59); + [temp addObject:itemView]; + } + self.userActiveStatusViewArray = temp; + [stateView setupAutoWidthFlowItems:[temp copy] withPerRowItemsCount:temp.count verticalMargin:0 horizontalMargin:-.5]; +} + +- (NSString *)addSeparatorWithStr:(NSString *)str { + NSMutableString *tempStr = [NSMutableString stringWithFormat:@"%@", str]; + NSInteger index = tempStr.length; + while ((index - 3) > 0) { + index -= 3; + [tempStr insertString:@"," atIndex:index]; + } + return tempStr; +} + +#pragma mark - get/set方法 + +- (void)setActivenessModel:(ActivenessModel *)activenessModel { + _activenessModel = activenessModel; + + _scrollView.dailyActiveness = activenessModel.dailyActiveness; + _scrollView.startMon = [[activenessModel.start_date substringWithRange:NSMakeRange(5, 2)] integerValue]; + + NSArray *statusArray = @[@[[NSString stringWithFormat:@"%@ 度", [self addSeparatorWithStr:_activenessModel.total_with_seal_top_line]], + @"过去一年的活跃度"], + @[[NSString stringWithFormat:@"%@ 天", [self addSeparatorWithStr:_activenessModel.longest_active_duration.days]], + @"最长连续活跃天数"], + @[[NSString stringWithFormat:@"%@ 天", [self addSeparatorWithStr:_activenessModel.current_active_duration.days]], + @"当前连续活跃天数"], + ]; + for (int i = 0; i < _userActiveStatusViewArray.count; i++) { + UserActiveStatusView *itemView = _userActiveStatusViewArray[i]; + itemView.title = statusArray[i][0]; + itemView.details = statusArray[i][1]; + } +} + +@end diff --git a/Coding_iOS/Views/Cell/UserCell.m b/Coding_iOS/Views/Cell/UserCell.m index 4c2238928..32aa37dad 100755 --- a/Coding_iOS/Views/Cell/UserCell.m +++ b/Coding_iOS/Views/Cell/UserCell.m @@ -13,6 +13,7 @@ @interface UserCell () @property (strong, nonatomic) UILabel *userNameLabel; @property (strong, nonatomic) UIButton *rightBtn; @property (strong, nonatomic) UIActivityIndicatorView *sendingStatus; +@property (strong, nonatomic) UIImageView *vipV; @end @@ -24,7 +25,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (self) { // Initialization code if (!_userIconView) { - _userIconView = [[UIImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, ([UserCell cellHeight]-40)/2, 40, 40)]; + _userIconView = [[YLImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, ([UserCell cellHeight]-40)/2, 40, 40)]; [_userIconView doCircleFrame]; [self.contentView addSubview:_userIconView]; } @@ -39,6 +40,13 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus [_rightBtn addTarget:self action:@selector(rightBtnClicked:) forControlEvents:UIControlEventTouchUpInside]; [self.contentView addSubview:_rightBtn]; } + if (!_vipV) { + _vipV = [UIImageView new]; + [self.contentView addSubview:_vipV]; + [_vipV mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.bottom.equalTo(_userIconView); + }]; + } } return self; } @@ -49,12 +57,15 @@ - (void)layoutSubviews{ if (!_curUser) { [_userIconView setImage:[UIImage imageNamed:@"add_user_icon"]]; _userNameLabel.text = @"添加好友"; + _vipV.image = nil; }else{ [_userIconView sd_setImageWithURL:[_curUser.avatar urlImageWithCodePathResizeToView:_userIconView] placeholderImage:kPlaceholderMonkeyRoundView(_userIconView)]; + _vipV.image = [UIImage imageNamed:[NSString stringWithFormat:@"vip_%@_40", _curUser.vip]]; _userNameLabel.text = _curUser.name; } + _vipV.hidden = kTarget_Enterprise; - if (_usersType == UsersTypeFriends_Message || _usersType == UsersTypeFriends_At || _usersType == UsersTypeFriends_Transpond) { + if (_usersType == UsersTypeFriends_Message || _usersType == UsersTypeFriends_At || _usersType == UsersTypeFriends_Transpond || _usersType == UsersType_CompanyMember) { _rightBtn.hidden = YES; }else if (_usersType == UsersTypeAddToProject){ NSString *imageName = _isInProject? @"btn_project_added":@"btn_project_add"; diff --git a/Coding_iOS/Views/Cell/UserInfoDetailTagCell.h b/Coding_iOS/Views/Cell/UserInfoDetailTagCell.h index 8bd0e40ad..7f1739e74 100644 --- a/Coding_iOS/Views/Cell/UserInfoDetailTagCell.h +++ b/Coding_iOS/Views/Cell/UserInfoDetailTagCell.h @@ -11,6 +11,7 @@ #import @interface UserInfoDetailTagCell : UITableViewCell +- (void)setTitleStr:(NSString *)titleStr; - (void)setTagStr:(NSString *)tagStr; + (CGFloat)cellHeightWithObj:(id)obj; @end diff --git a/Coding_iOS/Views/Cell/UserInfoDetailTagCell.m b/Coding_iOS/Views/Cell/UserInfoDetailTagCell.m index dc493a23b..d571804a2 100644 --- a/Coding_iOS/Views/Cell/UserInfoDetailTagCell.m +++ b/Coding_iOS/Views/Cell/UserInfoDetailTagCell.m @@ -25,6 +25,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus [self.contentView addSubview:_titleL]; _titleL.font = [UIFont systemFontOfSize:16]; _titleL.textColor = [UIColor blackColor]; + _titleL.text = @"个性标签"; } if (!_valueL) { _valueL = [[UILabel alloc] init]; @@ -48,8 +49,11 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus return self; } +- (void)setTitleStr:(NSString *)titleStr{ + _titleL.text = titleStr; +} + - (void)setTagStr:(NSString *)tagStr{ - _titleL.text = @"个性标签"; _valueL.text = tagStr; [_valueL sizeToFit]; } diff --git a/Coding_iOS/Views/Cell/UserInfoDetailUserCell.m b/Coding_iOS/Views/Cell/UserInfoDetailUserCell.m index ddd26e3e4..32b10c34d 100644 --- a/Coding_iOS/Views/Cell/UserInfoDetailUserCell.m +++ b/Coding_iOS/Views/Cell/UserInfoDetailUserCell.m @@ -20,7 +20,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (self) { // Initialization code if (!_iconView) { - _iconView = [[UIImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, ([UserInfoDetailUserCell cellHeight] - 50)/2, 50, 50)]; + _iconView = [[YLImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, ([UserInfoDetailUserCell cellHeight] - 50)/2, 50, 50)]; [_iconView doCircleFrame]; [self.contentView addSubview:_iconView]; } @@ -49,4 +49,4 @@ - (void)setName:(NSString *)name icon:(NSString *)iconUrl{ + (CGFloat)cellHeight{ return 70.0; } -@end \ No newline at end of file +@end diff --git a/Coding_iOS/Views/Cell/UserInfoIconCell.m b/Coding_iOS/Views/Cell/UserInfoIconCell.m index 64772db7d..0c5bb5cc7 100644 --- a/Coding_iOS/Views/Cell/UserInfoIconCell.m +++ b/Coding_iOS/Views/Cell/UserInfoIconCell.m @@ -19,13 +19,14 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { // Initialization code + self.clipsToBounds = self.contentView.clipsToBounds = YES; self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; if (!_iconView) { - _iconView = [[UIImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, 11, 22, 22)]; + _iconView = [[UIImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, ([UserInfoIconCell cellHeight] - 22)/ 2, 22, 22)]; [self.contentView addSubview:_iconView]; } if (!_titleL) { - _titleL = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(_iconView.frame) + kPaddingLeftWidth, 12, kScreen_Width/2, 20)]; + _titleL = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(_iconView.frame) + kPaddingLeftWidth, ([UserInfoIconCell cellHeight] - 20)/ 2, kScreen_Width/2, 20)]; _titleL.textAlignment = NSTextAlignmentLeft; _titleL.font = [UIFont systemFontOfSize:15]; _titleL.textColor = kColor222; @@ -41,10 +42,11 @@ - (void)setTitle:(NSString *)title icon:(NSString *)iconName{ } + (CGFloat)cellHeight{ - return 44; + return 50; } #pragma mark Tip - (void)prepareForReuse{ + [super prepareForReuse]; [self removeTip]; self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; } diff --git a/Coding_iOS/Views/Cell/UserSearchCell.m b/Coding_iOS/Views/Cell/UserSearchCell.m index 7cadd5d78..5d74dd3a0 100644 --- a/Coding_iOS/Views/Cell/UserSearchCell.m +++ b/Coding_iOS/Views/Cell/UserSearchCell.m @@ -26,7 +26,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (self) { // Initialization code if (!_userIconView) { - _userIconView = [[UIImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, (kUserSearchCellHeight-40)/2, 40, 40)]; + _userIconView = [[YLImageView alloc] initWithFrame:CGRectMake(kPaddingLeftWidth, (kUserSearchCellHeight-40)/2, 40, 40)]; [_userIconView doCircleFrame]; [self.contentView addSubview:_userIconView]; } diff --git a/Coding_iOS/Views/Cell/ValueListCell.m b/Coding_iOS/Views/Cell/ValueListCell.m index 3a242886d..d1fe8f4b4 100755 --- a/Coding_iOS/Views/Cell/ValueListCell.m +++ b/Coding_iOS/Views/Cell/ValueListCell.m @@ -6,7 +6,7 @@ // Copyright (c) 2014年 Coding. All rights reserved. // -#define kValueListCell_ImageWidth 21.0 +#define kValueListCell_ImageWidth 22.0 #define kValueListCell_CheckMarkWidth 22.0 #define kValueListCell_LeftPading 20.0 @@ -27,10 +27,11 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus if (!_titleLabel) { _titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(kValueListCell_LeftPading, 7, (kScreen_Width - 120), 30)]; _titleLabel.backgroundColor = [UIColor clearColor]; - _titleLabel.font = [UIFont systemFontOfSize:16]; - _titleLabel.textColor = [UIColor blackColor]; + _titleLabel.font = [UIFont systemFontOfSize:15]; + _titleLabel.textColor = kColorDark2; [self.contentView addSubview:_titleLabel]; } + self.clipsToBounds = YES; } return self; } diff --git a/Coding_iOS/Views/Cell/WikiHistoryCell.h b/Coding_iOS/Views/Cell/WikiHistoryCell.h new file mode 100644 index 000000000..d8e51e8fd --- /dev/null +++ b/Coding_iOS/Views/Cell/WikiHistoryCell.h @@ -0,0 +1,17 @@ +// +// WikiHistoryCell.h +// Coding_Enterprise_iOS +// +// Created by Easeeeeeeeee on 2017/4/10. +// Copyright © 2017年 Coding. All rights reserved. +// +#define kCellIdentifier_WikiHistoryCell @"WikiHistoryCell" + +#import +#import "EAWiki.h" + +@interface WikiHistoryCell : UITableViewCell +@property (strong, nonatomic) EAWiki *curWiki; + ++ (CGFloat)cellHeightWithObj:(EAWiki *)obj; +@end diff --git a/Coding_iOS/Views/Cell/WikiHistoryCell.m b/Coding_iOS/Views/Cell/WikiHistoryCell.m new file mode 100644 index 000000000..a4768548e --- /dev/null +++ b/Coding_iOS/Views/Cell/WikiHistoryCell.m @@ -0,0 +1,99 @@ +// +// WikiHistoryCell.m +// Coding_Enterprise_iOS +// +// Created by Easeeeeeeeee on 2017/4/10. +// Copyright © 2017年 Coding. All rights reserved. +// + +#define kWikiHistoryCell_MsgWidth (kScreen_Width - 120) + +#import "WikiHistoryCell.h" + +@interface WikiHistoryCell () +@property (strong, nonatomic) UILabel *versionL, *timeL, *editorL, *msgL; +@end + +@implementation WikiHistoryCell +- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + // Initialization code + self.selectionStyle = UITableViewCellSelectionStyleNone; + + _versionL = [UILabel labelWithFont:[UIFont systemFontOfSize:15] textColor:kColorDark3]; + _timeL = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDark3]; + _editorL = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDark3]; + _msgL = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDark3]; + UILabel *editorTitleL = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDark7]; + UILabel *msgTitleL = [UILabel labelWithFont:[UIFont systemFontOfSize:14] textColor:kColorDark7]; + UIView *lineV = [UIView new]; + lineV.backgroundColor = kColorDDD; + _timeL.textAlignment = _editorL.textAlignment = _msgL.textAlignment = NSTextAlignmentRight; + + [self.contentView addSubview:_versionL]; + [self.contentView addSubview:_timeL]; + [self.contentView addSubview:lineV]; + [self.contentView addSubview:editorTitleL]; + [self.contentView addSubview:_editorL]; + [self.contentView addSubview:msgTitleL]; + [self.contentView addSubview:_msgL]; + + [_versionL mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.contentView).offset(10); + make.left.equalTo(self.contentView).offset(kPaddingLeftWidth); + make.height.mas_equalTo(24); + }]; + [_timeL mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.mas_equalTo(self.contentView).offset(-kPaddingLeftWidth); + make.centerY.equalTo(_versionL); + }]; + [lineV mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(kLine_MinHeight); + make.top.equalTo(self.contentView).offset(44); + make.left.equalTo(_versionL); + make.right.equalTo(self.contentView); + }]; + [editorTitleL mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(_versionL); + make.height.mas_equalTo(20); + make.top.equalTo(lineV.mas_bottom).offset(10); + }]; + [_editorL mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.equalTo(_timeL); + make.centerY.equalTo(editorTitleL); + }]; + [msgTitleL mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(20); + make.left.equalTo(_versionL); + make.top.equalTo(editorTitleL.mas_bottom).offset(10); + }]; + [_msgL mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.equalTo(_timeL); + make.top.equalTo(msgTitleL); + make.width.mas_equalTo(kWikiHistoryCell_MsgWidth); + }]; + editorTitleL.text = @"创建者"; + msgTitleL.text = @"提交信息"; + } + return self; +} + +- (void)setCurWiki:(EAWiki *)curWiki{ + _curWiki = curWiki; + + _versionL.text = [NSString stringWithFormat:@"版本 %@", _curWiki.version]; + _timeL.text = [_curWiki.createdAt stringWithFormat:@"MM-dd HH:mm"]; + _editorL.text = _curWiki.editor.name; + _msgL.text = _curWiki.msg.length > 0? _curWiki.msg : @"--"; +} + ++ (CGFloat)cellHeightWithObj:(EAWiki *)obj{ + CGFloat cellHeight = 115; + CGFloat msgHeight = [obj.msg getHeightWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake(kWikiHistoryCell_MsgWidth, CGFLOAT_MAX)]; + if (msgHeight > 20) { + cellHeight += (msgHeight - 20); + } + return cellHeight; +} +@end diff --git a/Coding_iOS/Views/Cell/WikiMenuListCell.h b/Coding_iOS/Views/Cell/WikiMenuListCell.h new file mode 100644 index 000000000..b9b484609 --- /dev/null +++ b/Coding_iOS/Views/Cell/WikiMenuListCell.h @@ -0,0 +1,19 @@ +// +// WikiMenuListCell.h +// Coding_Enterprise_iOS +// +// Created by Ease on 2017/4/5. +// Copyright © 2017年 Coding. All rights reserved. +// +#define kCellIdentifier_WikiMenuListCellLavel(__lavel__) [NSString stringWithFormat:@"WikiMenuListCellLavel_%d", __lavel__] + +#import +#import "EAWiki.h" + +@interface WikiMenuListCell : UITableViewCell +@property (copy, nonatomic) void(^selectedWikiBlock)(EAWiki *wiki); +@property (copy, nonatomic) void (^expandBlock)(EAWiki *wiki); + +- (void)setCurWiki:(EAWiki *)curWiki selectedWiki:(EAWiki *)selectedWiki; ++ (CGFloat)cellHeightWithObj:(EAWiki *)obj; +@end diff --git a/Coding_iOS/Views/Cell/WikiMenuListCell.m b/Coding_iOS/Views/Cell/WikiMenuListCell.m new file mode 100644 index 000000000..e1003d1ac --- /dev/null +++ b/Coding_iOS/Views/Cell/WikiMenuListCell.m @@ -0,0 +1,168 @@ +// +// WikiMenuListCell.m +// Coding_Enterprise_iOS +// +// Created by Ease on 2017/4/5. +// Copyright © 2017年 Coding. All rights reserved. +// +#define kWikiMenuListCell_Padding 20.0 +#define kWikiMenuListCell_PerWikiTab 30.0 +#define kWikiMenuListCell_PerWikiHeight 50.0 + +#import "WikiMenuListCell.h" + +@interface WikiMenuListCell () +@property (strong, nonatomic) EAWiki *curWiki; +@property (strong, nonatomic) EAWiki *selectedWiki; +@property (assign, nonatomic) NSInteger lavel; + +@property (strong, nonatomic) UIButton *expandBtn; +@property (strong, nonatomic) UILabel *titleL; +@property (strong, nonatomic) UIView *lineV; +@property (strong, nonatomic) UITableView *myTableView; +@end + +@implementation WikiMenuListCell + +- (void)setupLineV{ + if (!_lineV) { + _lineV = [UIView new]; + _lineV.backgroundColor = kColorDDD; + [self.contentView addSubview:_lineV]; + CGFloat left = kWikiMenuListCell_Padding + (_lavel * kWikiMenuListCell_PerWikiTab); + [_lineV mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.contentView).offset(left); + make.right.equalTo(self.contentView); + make.top.mas_equalTo(kWikiMenuListCell_PerWikiHeight - 1); + make.height.mas_equalTo(kLine_MinHeight); + }]; + } +} + +- (void)setupTitleL{ + if (!_titleL) { + _titleL = [UILabel labelWithFont:_lavel == 0? [UIFont systemFontOfSize:17 weight:UIFontWeightMedium]: [UIFont systemFontOfSize:15] textColor:kColorDark3]; + [self.contentView addSubview:_titleL]; + [_titleL mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.contentView).offset((kWikiMenuListCell_PerWikiHeight - 20)/ 2); + make.height.mas_equalTo(20); + make.right.equalTo(self.contentView).offset(-kWikiMenuListCell_Padding); + make.left.equalTo(self.contentView).offset(kWikiMenuListCell_Padding); + }]; + } + [_titleL mas_updateConstraints:^(MASConstraintMaker *make) { + CGFloat left = kWikiMenuListCell_Padding + (_lavel * kWikiMenuListCell_PerWikiTab) + (_curWiki.hasChildren? 20: 0); + make.left.equalTo(self.contentView).offset(left); + }]; + _titleL.text = _curWiki.title; + _titleL.textColor = (_selectedWiki.iid && [_curWiki.iid isEqualToNumber:_selectedWiki.iid])? kColorBrandBlue: kColorDark3; +} + +- (void)setupExpandBtn{ + _expandBtn.hidden = !_curWiki.hasChildren; + if (_curWiki.hasChildren) { + if (!_expandBtn) { + _expandBtn = [UIButton new]; + [_expandBtn setImage:[UIImage imageNamed:@"btn_fliter_down"] forState:UIControlStateNormal]; + _expandBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight; + _expandBtn.imageEdgeInsets = UIEdgeInsetsMake(0, -15, 0, 15); + [self.contentView addSubview:_expandBtn]; + CGFloat width = kWikiMenuListCell_Padding + (_lavel * kWikiMenuListCell_PerWikiTab) + 5 + 15; + [_expandBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.left.equalTo(self.contentView); + make.height.mas_equalTo(kWikiMenuListCell_PerWikiHeight); + make.width.mas_equalTo(width); + }]; + + __weak typeof(self) weakSelf = self; + [_expandBtn bk_addEventHandler:^(id sender) { + if (weakSelf.expandBlock) { + weakSelf.expandBlock(weakSelf.curWiki); + } + } forControlEvents:UIControlEventTouchUpInside]; + } + _expandBtn.imageView.transform = CGAffineTransformMakeRotation(_curWiki.isExpanded? 0: -M_PI_2); + } +} + +- (void)setupTableView{ + _myTableView.hidden = !_curWiki.isExpanded; + if (_curWiki.isExpanded) { + if (!_myTableView) { + _myTableView = ({ + UITableView *tableView = [[UITableView alloc] init]; + tableView.scrollEnabled = NO; + tableView.delegate = self; + tableView.dataSource = self; + [tableView registerClass:[WikiMenuListCell class] forCellReuseIdentifier:kCellIdentifier_WikiMenuListCellLavel((int)(_curWiki.lavel + 1))]; + tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + [self.contentView addSubview:tableView]; + [tableView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.contentView).insets(UIEdgeInsetsMake(kWikiMenuListCell_PerWikiHeight, 0, 0, 0)); + }]; + tableView; + }); + } + [_myTableView reloadData]; + } +} + +- (void)setCurWiki:(EAWiki *)curWiki selectedWiki:(EAWiki *)selectedWiki{ + _curWiki = curWiki; + _selectedWiki = selectedWiki; + _lavel = _curWiki.lavel; + + [self setupLineV]; + [self setupTitleL]; + [self setupExpandBtn]; + [self setupTableView]; +} + ++ (CGFloat)cellHeightWithObj:(EAWiki *)obj{ + CGFloat cellHeight = 0; + cellHeight += kWikiMenuListCell_PerWikiHeight; + if (obj.isExpanded) { + for (EAWiki *wiki in obj.childrenDisplayList) { + cellHeight += [self cellHeightWithObj:wiki]; + } + } + return cellHeight; +} + +#pragma mark Table +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + return _curWiki.childrenDisplayList.count; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ + return [WikiMenuListCell cellHeightWithObj:_curWiki.childrenDisplayList[indexPath.row]]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + WikiMenuListCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_WikiMenuListCellLavel((int)(_curWiki.lavel + 1)) forIndexPath:indexPath]; + [cell setCurWiki:_curWiki.childrenDisplayList[indexPath.row] selectedWiki:_selectedWiki]; + __weak typeof(self) weakSelf = self; + cell.expandBlock = ^(EAWiki *wiki){ + if (weakSelf.expandBlock) { + weakSelf.expandBlock(wiki); + } + }; + cell.selectedWikiBlock = ^(EAWiki *wiki){ + [weakSelf handleSelectedWiki:wiki]; + }; + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + [self handleSelectedWiki:_curWiki.childrenDisplayList[indexPath.row]]; +} + +- (void)handleSelectedWiki:(EAWiki *)wiki{ + _selectedWiki = wiki; + if (_selectedWikiBlock) { + _selectedWikiBlock(wiki); + } +} + +@end diff --git a/Coding_iOS/Views/CodeBranchTagButton.h b/Coding_iOS/Views/CodeBranchTagButton.h index 9a142427a..b40176461 100644 --- a/Coding_iOS/Views/CodeBranchTagButton.h +++ b/Coding_iOS/Views/CodeBranchTagButton.h @@ -14,7 +14,9 @@ @property (strong, nonatomic) Project *curProject; @property (nonatomic, strong) NSArray *branchList, *tagList; @property (nonatomic, strong, readonly) NSArray *dataList; +@property (weak, nonatomic) UIView *showingContainerView; @property (nonatomic,copy) void(^selectedBranchTagBlock)(NSString *branchTag); + (instancetype)buttonWithProject:(Project *)project andTitleStr:(NSString *)titleStr; +- (void)dismissShowingList; @end diff --git a/Coding_iOS/Views/CodeBranchTagButton.m b/Coding_iOS/Views/CodeBranchTagButton.m index 05174839d..e6d0f8ef0 100644 --- a/Coding_iOS/Views/CodeBranchTagButton.m +++ b/Coding_iOS/Views/CodeBranchTagButton.m @@ -38,18 +38,31 @@ - (instancetype)initWithFrame:(CGRect)frame if (self) { _isShowing = NO; [self addTarget:self action:@selector(changeShowing) forControlEvents:UIControlEventTouchUpInside]; - [self addLineUp:YES andDown:NO andColor:[UIColor lightGrayColor]]; + [self addLineUp:YES andDown:YES andColor:kColorDDD]; } return self; } +- (UIView *)showingContainerView{ + if (!_showingContainerView) { + _showingContainerView = kKeyWindow; + } + return _showingContainerView; +} + + (instancetype)buttonWithProject:(Project *)project andTitleStr:(NSString *)titleStr{ - CodeBranchTagButton *button = [[CodeBranchTagButton alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 49)]; + CodeBranchTagButton *button = [[CodeBranchTagButton alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 44.0)]; button.titleStr = titleStr; button.curProject = project; return button; } +- (void)dismissShowingList{ + if (self.isShowing) { + [self changeShowing]; + } +} + - (UIView *)myTapBackgroundView{ if (!_myTapBackgroundView) { _myTapBackgroundView = ({ @@ -77,11 +90,15 @@ - (UIView *)myContentView{ - (UITableView *)myTableView{ if (!_myTableView) { _myTableView = ({ - UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped]; + UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; + tableView.backgroundColor = [UIColor whiteColor]; [tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:kCellIdentifier_BranchTag]; - tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; + tableView.separatorStyle = UITableViewCellSeparatorStyleNone; tableView.dataSource = self; tableView.delegate = self; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); } @@ -92,15 +109,15 @@ - (UISegmentedControl *)mySegmentedControl{ if (!_mySegmentedControl) { _mySegmentedControl = ({ UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:@[@"分支", @"标签"]]; - segmentedControl.tintColor = kColorBrandGreen; + segmentedControl.tintColor = kColorBrandBlue; [segmentedControl setTitleTextAttributes:@{ - NSFontAttributeName: [UIFont boldSystemFontOfSize:16], + NSFontAttributeName: [UIFont systemFontOfSize:13], NSForegroundColorAttributeName: [UIColor whiteColor] } forState:UIControlStateSelected]; [segmentedControl setTitleTextAttributes:@{ - NSFontAttributeName: [UIFont boldSystemFontOfSize:16], - NSForegroundColorAttributeName: kColorBrandGreen + NSFontAttributeName: [UIFont systemFontOfSize:13], + NSForegroundColorAttributeName: kColorBrandBlue } forState:UIControlStateNormal]; [segmentedControl addTarget:self action:@selector(segmentedControlSelected:) forControlEvents:UIControlEventValueChanged]; segmentedControl; @@ -122,7 +139,13 @@ - (void)loadUIElement{ [self.myContentView addSubview:self.mySegmentedControl]; self.mySegmentedControl.frame = CGRectMake(12, (kCodeBranchTagButton_NavHeight - 30)/2, kScreen_Width - 2*12, 30); - self.myTableView.frame = CGRectMake(0, kCodeBranchTagButton_NavHeight, kScreen_Width, kCodeBranchTagButton_ContentHeight-kCodeBranchTagButton_NavHeight); + { + UIView *lineV = [[UIView alloc] initWithFrame:CGRectMake(0, kCodeBranchTagButton_NavHeight, kScreen_Width, kLine_MinHeight)]; + lineV.backgroundColor = kColorDDD; + [self.myContentView addSubview:lineV]; + } + self.myContentView.frame = CGRectMake(0, 0, kScreen_Width, 0); + self.myTableView.frame = CGRectMake(0, kCodeBranchTagButton_NavHeight, kScreen_Width, 0); // _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; // [_myRefreshControl addTarget:self action:@selector(queryToRefresh) forControlEvents:UIControlEventValueChanged]; @@ -136,14 +159,15 @@ - (void)changeShowing{ if (!_myContentView) {//未载入过 [self loadUIElement]; } - CGPoint origin = [self convertPoint:CGPointZero toView:kKeyWindow]; - CGFloat contentHeight = self.isShowing? 0: kCodeBranchTagButton_ContentHeight; + CGPoint origin = [self convertPoint:CGPointMake(0, CGRectGetHeight(self.bounds)) toView:self.showingContainerView]; + CGFloat contentHeight = self.isShowing? 0: CGRectGetHeight(self.showingContainerView.bounds) - origin.y; if (self.isShowing) {//隐藏 self.enabled = NO; [UIView animateWithDuration:0.3 animations:^{ self.myTapBackgroundView.backgroundColor = [UIColor colorWithWhite:0 alpha:0]; self.myContentView.alpha = 0; - self.myContentView.frame = CGRectMake(0, origin.y-contentHeight, kScreen_Width, contentHeight); + self.myContentView.height = contentHeight; + self.myTableView.height = 0; self.imageView.transform = CGAffineTransformRotate(self.imageView.transform, DEGREES_TO_RADIANS(180)); } completion:^(BOOL finished) { [self.myTapBackgroundView removeFromSuperview]; @@ -152,14 +176,17 @@ - (void)changeShowing{ self.isShowing = NO; }]; }else{//显示 + self.myTapBackgroundView.y = self.myContentView.y = origin.y; self.myContentView.frame = CGRectMake(0, origin.y, kScreen_Width, 0); - [kKeyWindow addSubview:self.myTapBackgroundView]; - [kKeyWindow addSubview:self.myContentView]; + self.myTableView.height = 0; + [self.showingContainerView addSubview:self.myTapBackgroundView]; + [self.showingContainerView addSubview:self.myContentView]; self.enabled = NO; [UIView animateWithDuration:0.3 animations:^{ self.myTapBackgroundView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.2]; self.myContentView.alpha = 1.0; - self.myContentView.frame = CGRectMake(0, origin.y-contentHeight, kScreen_Width, contentHeight); + self.myContentView.height = contentHeight; + self.myTableView.height = contentHeight - kCodeBranchTagButton_NavHeight; self.imageView.transform = CGAffineTransformRotate(self.imageView.transform, DEGREES_TO_RADIANS(180)); } completion:^(BOOL finished) { self.enabled = YES; @@ -182,8 +209,8 @@ - (void)setTitleStr:(NSString *)titleStr{ } - (void)refreshSelfUI{ - self.backgroundColor = [UIColor colorWithHexString:@"0xf3f3f3"]; - self.titleLabel.font = [UIFont systemFontOfSize:15]; + self.backgroundColor = [UIColor whiteColor]; + self.titleLabel.font = [UIFont systemFontOfSize:14]; [self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; [self setTitleColor:[UIColor darkGrayColor] forState:UIControlStateHighlighted]; @@ -191,7 +218,7 @@ - (void)refreshSelfUI{ [self setImage:[UIImage imageNamed:@"icon_triangle"] forState:UIControlStateNormal]; CGFloat titleWidth = [_titleStr getWidthWithFont:self.titleLabel.font constrainedToSize:CGSizeMake(kScreen_Width, 30)]; - self.titleEdgeInsets = UIEdgeInsetsMake(0, -20, 0, 20); + self.titleEdgeInsets = UIEdgeInsetsMake(0, -10, 0, 10); self.imageEdgeInsets = UIEdgeInsetsMake(0, titleWidth, 0, -titleWidth); } @@ -237,26 +264,29 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger return [self.dataList count]; } -- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ - return 0.5; -} - -- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ - return 0.5; -} - - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_BranchTag forIndexPath:indexPath]; - cell.textLabel.textColor = [UIColor blackColor]; cell.textLabel.font = [UIFont systemFontOfSize:15]; - + cell.backgroundColor = [UIColor whiteColor]; + CodeBranchOrTag *curBranchOrTag = [self.dataList objectAtIndex:indexPath.row]; cell.textLabel.text = curBranchOrTag.name; if ([curBranchOrTag.name isEqualToString:self.titleStr]) { - cell.backgroundColor = [UIColor colorWithHexString:@"0xf3f3f3"]; + cell.textLabel.textColor = kColorBrandBlue; + cell.accessoryType = UITableViewCellAccessoryCheckmark; }else{ - cell.backgroundColor = [UIColor whiteColor]; + cell.textLabel.textColor = [UIColor blackColor]; + cell.accessoryType = UITableViewCellAccessoryNone; + } + + static NSInteger lineTag = 11011; + if (![cell.contentView viewWithTag:lineTag]) { + CGFloat lineH = kLine_MinHeight; + UIView *lineV = [[UIView alloc] initWithFrame:CGRectMake(15, 44 - lineH, kScreen_Width, lineH)]; + lineV.tag = lineTag; + lineV.backgroundColor = kColorDDD; + [cell.contentView addSubview:lineV]; } return cell; } diff --git a/Coding_iOS/Views/CodingBannersView.m b/Coding_iOS/Views/CodingBannersView.m index d05e32b36..27092ca01 100644 --- a/Coding_iOS/Views/CodingBannersView.m +++ b/Coding_iOS/Views/CodingBannersView.m @@ -29,7 +29,7 @@ - (instancetype)init if (self) { self.backgroundColor = kColorTableBG; _padding_top = 0; - _padding_bottom = 40; + _padding_bottom = 44; _image_width = kScreen_Width; _ratio = 0.4; CGFloat viewHeight = _padding_top + _padding_bottom + _image_width * _ratio; @@ -85,7 +85,7 @@ - (void)setCurBannerList:(NSArray *)curBannerList{ } if (!_myPageControl) { _myPageControl = ({ - SMPageControl *pageControl = [[SMPageControl alloc] initWithFrame:CGRectMake(kScreen_Width - kPaddingLeftWidth - 30, _mySlideView.bottom + (40 - 10)/2, 30, 10)]; + SMPageControl *pageControl = [[SMPageControl alloc] initWithFrame:CGRectMake(kScreen_Width - kPaddingLeftWidth - 30, _mySlideView.bottom + (_padding_bottom - 10)/2, 30, 10)]; pageControl.userInteractionEnabled = NO; pageControl.backgroundColor = [UIColor clearColor]; pageControl.pageIndicatorImage = [UIImage imageNamed:@"banner__page_unselected"]; @@ -100,7 +100,7 @@ - (void)setCurBannerList:(NSArray *)curBannerList{ if (!_typeLabel) { _typeLabel = ({ - UILabel *label = [UILabel labelWithFont:[UIFont systemFontOfSize:10] textColor:kColor666]; + UILabel *label = [UILabel labelWithFont:[UIFont systemFontOfSize:10] textColor:kColorDark7]; [label setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; [label setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; [label doBorderWidth:0.5 color:nil cornerRadius:2.0]; @@ -113,7 +113,7 @@ - (void)setCurBannerList:(NSArray *)curBannerList{ } if (!_titleLabel) { - _titleLabel = [UILabel labelWithFont:[UIFont systemFontOfSize:12] textColor:kColor222]; + _titleLabel = [UILabel labelWithFont:[UIFont systemFontOfSize:12] textColor:kColorDark4]; _titleLabel.text = [(CodingBanner *)_curBannerList.firstObject title]; [self addSubview:_titleLabel]; } @@ -123,8 +123,8 @@ - (void)setCurBannerList:(NSArray *)curBannerList{ make.height.mas_equalTo(18); }]; [_titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.equalTo(_typeLabel.mas_right).offset(5); - make.right.equalTo(_myPageControl.mas_left).offset(-5); + make.left.equalTo(_typeLabel.mas_right).offset(10); + make.right.equalTo(_myPageControl.mas_left).offset(-10); make.centerY.equalTo(_myPageControl); }]; [self reloadData]; diff --git a/Coding_iOS/Views/CodingShareView.m b/Coding_iOS/Views/CodingShareView.m index e75bc1825..9a214a2c7 100644 --- a/Coding_iOS/Views/CodingShareView.m +++ b/Coding_iOS/Views/CodingShareView.m @@ -13,7 +13,7 @@ #import "CodingShareView.h" #import "SMPageControl.h" -#import +#import #import #import "PrivateMessage.h" @@ -22,7 +22,7 @@ #import "ReportIllegalViewController.h" -@interface CodingShareView () +@interface CodingShareView () @property (strong, nonatomic) UIView *bgView; @property (strong, nonatomic) UIView *contentView; @property (strong, nonatomic) UILabel *titleL; @@ -82,7 +82,7 @@ - (instancetype)init button.titleLabel.font = [UIFont systemFontOfSize:15]; [button setTitle:@"取消" forState:UIControlStateNormal]; [button setTitleColor:[UIColor colorWithHexString:@"0x808080"] forState:UIControlStateNormal]; - [button setTitleColor:kColorBrandGreen forState:UIControlStateHighlighted]; + [button setTitleColor:kColorBrandBlue forState:UIControlStateHighlighted]; [button addTarget:self action:@selector(p_dismiss) forControlEvents:UIControlEventTouchUpInside]; button; }); @@ -196,7 +196,7 @@ + (NSDictionary *)snsNameDict{ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ snsNameDict = @{ - @"coding": @"Coding好友", + @"coding": @"CODING 好友", @"copylink": @"复制链接", @"evernote": @"印象笔记", @"sina": @"新浪微博", @@ -248,6 +248,16 @@ +(NSArray *)supportSnsValues{ return resultSnsValues; } +- (UMSocialPlatformType)p_umPlatformTypeWithSnsName:(NSString *)snsName{ + UMSocialPlatformType pT = ([snsName isEqualToString:@"wxsession"]? UMSocialPlatformType_WechatSession: + [snsName isEqualToString:@"wxtimeline"]? UMSocialPlatformType_WechatTimeLine: + [snsName isEqualToString:@"qq"]? UMSocialPlatformType_QQ: + [snsName isEqualToString:@"qzone"]? UMSocialPlatformType_Qzone: + [snsName isEqualToString:@"sina"]? UMSocialPlatformType_Sina: + UMSocialPlatformType_UnKnown); + return pT; +} + +(BOOL)p_canOpen:(NSString*)url{ return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:url]]; } @@ -327,13 +337,17 @@ - (void)p_doShareToSnsName:(NSString *)snsName{ [weakSelf p_willUploadENNote:note]; }]; }else{ - [[UMSocialControllerService defaultControllerService] setSocialUIDelegate:self]; - UMSocialSnsPlatform *snsPlatform = [UMSocialSnsPlatformManager getSocialPlatformWithName:snsName]; - if (snsPlatform) { - snsPlatform.snsClickHandler([BaseViewController presentingVC],[UMSocialControllerService defaultControllerService],YES); - } + [[UMSocialManager defaultManager] shareToPlatform:[self p_umPlatformTypeWithSnsName:snsName] messageObject:[self p_curShareObjWithSocialPlatform:snsName] currentViewController:[BaseViewController presentingVC] completion:^(id data, NSError *error) { + if (!error) { + [NSObject showHudTipStr:@"分享成功"]; + }else{ + [NSObject showHudTipStr:@"分享失败"]; + DebugLog(@"%@", error); + } + }]; } } + - (void)p_willUploadENNote:(ENNote *)noteToSave{ if (!noteToSave) { [NSObject showHudTipStr:@"不支持保存到印象笔记"]; @@ -392,9 +406,9 @@ - (NSString *)p_shareTitle{ if ([_objToShare isKindOfClass:[Tweet class]]) { title = [NSString stringWithFormat:@"%@ 的冒泡", [(Tweet *)_objToShare owner].name]; }else if ([_objToShare isKindOfClass:[UIWebView class]]){ - title = @"Coding 链接"; + title = @"CODING 链接"; }else{ - title = @"Coding - 让开发更简单"; + title = @"CODING - 让开发更简单"; } return title; } @@ -407,6 +421,11 @@ - (NSString *)p_shareText{ }else{ text = @"#Coding# 软件开发,云端协作"; } + NSInteger maxLength = 100; + if (text.length > maxLength) { + NSInteger location = maxLength - 3; + text = [text stringByReplacingCharactersInRange:NSMakeRange(location, text.length - location) withString:@"..."]; + } return text; } - (NSString *)p_imageUrlSquare:(BOOL)needSquare{ @@ -468,76 +487,28 @@ - (void)goToInform{ [ReportIllegalViewController showReportWithIllegalContent:[self p_shareLinkStr] andType:IllegalContentTypeWebsite]; } -#pragma mark UMSocialUIDelegate --(void)didFinishGetUMSocialDataInViewController:(UMSocialResponseEntity *)response{ - NSLog(@"didFinishGetUMSocialDataInViewController : %@",response); - if(response.responseCode == UMSResponseCodeSuccess){ - NSString *snsName = [[response.data allKeys] firstObject]; - NSLog(@"share to sns name is %@",snsName); - [NSObject performSelector:@selector(showStatusBarSuccessStr:) withObject:@"分享成功" afterDelay:0.3]; - }else if (response.responseCode != UMSResponseCodeCancel){ - NSString *snsName = [[response.data allKeys] firstObject]; - NSString *errorTipStr = response.data[snsName][@"msg"]; - [NSObject performSelector:@selector(showStatusBarErrorStr:) withObject:errorTipStr ?: @"分享失败" afterDelay:0.3]; - } -} - --(void)didSelectSocialPlatform:(NSString *)platformName withSocialData:(UMSocialData *)socialData{ - //设置分享内容,和回调对象 - { - socialData.shareText = [self p_shareText]; - socialData.shareImage = [UIImage imageNamed:@"logo_about"]; - NSString *imageUrl = [self p_imageUrlSquare:![platformName isEqualToString:@"sina"]]; - socialData.urlResource.url = imageUrl; - socialData.urlResource.resourceType = imageUrl.length > 0? UMSocialUrlResourceTypeImage: UMSocialUrlResourceTypeDefault; - } - if ([platformName isEqualToString:@"wxsession"]) { - UMSocialWechatSessionData *wechatSessionData = [UMSocialWechatSessionData new]; - wechatSessionData.title = [self p_shareTitle]; - wechatSessionData.url = [self p_shareLinkStr]; - wechatSessionData.wxMessageType = UMSocialWXMessageTypeWeb; - socialData.extConfig.wechatSessionData = wechatSessionData; - }else if ([platformName isEqualToString:@"wxtimeline"]){ - UMSocialWechatTimelineData *wechatTimelineData = [UMSocialWechatTimelineData new]; - wechatTimelineData.shareText = !_objToShare? [self p_shareTitle]: [NSString stringWithFormat:@"「%@」%@", [self p_shareTitle], [self p_shareText]]; - wechatTimelineData.url = [self p_shareLinkStr]; - wechatTimelineData.wxMessageType = UMSocialWXMessageTypeWeb; - socialData.extConfig.wechatTimelineData = wechatTimelineData; - }else if ([platformName isEqualToString:@"qq"]){ - UMSocialQQData *qqData = [UMSocialQQData new]; - qqData.title = [self p_shareTitle]; - qqData.url = [self p_shareLinkStr]; - qqData.qqMessageType = UMSocialQQMessageTypeDefault; - socialData.extConfig.qqData = qqData; - }else if ([platformName isEqualToString:@"qzone"]){ - UMSocialQzoneData *qzoneData = [UMSocialQzoneData new]; - qzoneData.title = [self p_shareTitle]; - qzoneData.url = [self p_shareLinkStr]; - socialData.extConfig.qzoneData = qzoneData; +- (UMSocialMessageObject *)p_curShareObjWithSocialPlatform:(NSString *)platformName{ + UMSocialMessageObject *messageObject = [UMSocialMessageObject messageObject]; + UMShareWebpageObject *shareObject = [UMShareWebpageObject shareObjectWithTitle:[self p_shareTitle] descr:[self p_shareText] thumImage:[self p_imageUrlSquare:![platformName isEqualToString:@"sina"]] ?: [UIImage imageNamed:@"logo_about"]]; + shareObject.webpageUrl = [self p_shareLinkStr]; + if ([platformName isEqualToString:@"wxtimeline"]){ + shareObject.title = [NSString stringWithFormat:@"「%@」%@", [self p_shareTitle], [self p_shareText]]; }else if ([platformName isEqualToString:@"sina"]){ NSString *shareTitle, *shareText, *shareTail; - shareTitle = !_objToShare? @"#Coding# 让开发更简单": [NSString stringWithFormat:@"「%@」", [self p_shareTitle]]; - shareText = !_objToShare? @"": [self p_shareText]; - - shareTail = [NSString stringWithFormat:@"%@(分享自@Coding)", [self p_shareLinkStr]]; + shareTitle = [NSString stringWithFormat:@"「%@」", [self p_shareTitle]]; + shareText = [self p_shareText]; + shareTail = @"(分享自@Coding)"; NSInteger maxShareLength = 140; NSInteger maxTextLength = maxShareLength - shareTitle.length - shareTail.length; if (shareText.length > maxTextLength) { shareText = [shareText stringByReplacingCharactersInRange:NSMakeRange(maxTextLength - 3, shareText.length - (maxTextLength - 3)) withString:@"..."]; } NSString *shareContent = [NSString stringWithFormat:@"%@%@ %@", shareTitle, shareText, shareTail]; - - socialData.shareText = shareContent; - socialData.shareImage = nil; + shareObject.title = shareContent; } - - NSLog(@"%@ : %@", platformName, socialData); -} - --(BOOL)isDirectShareInIconActionSheet{ - return YES; + messageObject.shareObject = shareObject; + return messageObject; } - @end @interface CodingShareView_Item () diff --git a/Coding_iOS/Views/DynamicActivityCell.m b/Coding_iOS/Views/DynamicActivityCell.m index b6abb5353..a4d38d0c1 100644 --- a/Coding_iOS/Views/DynamicActivityCell.m +++ b/Coding_iOS/Views/DynamicActivityCell.m @@ -58,7 +58,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus make.edges.equalTo(self.contentView).insets(UIEdgeInsetsMake(50, 60, 5, 20)); }]; [_tipLabel setBackgroundColor:[UIColor colorWithHexString:@"0xF0F0F0"]]; - [_tipLabel setTextColor:kColorBrandGreen]; + [_tipLabel setTextColor:kColorBrandBlue]; _tipLabel.font = [UIFont fontWithName:@"Helvetica" size:12]; } return self; @@ -126,14 +126,26 @@ + (NSAttributedString *)attrContentWithObj:(ProjectLineNote*)curActivity{ contentStr = [NSString stringWithFormat:@"编辑合并请求 - %@", [curActivity.created_at stringDisplay_HHmm]]; } else if ([curActivity.action isEqualToString:@"update_title"]) { contentStr = [NSString stringWithFormat:@"编辑了标题 - %@", [curActivity.created_at stringDisplay_HHmm]]; + } else if ([curActivity.action isEqualToString:@"add_reviewer"]) { + contentStr = [NSString stringWithFormat:@"添加了评审者 %@ - %@", curActivity.comment.reviewer.name, [curActivity.created_at stringDisplay_HHmm]]; + } else if ([curActivity.action isEqualToString:@"del_reviewer"]) { + contentStr = [NSString stringWithFormat:@"移除了评审者 %@ - %@", curActivity.comment.reviewer.name, [curActivity.created_at stringDisplay_HHmm]]; + } else if ([curActivity.action isEqualToString:@"add_watcher"]) { + contentStr = [NSString stringWithFormat:@"添加了关注者 %@ - %@", curActivity.comment.watcher.name, [curActivity.created_at stringDisplay_HHmm]]; + } else if ([curActivity.action isEqualToString:@"del_watcher"]) { + contentStr = [NSString stringWithFormat:@"移除了关注者 %@ - %@", curActivity.comment.watcher.name, [curActivity.created_at stringDisplay_HHmm]]; + } else if ([curActivity.action isEqualToString:@"add_label"]) { + contentStr = [NSString stringWithFormat:@"添加了标签 %@ - %@", curActivity.comment.label.name, [curActivity.created_at stringDisplay_HHmm]]; + } else if ([curActivity.action isEqualToString:@"del_label"]) { + contentStr = [NSString stringWithFormat:@"移除了标签 %@ - %@", curActivity.comment.label.name, [curActivity.created_at stringDisplay_HHmm]]; } contentStr = contentStr? contentStr: @"..."; attrContent = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@ %@", userName, contentStr]]; [attrContent addAttributes:@{NSFontAttributeName : [UIFont boldSystemFontOfSize:13], - NSForegroundColorAttributeName : kColor222} + NSForegroundColorAttributeName : kColorDark3} range:NSMakeRange(0, userName.length)]; [attrContent addAttributes:@{NSFontAttributeName : [UIFont systemFontOfSize:13], - NSForegroundColorAttributeName : kColor999} + NSForegroundColorAttributeName : kColorDark7} range:NSMakeRange(userName.length + 1, contentStr.length)]; NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; paragraphStyle.minimumLineHeight = 18; diff --git a/Coding_iOS/Views/EAFliterMenu.h b/Coding_iOS/Views/EAFliterMenu.h new file mode 100644 index 000000000..c266ed077 --- /dev/null +++ b/Coding_iOS/Views/EAFliterMenu.h @@ -0,0 +1,19 @@ +// +// EAFliterMenu.h +// Coding_iOS +// +// Created by Ease on 2017/2/15. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import + +@interface EAFliterMenu : UIView +@property (strong, nonatomic) NSArray *items; +@property (nonatomic, assign) NSInteger selectIndex; +@property (nonatomic, assign, readonly) BOOL isShowing; +@property (nonatomic, copy) void (^clickBlock)(NSInteger selectIndex); +- (id)initWithFrame:(CGRect)frame items:(NSArray *)items; +- (void)showMenuInView:(UIView *)containerView; +- (void)dismissMenu; +@end diff --git a/Coding_iOS/Views/EAFliterMenu.m b/Coding_iOS/Views/EAFliterMenu.m new file mode 100644 index 000000000..062719967 --- /dev/null +++ b/Coding_iOS/Views/EAFliterMenu.m @@ -0,0 +1,146 @@ +// +// EAFliterMenu.m +// Coding_iOS +// +// Created by Ease on 2017/2/15. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "EAFliterMenu.h" +#import "XHRealTimeBlur.h" +#import "pop.h" + +@interface EAFliterMenu () +@property (nonatomic, strong) XHRealTimeBlur *realTimeBlur; +@property (nonatomic, strong) UITableView *tableview; + +@end + +@implementation EAFliterMenu + +- (id)initWithFrame:(CGRect)frame items:(NSArray *)items{ + self = [super initWithFrame:frame]; + if (self) { + // Initialization code + self.items = items; + [self setup]; + } + return self; +} +// 设置属性 +- (void)setup { + self.backgroundColor = [UIColor clearColor]; + + _realTimeBlur = [[XHRealTimeBlur alloc] initWithFrame:self.bounds]; + _realTimeBlur.clipsToBounds = YES; + _realTimeBlur.blurStyle = XHBlurStyleTranslucentWhite; + _realTimeBlur.showDuration = 0.1; + _realTimeBlur.disMissDuration = 0.2; + typeof(self) __weak weakSelf = self; + + _realTimeBlur.willShowBlurViewcomplted = ^(void) { + POPBasicAnimation *alphaAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewAlpha]; + alphaAnimation.fromValue = @0.0; + alphaAnimation.toValue = @1.0; + alphaAnimation.duration = 0.3f; + [weakSelf.tableview pop_addAnimation:alphaAnimation forKey:@"alphaAnimationS"]; + }; + + _realTimeBlur.willDismissBlurViewCompleted = ^(void) { + POPBasicAnimation *alphaAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewAlpha]; + alphaAnimation.fromValue = @1.0; + alphaAnimation.toValue = @0.0; + alphaAnimation.duration = 0.2f; + [weakSelf.tableview pop_addAnimation:alphaAnimation forKey:@"alphaAnimationE"]; + }; + + _realTimeBlur.didDismissBlurViewCompleted = ^(BOOL finished) { + [weakSelf removeFromSuperview]; + }; + + + _realTimeBlur.hasTapGestureEnable = YES; + + _tableview = ({ + UITableView *tableview=[[UITableView alloc] initWithFrame:self.bounds]; + tableview.backgroundColor=[UIColor clearColor]; + tableview.delegate=self; + tableview.dataSource=self; + [tableview registerClass:[UITableViewCell class] forCellReuseIdentifier:@"UITableViewCell"]; + tableview.tableFooterView=[UIView new]; + tableview.separatorStyle=UITableViewCellSeparatorStyleNone; + tableview.estimatedRowHeight = 0; + tableview.estimatedSectionHeaderHeight = 0; + tableview.estimatedSectionFooterHeight = 0; + tableview; + }); + [self addSubview:_tableview]; + _tableview.contentInset=UIEdgeInsetsMake(15, 0,0,0); + + + int contentHeight=320; + if ((kScreen_Height-64)>contentHeight) { + UIView *contentView=[[UIView alloc] initWithFrame:CGRectMake(0,64+contentHeight , kScreen_Width, kScreen_Height-64-contentHeight)]; + contentView.backgroundColor=[UIColor clearColor]; + [self addSubview:contentView]; + UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didClickedContentView:)]; + [contentView addGestureRecognizer:tapGestureRecognizer]; + } +} + +#pragma mark -- event & action +- (void)showMenuInView:(UIView *)containerView{ + _isShowing= YES; + [containerView addSubview:self]; + [_realTimeBlur showBlurViewAtView:self]; + [_tableview reloadData]; +} + +- (void)dismissMenu{ + UIView *presentView=[[[UIApplication sharedApplication].keyWindow rootViewController] view]; + if ([[presentView.subviews firstObject] isMemberOfClass:NSClassFromString(@"RDVTabBar")]) { + [presentView bringSubviewToFront:[presentView.subviews firstObject]]; + } + _isShowing= NO; + [_realTimeBlur disMiss]; +} + +#pragma mark table +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + return _items.count; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ + return 50; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell" forIndexPath:indexPath]; + cell.backgroundColor=[UIColor clearColor]; + + [cell.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; + UILabel *titleL = [UILabel labelWithFont:[UIFont systemFontOfSize:15] textColor:indexPath.row == _selectIndex? kColorLightBlue: kColor222]; + titleL.text = _items[indexPath.row]; + [cell.contentView addSubview:titleL]; + [titleL mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(cell); + make.left.equalTo(cell).offset(20); + }]; + cell.accessoryType = indexPath.row == _selectIndex? UITableViewCellAccessoryCheckmark: UITableViewCellAccessoryNone; + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + [self dismissMenu]; + _selectIndex = indexPath.row; + if (_clickBlock) { + _clickBlock(_selectIndex); + } +} + +- (void)didClickedContentView:(UIGestureRecognizer *)sender { + [self dismissMenu]; +} + +@end diff --git a/Coding_iOS/Views/EaseInputTipsView.m b/Coding_iOS/Views/EaseInputTipsView.m index da7d2d2aa..45dce8018 100644 --- a/Coding_iOS/Views/EaseInputTipsView.m +++ b/Coding_iOS/Views/EaseInputTipsView.m @@ -25,7 +25,7 @@ + (instancetype)tipsViewWithType:(EaseInputTipsViewType)type{ } - (instancetype)initWithTipsType:(EaseInputTipsViewType)type{ - CGFloat padingWith = type == EaseInputTipsViewTypeLogin? kLoginPaddingLeftWidth: 0.0; + CGFloat padingWith = 0.0; self = [super initWithFrame:CGRectMake(padingWith, 0, kScreen_Width-2*padingWith, 120)]; if (self) { [self addRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight cornerRadii:CGSizeMake(2, 2)]; @@ -41,6 +41,9 @@ - (instancetype)initWithTipsType:(EaseInputTipsViewType)type{ make.edges.equalTo(self); }]; tableView.tableFooterView = [UIView new]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); _type = type; @@ -61,7 +64,7 @@ - (void)setActive:(BOOL)active{ } - (void)setValueStr:(NSString *)valueStr{ - _valueStr = valueStr; + _valueStr = [valueStr lowercaseString]; if (_valueStr.length <= 0) { self.dataList = nil; }else if ([_valueStr rangeOfString:@"@"].location == NSNotFound) { @@ -140,7 +143,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } UILabel *label = (UILabel *)[cell.contentView viewWithTag:labelTag]; - label.textColor = [UIColor colorWithHexString:_type == EaseInputTipsViewTypeLogin? @"0x222222": @"0x666666"]; + label.textColor = kColorDark7; label.text = [_dataList objectAtIndex:indexPath.row]; return cell; } @@ -160,4 +163,4 @@ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPa return 35; } -@end \ No newline at end of file +@end diff --git a/Coding_iOS/Views/EaseMarkdownTextView.m b/Coding_iOS/Views/EaseMarkdownTextView.m index cab697929..379376997 100644 --- a/Coding_iOS/Views/EaseMarkdownTextView.m +++ b/Coding_iOS/Views/EaseMarkdownTextView.m @@ -58,11 +58,6 @@ - (NSArray *)buttons { [self createButtonWithTitle:@"@" andEventHandler:^{ [self doAT]; }], - [self createButtonWithTitle:@"#" andEventHandler:^{ [self insertText:@"#"]; }], - [self createButtonWithTitle:@"*" andEventHandler:^{ [self insertText:@"*"]; }], - [self createButtonWithTitle:@"`" andEventHandler:^{ [self insertText:@"`"]; }], - [self createButtonWithTitle:@"-" andEventHandler:^{ [self insertText:@"-"]; }], - [self createButtonWithTitle:@"照片" andEventHandler:^{ [self doPhoto]; }], [self createButtonWithTitle:@"标题" andEventHandler:^{ [self doTitle]; }], @@ -72,6 +67,17 @@ - (NSArray *)buttons { [self createButtonWithTitle:@"引用" andEventHandler:^{ [self doQuote]; }], [self createButtonWithTitle:@"列表" andEventHandler:^{ [self doList]; }], + [self createButtonWithTitle:@"分割线" andEventHandler:^{ + NSRange selectionRange = self.selectedRange; + NSString *insertStr = [self needPreNewLine]? @"\n\n------\n": @"\n------\n"; + + selectionRange.location += insertStr.length; + selectionRange.length = 0; + + [self insertText:insertStr]; + [self setSelectionRange:selectionRange]; + }], + [self createButtonWithTitle:@"链接" andEventHandler:^{ NSString *tipStr = @"在此输入链接地址"; NSRange selectionRange = self.selectedRange; @@ -92,17 +98,11 @@ - (NSArray *)buttons { [self setSelectionRange:selectionRange]; }], - [self createButtonWithTitle:@"分割线" andEventHandler:^{ - NSRange selectionRange = self.selectedRange; - NSString *insertStr = [self needPreNewLine]? @"\n\n------\n": @"\n------\n"; - - selectionRange.location += insertStr.length; - selectionRange.length = 0; - - [self insertText:insertStr]; - [self setSelectionRange:selectionRange]; - }], - + [self createButtonWithTitle:@"#" andEventHandler:^{ [self insertText:@"#"]; }], + [self createButtonWithTitle:@"*" andEventHandler:^{ [self insertText:@"*"]; }], + [self createButtonWithTitle:@"`" andEventHandler:^{ [self insertText:@"`"]; }], + [self createButtonWithTitle:@"-" andEventHandler:^{ [self insertText:@"-"]; }], + [self createButtonWithTitle:@"_" andEventHandler:^{ [self insertText:@"_"]; }], [self createButtonWithTitle:@"+" andEventHandler:^{ [self insertText:@"+"]; }], [self createButtonWithTitle:@"~" andEventHandler:^{ [self insertText:@"~"]; }], @@ -222,7 +222,7 @@ - (void)atSomeUser:(User *)curUser andRange:(NSRange)range{ #pragma mark Photo - (void)doPhoto{ // - [[UIActionSheet bk_actionSheetCustomWithTitle:nil buttonTitles:@[@"拍照", @"从相册选择"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + [[UIAlertController ea_actionSheetCustomWithTitle:nil buttonTitles:@[@"拍照", @"从相册选择"] destructiveTitle:nil cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { [self presentPhotoVCWithIndex:index]; }] showInView:self]; } @@ -272,7 +272,7 @@ - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{ } - (void)doUploadPhoto:(UIImage *)image{ - if (_isForProjectTweet || !_curProject) { + if (!_isForProjectTweet || !_curProject) { [self hudTipWillShow:YES]; __weak typeof(self) weakSelf = self; [[Coding_NetAPIManager sharedManager] uploadTweetImage:image doneBlock:^(NSString *imagePath, NSError *error) { @@ -294,23 +294,46 @@ - (void)doUploadPhoto:(UIImage *)image{ }]; }else{ //保存到app内 - NSString *dateMarkStr = [[NSDate date] stringWithFormat:@"yyyyMMdd_HHmmss"]; - NSString *originalFileName = [NSString stringWithFormat:@"%@.jpg", dateMarkStr]; - + NSString *originalFileName = [NSString stringWithFormat:@"%@.JPG", [NSUUID UUID].UUIDString]; NSString *fileName = [NSString stringWithFormat:@"%@|||%@|||%@", self.curProject.id.stringValue, @"0", originalFileName]; if ([Coding_FileManager writeUploadDataWithName:fileName andImage:image]) { [self hudTipWillShow:YES]; self.uploadingPhotoName = originalFileName; - Coding_UploadTask *uploadTask =[[Coding_FileManager sharedManager] addUploadTaskWithFileName:fileName projectIsPublic:_curProject.is_public.boolValue]; - @weakify(self) - [RACObserve(uploadTask, progress.fractionCompleted) subscribeNext:^(NSNumber *fractionCompleted) { - @strongify(self); - dispatch_async(dispatch_get_main_queue(), ^{ - if (self.HUD) { - self.HUD.progress = MAX(0, fractionCompleted.floatValue-0.05) ; - } - }); - }]; + + + __weak typeof(self) weakSelf = self; + if ([NSObject isPrivateCloud].boolValue) { + Coding_UploadTask *uploadTask =[[Coding_FileManager sharedManager] addUploadTaskWithFileName:fileName projectIsPublic:_curProject.is_public.boolValue]; + [RACObserve(uploadTask, progress.fractionCompleted) subscribeNext:^(NSNumber *fractionCompleted) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (weakSelf.HUD) { + weakSelf.HUD.progress = MAX(0, fractionCompleted.floatValue-0.05); + DebugLog(@"uploadingPhotoName - %@ : %.2f", weakSelf.uploadingPhotoName, fractionCompleted.floatValue); + } + }); + }]; + }else{ + [[Coding_FileManager sharedManager] addUploadTaskWithFileName:fileName isQuick:YES resultBlock:^(Coding_UploadTask *uploadTask) { + [RACObserve(uploadTask, progress.fractionCompleted) subscribeNext:^(NSNumber *fractionCompleted) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (weakSelf.HUD) { + weakSelf.HUD.progress = MAX(0, fractionCompleted.floatValue-0.05); + DebugLog(@"uploadingPhotoName - %@ : %.2f", weakSelf.uploadingPhotoName, fractionCompleted.floatValue); + } + }); + }]; + }]; + } +// Coding_UploadTask *uploadTask =[[Coding_FileManager sharedManager] addUploadTaskWithFileName:fileName projectIsPublic:_curProject.is_public.boolValue]; +// @weakify(self) +// [RACObserve(uploadTask, progress.fractionCompleted) subscribeNext:^(NSNumber *fractionCompleted) { +// @strongify(self); +// dispatch_async(dispatch_get_main_queue(), ^{ +// if (self.HUD) { +// self.HUD.progress = MAX(0, fractionCompleted.floatValue-0.05) ; +// } +// }); +// }]; }else{ [NSObject showHudTipStr:[NSString stringWithFormat:@"%@ 文件处理失败", originalFileName]]; } diff --git a/Coding_iOS/Views/EaseStartView.h b/Coding_iOS/Views/EaseStartView.h index cfc6d7a78..f7fac1e8d 100644 --- a/Coding_iOS/Views/EaseStartView.h +++ b/Coding_iOS/Views/EaseStartView.h @@ -9,7 +9,7 @@ #import @interface EaseStartView : UIView -+ (instancetype)startView; - (void)startAnimationWithCompletionBlock:(void(^)(EaseStartView *easeStartView))completionHandler; + @end diff --git a/Coding_iOS/Views/EaseStartView.m b/Coding_iOS/Views/EaseStartView.m index 4a43538af..8c1630a70 100644 --- a/Coding_iOS/Views/EaseStartView.m +++ b/Coding_iOS/Views/EaseStartView.m @@ -10,95 +10,102 @@ #import #import "StartImagesManager.h" +#import "WebViewController.h" + @interface EaseStartView () @property (strong, nonatomic) UIImageView *bgImageView, *logoIconView; -@property (strong, nonatomic) UILabel *descriptionStrLabel; +@property (strong, nonatomic) StartImage *st; @end @implementation EaseStartView -+ (instancetype)startView{ - UIImage *logoIcon = [UIImage imageNamed:@"logo_coding_top"]; - StartImage *st = [[StartImagesManager shareManager] randomImage]; - return [[self alloc] initWithBgImage:st.image logoIcon:logoIcon descriptionStr:st.descriptionStr]; -} - -- (instancetype)initWithBgImage:(UIImage *)bgImage logoIcon:(UIImage *)logoIcon descriptionStr:(NSString *)descriptionStr{ - self = [super initWithFrame:kScreen_Bounds]; +- (instancetype)init{ + self = [super init]; if (self) { + self.frame = kScreen_Bounds; //add custom code - UIColor *blackColor = [UIColor blackColor]; - self.backgroundColor = blackColor; + UIColor *bgColor = [UIColor whiteColor]; + self.backgroundColor = bgColor; - _bgImageView = [[UIImageView alloc] initWithFrame:kScreen_Bounds]; - _bgImageView.contentMode = UIViewContentModeScaleAspectFill; + _bgImageView = [[YLImageView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, kScreen_Height - 110 - kSafeArea_Bottom)]; + _bgImageView.clipsToBounds = YES; _bgImageView.alpha = 0.0; + _bgImageView.contentMode = UIViewContentModeScaleAspectFill; [self addSubview:_bgImageView]; - if (![NSDate isDuringMidAutumn]) { - [self addGradientLayerWithColors:@[(id)[blackColor colorWithAlphaComponent:0.4].CGColor, (id)[blackColor colorWithAlphaComponent:0.0].CGColor] locations:nil startPoint:CGPointMake(0.5, 0.0) endPoint:CGPointMake(0.5, 0.4)]; - } - + _logoIconView = [[UIImageView alloc] init]; - _logoIconView.contentMode = UIViewContentModeScaleAspectFit; + _logoIconView.contentMode = UIViewContentModeScaleAspectFill; + _logoIconView.image = [UIImage imageNamed:@"logo_coding"]; [self addSubview:_logoIconView]; - _descriptionStrLabel = [[UILabel alloc] init]; - _descriptionStrLabel.font = [UIFont systemFontOfSize:10]; - _descriptionStrLabel.textColor = [UIColor colorWithWhite:1.0 alpha:0.5]; - _descriptionStrLabel.textAlignment = NSTextAlignmentCenter; - _descriptionStrLabel.alpha = 0.0; - [self addSubview:_descriptionStrLabel]; - - [_descriptionStrLabel mas_makeConstraints:^(MASConstraintMaker *make) { - make.centerX.equalTo(@[self, _logoIconView]); - make.height.mas_equalTo(10); - make.bottom.equalTo(self.mas_bottom).offset(-15); - make.left.equalTo(self.mas_left).offset(20); - make.right.equalTo(self.mas_right).offset(-20); - }]; - [_logoIconView mas_makeConstraints:^(MASConstraintMaker *make) { make.centerX.equalTo(self); - make.top.mas_equalTo(kScreen_Height/7); - make.width.mas_equalTo(kScreen_Width *2/3); - make.height.mas_equalTo(kScreen_Width/4 *2/3); + make.centerY.equalTo(self.mas_bottom).offset(-55 - kSafeArea_Bottom); + make.size.mas_equalTo(CGSizeMake(65, 65)); }]; - [self configWithBgImage:bgImage logoIcon:logoIcon descriptionStr:descriptionStr]; + __weak typeof(self) weakSelf = self; + _bgImageView.userInteractionEnabled = YES; + [_bgImageView bk_whenTapped:^{ + [weakSelf bgImageViewTapped]; + }]; } return self; } -- (void)configWithBgImage:(UIImage *)bgImage logoIcon:(UIImage *)logoIcon descriptionStr:(NSString *)descriptionStr{ - bgImage = [bgImage scaleToSize:[_bgImageView doubleSizeOfFrame] usingMode:NYXResizeModeAspectFill]; - self.bgImageView.image = bgImage; - self.logoIconView.image = logoIcon; - self.descriptionStrLabel.text = descriptionStr; - [self updateConstraintsIfNeeded]; +- (void)setSt:(StartImage *)st{ + _st = st; + [self.bgImageView sd_setImageWithURL:[NSURL URLWithString:self.st.url]]; + DebugLog(@"setSt : ---- %@", st.url); +} + +- (void)bgImageViewTapped{ + if ([BaseViewController presentingVC].navigationController.viewControllers.count <= 1) { + NSString *linkStr = self.st.group.link; + UIViewController *vc = [BaseViewController analyseVCFromLinkStr:linkStr] ?: [WebViewController webVCWithUrlStr:linkStr]; + [BaseViewController goToVC:vc]; + } } - (void)startAnimationWithCompletionBlock:(void(^)(EaseStartView *easeStartView))completionHandler{ + __weak typeof(self) weakSelf = self; + //加载数据 st + [[StartImagesManager shareManager] refreshImagesBlock:^(NSArray *images, NSError *error) { + if (images.count > 0) { + NSInteger index = arc4random() % images.count; + weakSelf.st = images[index]; + } + }]; + [kKeyWindow addSubview:self]; [kKeyWindow bringSubviewToFront:self]; _bgImageView.alpha = 0.0; - _descriptionStrLabel.alpha = 0.0; - - @weakify(self); - [UIView animateWithDuration:2.0 animations:^{ - @strongify(self); - self.bgImageView.alpha = 1.0; - self.descriptionStrLabel.alpha = 1.0; + + [UIView animateWithDuration:1.0 animations:^{ + weakSelf.bgImageView.alpha = 1.0; } completion:^(BOOL finished) { - [UIView animateWithDuration:0.6 delay:0.3 options:UIViewAnimationOptionCurveEaseIn animations:^{ - @strongify(self); - [self setX:-kScreen_Width]; - } completion:^(BOOL finished) { - @strongify(self); - [self removeFromSuperview]; - if (completionHandler) { - completionHandler(self); - } - }]; + if (!weakSelf.st) {//此时若 st 还未加载到,则省去展示停顿时间 + [UIView animateWithDuration:.3 delay:.0 options:UIViewAnimationOptionCurveEaseIn animations:^{ + weakSelf.alpha = .0; + } completion:^(BOOL finished) { + [weakSelf p_animationCompletedWithBlock:completionHandler]; + }]; + }else{//若 st 数据已加载,停留展示,然后消失 + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [UIView animateWithDuration:0.6 delay:.0 options:UIViewAnimationOptionCurveEaseIn animations:^{ + weakSelf.x = -kScreen_Width; + } completion:^(BOOL finished) { + [weakSelf p_animationCompletedWithBlock:completionHandler]; + }]; + }); + } }]; } +- (void)p_animationCompletedWithBlock:(void(^)(EaseStartView *easeStartView))completionHandler{ + [self removeFromSuperview]; + if (completionHandler) { + completionHandler(self); + } +} + @end diff --git a/Coding_iOS/Views/FileDownloadView.h b/Coding_iOS/Views/FileDownloadView.h index fb2078882..2809492a3 100644 --- a/Coding_iOS/Views/FileDownloadView.h +++ b/Coding_iOS/Views/FileDownloadView.h @@ -11,9 +11,11 @@ #import "FileVersion.h" @interface FileDownloadView : UIView -@property (strong, nonatomic) ProjectFile *file; -@property (strong, nonatomic) FileVersion *version; @property (nonatomic,copy) void(^completionBlock)(); @property (nonatomic,copy) void(^otherMethodOpenBlock)();//用其他应用打开 + +- (void)setFile:(ProjectFile *)file version:(FileVersion *)version; - (void)reloadData; +- (DownloadState)downloadState; +- (void)startDownload; @end diff --git a/Coding_iOS/Views/FileDownloadView.m b/Coding_iOS/Views/FileDownloadView.m index 2b992fe40..f09aa747a 100644 --- a/Coding_iOS/Views/FileDownloadView.m +++ b/Coding_iOS/Views/FileDownloadView.m @@ -12,6 +12,9 @@ #import "YLImageView.h" @interface FileDownloadView () +@property (strong, nonatomic) ProjectFile *file; +@property (strong, nonatomic) FileVersion *version; + @property (strong, nonatomic) UIImageView *iconView; @property (strong, nonatomic) ASProgressPopUpView *progressView; @property (strong, nonatomic) UIButton *stateButton; @@ -32,19 +35,9 @@ - (instancetype)initWithFrame:(CGRect)frame{ return self; } -- (void)setFile:(ProjectFile *)file{ +- (void)setFile:(ProjectFile *)file version:(FileVersion *)version{ _file = file; - if (!_file) { - return; - } - [self loadLayoutWithCurFile]; - [self reloadData]; -} -- (void)setVersion:(FileVersion *)version{ _version = version; - if (!_version) { - return; - } [self loadLayoutWithCurFile]; [self reloadData]; } @@ -66,8 +59,8 @@ - (NSString *)owner_preview{ - (NSString *)fileType{ return [self.curData valueForKey:@"fileType"]; } -- (NSString *)storage_key{ - return [self.curData valueForKey:@"storage_key"]; +- (NSURL *)diskFileUrl{ + return [self.curData valueForKey:@"diskFileUrl"]; } - (NSString *)name{ if (_version) { @@ -101,7 +94,7 @@ - (void)reloadData{ }]; [_progressView hidePopUpViewAnimated:NO]; }else{ - _iconView.image = [UIImage imageWithFileType:self.fileType]; + _iconView.image = [UIImage big_imageWithFileType:self.fileType]; [_progressView showPopUpViewAnimated:NO]; } Coding_DownloadTask *cDownloadTask = [self cDownloadTask]; @@ -130,14 +123,15 @@ - (void)loadLayoutWithCurFile{ _toolBarView.backgroundColor = kColorTableSectionBg; [self addSubview:_toolBarView]; [_toolBarView mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.right.bottom.equalTo(self); + make.left.right.equalTo(self); + make.bottom.equalTo(self).offset(-kSafeArea_Bottom); make.height.mas_equalTo(49); }]; } if (!_sizeLabel) { _sizeLabel = [[UILabel alloc] initWithFrame:CGRectZero]; _sizeLabel.textAlignment = NSTextAlignmentCenter; - _sizeLabel.textColor = kColor666; + _sizeLabel.textColor = kColorDark4; _sizeLabel.font = [UIFont systemFontOfSize:14]; _sizeLabel.text = @"正在下载中..."; [_toolBarView addSubview:_sizeLabel]; @@ -151,7 +145,7 @@ - (void)loadLayoutWithCurFile{ _progressView.popUpViewCornerRadius = 12.0; _progressView.font = [UIFont fontWithName:@"Futura-CondensedExtraBold" size:12]; [_progressView setTrackTintColor:kColorNavBG]; - _progressView.popUpViewAnimatedColors = @[kColorBrandGreen]; + _progressView.popUpViewAnimatedColors = @[kColorDark4]; _progressView.hidden = YES; [_progressView hidePopUpViewAnimated:NO]; [_toolBarView addSubview:self.progressView]; @@ -164,33 +158,34 @@ - (void)loadLayoutWithCurFile{ } if (!_stateButton) { _stateButton = [UIButton new]; - [_stateButton setTitleColor:kColorBrandGreen forState:UIControlStateNormal]; + _stateButton.titleLabel.font = [UIFont systemFontOfSize:17 weight:UIFontWeightMedium]; + [_stateButton setTitleColor:kColorDark4 forState:UIControlStateNormal]; [_stateButton addTarget:self action:@selector(clickedByUser) forControlEvents:UIControlEventTouchUpInside]; [_toolBarView addSubview:_stateButton]; } }else{ - buttonHeight = 45; + buttonHeight = 50; if (!_iconView) { _iconView = [[UIImageView alloc] initWithFrame:CGRectZero]; _iconView.contentMode = UIViewContentModeScaleAspectFill; - _iconView.layer.masksToBounds = YES; - _iconView.layer.cornerRadius = 2.0; - _iconView.layer.borderWidth = 0.5; - _iconView.layer.borderColor = kColorDDD.CGColor; +// _iconView.layer.masksToBounds = YES; +// _iconView.layer.cornerRadius = 2.0; +// _iconView.layer.borderWidth = 0.5; +// _iconView.layer.borderColor = kColorDDD.CGColor; [self addSubview:_iconView]; } if (!_nameLabel) { _nameLabel = [[UILabel alloc] initWithFrame:CGRectZero]; _nameLabel.textAlignment = NSTextAlignmentCenter; - _nameLabel.textColor = kColor222; - _nameLabel.font = [UIFont systemFontOfSize:16]; + _nameLabel.textColor = kColorDark4; + _nameLabel.font = [UIFont systemFontOfSize:15]; [self addSubview:_nameLabel]; } if (!_sizeLabel) { _sizeLabel = [[UILabel alloc] initWithFrame:CGRectZero]; _sizeLabel.textAlignment = NSTextAlignmentCenter; - _sizeLabel.textColor = kColor999; - _sizeLabel.font = [UIFont systemFontOfSize:12]; + _sizeLabel.textColor = kColorDark7; + _sizeLabel.font = [UIFont systemFontOfSize:14]; [self addSubview:_sizeLabel]; } if (!_progressView) { @@ -198,20 +193,26 @@ - (void)loadLayoutWithCurFile{ _progressView.popUpViewCornerRadius = 12.0; _progressView.font = [UIFont fontWithName:@"Futura-CondensedExtraBold" size:12]; [_progressView setTrackTintColor:[UIColor colorWithHexString:@"0xe6e6e6"]]; - _progressView.popUpViewAnimatedColors = @[kColorBrandGreen]; + _progressView.popUpViewAnimatedColors = @[kColorDark4]; _progressView.hidden = YES; [_progressView hidePopUpViewAnimated:NO]; [self addSubview:self.progressView]; } if (!_stateButton) { - _stateButton = [[UIButton alloc] init]; - _stateButton = [UIButton buttonWithStyle:StrapPrimaryStyle andTitle:@"下载原文件" andFrame:CGRectMake(0, 0, buttonHeight, buttonHeight) target:self action:@selector(clickedByUser)]; + _stateButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, buttonHeight, buttonHeight)]; + _stateButton.titleLabel.font = [UIFont systemFontOfSize:17 weight:UIFontWeightMedium]; + [_stateButton setTitleColor:kColorWhite forState:UIControlStateNormal]; + [_stateButton setBackgroundColor:kColorDark4]; + [_stateButton doBorderWidth:0 color:nil cornerRadius:4.0]; + [_stateButton addTarget:self action:@selector(clickedByUser) forControlEvents:UIControlEventTouchUpInside]; + [_stateButton setTitle:@"下载原文件" forState:UIControlStateNormal]; +// _stateButton = [UIButton buttonWithStyle:StrapPrimaryStyle andTitle:@"下载原文件" andFrame:CGRectMake(0, 0, buttonHeight, buttonHeight) target:self action:@selector(clickedByUser)]; [self addSubview:_stateButton]; } [_iconView mas_makeConstraints:^(MASConstraintMaker *make) { - make.size.mas_equalTo(CGSizeMake(45, 45)); - make.bottom.equalTo(_nameLabel.mas_top).offset(-50); + make.size.mas_equalTo(CGSizeMake(90, 90)); + make.bottom.equalTo(_nameLabel.mas_top).offset(-20); }]; [_nameLabel mas_makeConstraints:^(MASConstraintMaker *make) { @@ -220,7 +221,7 @@ - (void)loadLayoutWithCurFile{ [_sizeLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.height.mas_equalTo(20); - make.top.equalTo(_nameLabel.mas_bottom).offset(20); + make.top.equalTo(_nameLabel.mas_bottom).offset(10); }]; [_progressView mas_makeConstraints:^(MASConstraintMaker *make) {//上下居中基准 @@ -274,7 +275,7 @@ - (void)updatePregress:(double)fractionCompleted{ - (void)clickedByUser{ Coding_FileManager *manager = [Coding_FileManager sharedManager]; - NSURL *fileUrl = [Coding_FileManager diskDownloadUrlForKey:self.storage_key]; + NSURL *fileUrl = self.diskFileUrl; if (fileUrl) {//已经下载到本地了 if (_otherMethodOpenBlock) { _otherMethodOpenBlock(); @@ -321,6 +322,46 @@ - (void)clickedByUser{ } } +- (void)startDownload{ + Coding_FileManager *manager = [Coding_FileManager sharedManager]; + NSURL *fileUrl = self.diskFileUrl; + if (fileUrl) {//已经下载到本地了 + }else{//要下载 + NSURLSessionDownloadTask *downloadTask; + if (self.cDownloadTask) {//暂停或者重新开始 + downloadTask = self.cDownloadTask.task; + switch (downloadTask.state) { + case NSURLSessionTaskStateSuspended: + [downloadTask resume]; + [self changeToState:DownloadStateDownloading]; + break; + default: + break; + } + }else{//新建下载 + if (!self.project_id) { + [NSObject showHudTipStr:@"下载失败~"]; + return; + } + __weak typeof(self) weakSelf = self; + Coding_DownloadTask *cDownloadTask = [manager addDownloadTaskForObj:self.curData completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) { + if (error) { + [weakSelf changeToState:DownloadStateDefault]; + [NSObject showError:error]; + DebugLog(@"ERROR:%@", error.description); + }else{ + [weakSelf changeToState:DownloadStateDownloaded]; + DebugLog(@"File downloaded to: %@", filePath); + } + }]; + self.progress = cDownloadTask.progress; + _progressView.progress = 0.0; + _progressView.hidden = NO; + [self changeToState:DownloadStateDownloading]; + } + } +} + - (void)changeToState:(DownloadState)state{ NSString *stateTitle; switch (state) { @@ -367,11 +408,11 @@ - (void)changeToState:(DownloadState)state{ [self.progressView setHidden:!(state == DownloadStateDownloading || state == DownloadStatePausing)]; [_stateButton setTitle:stateTitle forState:UIControlStateNormal]; - if (state == DownloadStateDownloaded) { - [_stateButton defaultStyle]; - }else{ - [_stateButton primaryStyle]; - } +// if (state == DownloadStateDownloaded) { +// [_stateButton defaultStyle]; +// }else{ +// [_stateButton primaryStyle]; +// } } if (state == DownloadStateDownloaded && self.completionBlock && !self.hidden) { diff --git a/Coding_iOS/Views/MartFunctionTipView.h b/Coding_iOS/Views/MartFunctionTipView.h new file mode 100644 index 000000000..32328d02a --- /dev/null +++ b/Coding_iOS/Views/MartFunctionTipView.h @@ -0,0 +1,16 @@ +// +// MartFunctionTipView.h +// CodingMart +// +// Created by Ease on 16/8/12. +// Copyright © 2016年 net.coding. All rights reserved. +// + +#import +#import "AMPopTip.h"//没有用 pod 管理,是因为 pod 上面的版本太低,还没有 bubbleOffset 属性 + +@interface MartFunctionTipView : UIView ++ (void)showFunctionImages:(NSArray *)imageNames; ++ (void)showFunctionImages:(NSArray *)imageNames onlyOneTime:(BOOL)onlyOneTime; ++ (AMPopTip *)showText:(NSString *)text direction:(AMPopTipDirection)direction bubbleOffset:(CGFloat)bubbleOffset inView:(UIView *)view fromFrame:(CGRect)frame dismissHandler:(void (^)())dismissHandler; +@end diff --git a/Coding_iOS/Views/MartFunctionTipView.m b/Coding_iOS/Views/MartFunctionTipView.m new file mode 100644 index 000000000..08056d5b9 --- /dev/null +++ b/Coding_iOS/Views/MartFunctionTipView.m @@ -0,0 +1,110 @@ +// +// MartFunctionTipView.m +// CodingMart +// +// Created by Ease on 16/8/12. +// Copyright © 2016年 net.coding. All rights reserved. +// + +#import "MartFunctionTipView.h" +#import + +@interface MartFunctionTipView () +@property (strong, nonatomic) UIImageView *imageV; +@property (strong, nonatomic) NSArray *imageNames; +@property (assign, nonatomic) NSUInteger curIndex; +@end + +@implementation MartFunctionTipView + +- (instancetype)init +{ + self = [super init]; + if (self) { + _imageV = [UIImageView new]; + _imageV.frame = self.frame = kScreen_Bounds; + _imageV.backgroundColor = self.backgroundColor = [UIColor clearColor]; + [self addSubview:_imageV]; + + __weak typeof(self) weakSelf = self;; + _imageV.userInteractionEnabled = YES; + [_imageV bk_whenTapped:^{ + [weakSelf tapped]; + }]; + } + return self; +} + +- (void)tapped{ + _curIndex += 1; + if (_imageNames.count > _curIndex) { + _imageV.image = [UIImage imageNamed:_imageNames[_curIndex]]; + }else{ + [self dismiss]; + } +} + ++ (void)showFunctionImages:(NSArray *)imageNames{ + if (kScreen_Height == 480) {//iPhone 4 的尺寸,忽略 + return; + } + if (imageNames.count <= 0) { + return; + } + MartFunctionTipView *tipV = [MartFunctionTipView new]; + tipV.imageNames = imageNames; + [tipV show]; +} + ++ (void)showFunctionImages:(NSArray *)imageNames onlyOneTime:(BOOL)onlyOneTime{ + if (kScreen_Height == 480) {//iPhone 4 的尺寸,忽略 + return; + } + if (imageNames.count <= 0) { + return; + } + if (onlyOneTime) { + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + NSMutableArray *hasShowedImages = @[].mutableCopy; + for (NSString *imageName in imageNames) { + if ([defaults objectForKey:imageName]) { + [hasShowedImages addObject:imageName]; + }else{ + [defaults setObject:@1 forKey:imageName]; + } + } + [defaults synchronize]; + NSMutableArray *needShowImages = imageNames.mutableCopy; + [needShowImages removeObjectsInArray:hasShowedImages]; + imageNames = needShowImages; + } + [self showFunctionImages:imageNames]; +} + +- (void)show{ + if (_imageNames.count <= 0) { + return; + } + _curIndex = 0; + _imageV.image = [UIImage imageNamed:_imageNames[_curIndex]]; + [kKeyWindow addSubview:self]; +} + +- (void)dismiss{ + [self removeFromSuperview]; +} ++ (AMPopTip *)showText:(NSString *)text direction:(AMPopTipDirection)direction bubbleOffset:(CGFloat)bubbleOffset inView:(UIView *)view fromFrame:(CGRect)frame dismissHandler:(void (^)())dismissHandler{ + AMPopTip *popTip = [AMPopTip popTip]; + popTip.shouldDismissOnTap = YES; + popTip.font = [UIFont systemFontOfSize:15]; + popTip.radius = 4.0; + popTip.arrowSize = CGSizeMake(10, 5); + popTip.padding = 10; + popTip.dismissHandler = dismissHandler; +// popTip.popoverColor = [UIColor colorWithHexString:@"0x262728" andAlpha:0.8]; + popTip.popoverColor = kColorBrandBlue; + popTip.bubbleOffset = bubbleOffset; + [popTip showText:text direction:direction maxWidth:kScreen_Width - 30 inView:view fromFrame:frame duration:0]; + return popTip; +} +@end diff --git a/Coding_iOS/Views/NSLayoutConstraintLine.h b/Coding_iOS/Views/NSLayoutConstraintLine.h new file mode 100644 index 000000000..825ce0568 --- /dev/null +++ b/Coding_iOS/Views/NSLayoutConstraintLine.h @@ -0,0 +1,13 @@ +// +// NSLayoutConstraintLine.h +// CodingMart +// +// Created by Ease on 16/3/22. +// Copyright © 2016年 net.coding. All rights reserved. +// + +#import + +@interface NSLayoutConstraintLine : NSLayoutConstraint + +@end diff --git a/Coding_iOS/Views/NSLayoutConstraintLine.m b/Coding_iOS/Views/NSLayoutConstraintLine.m new file mode 100644 index 000000000..780133a51 --- /dev/null +++ b/Coding_iOS/Views/NSLayoutConstraintLine.m @@ -0,0 +1,18 @@ +// +// NSLayoutConstraintLine.m +// CodingMart +// +// Created by Ease on 16/3/22. +// Copyright © 2016年 net.coding. All rights reserved. +// + +#import "NSLayoutConstraintLine.h" + +@implementation NSLayoutConstraintLine +- (void)awakeFromNib{ + [super awakeFromNib]; + if (self.constant == 1) { + self.constant = 1/[UIScreen mainScreen].scale; + } +} +@end diff --git a/Coding_iOS/Views/PhoneCodeButton.m b/Coding_iOS/Views/PhoneCodeButton.m index c7d07fb46..08a100864 100644 --- a/Coding_iOS/Views/PhoneCodeButton.m +++ b/Coding_iOS/Views/PhoneCodeButton.m @@ -11,7 +11,7 @@ @interface PhoneCodeButton () @property (nonatomic, strong, readwrite) NSTimer *timer; @property (assign, nonatomic) NSTimeInterval durationToValidity; -@property (strong, nonatomic) UIView *lineView; +//@property (strong, nonatomic) UIView *lineView; @end @implementation PhoneCodeButton @@ -20,19 +20,19 @@ - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { - self.titleLabel.font = [UIFont systemFontOfSize:14]; + self.titleLabel.font = [UIFont systemFontOfSize:15]; self.enabled = YES; - _lineView = [[UIView alloc] initWithFrame:CGRectMake(-10, 5, 0.5, CGRectGetHeight(frame) - 2*5)]; - _lineView.backgroundColor = [UIColor colorWithHexString:@"0xD8D8D8"]; - [self addSubview:_lineView]; +// _lineView = [[UIView alloc] initWithFrame:CGRectMake(-10, 5, 0.5, CGRectGetHeight(frame) - 2*5)]; +// _lineView.backgroundColor = [UIColor colorWithHexString:@"0xD8D8D8"]; +// [self addSubview:_lineView]; } return self; } - (void)setEnabled:(BOOL)enabled{ [super setEnabled:enabled]; - UIColor *foreColor = [UIColor colorWithHexString:enabled? @"0x3BBD79": @"0xCCCCCC"]; + UIColor *foreColor = enabled? kColorDark2: kColorDarkA; [self setTitleColor:foreColor forState:UIControlStateNormal]; if (enabled) { [self setTitle:@"发送验证码" forState:UIControlStateNormal]; diff --git a/Coding_iOS/Views/PopFliterMenu.m b/Coding_iOS/Views/PopFliterMenu.m index 8b4c76e60..cb10e4644 100644 --- a/Coding_iOS/Views/PopFliterMenu.m +++ b/Coding_iOS/Views/PopFliterMenu.m @@ -29,7 +29,7 @@ - (id)initWithFrame:(CGRect)frame items:(NSArray *)items { // Initialization code self.items = @[@{@"all":@""},@{@"created":@""},@{@"joined":@""},@{@"watched":@""},@{@"stared":@""}].mutableCopy; self.pCount=[ProjectCount new]; - self.showStatus=FALSE; + self.showStatus= NO; [self setup]; } return self; @@ -93,6 +93,9 @@ - (void)setup { [tableview registerClass:[UITableViewCell class] forCellReuseIdentifier:@"UITableViewCell"]; tableview.tableFooterView=[UIView new]; tableview.separatorStyle=UITableViewCellSeparatorStyleNone; + tableview.estimatedRowHeight = 0; + tableview.estimatedSectionHeaderHeight = 0; + tableview.estimatedSectionFooterHeight = 0; tableview; }); [self addSubview:_tableview]; @@ -111,7 +114,7 @@ - (void)setup { #pragma mark -- event & action - (void)showMenuAtView:(UIView *)containerView { - _showStatus=TRUE; + _showStatus= YES; [containerView addSubview:self]; [_realTimeBlur showBlurViewAtView:self]; [_tableview reloadData]; @@ -123,7 +126,7 @@ - (void)dismissMenu if ([[presentView.subviews firstObject] isMemberOfClass:NSClassFromString(@"RDVTabBar")]) { [presentView bringSubviewToFront:[presentView.subviews firstObject]]; } - _showStatus=FALSE; + _showStatus= NO; [_realTimeBlur disMiss]; } @@ -158,38 +161,11 @@ -(void)updateDateSource:(ProjectCount*)pCount _items = @[@{@"all":[pCount.all stringValue]},@{@"created":[pCount.created stringValue]},@{@"joined":[pCount.joined stringValue]},@{@"watched":[pCount.watched stringValue]},@{@"stared":[pCount.stared stringValue]}].mutableCopy; } - -//转化为Projects类对应类型 --(NSInteger)convertToProjectType -{ - switch (_selectNum) { - case 0: - return ProjectsTypeAll; - break; - case 1: - return ProjectsTypeCreated; - break; - case 2: - return ProjectsTypeJoined; - break; - case 3: - return ProjectsTypeWatched; - break; - case 4: - return ProjectsTypeStared; - break; - default: - NSLog(@"type error"); - return ProjectsTypeAll; - break; - } -} - - #pragma mark -- uitableviewdelegate & datasource - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - return 3; + return 1; +// return 3; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ @@ -217,7 +193,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N titleLab.font=[UIFont systemFontOfSize:15]; [cell.contentView addSubview:titleLab]; if (indexPath.section==0) { - titleLab.textColor=(indexPath.row==_selectNum)?kColorBrandGreen:kColor222; + titleLab.textColor=(indexPath.row==_selectNum)?kColorBrandBlue:kColor222; titleLab.text=[self formatTitleStr:[_items objectAtIndex:indexPath.row]]; }else if (indexPath.section==1) { if(indexPath.row==0){ @@ -227,7 +203,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N [cell.contentView addSubview:seperatorLine]; cell.selectionStyle=UITableViewCellSelectionStyleNone; }else{ - titleLab.textColor=(indexPath.row+kfirstRowNum==_selectNum)?kColorBrandGreen:kColor222; + titleLab.textColor=(indexPath.row+kfirstRowNum==_selectNum)?kColorBrandBlue:kColor222; titleLab.text=[self formatTitleStr:[_items objectAtIndex:3+indexPath.row-1]]; } }else @@ -259,7 +235,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath if (indexPath.section==0) { _selectNum=indexPath.row; [self dismissMenu]; - _clickBlock([self convertToProjectType]); + _clickBlock(self.selectNum); }else if (indexPath.section==1) { if(indexPath.row==0){ _closeBlock(); @@ -267,7 +243,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath } _selectNum=indexPath.row+kfirstRowNum-1; [self dismissMenu]; - _clickBlock([self convertToProjectType]); + _clickBlock(self.selectNum); }else { if(indexPath.row==0){ diff --git a/Coding_iOS/Views/ProjectTagLabel.m b/Coding_iOS/Views/ProjectTagLabel.m index 93b2c11e3..9e075a8b8 100644 --- a/Coding_iOS/Views/ProjectTagLabel.m +++ b/Coding_iOS/Views/ProjectTagLabel.m @@ -48,7 +48,7 @@ - (void)setup{ [self setSize:CGSizeZero]; return; } - UIColor *tagColor = self.curTag.color.length > 1? [UIColor colorWithHexString:[self.curTag.color stringByReplacingOccurrencesOfString:@"#" withString:@"0x"]]: kColorBrandGreen; + UIColor *tagColor = self.curTag.color.length > 1? [UIColor colorWithHexString:[self.curTag.color stringByReplacingOccurrencesOfString:@"#" withString:@"0x"]]: kColorBrandBlue; self.layer.backgroundColor = tagColor.CGColor; self.textColor = [tagColor isDark]? [UIColor whiteColor]: [UIColor blackColor]; diff --git a/Coding_iOS/Views/ProjectTagsView.m b/Coding_iOS/Views/ProjectTagsView.m index dc53536b7..855074a24 100644 --- a/Coding_iOS/Views/ProjectTagsView.m +++ b/Coding_iOS/Views/ProjectTagsView.m @@ -6,11 +6,11 @@ // Copyright (c) 2015年 Coding. All rights reserved. // -#define kProjectTagsView_Padding_Icon 22.0 +#define kProjectTagsView_Padding_Icon 28.0 #define kProjectTagsView_Height_PerLine 30.0 #define kProjectTagsViewLabel_Font [UIFont systemFontOfSize:12] -#define kProjectTagsViewLabel_Height_Content 22.0 +#define kProjectTagsViewLabel_Height_Content 24.0 #define kProjectTagsViewLabel_MinWidth 44.0 #define kProjectTagsViewLabel_Padding_Content 10.0 #define kProjectTagsViewLabel_Padding_Space 5.0 @@ -145,7 +145,7 @@ - (void)p_refreshAddButtonHasTags:(BOOL)hasTags{ if (!_addTagButton) { _addTagButton = [UIButton new]; _addTagButton.layer.cornerRadius = 2; - _addTagButton.layer.borderColor = kColorDDD.CGColor; + _addTagButton.layer.borderColor = kColorDark7.CGColor; @weakify(self); [_addTagButton bk_addEventHandler:^(id sender) { @strongify(self); @@ -157,10 +157,10 @@ - (void)p_refreshAddButtonHasTags:(BOOL)hasTags{ } NSString *buttonTitle = @"添加标签"; if (hasTags) { - _addTagButton.layer.borderWidth = 0.5f; + _addTagButton.layer.borderWidth = 1.0f; _addTagButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter; _addTagButton.titleLabel.font = kProjectTagsViewLabel_Font; - [_addTagButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; + [_addTagButton setTitleColor:kColorDark7 forState:UIControlStateNormal]; [_addTagButton setTitleColor:[UIColor colorWithWhite:0 alpha:0.5] forState:UIControlStateHighlighted]; CGFloat textWidth = [buttonTitle getWidthWithFont:kProjectTagsViewLabel_Font constrainedToSize:CGSizeMake(CGFLOAT_MAX, kProjectTagsViewLabel_Height_Content)]; @@ -172,8 +172,8 @@ - (void)p_refreshAddButtonHasTags:(BOOL)hasTags{ _addTagButton.layer.borderWidth = 0.f; _addTagButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; _addTagButton.titleLabel.font = [UIFont systemFontOfSize:15]; - [_addTagButton setTitleColor:kColorBrandGreen forState:UIControlStateNormal]; - [_addTagButton setTitleColor:[UIColor colorWithHexString:@"0x3bbd79" andAlpha:0.5] forState:UIControlStateHighlighted]; + [_addTagButton setTitleColor:kColorBrandBlue forState:UIControlStateNormal]; + [_addTagButton setTitleColor:[UIColor colorWithHexString:@"0x0060FF" andAlpha:0.5] forState:UIControlStateHighlighted]; [_addTagButton setSize:CGSizeMake(kScreen_Width - 2*kPaddingLeftWidth, kProjectTagsViewLabel_Height_Content)]; [_addTagButton setTitle:buttonTitle forState:UIControlStateNormal]; @@ -224,7 +224,7 @@ - (void)setup{ [self setSize:CGSizeZero]; return; } - UIColor *tagColor = self.curTag.color.length > 1? [UIColor colorWithHexString:[self.curTag.color stringByReplacingOccurrencesOfString:@"#" withString:@"0x"]]: kColorBrandGreen; + UIColor *tagColor = self.curTag.color.length > 1? [UIColor colorWithHexString:[self.curTag.color stringByReplacingOccurrencesOfString:@"#" withString:@"0x"]]: kColorBrandBlue; self.layer.backgroundColor = tagColor.CGColor; self.textColor = [tagColor isDark]? [UIColor whiteColor]: [UIColor blackColor]; diff --git a/Coding_iOS/Views/ScreenView.h b/Coding_iOS/Views/ScreenView.h new file mode 100644 index 000000000..8a32d6287 --- /dev/null +++ b/Coding_iOS/Views/ScreenView.h @@ -0,0 +1,27 @@ +// +// ScreenView.h +// Coding_iOS +// +// Created by 张达棣 on 16/12/7. +// Copyright © 2016年 Coding. All rights reserved. +// + +#import + +@interface ScreenView : UIView + +@property (nonatomic, copy) void(^selectBlock)(NSString *keyword, NSString *status, NSString *label); +@property (nonatomic, strong) NSString *keyword; +@property (nonatomic, strong) NSString *status; //任务状态,进行中的为1,已完成的为2 +@property (nonatomic, strong) NSString *label; //任务标签 + +@property (nonatomic, strong) NSArray *tastArray; +@property (nonatomic, strong) NSArray *labels; + ++ (instancetype)creat; + +- (void)showOrHide; + +@end + + diff --git a/Coding_iOS/Views/ScreenView.m b/Coding_iOS/Views/ScreenView.m new file mode 100644 index 000000000..d37607e3e --- /dev/null +++ b/Coding_iOS/Views/ScreenView.m @@ -0,0 +1,273 @@ +// +// ScreenView.m +// Coding_iOS +// +// Created by 张达棣 on 16/12/7. +// Copyright © 2016年 Coding. All rights reserved. +// + +#import "ScreenView.h" +#import "Coding_NetAPIManager.h" +#import "TaskSelectionCell.h" +#import "ScreenCell.h" + +#define KMainLeftWith 45 + +@interface ScreenView () +@property (nonatomic, strong) UITableView *tableView; +@property (nonatomic, assign) NSInteger selectNum; //选中数据 +@property (nonatomic, strong) UISearchBar *searchBar; +@property (nonatomic, strong) UIView *mainView; +@end + +@implementation ScreenView + +#pragma mark - 生命周期方法 + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + + [self creatView]; + } + return self; +} + + +#pragma mark - 外部方法 + ++ (instancetype)creat { + ScreenView *screenView = [[ScreenView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, kScreen_Height)]; + screenView.hidden = YES; + [kKeyWindow addSubview:screenView]; + return screenView; +} + +- (void)showOrHide { + if (self.hidden) { + [self show]; + } else { + [self hide]; + } +} + +#pragma makr - 消息 + +#pragma mark - 系统委托 +#pragma mark UITableViewDataSource + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return _labels.count + _tastArray.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + if (indexPath.row < _tastArray.count) { + TaskSelectionCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_TaskSelectionCell forIndexPath:indexPath]; + cell.title = _tastArray[indexPath.row]; + cell.isSel = indexPath.row == _selectNum; + cell.isShowLine = indexPath.row == _tastArray.count - 1; + return cell; + + } else { + ScreenCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_ScreenCell forIndexPath:indexPath]; + cell.color = _labels[indexPath.row - _tastArray.count][@"color"]; + cell.title = _labels[indexPath.row - _tastArray.count][@"name"]; + cell.isSel = indexPath.row == _selectNum; + + return cell; + + } +} + +#pragma mark UITableViewDelegate + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + self.keyword = nil; + _searchBar.text = nil; + _selectNum = indexPath.row; + [tableView reloadData]; + if (indexPath.row < _tastArray.count) { + self.label = nil; + self.status = [NSString stringWithFormat:@"%ld", indexPath.row + 1]; + } else { + self.status = nil; + self.label = _labels[indexPath.row - _tastArray.count][@"name"]; + } + [self clickDis]; + +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { + return 50; +} + +- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { + [self.searchBar resignFirstResponder]; +} + +#pragma mark UISearchBarDelegate + +- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar { + self.keyword = _searchBar.text; + [self clickDis]; +} + +#pragma mark - 自定义委托 + +#pragma mark - 响应方法 + +#pragma mark - 私有方法 + +- (void)creatView { + self.hidden = YES; + self.backgroundColor = [UIColor colorWithRed:0/255.0 green:0/255.0 blue:0/255.0 alpha:.5]; + _selectNum = -1; + + UIButton *bgButton = [[UIButton alloc] init]; + [bgButton addTarget:self action:@selector(hide) forControlEvents:UIControlEventTouchDown]; + [self addSubview:bgButton]; + bgButton.sd_layout.leftSpaceToView(self, 0).topEqualToView(self).bottomEqualToView(self).rightEqualToView(self); + + UIView *mainView = [[UIView alloc] init]; + mainView.backgroundColor = [UIColor whiteColor]; + [self addSubview:mainView]; + mainView.sd_layout.leftSpaceToView(self, KMainLeftWith).topSpaceToView(self, 0).bottomEqualToView(self).rightEqualToView(self); + _mainView = mainView; + + UISearchBar *searchBar = [[UISearchBar alloc] init]; + UITextField *searchField = [searchBar valueForKey:@"searchField"]; + searchField.backgroundColor = [UIColor clearColor]; + searchField.borderStyle = UITextBorderStyleNone; + searchField.placeholder = @"查找相关任务"; + searchBar.barTintColor = [UIColor colorWithRGBHex:0xf0f2f5]; + searchBar.cornerRadius = 4; + searchBar.masksToBounds = YES; + searchBar.returnKeyType = UIReturnKeySearch; + searchBar.delegate = self; + [mainView addSubview:searchBar]; + searchBar.sd_layout.leftSpaceToView(mainView, 15).topSpaceToView(mainView, 15 + kSafeArea_Top).rightSpaceToView(mainView, 15).heightIs(31); + _searchBar = searchBar; + + UIButton *resetButton = [[UIButton alloc] init]; + [resetButton setTitle:@"重置" forState:UIControlStateNormal]; + [resetButton setTitleColor:[UIColor colorWithRGBHex:0x222222] forState:UIControlStateNormal]; + resetButton.titleLabel.font = [UIFont systemFontOfSize:15]; + resetButton.backgroundColor = [UIColor whiteColor]; + [resetButton addTarget:self action:@selector(resetButtonClick) forControlEvents:UIControlEventTouchUpInside]; + [mainView addSubview:resetButton]; + resetButton.sd_layout.leftSpaceToView(mainView, 0).bottomSpaceToView(mainView, kSafeArea_Bottom).rightSpaceToView(mainView, 0).heightIs(48.5); + + UILabel *line = [[UILabel alloc] init]; + line.backgroundColor = kColorDDD; + [mainView addSubview:line]; + line.sd_layout.leftSpaceToView(mainView, 0).rightSpaceToView(mainView, 0).bottomSpaceToView(resetButton, 0).heightIs(.5); + + UITableView *tableView = [[UITableView alloc] init]; + tableView.backgroundColor = [UIColor clearColor]; + tableView.backgroundView = nil; + tableView.dataSource = self; + tableView.delegate = self; + tableView.tableFooterView = [[UIView alloc] init]; + tableView.separatorStyle= UITableViewCellSeparatorStyleNone; + [tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"zcell"]; + [tableView registerClass:[TaskSelectionCell class] forCellReuseIdentifier:kCellIdentifier_TaskSelectionCell]; + [tableView registerClass:[ScreenCell class] forCellReuseIdentifier:kCellIdentifier_ScreenCell]; + [mainView addSubview:tableView]; + tableView.sd_layout.leftSpaceToView(mainView, 0).topSpaceToView(searchBar, 0).bottomSpaceToView(resetButton, 0).rightEqualToView(mainView); + _tableView = tableView; + + + UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] + initWithTarget:self + action:@selector(handlePan:)]; + [self addGestureRecognizer:panGestureRecognizer]; +} + + +- (void)clickDis { + [self hide]; + if (_selectBlock) { + _selectBlock(_keyword, _status, _label); + } +} + + +- (void)resetButtonClick { + [self hide]; + _keyword = _status = _label = nil; + _selectNum = -1; + _searchBar.text = nil; + [_tableView reloadData]; + if (_selectBlock) { + _selectBlock(_keyword, _status, _label); + } +} + +#pragma mark - get/set方法 + +- (void)show { + if (![_searchBar.text isEqualToString:_keyword]) { + _searchBar.text = _keyword; + } + _mainView.x = kScreen_Width - KMainLeftWith; + self.backgroundColor = [UIColor colorWithRed:0/255.0 green:0/255.0 blue:0/255.0 alpha:.5]; + + self.hidden = NO; + [UIView animateWithDuration:.3 animations:^{ + self.alpha = 1; + _mainView.x = KMainLeftWith; + }]; + +} + +- (void)hide { + [self.searchBar resignFirstResponder]; + + [UIView animateWithDuration:.3 animations:^{ + self.alpha = 0; + _mainView.x += (kScreen_Width - KMainLeftWith); + } completion:^(BOOL finished) { + self.hidden = YES; + + }]; +} + +- (void)handlePan:(UIPanGestureRecognizer*) recognizer { + [_searchBar resignFirstResponder]; + CGPoint translation = [recognizer translationInView:_mainView]; + if (_mainView.x + translation.x > KMainLeftWith) { + _mainView.x += translation.x; + [recognizer setTranslation:CGPointZero inView:_mainView]; + } else { + _mainView.x = KMainLeftWith; + } + + CGFloat alpha = .5; + alpha -= (_mainView.x / kScreen_Width * alpha); + + self.backgroundColor = [UIColor colorWithRed:0/255.0 green:0/255.0 blue:0/255.0 alpha:alpha]; + + + if (recognizer.state == UIGestureRecognizerStateEnded) { + [self hide]; + } +} + +- (void)setTastArray:(NSArray *)tastArray { + _tastArray = tastArray; + [_tableView reloadData]; + +} + +- (void)setLabels:(NSArray *)labels { + _labels = labels; + [_tableView reloadData]; +} + + +@end diff --git a/Coding_iOS/Views/Search/CategorySearchBar.h b/Coding_iOS/Views/Search/CategorySearchBar.h index 183564312..5ffd9fd59 100644 --- a/Coding_iOS/Views/Search/CategorySearchBar.h +++ b/Coding_iOS/Views/Search/CategorySearchBar.h @@ -7,14 +7,10 @@ // #import -typedef void(^SelectBlock)(); @interface CategorySearchBar : UISearchBar --(void)patchWithCategoryWithSelectBlock:(SelectBlock)block; --(void)setSearchCategory:(NSString*)title; @end - @interface MainSearchBar : UISearchBar @property (strong, nonatomic) UIButton *scanBtn; @end diff --git a/Coding_iOS/Views/Search/CategorySearchBar.m b/Coding_iOS/Views/Search/CategorySearchBar.m index 88275b97c..f73960ed1 100644 --- a/Coding_iOS/Views/Search/CategorySearchBar.m +++ b/Coding_iOS/Views/Search/CategorySearchBar.m @@ -9,56 +9,27 @@ #import "CategorySearchBar.h" @interface CategorySearchBar () -@property (copy,nonatomic)SelectBlock curBlock; -@property (strong, nonatomic)UIButton *categoryBtn; -@property (strong, nonatomic)UIButton *iconBtn; @end @implementation CategorySearchBar - --(void)layoutSubviews{ - self.autoresizesSubviews = YES; - UITextField *searchField = self.eaTextField; - [searchField setFrame:CGRectMake(60, 4.5, self.frame.size.width - 75, 22)]; - searchField.leftView = nil; - searchField.textAlignment = NSTextAlignmentLeft; -} - --(void)patchWithCategoryWithSelectBlock:(SelectBlock)block{ - [self addSubview:self.categoryBtn]; - [self addSubview:self.iconBtn]; - _curBlock = block; -} - --(UIButton*)categoryBtn{ - if (!_categoryBtn) { - _categoryBtn=[UIButton new]; - _categoryBtn.frame=CGRectMake(5, 0, 40, 31); - [_categoryBtn addTarget:self action:@selector(selectCategoryAction) forControlEvents:UIControlEventTouchUpInside]; - _categoryBtn.titleLabel.font = self.eaTextField.font; - [_categoryBtn setTitleColor:kColor666 forState:UIControlStateNormal]; - [_categoryBtn setTitle:@"项目" forState:UIControlStateNormal]; +- (instancetype)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + [self setSearchFieldBackgroundImage:[UIImage imageWithColor:[UIColor colorWithHexString:@"0xEBECEC"] withFrame:CGRectMake(0, 0, 1, 28)] forState:UIControlStateNormal]; + UITextField *searchField = self.eaTextField; + searchField.layer.masksToBounds = YES; + searchField.layer.cornerRadius = 4.0; } - return _categoryBtn; + return self; } --(UIButton*)iconBtn{ - if (!_iconBtn) { - _iconBtn=[[UIButton alloc] initWithFrame:CGRectMake(45, 11, 8, 8)]; - [_iconBtn addTarget:self action:@selector(selectCategoryAction) forControlEvents:UIControlEventTouchUpInside]; - [_iconBtn setBackgroundImage:[UIImage imageNamed:@"btn_fliter_down"] forState:UIControlStateNormal]; - } - return _iconBtn; -} - -#pragma mark -- event --(void)selectCategoryAction{ - _curBlock(); -} - --(void)setSearchCategory:(NSString*)title{ - [_categoryBtn setTitle:title forState:UIControlStateNormal]; +-(void)layoutSubviews{ + [super layoutSubviews]; + UITextField *searchField = self.eaTextField; + searchField.leftView.frame = CGRectMake(8, (CGRectGetHeight(searchField.bounds) - 13)/2, 20, 13); + searchField.leftView.contentMode = UIViewContentModeLeft; } @end diff --git a/Coding_iOS/Views/Search/TopicHotkeyView.m b/Coding_iOS/Views/Search/TopicHotkeyView.m index 8a4b84bc0..e8dd594e0 100644 --- a/Coding_iOS/Views/Search/TopicHotkeyView.m +++ b/Coding_iOS/Views/Search/TopicHotkeyView.m @@ -8,7 +8,7 @@ #import "TopicHotkeyView.h" -#define kFirst_Hotkey_Color @"0x3bbd79" +#define kFirst_Hotkey_Color @"0x0060FF" #define kOther_Hotkey_Text_Color @"0x222222" #define kOther_HotKey_Border_Color @"0xb5b5b5" diff --git a/Coding_iOS/Views/ShopBannerView.m b/Coding_iOS/Views/ShopBannerView.m index 2b86c0d67..d38c2be27 100644 --- a/Coding_iOS/Views/ShopBannerView.m +++ b/Coding_iOS/Views/ShopBannerView.m @@ -93,7 +93,7 @@ - (UIImageView *)p_reuseViewForIndex:(NSInteger)pageIndex{ if (!_imageViewList) { _imageViewList = [[NSMutableArray alloc] initWithCapacity:3]; for (int i = 0; i < 3; i++) { - UIImageView *view = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.width,self.height)]; + UIImageView *view = [[YLImageView alloc] initWithFrame:CGRectMake(0, 0, self.width,self.height)]; view.backgroundColor = [UIColor colorWithHexString:@"0xe5e5e5"]; view.clipsToBounds = YES; view.contentMode = UIViewContentModeScaleAspectFill; diff --git a/Coding_iOS/Views/ShopGoodsInfoView.m b/Coding_iOS/Views/ShopGoodsInfoView.m index 16d752bf6..783a25996 100644 --- a/Coding_iOS/Views/ShopGoodsInfoView.m +++ b/Coding_iOS/Views/ShopGoodsInfoView.m @@ -40,7 +40,7 @@ - (void)setUpContentView { UIView *superView = self; - _coverView = [[UIImageView alloc] initWithFrame:CGRectZero]; + _coverView = [[YLImageView alloc] initWithFrame:CGRectZero]; _coverView.backgroundColor = [UIColor colorWithHexString:@"0xe5e5e5"]; _coverView.contentMode = UIViewContentModeScaleAspectFill; _coverView.layer.masksToBounds =YES; @@ -53,40 +53,39 @@ - (void)setUpContentView [superView addSubview:_titleLabel]; _descLabel = [[UILabel alloc] initWithFrame:CGRectZero]; - _descLabel.font = [UIFont systemFontOfSize:12]; + _descLabel.font = [UIFont systemFontOfSize:14]; _descLabel.numberOfLines = 0 ; _descLabel.backgroundColor = [UIColor clearColor]; - _descLabel.textColor = kColor999; + _descLabel.textColor = kColorDark7; [superView addSubview:_descLabel]; _countLabel = [[UILabel alloc] initWithFrame:CGRectZero]; - _countLabel.font = FONT(12); + _countLabel.font = FONT(15); _countLabel.backgroundColor = [UIColor clearColor]; _countLabel.text = @"ⅹ1"; - _countLabel.textColor = kColorBrandGreen; + _countLabel.textColor = kColorBrandBlue; [superView addSubview:_countLabel]; _codingCoinView = [UIButton buttonWithType:UIButtonTypeCustom]; [_codingCoinView setImage:[UIImage imageNamed:@"shop_coding_coin_icon"] forState:UIControlStateNormal]; [_codingCoinView setTitle:@" 码币 " forState:UIControlStateNormal]; - [_codingCoinView setTitleColor:kColor222 forState:UIControlStateNormal]; - [_codingCoinView.titleLabel setFont:[UIFont boldSystemFontOfSize:12.0]]; + [_codingCoinView setTitleColor:kColorDark7 forState:UIControlStateNormal]; + [_codingCoinView.titleLabel setFont:[UIFont systemFontOfSize:14.0]]; [superView addSubview:_codingCoinView]; + _priceLabel = [UILabel labelWithFont:[UIFont systemFontOfSize:15] textColor:kColorBrandOrange]; + [superView addSubview:_priceLabel]; - float _coverViewHeight = 90; - NSLog(@"_coverViewHeight %lf",_coverViewHeight); [_coverView mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.left.equalTo(superView).offset(12); - make.width.offset(_coverViewHeight); - make.height.offset(108/2); + make.top.equalTo(superView).offset(15); + make.left.equalTo(superView).offset(12); + make.width.height.mas_equalTo(80); }]; - [_titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(_coverView.mas_top); - make.left.equalTo(_coverView.mas_right).offset(14); - make.right.equalTo(superView.mas_right).offset(-(20+13)); + make.left.equalTo(_coverView.mas_right).offset(20); + make.right.offset(-(20+13)); }]; [_countLabel mas_makeConstraints:^(MASConstraintMaker *make) { @@ -96,16 +95,22 @@ - (void)setUpContentView }]; [_codingCoinView mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(_titleLabel.mas_bottom).offset(14); + make.centerY.equalTo(_coverView); +// make.top.equalTo(_titleLabel.mas_bottom).offset(10); make.left.equalTo(_titleLabel.mas_left); }]; + [_priceLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(_titleLabel); + make.bottom.equalTo(_coverView); + }]; + DashesLineView *lineView = [[DashesLineView alloc] init]; - lineView.lineColor = kColorCCC; + lineView.lineColor = kColorDDD; lineView.backgroundColor = [UIColor clearColor]; [superView addSubview:lineView]; [lineView mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(_coverView.mas_bottom).offset(10); + make.top.equalTo(_coverView.mas_bottom).offset(15); make.left.equalTo(_coverView.mas_left); make.right.equalTo(superView.mas_right).offset(-12); make.height.offset(0.5); @@ -114,7 +119,6 @@ - (void)setUpContentView [_descLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(lineView.mas_bottom).offset(10); make.left.right.equalTo(lineView); - }]; [self mas_makeConstraints:^(MASConstraintMaker *make) { @@ -124,10 +128,10 @@ - (void)setUpContentView }]; UIView *bottomLineView = [[UIView alloc] init]; - bottomLineView.backgroundColor = [UIColor colorWithHexString:@"0xC8C8C8"]; + bottomLineView.backgroundColor = kColorDDD; [superView addSubview:bottomLineView]; [bottomLineView mas_makeConstraints:^(MASConstraintMaker *make) { - make.height.offset(0.5); + make.height.mas_equalTo(kLine_MinHeight); make.left.right.bottom.equalTo(superView); }]; @@ -135,15 +139,19 @@ - (void)setUpContentView - (void)configViewWithModel:(ShopGoods *)model { - _titleLabel.text = model.name; + _titleLabel.text = [model.name componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"¥¥"]].firstObject; NSString *points_cost = [NSString stringWithFormat:@" %@ 码币",[model.points_cost stringValue]]; [_codingCoinView setTitle:points_cost forState:UIControlStateNormal]; - - + CGFloat price = model.points_cost.floatValue * 50; + if (price - ((int)price) < .1) { + _priceLabel.text = [NSString stringWithFormat:@"¥%.0f", price]; + }else{ + _priceLabel.text = [NSString stringWithFormat:@"¥%.1f", price]; + } [_coverView sd_setImageWithURL:[model.image urlImageWithCodePathResize:90* 2] placeholderImage:nil]; - HtmlMedia *mHtml = [[HtmlMedia alloc] initWithString:model.description_mine showType:MediaShowTypeNone]; - _descLabel.text = mHtml.contentDisplay; + [_descLabel ea_setText:mHtml.contentDisplay lineSpacing:5]; +// _descLabel.text = mHtml.contentDisplay; CGFloat height = [self systemLayoutSizeFittingSize:UILayoutFittingExpandedSize].height; self.frame = CGRectMake(0, 0, kScreen_Width, height); diff --git a/Coding_iOS/Views/TableListView/CodingSearchDisplayView.h b/Coding_iOS/Views/TableListView/CodingSearchDisplayView.h new file mode 100644 index 000000000..0877c8226 --- /dev/null +++ b/Coding_iOS/Views/TableListView/CodingSearchDisplayView.h @@ -0,0 +1,33 @@ +// +// CodingSearchDisplayView.h +// Coding_iOS +// +// Created by Ease on 2016/12/15. +// Copyright © 2016年 Coding. All rights reserved. +// + +typedef NS_ENUM(NSUInteger, eSearchType) { + eSearchType_Project=0, + eSearchType_Task, +// eSearchType_Topic, + eSearchType_Tweet, + eSearchType_Document, + eSearchType_User, + eSearchType_Merge, +// eSearchType_Pull, + eSearchType_All +}; + + +#import +#import "PublicSearchModel.h" + +@interface CodingSearchDisplayView : UIView +@property (nonatomic,assign)eSearchType curSearchType; +@property (strong, nonatomic) NSString *searchBarText; +@property (nonatomic, strong) PublicSearchModel *searchPros; +@property (copy, nonatomic) void(^cellClickedBlock)(id clickedItem, eSearchType searType); +@property (copy, nonatomic) void(^goToConversationBlock)(User *curUser); +@property (copy, nonatomic) void(^refreshAllBlock)(); + +@end diff --git a/Coding_iOS/Views/TableListView/CodingSearchDisplayView.m b/Coding_iOS/Views/TableListView/CodingSearchDisplayView.m new file mode 100644 index 000000000..0facb89e0 --- /dev/null +++ b/Coding_iOS/Views/TableListView/CodingSearchDisplayView.m @@ -0,0 +1,610 @@ +// +// CodingSearchDisplayView.m +// Coding_iOS +// +// Created by Ease on 2016/12/15. +// Copyright © 2016年 Coding. All rights reserved. +// + +#import "CodingSearchDisplayView.h" +#import "TopicHotkeyView.h" +#import "Coding_NetAPIManager.h" +#import "ODRefreshControl.h" +#import "SVPullToRefresh.h" +#import "XHRealTimeBlur.h" +#import "CSSearchModel.h" +#import "RKSwipeBetweenViewControllers.h" +#import "CSHotTopicView.h" +#import "CSMyTopicVC.h" +#import "UserInfoViewController.h" +#import "WebViewController.h" +#import "CSHotTopicPagesVC.h" +#import "CSTopicDetailVC.h" +#import "PublicSearchModel.h" +#import "Login.h" +#import "NSString+Attribute.h" + +// cell-------------- +#import "ProjectAboutMeListCell.h" +#import "FileSearchCell.h" +#import "TweetSearchCell.h" +#import "UserSearchCell.h" +#import "TaskSearchCell.h" +#import "TopicSearchCell.h" +#import "PRMRSearchCell.h" + +// nav-------- +#import "TweetDetailViewController.h" +#import "ConversationViewController.h" + + +@interface CodingSearchDisplayView () +@property (nonatomic, strong) UITableView *searchTableView; +@property (nonatomic, strong) UILabel *headerLabel; + +@property (nonatomic, strong) NSMutableArray *dateSource; +@property (nonatomic, assign) BOOL isLoading; + + +@end + +@implementation CodingSearchDisplayView + +- (instancetype)initWithFrame:(CGRect)frame{ + self = [super initWithFrame:frame]; + if (self) { + _searchTableView = ({ + UITableView *tableView = [[UITableView alloc] initWithFrame:frame style:UITableViewStylePlain]; + tableView.backgroundColor = [UIColor whiteColor]; + tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + [tableView registerClass:[TweetSearchCell class] forCellReuseIdentifier:@"TweetSearchCell"]; + [tableView registerClass:[ProjectAboutMeListCell class] forCellReuseIdentifier:@"ProjectAboutMeListCell"]; + [tableView registerClass:[FileSearchCell class] forCellReuseIdentifier:@"FileSearchCell"]; + [tableView registerClass:[UserSearchCell class] forCellReuseIdentifier:@"UserSearchCell"]; + [tableView registerClass:[TaskSearchCell class] forCellReuseIdentifier:@"TaskSearchCell"]; + [tableView registerClass:[TopicSearchCell class] forCellReuseIdentifier:@"TopicSearchCell"]; + [tableView registerClass:[PRMRSearchCell class] forCellReuseIdentifier:@"PRMRSearchCell"]; + + tableView.dataSource = self; + tableView.delegate = self; + { + __weak typeof(self) weakSelf = self; + [tableView addInfiniteScrollingWithActionHandler:^{ + [weakSelf loadMore]; + }]; + } + + [self addSubview:tableView]; + + self.headerLabel = ({ + UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 2, kScreen_Width, 44)]; + label.backgroundColor = [UIColor clearColor]; + label.textColor = kColor999; + label.textAlignment = NSTextAlignmentCenter; + label.font = [UIFont systemFontOfSize:12]; + label; + }); + + UIView *headview = ({ + UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 44)]; + v.backgroundColor = [UIColor whiteColor]; + [v addSubview:self.headerLabel]; + v; + }); + tableView.tableHeaderView = headview; + + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; + tableView; + }); + } + return self; +} + +- (void)setSearchPros:(PublicSearchModel *)searchPros{ + _searchPros = searchPros; + self.dateSource = @[].mutableCopy; + switch (_curSearchType) { + case eSearchType_Project: + [self.dateSource addObjectsFromArray:_searchPros.projects.list]; + break; + case eSearchType_Tweet: + [self.dateSource addObjectsFromArray:_searchPros.tweets.list]; + break; + case eSearchType_Document: + [self.dateSource addObjectsFromArray:_searchPros.files.list]; + break; + case eSearchType_User: + [self.dateSource addObjectsFromArray:_searchPros.friends.list]; + break; + case eSearchType_Task: + [self.dateSource addObjectsFromArray:_searchPros.tasks.list]; + break; +// case eSearchType_Topic: +// [self.dateSource addObjectsFromArray:_searchPros.project_topics.list]; +// break; + case eSearchType_Merge: + [self.dateSource addObjectsFromArray:_searchPros.merge_requests.list]; + break; +// case eSearchType_Pull: +// [self.dateSource addObjectsFromArray:_searchPros.pull_requests.list]; +// break; + default: + break; + } + + __weak typeof(self) weakSelf = self; + [_searchTableView configBlankPage:EaseBlankPageTypeProject_SEARCH hasData:[self noEmptyList] hasError:NO reloadButtonBlock:^(id sender) { + if (weakSelf.refreshAllBlock) { + weakSelf.refreshAllBlock(); + } + }]; + + //空白页按钮事件 + _searchTableView.blankPageView.clickButtonBlock=^(EaseBlankPageType curType) { + if (weakSelf.refreshAllBlock) { + weakSelf.refreshAllBlock(); + } + }; + + [self refreshHeaderTitle]; + [self.searchTableView reloadData]; + [weakSelf.searchTableView.infiniteScrollingView stopAnimating]; + _searchTableView.showsInfiniteScrolling = [self showTotalPage]; +} + +- (void)loadMore { + if(_isLoading){ + [_searchTableView.infiniteScrollingView stopAnimating]; + return; + } + + //判断分类 + int currentPage = 0; + int totalPage = 0; + + switch (_curSearchType) { + case eSearchType_Project: + currentPage=[_searchPros.projects.page intValue]; + totalPage=[_searchPros.projects.totalPage intValue]; + break; + case eSearchType_Tweet: + currentPage=[_searchPros.tweets.page intValue]; + totalPage=[_searchPros.tweets.totalPage intValue]; + break; + case eSearchType_Document: + currentPage=[_searchPros.files.page intValue]; + totalPage=[_searchPros.files.totalPage intValue]; + break; + case eSearchType_User: + currentPage=[_searchPros.friends.page intValue]; + totalPage=[_searchPros.friends.totalPage intValue]; + break; + case eSearchType_Task: + currentPage=[_searchPros.tasks.page intValue]; + totalPage=[_searchPros.tasks.totalPage intValue]; + break; +// case eSearchType_Topic: +// currentPage=[_searchPros.project_topics.page intValue]; +// totalPage=[_searchPros.project_topics.totalPage intValue]; +// break; + case eSearchType_Merge: + currentPage=[_searchPros.merge_requests.page intValue]; + totalPage=[_searchPros.merge_requests.totalPage intValue]; + break; +// case eSearchType_Pull: +// currentPage=[_searchPros.pull_requests.page intValue]; +// totalPage=[_searchPros.pull_requests.totalPage intValue]; +// break; + default: + break; + } + + if(currentPage >= totalPage) + { + [_searchTableView.infiniteScrollingView stopAnimating]; + return; + } + + [self requestDataWithPage:currentPage + 1]; +} + +- (void)requestDataWithPage:(NSInteger)page { + + _isLoading = YES; + + __weak typeof(self) weakSelf = self; + if (_curSearchType==eSearchType_Tweet) { + [[Coding_NetAPIManager sharedManager] requestWithSearchString:_searchBarText typeStr:@"tweet" andPage:page andBlock:^(id data, NSError *error) { + if(data) { + NSDictionary *dataDic = (NSDictionary *)data; + NSArray *resultA = [NSObject arrayFromJSON:dataDic[@"list"] ofObjects:@"Tweet"]; + [weakSelf.searchPros.tweets.list addObjectsFromArray:resultA]; + //更新page + weakSelf.searchPros.tweets.page = dataDic[@"page"] ; + weakSelf.searchPros.tweets.totalPage = dataDic[@"totalPage"] ; + [weakSelf.dateSource addObjectsFromArray:resultA]; + [weakSelf.searchTableView reloadData]; + [weakSelf.searchTableView.infiniteScrollingView stopAnimating]; + weakSelf.searchTableView.showsInfiniteScrolling = [weakSelf showTotalPage]; + } + weakSelf.isLoading = NO; + }]; + }else if(_curSearchType==eSearchType_Project){ + [[Coding_NetAPIManager sharedManager] requestWithSearchString:_searchBarText typeStr:@"project" andPage:page andBlock:^(id data, NSError *error) { + if(data) { + NSDictionary *dataDic = (NSDictionary *)data; + NSArray *resultA = [NSObject arrayFromJSON:dataDic[@"list"] ofObjects:@"Project"]; + [weakSelf.searchPros.projects.list addObjectsFromArray:resultA]; + //更新page + weakSelf.searchPros.projects.page = dataDic[@"page"] ; + weakSelf.searchPros.projects.totalPage = dataDic[@"totalPage"] ; + [weakSelf.dateSource addObjectsFromArray:resultA]; + [weakSelf.searchTableView reloadData]; + [weakSelf.searchTableView.infiniteScrollingView stopAnimating]; + weakSelf.searchTableView.showsInfiniteScrolling = [weakSelf showTotalPage]; + } + weakSelf.isLoading = NO; + }]; + }else if(_curSearchType==eSearchType_Document){ + [[Coding_NetAPIManager sharedManager] requestWithSearchString:_searchBarText typeStr:@"file" andPage:page andBlock:^(id data, NSError *error) { + if(data) { + NSDictionary *dataDic = (NSDictionary *)data; + NSArray *resultA = [NSObject arrayFromJSON:dataDic[@"list"] ofObjects:@"ProjectFile"]; + [weakSelf.searchPros.files.list addObjectsFromArray:resultA]; + //更新page + weakSelf.searchPros.files.page = dataDic[@"page"] ; + weakSelf.searchPros.files.totalPage = dataDic[@"totalPage"] ; + [weakSelf.dateSource addObjectsFromArray:resultA]; + [weakSelf.searchTableView reloadData]; + [weakSelf.searchTableView.infiniteScrollingView stopAnimating]; + weakSelf.searchTableView.showsInfiniteScrolling = [weakSelf showTotalPage]; + } + weakSelf.isLoading = NO; + }]; + }else if(_curSearchType==eSearchType_Merge){ + [[Coding_NetAPIManager sharedManager] requestWithSearchString:_searchBarText typeStr:@"mr" andPage:page andBlock:^(id data, NSError *error) { + if(data) { + NSDictionary *dataDic = (NSDictionary *)data; + NSArray *resultA = [NSObject arrayFromJSON:dataDic[@"list"] ofObjects:@"MRPR"]; + [weakSelf.searchPros.merge_requests.list addObjectsFromArray:resultA]; + //更新page + weakSelf.searchPros.merge_requests.page = dataDic[@"page"] ; + weakSelf.searchPros.merge_requests.totalPage = dataDic[@"totalPage"] ; + [weakSelf.dateSource addObjectsFromArray:resultA]; + [weakSelf.searchTableView reloadData]; + [weakSelf.searchTableView.infiniteScrollingView stopAnimating]; + weakSelf.searchTableView.showsInfiniteScrolling = [weakSelf showTotalPage]; + } + weakSelf.isLoading = NO; + }]; +// }else if(_curSearchType==eSearchType_Pull){ +// [[Coding_NetAPIManager sharedManager] requestWithSearchString:_searchBarText typeStr:@"pr" andPage:page andBlock:^(id data, NSError *error) { +// if(data) { +// NSDictionary *dataDic = (NSDictionary *)data; +// NSArray *resultA = [NSObject arrayFromJSON:dataDic[@"list"] ofObjects:@"MRPR"]; +// [weakSelf.searchPros.pull_requests.list addObjectsFromArray:resultA]; +// //更新page +// weakSelf.searchPros.pull_requests.page = dataDic[@"page"] ; +// weakSelf.searchPros.pull_requests.totalPage = dataDic[@"totalPage"] ; +// [weakSelf.dateSource addObjectsFromArray:resultA]; +// [weakSelf.searchTableView reloadData]; +// [weakSelf.searchTableView.infiniteScrollingView stopAnimating]; +// weakSelf.searchTableView.showsInfiniteScrolling = [weakSelf showTotalPage]; +// } +// weakSelf.isLoading = NO; +// }]; + }else if(_curSearchType==eSearchType_Task){ + [[Coding_NetAPIManager sharedManager] requestWithSearchString:_searchBarText typeStr:@"task" andPage:page andBlock:^(id data, NSError *error) { + if(data) { + NSDictionary *dataDic = (NSDictionary *)data; + NSArray *resultA = [NSObject arrayFromJSON:dataDic[@"list"] ofObjects:@"Task"]; + + //task 处理 description 关键字 + NSArray *resultTask =dataDic[@"list"]; + for (int i=0;i<[resultA count];i++) { + Task *curTask=[resultA objectAtIndex:i]; + if ([resultTask count]>i) { + curTask.descript= [[[resultTask objectAtIndex:i] objectForKey:@"description"] firstObject]; + } + } + + [weakSelf.searchPros.tasks.list addObjectsFromArray:resultA]; + //更新page + weakSelf.searchPros.tasks.page = dataDic[@"page"] ; + weakSelf.searchPros.tasks.totalPage = dataDic[@"totalPage"] ; + + + [weakSelf.dateSource addObjectsFromArray:resultA]; + [weakSelf.searchTableView reloadData]; + [weakSelf.searchTableView.infiniteScrollingView stopAnimating]; + weakSelf.searchTableView.showsInfiniteScrolling = [weakSelf showTotalPage]; + } + weakSelf.isLoading = NO; + }]; + }else if(_curSearchType==eSearchType_User){ + [[Coding_NetAPIManager sharedManager] requestWithSearchString:_searchBarText typeStr:@"user" andPage:page andBlock:^(id data, NSError *error) { + if(data) { + NSDictionary *dataDic = (NSDictionary *)data; + NSArray *resultA = [NSObject arrayFromJSON:dataDic[@"list"] ofObjects:@"User"]; + [weakSelf.searchPros.friends.list addObjectsFromArray:resultA]; + //更新page + weakSelf.searchPros.friends.page = dataDic[@"page"] ; + weakSelf.searchPros.friends.totalPage = dataDic[@"totalPage"] ; + [weakSelf.dateSource addObjectsFromArray:resultA]; + [weakSelf.searchTableView reloadData]; + [weakSelf.searchTableView.infiniteScrollingView stopAnimating]; + weakSelf.searchTableView.showsInfiniteScrolling = [weakSelf showTotalPage]; + } + weakSelf.isLoading = NO; + }]; +// }else if(_curSearchType==eSearchType_Topic){ +// [[Coding_NetAPIManager sharedManager] requestWithSearchString:_searchBarText typeStr:@"topic" andPage:page andBlock:^(id data, NSError *error) { +// if(data) { +// NSDictionary *dataDic = (NSDictionary *)data; +// NSArray *resultA = [NSObject arrayFromJSON:dataDic[@"list"] ofObjects:@"ProjectTopic"]; +// +// //topic 处理 content 关键字 +// NSArray *resultTopic =dataDic[@"list"]; +// for (int i=0;i<[resultA count];i++) { +// ProjectTopic *curTopic=[resultA objectAtIndex:i]; +// if ([resultTopic count]>i) { +// curTopic.contentStr= [[[resultTopic objectAtIndex:i] objectForKey:@"content"] firstObject]; +// } +// } +// +// [weakSelf.searchPros.project_topics.list addObjectsFromArray:resultA]; +// //更新page +// weakSelf.searchPros.project_topics.page = dataDic[@"page"] ; +// weakSelf.searchPros.project_topics.totalPage = dataDic[@"totalPage"] ; +// [weakSelf.dateSource addObjectsFromArray:resultA]; +// [weakSelf.searchTableView reloadData]; +// [weakSelf.searchTableView.infiniteScrollingView stopAnimating]; +// weakSelf.searchTableView.showsInfiniteScrolling = [weakSelf showTotalPage]; +// } +// weakSelf.isLoading = NO; +// }]; + }else{ + [self.searchTableView.infiniteScrollingView stopAnimating]; + self.searchTableView.showsInfiniteScrolling = NO; + self.isLoading=NO; + } +} + +//更新header数量和类型统计 +- (void)refreshHeaderTitle{ + NSString *titleStr; + switch (_curSearchType) { + case eSearchType_Project: + if ([_searchPros.projects.totalRow longValue]==0) { + titleStr=nil; + }else{ + titleStr=[NSString stringWithFormat:@"共搜索到 %ld 个与\"%@\"相关的项目", [_searchPros.projects.totalRow longValue],_searchBarText]; + } + break; + case eSearchType_Tweet: + if ([_searchPros.tweets.totalRow longValue]==0) { + titleStr=nil; + }else{ + titleStr=[NSString stringWithFormat:@"共搜索到 %ld 个与\"%@\"相关的冒泡", [_searchPros.tweets.totalRow longValue],_searchBarText]; + } + break; + case eSearchType_Document: + if ([_searchPros.files.totalRow longValue]==0) { + titleStr=nil; + }else{ + titleStr=[NSString stringWithFormat:@"共搜索到 %ld 个与\"%@\"相关的文档", [_searchPros.files.totalRow longValue],_searchBarText]; + } + break; + case eSearchType_User: + if ([_searchPros.friends.totalRow longValue]==0) { + titleStr=nil; + }else{ + titleStr=[NSString stringWithFormat:@"共搜索到 %ld 个与\"%@\"相关的用户", [_searchPros.friends.totalRow longValue],_searchBarText]; + } + break; + case eSearchType_Task: + if ([_searchPros.tasks.totalRow longValue]==0) { + titleStr=nil; + }else{ + titleStr=[NSString stringWithFormat:@"共搜索到 %ld 个与\"%@\"相关的任务", [_searchPros.tasks.totalRow longValue],_searchBarText]; + } + break; +// case eSearchType_Topic: +// if ([_searchPros.project_topics.totalRow longValue]==0) { +// titleStr=nil; +// }else{ +// titleStr=[NSString stringWithFormat:@"共搜索到 %ld 个与\"%@\"相关的讨论", [_searchPros.project_topics.totalRow longValue],_searchBarText]; +// } +// break; + case eSearchType_Merge: + if ([_searchPros.merge_requests.totalRow longValue]==0) { + titleStr=nil; + }else{ + titleStr=[NSString stringWithFormat:@"共搜索到 %ld 个与\"%@\"相关的合并请求", [_searchPros.merge_requests.totalRow longValue],_searchBarText]; + } + break; +// case eSearchType_Pull: +// if ([_searchPros.pull_requests.totalRow longValue]==0) { +// titleStr=nil; +// }else{ +// titleStr=[NSString stringWithFormat:@"共搜索到 %ld 个与\"%@\"相关的 Pull 请求", [_searchPros.pull_requests.totalRow longValue],_searchBarText]; +// } +// break; + default: + break; + } + self.headerLabel.text=titleStr; +} + +//是否显示加载更多 +-(BOOL)showTotalPage{ + switch (_curSearchType) { + case eSearchType_Project: + return _searchPros.projects.page<_searchPros.projects.totalPage; + break; + case eSearchType_Tweet: + return _searchPros.tweets.page<_searchPros.tweets.totalPage; + break; + case eSearchType_Document: + return _searchPros.files.page<_searchPros.files.totalPage; + break; + case eSearchType_User: + return _searchPros.friends.page<_searchPros.friends.totalPage; + break; + case eSearchType_Task: + return _searchPros.tasks.page<_searchPros.tasks.totalPage; + break; +// case eSearchType_Topic: +// return _searchPros.project_topics.page<_searchPros.project_topics.totalPage; +// break; + case eSearchType_Merge: + return _searchPros.merge_requests.page<_searchPros.merge_requests.totalPage; + break; +// case eSearchType_Pull: +// return _searchPros.pull_requests.page<_searchPros.pull_requests.totalPage; +// break; + default: + return NO; + break; + } +} + +//判断是否空 +-(BOOL)noEmptyList{ + switch (_curSearchType) { + case eSearchType_Project: + return [_searchPros.projects.list count]; + break; + case eSearchType_Tweet: + return [_searchPros.tweets.list count]; + break; + case eSearchType_Document: + return [_searchPros.files.list count]; + break; + case eSearchType_User: + return [_searchPros.friends.list count]; + break; + case eSearchType_Task: + return [_searchPros.tasks.list count]; + break; +// case eSearchType_Topic: +// return [_searchPros.project_topics.list count]; +// break; + case eSearchType_Merge: + return [_searchPros.merge_requests.list count]; + break; +// case eSearchType_Pull: +// return [_searchPros.pull_requests.list count]; +// break; + default: + return TRUE; + break; + } +} + +#pragma mark - UITableViewDelegate & UITableViewDataSource Support + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + + return [_dateSource count]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + if (_curSearchType==eSearchType_Tweet) { + TweetSearchCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TweetSearchCell" forIndexPath:indexPath]; + cell.selectionStyle = UITableViewCellSelectionStyleNone; + Tweet *tweet = _dateSource[indexPath.row]; + cell.tweet = tweet; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; + return cell; + }else if(_curSearchType==eSearchType_Project){ + ProjectAboutMeListCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ProjectAboutMeListCell" forIndexPath:indexPath]; + cell.openKeywords=TRUE; + Project *project=_dateSource[indexPath.row]; + [cell setProject:project hasSWButtons:NO hasBadgeTip:YES hasIndicator:NO]; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; + return cell; + }else if(_curSearchType==eSearchType_Document){ + FileSearchCell *cell = [tableView dequeueReusableCellWithIdentifier:@"FileSearchCell" forIndexPath:indexPath]; + ProjectFile *file =_dateSource[indexPath.row]; + cell.file = file; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; + return cell; + }else if(_curSearchType==eSearchType_User){ + UserSearchCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UserSearchCell" forIndexPath:indexPath]; + User *curUser = _dateSource[indexPath.row]; + cell.curUser = curUser; + __weak typeof(self) weakSelf = self; + cell.rightBtnClickedBlock=^(User *curUser) { + if (weakSelf.goToConversationBlock) { + weakSelf.goToConversationBlock(curUser); + } + }; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; + return cell; + }else if(_curSearchType==eSearchType_Task){ + TaskSearchCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TaskSearchCell" forIndexPath:indexPath]; + Task *task =_dateSource[indexPath.row]; + cell.task=task; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; + return cell; +// }else if(_curSearchType==eSearchType_Topic){ +// TopicSearchCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TopicSearchCell" forIndexPath:indexPath]; +// ProjectTopic *topic =_dateSource[indexPath.row]; +// cell.curTopic = topic; +// [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; +// return cell; + }else if(_curSearchType==eSearchType_Merge){ + PRMRSearchCell *cell = [tableView dequeueReusableCellWithIdentifier:@"PRMRSearchCell" forIndexPath:indexPath]; + MRPR *curMRPR =_dateSource[indexPath.row]; + cell.curMRPR = curMRPR; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; + return cell; +// }else if(_curSearchType==eSearchType_Pull){ +// PRMRSearchCell *cell = [tableView dequeueReusableCellWithIdentifier:@"PRMRSearchCell" forIndexPath:indexPath]; +// MRPR *curMRPR =_dateSource[indexPath.row]; +// cell.curMRPR = curMRPR; +// [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; +// return cell; + }else{ + return [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"]; + } +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { + if (_curSearchType==eSearchType_Tweet) { + Tweet *tweet = _dateSource[indexPath.row]; + return[TweetSearchCell cellHeightWithObj:tweet]; + }else if(_curSearchType==eSearchType_Project){ + return kProjectAboutMeListCellHeight; + }else if(_curSearchType==eSearchType_Document){ + return kFileSearchCellHeight; + }else if(_curSearchType==eSearchType_User){ + return kUserSearchCellHeight; + }else if(_curSearchType==eSearchType_Task){ + Task *task = _dateSource[indexPath.row]; + return [TaskSearchCell cellHeightWithObj:task]; +// }else if(_curSearchType==eSearchType_Topic){ +// ProjectTopic *topic = _dateSource[indexPath.row]; +// return [TopicSearchCell cellHeightWithObj:topic]; +// }else if (_curSearchType==eSearchType_Pull){ +// MRPR *mrpr = _dateSource[indexPath.row]; +// return [PRMRSearchCell cellHeightWithObj:mrpr]; + }else if (_curSearchType==eSearchType_Merge){ + MRPR *mrpr = _dateSource[indexPath.row]; + return [PRMRSearchCell cellHeightWithObj:mrpr]; + }else{ + return 100; + } +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + [tableView deselectRowAtIndexPath:indexPath animated:NO]; + if (_cellClickedBlock) { + _cellClickedBlock(_dateSource[indexPath.row], _curSearchType); + } +} + +@end diff --git a/Coding_iOS/Views/TableListView/EABoardTaskListBlankView.h b/Coding_iOS/Views/TableListView/EABoardTaskListBlankView.h new file mode 100644 index 000000000..7222c9460 --- /dev/null +++ b/Coding_iOS/Views/TableListView/EABoardTaskListBlankView.h @@ -0,0 +1,15 @@ +// +// EABoardTaskListBlankView.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/4/27. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import + +@interface EABoardTaskListBlankView : UIView +@property (weak, nonatomic) IBOutlet UIButton *createDefaultBtn; +@property (weak, nonatomic) IBOutlet UIButton *addBtn; + +@end diff --git a/Coding_iOS/Views/TableListView/EABoardTaskListBlankView.m b/Coding_iOS/Views/TableListView/EABoardTaskListBlankView.m new file mode 100644 index 000000000..511097b43 --- /dev/null +++ b/Coding_iOS/Views/TableListView/EABoardTaskListBlankView.m @@ -0,0 +1,21 @@ +// +// EABoardTaskListBlankView.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/4/27. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "EABoardTaskListBlankView.h" + +@implementation EABoardTaskListBlankView + +/* +// Only override drawRect: if you perform custom drawing. +// An empty implementation adversely affects performance during animation. +- (void)drawRect:(CGRect)rect { + // Drawing code +} +*/ + +@end diff --git a/Coding_iOS/Views/TableListView/EABoardTaskListBlankView.xib b/Coding_iOS/Views/TableListView/EABoardTaskListBlankView.xib new file mode 100644 index 000000000..212535501 --- /dev/null +++ b/Coding_iOS/Views/TableListView/EABoardTaskListBlankView.xib @@ -0,0 +1,261 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Coding_iOS/Views/TableListView/EABoardTaskListView.h b/Coding_iOS/Views/TableListView/EABoardTaskListView.h new file mode 100644 index 000000000..cfb52820f --- /dev/null +++ b/Coding_iOS/Views/TableListView/EABoardTaskListView.h @@ -0,0 +1,17 @@ +// +// EABoardTaskListView.h +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/4/27. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import +#import "EABoardTaskList.h" + +@interface EABoardTaskListView : UIView +@property (strong, nonatomic) EABoardTaskList *myBoardTL; +@property (copy, nonatomic) void(^boardTLsChangedBlock)(); + +- (void)refresh; +@end diff --git a/Coding_iOS/Views/TableListView/EABoardTaskListView.m b/Coding_iOS/Views/TableListView/EABoardTaskListView.m new file mode 100644 index 000000000..77b1ee322 --- /dev/null +++ b/Coding_iOS/Views/TableListView/EABoardTaskListView.m @@ -0,0 +1,312 @@ +// +// EABoardTaskListView.m +// Coding_iOS +// +// Created by Easeeeeeeeee on 2018/4/27. +// Copyright © 2018年 Coding. All rights reserved. +// + +#import "EABoardTaskListView.h" +#import "EATaskBoardListTaskCell.h" +#import "ODRefreshControl.h" +#import "Coding_NetAPIManager.h" +#import "SVPullToRefresh.h" +#import "EditTaskViewController.h" +#import "SettingTextViewController.h" +#import "TaskBoardsViewController.h" +#import "EABoardTaskListBlankView.h" + +@interface EABoardTaskListDefaultModel: NSObject +@property (strong, nonatomic) NSArray *defaultBoardTLTitleList; +@property (assign, nonatomic) NSInteger handledCount; +@end + +@implementation EABoardTaskListDefaultModel + +- (instancetype)init{ + self = [super init]; + if (self) { + _defaultBoardTLTitleList = @[@"需求分析", + @"产品分析", + @"开发中", + @"产品测试", + @"产品上线", + ]; + _handledCount = 0; + } + return self; +} +@end + +@interface EABoardTaskListView () +@property (strong, nonatomic) UITableView *myTableView; +@property (strong, nonatomic) ODRefreshControl *myRefreshControl; + +@end + +@implementation EABoardTaskListView + +- (instancetype)init{ + self = [super init]; + if (self) { + _myTableView = ({ + UITableView *tableView = [[UITableView alloc] initWithFrame:self.bounds style:UITableViewStylePlain]; + tableView.backgroundColor = [UIColor clearColor]; + tableView.delegate = self; + tableView.dataSource = self; + [tableView registerClass:[EATaskBoardListTaskCell class] forCellReuseIdentifier:EATaskBoardListTaskCell.nameOfClass]; + tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + [self addSubview:tableView]; + [tableView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self); + }]; + UIEdgeInsets insets = UIEdgeInsetsMake(0, 0, 49, 0); + tableView.contentInset = insets; + tableView.scrollIndicatorInsets = insets; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; + tableView; + }); + _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; + [_myRefreshControl addTarget:self action:@selector(refresh) forControlEvents:UIControlEventValueChanged]; + __weak typeof(self) weakSelf = self; + [_myTableView addInfiniteScrollingWithActionHandler:^{ + [weakSelf refreshMore]; + }]; + } + return self; +} + +- (void)setMyBoardTL:(EABoardTaskList *)myBoardTL{ + _myBoardTL = myBoardTL; + [self.myTableView reloadData]; + [self refresh]; +} + +- (void)refresh{ + _myTableView.scrollEnabled = !_myBoardTL.isBlankType; + if (!_myBoardTL.isBlankType) { + _myBoardTL.willLoadMore = NO; + [self sendRequest]; + }else{ + [self.myTableView reloadData]; + } +} + +- (void)refreshMore{ + _myBoardTL.willLoadMore = YES; + [self sendRequest]; +} + +- (void)sendRequest{ + if (_myBoardTL.isLoading) { + return; + } + if (self.myBoardTL.list.count <= 0) { + [self beginLoading]; + } + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_TaskInBoardTaskList:_myBoardTL andBlock:^(EABoardTaskList *data, NSError *error) { + [weakSelf endLoading]; + [weakSelf.myRefreshControl endRefreshing]; + [weakSelf.myTableView.infiniteScrollingView stopAnimating]; + if (data) { + [weakSelf.myBoardTL configWithObj:data]; + [weakSelf.myTableView reloadData]; + weakSelf.myTableView.showsInfiniteScrolling = weakSelf.myBoardTL.canLoadMore; + } + [weakSelf configBlankPage:EaseBlankPageTypeTask hasData:(weakSelf.myBoardTL.list.count > 0) hasError:(error != nil) reloadButtonBlock:^(id sender) { + [weakSelf refresh]; + }]; + }]; +} + +#pragma mark Table + +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ + if (_myBoardTL.isBlankType) { + return self.height; + }else{ + return 50; + } +} + +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ + return [self p_headerV]; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + return _myBoardTL.list.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + EATaskBoardListTaskCell *cell = [tableView dequeueReusableCellWithIdentifier:EATaskBoardListTaskCell.nameOfClass forIndexPath:indexPath]; + cell.task = _myBoardTL.list[indexPath.row]; + __weak typeof(self) weakSelf = self; + cell.taskStatusChangedBlock = ^(Task *task) { + [weakSelf refresh]; + }; + return cell; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ + return [EATaskBoardListTaskCell cellHeightWithObj:_myBoardTL.list[indexPath.row]]; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + EditTaskViewController *vc = [[EditTaskViewController alloc] init]; + vc.myTask = _myBoardTL.list[indexPath.row]; + __weak typeof(self) weakSelf = self; + vc.taskChangedBlock = ^(){ + [weakSelf refresh]; + }; + [BaseViewController goToVC:vc]; +} + +#pragma mark header view + +- (UIView *)p_headerV{ + if (_myBoardTL.isBlankType && !_myBoardTL.curPro.hasEverHandledBoard) { + EABoardTaskListBlankView *blankV = [[NSBundle mainBundle] loadNibNamed:EABoardTaskListBlankView.nameOfClass owner:nil options:nil].firstObject; + [blankV.addBtn addTarget:self action:@selector(addBtnClicked) forControlEvents:UIControlEventTouchUpInside]; + [blankV.createDefaultBtn addTarget:self action:@selector(createDefaultBtnClicked) forControlEvents:UIControlEventTouchUpInside]; + return blankV; + }else{ + UIView *headerV = [UIView new]; + headerV.backgroundColor = kColorTableSectionBg; + if (_myBoardTL.isBlankType) { + UIButton *addBtn = [UIButton new]; + addBtn.titleLabel.font = [UIFont systemFontOfSize:15]; + [addBtn setTitle:@"创建任务列表" forState:UIControlStateNormal]; + [addBtn setTitleColor:kColorDark2 forState:UIControlStateNormal]; + [addBtn setBackgroundColor:kColorD8DDE4]; + addBtn.cornerRadius = 2.0; + addBtn.masksToBounds = YES; + [addBtn addTarget:self action:@selector(addBtnClicked) forControlEvents:UIControlEventTouchUpInside]; + [headerV addSubview:addBtn]; + [addBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.offset(20); + make.left.offset(15); + make.right.offset(-15); + make.height.mas_equalTo(50); + }]; + }else{ + UILabel *titleL = [UILabel labelWithFont:[UIFont systemFontOfSize:15] textColor:kColorDark7]; + titleL.text = [NSString stringWithFormat:@"%@ · %@", _myBoardTL.title ?: @"--", _myBoardTL.totalRow ?: @"--"]; + [headerV addSubview:titleL]; + [titleL mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.offset(25); + make.centerY.equalTo(headerV); + make.right.lessThanOrEqualTo(headerV).offset(-70); + }]; + if (_myBoardTL.canEdit) { + UIButton *editBtn = [UIButton new]; + [editBtn setImage:[UIImage imageNamed:@"editBoardList"] forState:UIControlStateNormal]; + [editBtn addTarget:self action:@selector(editBtnClicked) forControlEvents:UIControlEventTouchUpInside]; + [headerV addSubview:editBtn]; + [editBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.size.mas_equalTo(CGSizeMake(44, 44)); + make.right.offset(-20); + make.centerY.equalTo(headerV); + }]; + } + } + return headerV; + } +} + +- (void)editBtnClicked{ + __weak typeof(self) weakSelf = self; + [[UIAlertController ea_actionSheetCustomWithTitle:nil buttonTitles:@[@"编辑任务列表"] destructiveTitle:@"删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { + [weakSelf editBoardTL]; + }else if (index == 1){ + [weakSelf showDeleteAlert]; + } + }] showInView:self]; +} + +- (void)editBoardTL{ + __weak typeof(self) weakSelf = self; + SettingTextViewController *vc = [SettingTextViewController settingTextVCWithTitle:@"编辑任务列表" textValue:_myBoardTL.title doneBlock:^(NSString *textValue) { + [NSObject showHUDQueryStr:@"正在修改..."]; + [[Coding_NetAPIManager sharedManager] request_RenameBoardTaskList:weakSelf.myBoardTL withTitle:textValue andBlock:^(EABoardTaskList *data, NSError *error) { + [NSObject hideHUDQuery]; + if (data) { + [NSObject showHudTipStr:@"已修改"]; + weakSelf.myBoardTL.title = data.title; + [weakSelf.myTableView reloadData]; + } + }]; + }]; + vc.placeholderStr = @"列表名"; + [BaseViewController presentVC:vc]; +} + +- (void)showDeleteAlert{ + __weak typeof(self) weakSelf = self; + [[UIAlertController ea_actionSheetCustomWithTitle:@"你确定永远删除这个列表吗?" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { + [weakSelf deleteBoardTL]; + } + }] showInView:self]; +} + +- (void)deleteBoardTL{ + __weak typeof(self) weakSelf = self; + [NSObject showHUDQueryStr:@"正在删除..."]; + [[Coding_NetAPIManager sharedManager] request_DeleteBoardTaskList:_myBoardTL andBlock:^(id data, NSError *error) { + [NSObject hideHUDQuery]; + if (data) { + [NSObject showHudTipStr:@"已删除"]; + if (weakSelf.boardTLsChangedBlock) { + weakSelf.boardTLsChangedBlock(); + } + } + }]; +} + +- (void)addBtnClicked{ + if (!_myBoardTL.curPro.hasEverHandledBoard) { + _myBoardTL.curPro.hasEverHandledBoard = YES; + if (_boardTLsChangedBlock) { + _boardTLsChangedBlock(); + } + } + SettingTextViewController *vc = [SettingTextViewController settingTextVCWithTitle:@"创建任务列表" textValue:nil doneBlock:^(NSString *textValue) { + [NSObject showHUDQueryStr:@"正在添加..."]; + [[Coding_NetAPIManager sharedManager] request_AddBoardTaskListsInPro:self.myBoardTL.curPro withTitle:textValue andBlock:^(EABoardTaskList *data, NSError *error) { + [NSObject hideHUDQuery]; + if (data) { + [NSObject showHudTipStr:@"已添加"]; + if (self.boardTLsChangedBlock) { + self.boardTLsChangedBlock(); + } + } + }]; + }]; + vc.placeholderStr = @"列表名"; + [BaseViewController presentVC:vc]; +} + +- (void)createDefaultBtnClicked{ + __weak typeof(self) weakSelf = self; + EABoardTaskListDefaultModel *model = [EABoardTaskListDefaultModel new]; + [NSObject showHUDQueryStr:@"正在添加..."]; + for (NSString *title in model.defaultBoardTLTitleList) { + [[Coding_NetAPIManager sharedManager] request_AddBoardTaskListsInPro:self.myBoardTL.curPro withTitle:title andBlock:^(EABoardTaskList *data, NSError *error) { + model.handledCount += 1; + if (model.handledCount == model.defaultBoardTLTitleList.count) { + [NSObject hideHUDQuery]; + if (weakSelf.boardTLsChangedBlock) { + weakSelf.boardTLsChangedBlock(); + } + } + }]; + } +} + +@end + diff --git a/Coding_iOS/Views/TableListView/MRListView.m b/Coding_iOS/Views/TableListView/MRListView.m index 7b955cb4b..4f44570b2 100644 --- a/Coding_iOS/Views/TableListView/MRListView.m +++ b/Coding_iOS/Views/TableListView/MRListView.m @@ -37,6 +37,9 @@ - (instancetype)initWithFrame:(CGRect)frame{ UIEdgeInsets insets = UIEdgeInsetsMake(0, 0, 49, 0);//外部 segment bar 的高度 tableView.contentInset = insets; tableView.scrollIndicatorInsets = insets; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); @@ -114,7 +117,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ - return [MRPRListCell cellHeight]; + return [MRPRListCell cellHeightWithObj:[[self curMRPRS].list objectAtIndex:indexPath.row]]; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ diff --git a/Coding_iOS/Views/TableListView/NProjectFileListView.h b/Coding_iOS/Views/TableListView/NProjectFileListView.h new file mode 100644 index 000000000..6f35cd31d --- /dev/null +++ b/Coding_iOS/Views/TableListView/NProjectFileListView.h @@ -0,0 +1,16 @@ +// +// NProjectFileListView.h +// Coding_Enterprise_iOS +// +// Created by Easeeeeeeeee on 2017/5/11. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import +#import "Project.h" +#import "ProjectFile.h" + +@interface NProjectFileListView : UIView +@property (weak, nonatomic) UIViewController *containerVC; +- (id)initWithFrame:(CGRect)frame project:(Project *)project folder:(ProjectFile *)folder; +@end diff --git a/Coding_iOS/Controllers/FileListViewController.m b/Coding_iOS/Views/TableListView/NProjectFileListView.m old mode 100755 new mode 100644 similarity index 55% rename from Coding_iOS/Controllers/FileListViewController.m rename to Coding_iOS/Views/TableListView/NProjectFileListView.m index 9ffd659ad..ae978fec5 --- a/Coding_iOS/Controllers/FileListViewController.m +++ b/Coding_iOS/Views/TableListView/NProjectFileListView.m @@ -1,94 +1,96 @@ // -// FileListViewController.m -// Coding_iOS +// NProjectFileListView.m +// Coding_Enterprise_iOS // -// Created by Ease on 14/11/14. -// Copyright (c) 2014年 Coding. All rights reserved. +// Created by Easeeeeeeeee on 2017/5/11. +// Copyright © 2017年 Coding. All rights reserved. // -#import "FileListViewController.h" +#import "NProjectFileListView.h" #import "ODRefreshControl.h" #import "Coding_NetAPIManager.h" -#import "FileListFolderCell.h" +#import "Coding_FileManager.h" + +#import "FileListUploadCell.h" #import "FileListFileCell.h" -#import "ProjectFiles.h" -#import "BasicPreviewItem.h" +#import "FileListFolderCell.h" + #import "SettingTextViewController.h" #import "FolderToMoveViewController.h" +#import "QBImagePickerController.h" +#import "NFileListViewController.h" #import "FileViewController.h" + #import "EaseToolBar.h" -#import "QBImagePickerController.h" #import "Helper.h" -#import "FileListUploadCell.h" -#import "Coding_FileManager.h" - -@interface FileListViewController () +@interface NProjectFileListView () @property (nonatomic, strong) UITableView *myTableView; @property (nonatomic, strong) ODRefreshControl *refreshControl; -@property (strong, nonatomic) ProjectFiles *myFiles; @property (nonatomic, strong) EaseToolBar *myToolBar, *myEditToolBar; -@property (strong, nonatomic) NSArray *uploadFiles; +@property (strong, nonatomic) UISearchBar *mySearchBar; + +@property (nonatomic, strong) Project *curProject; +@property (strong, nonatomic) ProjectFile *curFolder; +@property (strong, nonatomic) ProjectFiles *myFiles; +@property (strong, nonatomic) NSArray *uploadFiles; +@property (nonatomic, strong) NSMutableArray *fileList, *folderList; @end -@implementation FileListViewController -- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil -{ - self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; - if (self) { - // Custom initialization - } - return self; -} +@implementation NProjectFileListView -- (void)viewDidLoad -{ - [super viewDidLoad]; - // Do any additional setup after loading the view. - self.title = self.curFolder.name; - _myFiles = [[ProjectFiles alloc] init]; - - // 添加myTableView - _myTableView = ({ - UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; - tableView.backgroundColor = [UIColor clearColor]; - tableView.dataSource = self; - tableView.delegate = self; - tableView.separatorStyle = UITableViewCellSeparatorStyleNone; - [tableView registerClass:[FileListFolderCell class] forCellReuseIdentifier:kCellIdentifier_FileListFolder]; - [tableView registerClass:[FileListFileCell class] forCellReuseIdentifier:kCellIdentifier_FileListFile]; - [tableView registerClass:[FileListUploadCell class] forCellReuseIdentifier:kCellIdentifier_FileListUpload]; - [self.view addSubview:tableView]; - [tableView mas_makeConstraints:^(MASConstraintMaker *make) { - make.edges.equalTo(self.view); +- (id)initWithFrame:(CGRect)frame project:(Project *)project folder:(ProjectFile *)folder{ + self = [super initWithFrame:frame]; + if (self) { + // Initialization code + _curProject = project; + _curFolder = folder ?: [[ProjectFile alloc] initWithFileId:@0 inProject:project.name ofUser:project.owner_user_name]; + _myFiles = [[ProjectFiles alloc] init]; + _myTableView = ({ + UITableView *tableView = [[UITableView alloc] initWithFrame:self.bounds style:UITableViewStylePlain]; + tableView.backgroundColor = [UIColor clearColor]; + tableView.delegate = self; + tableView.dataSource = self; + [tableView registerClass:[FileListFolderCell class] forCellReuseIdentifier:kCellIdentifier_FileListFolder]; + [tableView registerClass:[FileListFileCell class] forCellReuseIdentifier:kCellIdentifier_FileListFile]; + [tableView registerClass:[FileListUploadCell class] forCellReuseIdentifier:kCellIdentifier_FileListUpload]; + tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + [self addSubview:tableView]; + [tableView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self); + }]; + tableView.allowsMultipleSelectionDuringEditing = YES; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; + tableView; + }); + + _mySearchBar = ({ + UISearchBar *searchBar = [[UISearchBar alloc] init]; + searchBar.delegate = self; + [searchBar sizeToFit]; + [searchBar setPlaceholder:@"寻找文件"]; + [searchBar setPlaceholderColor:kColorDarkA]; + [searchBar setSearchIcon:[UIImage imageNamed:@"icon_search_searchbar"]]; + searchBar; + }); + _myTableView.tableHeaderView = _mySearchBar; + + _refreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; + [_refreshControl addTarget:self action:@selector(refresh) forControlEvents:UIControlEventValueChanged]; + [self refresh]; + + __weak typeof(self) weakSelf = self; + [[[[NSNotificationCenter defaultCenter] rac_addObserverForName:kNotificationUploadCompled object:nil] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(NSNotification *aNotification) { + //{NSURLResponse: response, NSError: error, ProjectFile: data} + NSDictionary* userInfo = [aNotification userInfo]; + [weakSelf completionUploadWithResult:[userInfo objectForKey:@"data"] error:[userInfo objectForKey:@"error"]]; }]; - tableView.allowsMultipleSelectionDuringEditing = YES; - tableView; - }); - - _refreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; - [_refreshControl addTarget:self action:@selector(refreshRootFolders) forControlEvents:UIControlEventValueChanged]; - - if (!self.rootFolders) { - self.rootFolders = [ProjectFolders emptyFolders]; - } - [self refresh]; - - __weak typeof(self) weakSelf = self; - - [[[[NSNotificationCenter defaultCenter] rac_addObserverForName:kNotificationUploadCompled object:nil] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(NSNotification *aNotification) { - //{NSURLResponse: response, NSError: error, ProjectFile: data} - NSDictionary* userInfo = [aNotification userInfo]; - [weakSelf completionUploadWithResult:[userInfo objectForKey:@"data"] error:[userInfo objectForKey:@"error"]]; - }]; -} -- (void)viewWillAppear:(BOOL)animated{ - [super viewWillAppear:animated]; - if (!_myTableView.isEditing) { - [_myTableView reloadData]; } + return self; } - (void)changeEditState{ @@ -99,16 +101,19 @@ - (void)changeEditStateToEditing:(BOOL)isEditing{ [_myTableView setEditing:isEditing animated:YES]; NSArray *rightBarButtonItems; if (isEditing) { - UIBarButtonItem *item1 = [UIBarButtonItem itemWithBtnTitle:@"完成" target:self action:@selector(changeEditState)]; - UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; - spaceItem.width = 20; - UIBarButtonItem *item2 = [UIBarButtonItem itemWithBtnTitle:@"反选" target:self action:@selector(reverseSelect)]; - rightBarButtonItems = @[item1, spaceItem, item2]; + UIBarButtonItem *item1 = [UIBarButtonItem itemWithBtnTitle:@"取消" target:self action:@selector(changeEditState)]; +// UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; +// spaceItem.width = 20; +// UIBarButtonItem *item2 = [UIBarButtonItem itemWithBtnTitle:@"反选" target:self action:@selector(reverseSelect)]; +// rightBarButtonItems = @[item1, spaceItem, item2]; + rightBarButtonItems = @[item1]; + _myTableView.tableHeaderView = nil; }else{ UIBarButtonItem *item1 = [UIBarButtonItem itemWithBtnTitle:@"编辑" target:self action:@selector(changeEditState)]; rightBarButtonItems = @[item1]; + _myTableView.tableHeaderView = _mySearchBar; } - [self.navigationItem setRightBarButtonItems:rightBarButtonItems animated:YES]; + [self.containerVC.navigationItem setRightBarButtonItems:rightBarButtonItems animated:YES]; [self configToolBar]; [self.myTableView performSelector:@selector(reloadData) withObject:nil afterDelay:0.3]; } @@ -116,7 +121,7 @@ - (void)changeEditStateToEditing:(BOOL)isEditing{ - (void)reverseSelect{ if (_myTableView.isEditing) { NSArray *selectedIndexList = [_myTableView indexPathsForSelectedRows]; - NSInteger startIndex = _curFolder.sub_folders.count + _uploadFiles.count; + NSInteger startIndex = _uploadFiles.count; NSInteger endIndex = [self totalDataRow]; NSMutableArray *reverseIndexList = [[NSMutableArray alloc] init]; for (NSInteger index = startIndex; index < endIndex; index++) { @@ -125,7 +130,6 @@ - (void)reverseSelect{ [reverseIndexList addObject:curIndex]; } } - for (NSIndexPath *indexPath in selectedIndexList) { [_myTableView deselectRowAtIndexPath:indexPath animated:YES]; } @@ -140,32 +144,36 @@ - (void)configuploadFiles{ if (!self.uploadFiles) { self.uploadFiles = [NSArray array]; } - [self.myTableView reloadData]; + [self updateDataWithSearchStr]; + //更新空白页状态 + [self configBlankPage:EaseBlankPageTypeFile hasData:([self totalDataRow] > 0) hasError:NO reloadButtonBlock:^(id sender) { + [self refresh]; + }]; } - (void)configToolBar{ //添加底部ToolBar if (!_myToolBar) { - EaseToolBarItem *item1 = [EaseToolBarItem easeToolBarItemWithTitle:@" 新建文件夹" image:@"button_file_createFolder_enable" disableImage:@"button_file_createFolder_unable"]; - EaseToolBarItem *item2 = [EaseToolBarItem easeToolBarItemWithTitle:@" 上传文件" image:@"button_file_upload_enable" disableImage:nil]; + EaseToolBarItem *item1 = [EaseToolBarItem easeToolBarItemWithTitle:@"新建文件夹" image:@"button_file_createFolder_enable" disableImage:@"button_file_createFolder_unable"]; + EaseToolBarItem *item2 = [EaseToolBarItem easeToolBarItemWithTitle:@"上传文件" image:@"button_file_upload_enable" disableImage:nil]; _myToolBar = [EaseToolBar easeToolBarWithItems:@[item1, item2]]; _myToolBar.delegate = self; - [self.view addSubview:_myToolBar]; + [self addSubview:_myToolBar]; [_myToolBar mas_makeConstraints:^(MASConstraintMaker *make) { - make.bottom.equalTo(self.view.mas_bottom); + make.bottom.equalTo(self.mas_bottom); make.size.mas_equalTo(_myToolBar.frame.size); }]; } if (!_myEditToolBar) { - EaseToolBarItem *item1 = [EaseToolBarItem easeToolBarItemWithTitle:@" 下载" image:@"button_file_download_enable" disableImage:@"button_file_createFolder_unable"]; - EaseToolBarItem *item2 = [EaseToolBarItem easeToolBarItemWithTitle:@" 移动" image:@"button_file_move_enable" disableImage:nil]; - EaseToolBarItem *item3 = [EaseToolBarItem easeToolBarItemWithTitle:@" 删除" image:@"button_file_denete_enable" disableImage:nil]; + EaseToolBarItem *item1 = [EaseToolBarItem easeToolBarItemWithTitle:@"下载" image:@"button_file_download_enable" disableImage:@"button_file_createFolder_unable"]; + EaseToolBarItem *item2 = [EaseToolBarItem easeToolBarItemWithTitle:@"移动" image:@"button_file_move_enable" disableImage:nil]; + EaseToolBarItem *item3 = [EaseToolBarItem easeToolBarItemWithTitle:@"删除" image:@"button_file_denete_enable" disableImage:nil]; _myEditToolBar = [EaseToolBar easeToolBarWithItems:@[item1, item2, item3]]; _myEditToolBar.delegate = self; - [self.view addSubview:_myEditToolBar]; + [self addSubview:_myEditToolBar]; [_myEditToolBar mas_makeConstraints:^(MASConstraintMaker *make) { - make.bottom.equalTo(self.view.mas_bottom); + make.bottom.equalTo(self.mas_bottom); make.size.mas_equalTo(_myToolBar.frame.size); }]; } @@ -176,11 +184,6 @@ - (void)configToolBar{ }else{ _myToolBar.hidden = NO; _myEditToolBar.hidden = YES; - - EaseToolBarItem *item1 = [_myToolBar itemOfIndex:0]; - item1.enabled = [self canCreatNewFolder]; - EaseToolBarItem *item2 = [_myToolBar itemOfIndex:1]; - item2.enabled = [self canUploadNewFile]; } UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0,CGRectGetHeight(_myToolBar.frame), 0.0); @@ -188,93 +191,38 @@ - (void)configToolBar{ self.myTableView.scrollIndicatorInsets = contentInsets; } -- (BOOL)canCreatNewFolder{ - return (self.curFolder == nil || (self.curFolder.parent_id.intValue == 0 && ![_curFolder isDefaultFolder] && ![_curFolder isShareFolder])); -} - -- (BOOL)canUploadNewFile{ - return ![self.curFolder isShareFolder]; -} - - (void)refresh{ [self configuploadFiles]; - if (![self.rootFolders isEmpty]) { - [self configToolBar]; - [self refreshFileList]; - }else{ - [self refreshRootFolders]; - } -} - -- (void)refreshRootFolders{ - if (_rootFolders.isLoading) { - return; - } - [self sendRequestRootFolders]; -} - -- (void)sendRequestRootFolders{ - if ([self totalDataRow] <= 0) { - [self.view beginLoading]; + [self configToolBar]; + self.containerVC.title = _curFolder.name ?: _curFolder.project_name; + if (![_curProject.id isKindOfClass:[NSNumber class]]) { + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_ProjectDetail_WithObj:_curProject andBlock:^(id data, NSError *error) { + weakSelf.curProject = data; + }]; } - __weak typeof(self) weakSelf = self; - [[Coding_NetAPIManager sharedManager] request_Folders:_rootFolders inProject:_curProject andBlock:^(id data, NSError *error) { - if (data) { - ProjectFolders *preRootFolders = weakSelf.rootFolders; - weakSelf.rootFolders = data; - ProjectFolder *curFolder = [weakSelf.rootFolders hasFolderWithId:weakSelf.curFolder.file_id]; - if (curFolder) { - weakSelf.curFolder = curFolder; - weakSelf.title = curFolder.name; - [weakSelf configuploadFiles]; - [weakSelf configToolBar]; - [weakSelf refreshFileList]; - }else{ - [weakSelf.refreshControl endRefreshing]; - [weakSelf.view endLoading]; - weakSelf.rootFolders = preRootFolders; - [NSObject showHudTipStr:@"文件夹不存在"]; - weakSelf.navigationItem.rightBarButtonItem = nil; - [weakSelf.view configBlankPage:EaseBlankPageTypeFolderDleted hasData:([weakSelf totalDataRow] > 0) hasError:NO reloadButtonBlock:nil]; - } - }else{ + if (!_myFiles.isLoading) { + if ([self totalDataRow] <= 0) { + [self beginLoading]; + } + __weak typeof(self) weakSelf = self; + weakSelf.myFiles.isLoading = YES; + [[Coding_NetAPIManager sharedManager] request_FilesInFolder:_curFolder andBlock:^(id data, NSError *error) { + weakSelf.myFiles.isLoading = NO; [weakSelf.refreshControl endRefreshing]; - [weakSelf.view endLoading]; - [weakSelf.view configBlankPage:EaseBlankPageTypeView hasData:([weakSelf totalDataRow] > 0) hasError:YES reloadButtonBlock:^(id sender) { - [weakSelf refreshRootFolders]; + [weakSelf endLoading]; + if (data) { + weakSelf.myFiles = data; + if (weakSelf.curFolder.isDefaultFolder && weakSelf.myFiles.list.count > 0) { + [weakSelf.myFiles addSharedFolder]; + } + [weakSelf updateDataWithSearchStr]; + } + [weakSelf configBlankPage:EaseBlankPageTypeFile hasData:([weakSelf totalDataRow] > 0) hasError:(error != nil) reloadButtonBlock:^(id sender) { + [weakSelf refresh]; }]; - } - }]; -} - -- (void)refreshFileList{ - if (_myFiles.isLoading) { - return; - } - [self sendRequestFileList]; -} - -- (void)sendRequestFileList{ - if ([self totalDataRow] <= 0) { - [self.view beginLoading]; - } - __weak typeof(self) weakSelf = self; - weakSelf.myFiles.isLoading = YES; - [[Coding_NetAPIManager sharedManager] request_FilesInFolder:_curFolder andBlock:^(id data, NSError *error) { - weakSelf.myFiles.isLoading = NO; - [weakSelf.refreshControl endRefreshing]; - [weakSelf.view endLoading]; - if (data) { - weakSelf.myFiles = data; - - self.navigationItem.rightBarButtonItem = weakSelf.myFiles.list.count > 0? [UIBarButtonItem itemWithBtnTitle:@"编辑" target:self action:@selector(changeEditState)]: nil; - - [weakSelf.myTableView reloadData]; - } - [weakSelf.view configBlankPage:EaseBlankPageTypeView hasData:([weakSelf totalDataRow] > 0) hasError:(error != nil) reloadButtonBlock:^(id sender) { - [weakSelf refreshRootFolders]; }]; - }]; + } } #pragma mark EaseToolBarDelegate @@ -305,24 +253,20 @@ - (void)easeToolBar:(EaseToolBar *)toolBar didClickedIndex:(NSInteger)index{ break; } } - + } - (void)creatFolderBtnClicked{ DebugLog(@"新建文件夹"); __weak typeof(self) weakSelf = self; - [SettingTextViewController showSettingFolderNameVCFromVC:self withTitle:@"新建文件夹" textValue:nil type:SettingTypeNewFolderName doneBlock:^(NSString *textValue) { + [SettingTextViewController showSettingFolderNameVCFromVC:self.containerVC withTitle:@"新建文件夹" textValue:nil type:SettingTypeNewFolderName doneBlock:^(NSString *textValue) { DebugLog(@"%@", textValue); [[Coding_NetAPIManager sharedManager] request_CreatFolder:textValue inFolder:weakSelf.curFolder inProject:weakSelf.curProject andBlock:^(id data, NSError *error) { if (data) { - if (weakSelf.curFolder) { - [weakSelf.curFolder.sub_folders insertObject:data atIndex:0]; - }else{ - [weakSelf.rootFolders.list insertObject:data atIndex:1]; - } - [weakSelf.myTableView reloadData]; - [weakSelf.view configBlankPage:EaseBlankPageTypeView hasData:([weakSelf totalDataRow] > 0) hasError:(error != nil) reloadButtonBlock:^(id sender) { - [weakSelf refreshRootFolders]; + [weakSelf.myFiles.folderList insertObject:data atIndex:0]; + [weakSelf updateDataWithSearchStr]; + [weakSelf configBlankPage:EaseBlankPageTypeFile hasData:([weakSelf totalDataRow] > 0) hasError:(error != nil) reloadButtonBlock:^(id sender) { + [weakSelf refresh]; }]; [NSObject showHudTipStr:@"创建文件夹成功"]; } @@ -337,20 +281,22 @@ - (void)uploadFileBtnClicked{ return; } QBImagePickerController *imagePickerController = [[QBImagePickerController alloc] init]; - imagePickerController.filterType = QBImagePickerControllerFilterTypePhotos; + imagePickerController.mediaType = QBImagePickerMediaTypeImage; imagePickerController.delegate = self; imagePickerController.allowsMultipleSelection = YES; imagePickerController.maximumNumberOfSelection = 6; - UINavigationController *navigationController = [[BaseNavigationController alloc] initWithRootViewController:imagePickerController]; - [self presentViewController:navigationController animated:YES completion:NULL]; + [self.containerVC presentViewController:imagePickerController animated:YES completion:NULL]; } - (NSArray *)selectedFiles{ NSArray *selectedIndexPath = [_myTableView indexPathsForSelectedRows]; NSMutableArray *selectedFiles = [[NSMutableArray alloc] initWithCapacity:selectedIndexPath.count]; for (NSIndexPath *indexPath in selectedIndexPath) { - if (indexPath.row >= _curFolder.sub_folders.count + _uploadFiles.count) { - ProjectFile *file = [_myFiles.list objectAtIndex:(indexPath.row - _curFolder.sub_folders.count - _uploadFiles.count)]; + if (indexPath.row >= _folderList.count + _uploadFiles.count) { + ProjectFile *file = [_fileList objectAtIndex:(indexPath.row - _folderList.count - _uploadFiles.count)]; + [selectedFiles addObject:file]; + }else if (indexPath.row >= _uploadFiles.count){ + ProjectFile *file = [_folderList objectAtIndex:(indexPath.row - _uploadFiles.count)]; [selectedFiles addObject:file]; } } @@ -358,13 +304,14 @@ - (NSArray *)selectedFiles{ } - (void)downloadFilesBtnClicked{ - NSArray *selectedFiles = [self selectedFiles]; + NSMutableArray *selectedFiles = [self selectedFiles].mutableCopy; + [selectedFiles removeObjectsInArray:self.folderList];//文件夹暂时不支持批量下载 if (selectedFiles.count > 0) { NSInteger downloadedCount = 0, downloadingCount = 0, addDownloadCount = 0; Coding_FileManager *manager = [Coding_FileManager sharedManager]; for (ProjectFile *file in selectedFiles) { - if ([file hasBeenDownload]) {//已下载 + if ([file diskFileUrl]) {//已下载 downloadedCount++; DebugLog(@"%@: 已在队列", file.name); }else if ([file cDownloadTask]) {//正在下载 @@ -379,8 +326,8 @@ - (void)downloadFilesBtnClicked{ NSString *tipStr = downloadingCount == 0? @"所选的文件都已经下载到本地了" : @"所选的文件都已经在下载队列中了"; [NSObject showHudTipStr:tipStr]; } - [self changeEditStateToEditing:NO]; } + [self changeEditStateToEditing:NO]; } - (void)moveFilesBtnClicked{ @@ -393,12 +340,12 @@ - (void)deleteFilesBtnClicked{ __weak typeof(self) weakSelf = self; NSArray *selectedFiles = [self selectedFiles]; if (selectedFiles.count > 0) { - [[UIActionSheet bk_actionSheetCustomWithTitle:[NSString stringWithFormat:@"确认删除选定的 %lu 个文件?\n删除后将无法恢复!", (unsigned long)selectedFiles.count] buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + [[UIAlertController ea_actionSheetCustomWithTitle:[NSString stringWithFormat:@"确认删除选定的 %lu 个文件?\n删除后将无法恢复!", (unsigned long)selectedFiles.count] buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf deleteFiles:selectedFiles]; [weakSelf changeEditStateToEditing:NO]; } - }] showInView:self.view]; + }] showInView:self]; } } @@ -411,17 +358,17 @@ - (void)deleteFiles:(NSArray *)selectedFiles{ __weak typeof(self) weakSelf = self; [[Coding_NetAPIManager sharedManager] request_DeleteFiles:fileIdList inProject:self.curProject.id andBlock:^(id data, NSError *error) { if (data) { - [weakSelf refreshRootFolders]; + [weakSelf refresh]; } }]; } #pragma mark QBImagePickerControllerDelegate -- (void)qb_imagePickerController:(QBImagePickerController *)imagePickerController didSelectAssets:(NSArray *)assets{ +- (void)qb_imagePickerController:(QBImagePickerController *)imagePickerController didFinishPickingAssets:(NSArray *)assets{ NSMutableArray *needToUploads = [NSMutableArray arrayWithCapacity:assets.count]; - for (ALAsset *assetItem in assets) { + for (PHAsset *assetItem in assets) { //保存到app内 - NSString* originalFileName = [[assetItem defaultRepresentation] filename]; + NSString* originalFileName = assetItem.fileName; NSString *fileName = [NSString stringWithFormat:@"%@|||%@|||%@", self.curProject.id.stringValue, self.curFolder.file_id.stringValue, originalFileName]; if ([Coding_FileManager writeUploadDataWithName:fileName andAsset:assetItem]) { [needToUploads addObject:fileName]; @@ -432,21 +379,27 @@ - (void)qb_imagePickerController:(QBImagePickerController *)imagePickerControlle for (NSString *fileName in needToUploads) { [self uploadFileWithFileName:fileName]; } - [self.view configBlankPage:EaseBlankPageTypeView hasData:([self totalDataRow] > 0) hasError:NO reloadButtonBlock:^(id sender) { - [self refreshRootFolders]; + [self configBlankPage:EaseBlankPageTypeFile hasData:([self totalDataRow] > 0) hasError:NO reloadButtonBlock:^(id sender) { + [self refresh]; }]; - [self dismissViewControllerAnimated:YES completion:nil]; + [self.containerVC dismissViewControllerAnimated:YES completion:nil]; } - (void)qb_imagePickerControllerDidCancel:(QBImagePickerController *)imagePickerController{ - [self dismissViewControllerAnimated:YES completion:nil]; + [self.containerVC dismissViewControllerAnimated:YES completion:nil]; } #pragma mark uploadTask - (void)uploadFileWithFileName:(NSString *)fileName{ - Coding_FileManager *manager = [Coding_FileManager sharedManager]; - [manager addUploadTaskWithFileName:fileName projectIsPublic:_curProject.is_public.boolValue]; - [self configuploadFiles]; + __weak typeof(self) weakSelf = self; + if ([NSObject isPrivateCloud].boolValue) { + [[Coding_FileManager sharedManager] addUploadTaskWithFileName:fileName projectIsPublic:_curProject.is_public.boolValue]; + [self configuploadFiles]; + }else{ + [[Coding_FileManager sharedManager] addUploadTaskWithFileName:fileName isQuick:NO resultBlock:^(Coding_UploadTask *uploadTask) { + [weakSelf configuploadFiles]; + }]; + } } - (void)removeUploadTaskWithFileName:(NSString *)fileName{ @@ -462,31 +415,27 @@ - (void)completionUploadWithResult:(id)responseObject error:(NSError *)error{ if (curFile.parent_id.integerValue != self.curFolder.file_id.integerValue) { return; } - - NSRange range = [curFile.owner_preview rangeOfString:@"project/"]; - if (curFile.owner_preview && range.location != NSNotFound) { - NSString *project_id = [[[curFile.owner_preview substringFromIndex:(range.location+range.length)] componentsSeparatedByString:@"/"] firstObject]; - if (project_id && project_id.integerValue != self.curProject.id.integerValue) { - return; - } + if (curFile.project_id && curFile.project_id.integerValue != self.curProject.id.integerValue) { + return; } - - curFile.project_id = self.curProject.id; - [self.myFiles.list insertObject:curFile atIndex:0]; + [self.myFiles.fileList insertObject:curFile atIndex:0]; self.curFolder.count = @(self.curFolder.count.integerValue +1); [self configuploadFiles]; - [self.view configBlankPage:EaseBlankPageTypeView hasData:([self totalDataRow] > 0) hasError:(error != nil) reloadButtonBlock:^(id sender) { - [self refreshRootFolders]; + [self configBlankPage:EaseBlankPageTypeFile hasData:([self totalDataRow] > 0) hasError:(error != nil) reloadButtonBlock:^(id sender) { + [self refresh]; }]; - if (self.navigationItem.rightBarButtonItem == nil) { - self.navigationItem.rightBarButtonItem = self.myFiles.list.count > 0? [UIBarButtonItem itemWithBtnTitle:@"编辑" target:self action:@selector(changeEditState)]: nil; - } } +#pragma mark ScrollView Delegate +- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{ + if (scrollView == _myTableView) { + [self.mySearchBar resignFirstResponder]; + } +} #pragma mark Table M - (NSInteger)totalDataRow{ - return (_uploadFiles.count + _curFolder.sub_folders.count + _myFiles.list.count); + return (_uploadFiles.count + _folderList.count + _fileList.count); } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ @@ -505,9 +454,9 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N [weakSelf removeUploadTaskWithFileName:fileName]; }; return cell; - }else if (indexPath.row < _curFolder.sub_folders.count + _uploadFiles.count) { + }else if (indexPath.row < _folderList.count + _uploadFiles.count) { FileListFolderCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_FileListFolder forIndexPath:indexPath]; - ProjectFolder *folder = [_curFolder.sub_folders objectAtIndex:indexPath.row - _uploadFiles.count]; + ProjectFile *folder = [_folderList objectAtIndex:indexPath.row - _uploadFiles.count]; cell.folder = folder; [cell setRightUtilityButtons:[self rightButtonsWithObj:folder] WithButtonWidth:[FileListFolderCell cellHeight]]; cell.delegate = self; @@ -515,7 +464,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N return cell; }else{ FileListFileCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_FileListFile forIndexPath:indexPath]; - ProjectFile *file = [_myFiles.list objectAtIndex:(indexPath.row - _curFolder.sub_folders.count - _uploadFiles.count)]; + ProjectFile *file = [_fileList objectAtIndex:(indexPath.row - _folderList.count - _uploadFiles.count)]; cell.file = file; cell.showDiskFileBlock = ^(NSURL *fileUrl, ProjectFile *file){ [weakSelf goToFileVC:file]; @@ -531,7 +480,7 @@ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPa CGFloat cellHeight = 0; if (indexPath.row < _uploadFiles.count) { cellHeight = [FileListUploadCell cellHeight]; - }else if (indexPath.row < _curFolder.sub_folders.count + _uploadFiles.count) { + }else if (indexPath.row < _folderList.count + _uploadFiles.count) { cellHeight = [FileListFolderCell cellHeight]; }else{ cellHeight = [FileListFileCell cellHeight]; @@ -541,44 +490,37 @@ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPa - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ if (tableView.isEditing) { - if (indexPath.row < _curFolder.sub_folders.count + _uploadFiles.count) { - if (indexPath.row < _uploadFiles.count) { - [NSObject showHudTipStr:@"正在上传的不能批处理"]; - }else{ - [NSObject showHudTipStr:@"文件夹不能批处理"]; - } + if (indexPath.row < _uploadFiles.count) { + [NSObject showHudTipStr:@"正在上传的不能批处理"]; [tableView deselectRowAtIndexPath:indexPath animated:YES]; + }else if (indexPath.row < _folderList.count + _uploadFiles.count) { + ProjectFile *clickedFolder = [_folderList objectAtIndex:indexPath.row - _uploadFiles.count]; + if (clickedFolder.isSharedFolder) { + [NSObject showHudTipStr:@"分享中文件夹不支持编辑"]; + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + } } }else{ [tableView deselectRowAtIndexPath:indexPath animated:YES]; if (indexPath.row < _uploadFiles.count) { - }else if (indexPath.row < _curFolder.sub_folders.count) { - ProjectFolder *clickedFolder = [_curFolder.sub_folders objectAtIndex:indexPath.row - _uploadFiles.count];; + }else if (indexPath.row < _folderList.count + _uploadFiles.count) { + ProjectFile *clickedFolder = [_folderList objectAtIndex:indexPath.row - _uploadFiles.count]; [self goToVCWithFolder:clickedFolder inProject:self.curProject]; }else{ - ProjectFile *file = [_myFiles.list objectAtIndex:(indexPath.row - _curFolder.sub_folders.count - _uploadFiles.count)]; + ProjectFile *file = [_fileList objectAtIndex:(indexPath.row - _folderList.count - _uploadFiles.count)]; [self goToFileVC:file]; } } } #pragma mark Edit Table -- (NSArray *)rightButtonsWithObj:(id)obj{ +- (NSArray *)rightButtonsWithObj:(ProjectFile *)obj{ NSMutableArray *rightUtilityButtons = [NSMutableArray new]; - if ([obj isKindOfClass:[ProjectFolder class]]) { - ProjectFolder *folder = (ProjectFolder *)obj; - if (![folder isDefaultFolder] && ![folder isShareFolder]) { - if (folder.sub_folders.count <= 0) { - [rightUtilityButtons sw_addUtilityButtonWithColor:kColorDDD icon:[UIImage imageNamed:@"icon_file_cell_move"]]; - } - [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:@"0xe6e6e6"] icon:[UIImage imageNamed:@"icon_file_cell_rename"]]; - [rightUtilityButtons sw_addUtilityButtonWithColor:kColorBrandRed icon:[UIImage imageNamed:@"icon_file_cell_delete"]]; - } - }else{ - [rightUtilityButtons sw_addUtilityButtonWithColor:kColorDDD icon:[UIImage imageNamed:@"icon_file_cell_move"]]; - [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:@"0xe6e6e6"] icon:[UIImage imageNamed:@"icon_file_cell_rename"]]; - [rightUtilityButtons sw_addUtilityButtonWithColor:kColorBrandRed icon:[UIImage imageNamed:@"icon_file_cell_delete"]]; + if (!obj.isSharedFolder) { + [rightUtilityButtons sw_addUtilityButtonWithColor:kColorD8DDE4 icon:[UIImage imageNamed:@"icon_file_cell_move"]]; + [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:@"0xF2F4F6"] icon:[UIImage imageNamed:@"icon_file_cell_rename"]]; + [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:@"0xF66262"] icon:[UIImage imageNamed:@"icon_file_cell_delete"]]; } return rightUtilityButtons; } @@ -586,14 +528,15 @@ - (NSArray *)rightButtonsWithObj:(id)obj{ - (BOOL)swipeableTableViewCellShouldHideUtilityButtonsOnSwipe:(SWTableViewCell *)cell{ return YES; } + - (BOOL)swipeableTableViewCell:(SWTableViewCell *)cell canSwipeToState:(SWCellState)state{ if (state == kCellStateRight) { NSIndexPath *indexPath = [self.myTableView indexPathForCell:cell]; if (indexPath.row < _uploadFiles.count) { return NO; - }else if (indexPath.row >= _curFolder.sub_folders.count + _uploadFiles.count) { - ProjectFile *file = [_myFiles.list objectAtIndex:(indexPath.row - _curFolder.sub_folders.count - _uploadFiles.count)]; + }else if (indexPath.row >= _folderList.count + _uploadFiles.count) { + ProjectFile *file = [_fileList objectAtIndex:(indexPath.row - _folderList.count - _uploadFiles.count)]; Coding_DownloadTask *cDownloadTask = file.cDownloadTask; if (cDownloadTask && cDownloadTask.task && cDownloadTask.task.state == NSURLSessionTaskStateRunning) { return NO; @@ -607,8 +550,8 @@ - (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerRightUtilityBut [cell hideUtilityButtonsAnimated:YES]; NSIndexPath *indexPath = [self.myTableView indexPathForCell:cell]; - if (indexPath.row < _curFolder.sub_folders.count && indexPath.row >= _uploadFiles.count) { - ProjectFolder *folder = [_curFolder.sub_folders objectAtIndex:indexPath.row - _uploadFiles.count]; + if (indexPath.row < _folderList.count + _uploadFiles.count && indexPath.row >= _uploadFiles.count) { + ProjectFile *folder = [_folderList objectAtIndex:indexPath.row - _uploadFiles.count]; NSInteger buttonCount = cell.rightUtilityButtons.count; if (index == buttonCount - 3) {//移动 [self moveFolder:folder fromFolder:self.curFolder]; @@ -616,15 +559,15 @@ - (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerRightUtilityBut [self renameFolder:folder]; }else{//删除 __weak typeof(self) weakSelf = self; - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:[NSString stringWithFormat:@"确定要删除文件夹:%@?",folder.name] buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + UIAlertController *actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:[NSString stringWithFormat:@"确定要删除文件夹:%@?",folder.name] buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf deleteFolder:folder]; } }]; - [actionSheet showInView:self.view]; + [actionSheet showInView:self]; } }else{ - ProjectFile *file = [_myFiles.list objectAtIndex:(indexPath.row - _curFolder.sub_folders.count - _uploadFiles.count)]; + ProjectFile *file = [_fileList objectAtIndex:(indexPath.row - _folderList.count - _uploadFiles.count)]; if (index == 0) { [self moveFiles:@[file] fromFolder:self.curFolder]; }else if (index == 1){ @@ -635,22 +578,22 @@ - (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerRightUtilityBut } } -- (void)deleteFolder:(ProjectFolder *)folder{ +- (void)deleteFolder:(ProjectFile *)folder{ __weak typeof(self) weakSelf = self; [[Coding_NetAPIManager sharedManager] request_DeleteFolder:folder andBlock:^(id data, NSError *error) { if (data) { - ProjectFolder *originalFolder = (ProjectFolder *)data; + ProjectFile *originalFolder = (ProjectFile *)data; DebugLog(@"删除文件夹成功:%@", originalFolder.name); - [weakSelf.curFolder.sub_folders removeObject:originalFolder]; + [weakSelf.myFiles.folderList removeObject:originalFolder]; weakSelf.curFolder.count = [NSNumber numberWithInt:weakSelf.curFolder.count.intValue-1]; - [weakSelf.myTableView reloadData]; - [weakSelf.view configBlankPage:EaseBlankPageTypeView hasData:([weakSelf totalDataRow] > 0) hasError:(error != nil) reloadButtonBlock:^(id sender) { - [weakSelf refreshRootFolders]; + [weakSelf updateDataWithSearchStr]; + [weakSelf configBlankPage:EaseBlankPageTypeFile hasData:([weakSelf totalDataRow] > 0) hasError:(error != nil) reloadButtonBlock:^(id sender) { + [weakSelf refresh]; }]; } }]; } -- (void)renameFolder:(ProjectFolder *)folder{ +- (void)renameFolder:(ProjectFile *)folder{ __weak typeof(self) weakSelf = self; @weakify(folder); [SettingTextViewController showSettingFolderNameVCFromVC:nil withTitle:@"重命名文件夹" textValue:folder.name type:SettingTypeFolderName doneBlock:^(NSString *textValue) { @@ -658,10 +601,10 @@ - (void)renameFolder:(ProjectFolder *)folder{ folder.next_name = textValue; [[Coding_NetAPIManager sharedManager] request_RenameFolder:folder andBlock:^(id data, NSError *error) { if (data) { - ProjectFolder *originalFolder = (ProjectFolder *)data; + ProjectFile *originalFolder = (ProjectFile *)data; originalFolder.name = originalFolder.next_name; [NSObject showHudTipStr:[NSString stringWithFormat:@"成功重命名为:%@", originalFolder.name]]; - [weakSelf.myTableView reloadData]; + [weakSelf updateDataWithSearchStr]; } }]; }]; @@ -681,7 +624,7 @@ - (void)renameFile:(ProjectFile *)file{ if (data) { file.name = textValue; [NSObject showHudTipStr:[NSString stringWithFormat:@"成功重命名为:%@", file.name]]; - [weakSelf.myTableView reloadData]; + [weakSelf updateDataWithSearchStr]; } }]; }]; @@ -689,13 +632,13 @@ - (void)renameFile:(ProjectFile *)file{ - (void)deleteFile:(ProjectFile *)file{ __weak typeof(self) weakSelf = self; __weak typeof(file) weakFile = file; - - NSURL *fileUrl = [file hasBeenDownload]; + + NSURL *fileUrl = [file diskFileUrl]; Coding_DownloadTask *cDownloadTask = [file cDownloadTask]; - UIActionSheet *actionSheet; + UIAlertController *actionSheet; if (fileUrl) { - actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"只是删除本地文件还是连同服务器文件一起删除?" buttonTitles:@[@"仅删除本地文件"] destructiveTitle:@"一起删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"只是删除本地文件还是连同服务器文件一起删除?" buttonTitles:@[@"仅删除本地文件"] destructiveTitle:@"一起删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { switch (index) { case 0: [weakSelf deleteFile:weakFile fromDisk:YES]; @@ -708,7 +651,7 @@ - (void)deleteFile:(ProjectFile *)file{ } }]; }else if (cDownloadTask){ - actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"确定将服务器上的该文件删除?" buttonTitles:@[@"只是取消下载"] destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"确定将服务器上的该文件删除?" buttonTitles:@[@"只是取消下载"] destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { switch (index) { case 0: [weakSelf deleteFile:weakFile fromDisk:YES]; @@ -721,23 +664,23 @@ - (void)deleteFile:(ProjectFile *)file{ } }]; }else{ - actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:@"确定将服务器上的该文件删除?" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { + actionSheet = [UIAlertController ea_actionSheetCustomWithTitle:@"确定将服务器上的该文件删除?" buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { if (index == 0) { [weakSelf deleteFile:weakFile fromDisk:NO]; } }]; } - [actionSheet showInView:self.view]; + [actionSheet showInView:self]; } - (void)deleteFile:(ProjectFile *)file fromDisk:(BOOL)fromDisk{ - + // 取消当前的下载任务 Coding_DownloadTask *cDownloadTask = [file cDownloadTask]; if (cDownloadTask) { [Coding_FileManager cancelCDownloadTaskForKey:file.storage_key]; } // 删除本地文件 - NSURL *fileUrl = [file hasBeenDownload]; + NSURL *fileUrl = [file diskFileUrl]; NSString *filePath = fileUrl.path; NSFileManager *fm = [NSFileManager defaultManager]; if ([fm fileExistsAtPath:filePath]) { @@ -753,12 +696,12 @@ - (void)deleteFile:(ProjectFile *)file fromDisk:(BOOL)fromDisk{ __weak typeof(self) weakSelf = self; [[Coding_NetAPIManager sharedManager] request_DeleteFiles:@[file.file_id] inProject:self.curProject.id andBlock:^(id data, NSError *error) { if (data) { - [weakSelf refreshRootFolders]; + [weakSelf refresh]; } }]; } } -- (void)moveFiles:(NSArray *)files fromFolder:(ProjectFolder *)folder{ +- (void)moveFiles:(NSArray *)files fromFolder:(ProjectFile *)folder{ NSMutableArray *fileIdList = [[NSMutableArray alloc] initWithCapacity:files.count]; for (ProjectFile *file in files) { [fileIdList addObject:file.file_id]; @@ -768,47 +711,44 @@ - (void)moveFiles:(NSArray *)files fromFolder:(ProjectFolder *)folder{ vc.fromFolder = folder; vc.toMovedIdList = fileIdList; vc.curProject = self.curProject; - vc.rootFolders = self.rootFolders; vc.curFolder = nil; - vc.moveToFolderBlock = ^(ProjectFolder *curFolder, NSArray *toMovedIdList){ + vc.moveToFolderBlock = ^(ProjectFile *curFolder, NSArray *toMovedIdList){ [weakSelf changeEditStateToEditing:NO]; [[Coding_NetAPIManager sharedManager] request_MoveFiles:toMovedIdList toFolder:curFolder andBlock:^(id data, NSError *error) { if (data) { - [weakSelf refreshRootFolders]; + [weakSelf refresh]; } }]; }; UINavigationController *nav = [[BaseNavigationController alloc] initWithRootViewController:vc]; - [self presentViewController:nav animated:YES completion:nil]; + [self.containerVC presentViewController:nav animated:YES completion:nil]; } -- (void)moveFolder:(ProjectFolder *)movedFolder fromFolder:(ProjectFolder *)folder{ +- (void)moveFolder:(ProjectFile *)movedFolder fromFolder:(ProjectFile *)folder{ __weak typeof(self) weakSelf = self; FolderToMoveViewController *vc = [[FolderToMoveViewController alloc] init]; vc.isMoveFolder = YES; vc.fromFolder = folder; vc.toMovedIdList = @[movedFolder.file_id]; vc.curProject = self.curProject; - vc.rootFolders = self.rootFolders; vc.curFolder = nil; - vc.moveToFolderBlock = ^(ProjectFolder *curFolder, NSArray *toMovedIdList){ + vc.moveToFolderBlock = ^(ProjectFile *curFolder, NSArray *toMovedIdList){ [weakSelf changeEditStateToEditing:NO]; [[Coding_NetAPIManager sharedManager] request_MoveFolder:toMovedIdList.firstObject toFolder:curFolder inProject:weakSelf.curProject andBlock:^(id data, NSError *error) { if (data) { - [weakSelf refreshRootFolders]; + [weakSelf refresh]; } }]; }; UINavigationController *nav = [[BaseNavigationController alloc] initWithRootViewController:vc]; - [self presentViewController:nav animated:YES completion:nil]; + [self.containerVC presentViewController:nav animated:YES completion:nil]; } #pragma mark toVC -- (void)goToVCWithFolder:(ProjectFolder *)folder inProject:(Project *)project{ - FileListViewController *vc = [[FileListViewController alloc] init]; +- (void)goToVCWithFolder:(ProjectFile *)folder inProject:(Project *)project{ + NFileListViewController *vc = [[NFileListViewController alloc] init]; vc.curFolder = folder; vc.curProject = project; - vc.rootFolders = self.rootFolders; - [self.navigationController pushViewController:vc animated:YES]; + [self.containerVC.navigationController pushViewController:vc animated:YES]; } - (void)goToFileVC:(ProjectFile *)file{ @@ -816,19 +756,37 @@ - (void)goToFileVC:(ProjectFile *)file{ @weakify(self); vc.fileHasBeenDeletedBlock = ^(){ @strongify(self); - [self refreshFileList]; + [self refresh]; }; vc.fileHasChangedBlock = ^(){ @strongify(self); - [self refreshFileList]; + [self refresh]; }; - [self.navigationController pushViewController:vc animated:YES]; + [self.containerVC.navigationController pushViewController:vc animated:YES]; +} +#pragma mark UISearchBarDelegate +- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar{ + return YES; +} +- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{ + [self updateDataWithSearchStr]; +} +- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{ + [searchBar resignFirstResponder]; } -- (void)dealloc -{ - _myTableView.delegate = nil; - _myTableView.dataSource = nil; +- (void)updateDataWithSearchStr{ + _fileList = _myFiles.fileList.mutableCopy; + _folderList = _myFiles.folderList.mutableCopy; + NSString *strippedStr = [_mySearchBar.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; + if (strippedStr.length > 0 && ![strippedStr isEmpty]) { + NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name contains[c] %@", strippedStr]; + [_folderList filterUsingPredicate:predicate]; + [_fileList filterUsingPredicate:predicate]; + } + [self.containerVC.navigationItem setRightBarButtonItem:self.fileList.count + self.folderList.count > 0? [UIBarButtonItem itemWithBtnTitle:@"编辑" target:self action:@selector(changeEditState)]: nil animated:YES]; + [_myTableView reloadData]; } + @end diff --git a/Coding_iOS/Views/TableListView/ProjectActivitiesView.m b/Coding_iOS/Views/TableListView/ProjectActivitiesView.m index fe5bfdf2e..120c24756 100755 --- a/Coding_iOS/Views/TableListView/ProjectActivitiesView.m +++ b/Coding_iOS/Views/TableListView/ProjectActivitiesView.m @@ -66,7 +66,9 @@ - (NSArray*)titlesArray if (_myProject.is_public.boolValue) { _titlesArray = @[@"全部", @"讨论", @"代码", @"其他"]; }else{ - _titlesArray = @[@"全部", @"任务", @"讨论", @"文件", @"代码", @"其他"]; +// _titlesArray = @[@"全部", @"任务", @"文件", @"代码", @"其他"]; +// _titlesArray = @[@"全部", @"任务", @"讨论", @"文件", @"代码", @"其他"]; + _titlesArray = @[@"全部", @"任务", @"Wiki", @"文件", @"代码", @"其他"]; } } return _titlesArray; @@ -76,32 +78,21 @@ - (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel{ return [self.titlesArray count]; } - (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view{ + ProjectActivityType type = (_myProject.is_public.boolValue? (index == 0? ProjectActivityTypeAll: + index == 1? ProjectActivityTypeTopic: + index == 2? ProjectActivityTypeCode: + ProjectActivityTypeOther): + (index == 0? ProjectActivityTypeAll: + index == 1? ProjectActivityTypeTask: + index == 2? ProjectActivityTypeWiki: + index == 3? ProjectActivityTypeFile: + index == 4? ProjectActivityTypeCode: + ProjectActivityTypeOther)); - if (_myProject.is_public.boolValue) { - switch (index) { - case 0: - index = ProjectActivityTypeAll; - break; - case 1: - index = ProjectActivityTypeTopic; - break; - case 2: - index = ProjectActivityTypeCode; - break; - case 3: - index = ProjectActivityTypeOther; - break; - default: - index = ProjectActivityTypeAll; - break; - } - }else{ - index = index; - } - ProjectActivities *curProActs = [_myProActivitiesDict objectForKey:[NSNumber numberWithUnsignedInteger:index]]; + ProjectActivities *curProActs = [_myProActivitiesDict objectForKey:@(type)]; if (!curProActs) { - curProActs = [ProjectActivities proActivitiesWithPro:_myProject type:index]; - [_myProActivitiesDict setObject:curProActs forKey:[NSNumber numberWithUnsignedInteger:index]]; + curProActs = [ProjectActivities proActivitiesWithPro:_myProject type:type]; + [_myProActivitiesDict setObject:curProActs forKey:@(type)]; } ProjectActivityListView *listView = (ProjectActivityListView *)view; if (listView) { diff --git a/Coding_iOS/Views/TableListView/ProjectActivityListView.m b/Coding_iOS/Views/TableListView/ProjectActivityListView.m index 0c69509bd..b2614d0fc 100755 --- a/Coding_iOS/Views/TableListView/ProjectActivityListView.m +++ b/Coding_iOS/Views/TableListView/ProjectActivityListView.m @@ -43,9 +43,14 @@ - (id)initWithFrame:(CGRect)frame proAtcs:(ProjectActivities *)proAtcs block:(Pr [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); - _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; [_myRefreshControl addTarget:self action:@selector(refresh) forControlEvents:UIControlEventValueChanged]; __weak typeof(self) weakSelf = self; diff --git a/Coding_iOS/Views/TableListView/ProjectCodeListView.h b/Coding_iOS/Views/TableListView/ProjectCodeListView.h index ad9275bcc..200ddf027 100755 --- a/Coding_iOS/Views/TableListView/ProjectCodeListView.h +++ b/Coding_iOS/Views/TableListView/ProjectCodeListView.h @@ -10,11 +10,16 @@ #import "CodeTree.h" #import "Projects.h" -@interface ProjectCodeListView : UIView +@interface ProjectCodeListView : UIView @property (copy, nonatomic) void (^codeTreeFileOfRefBlock)(CodeTree_File *, NSString *); -@property (copy, nonatomic) void (^refChangedBlock)(NSString *); +@property (copy, nonatomic) void (^codeTreeChangedBlock)(CodeTree *); + +@property (assign, nonatomic) BOOL hideBranchTagButton; - (id)initWithFrame:(CGRect)frame project:(Project *)project andCodeTree:(CodeTree *)codeTree; -- (void)addBranchTagButton; +- (void)refreshToQueryData; + +- (void)createFileClicked; +- (void)uploadImageClicked; @end diff --git a/Coding_iOS/Views/TableListView/ProjectCodeListView.m b/Coding_iOS/Views/TableListView/ProjectCodeListView.m index 6c476aa48..ac0243a7f 100755 --- a/Coding_iOS/Views/TableListView/ProjectCodeListView.m +++ b/Coding_iOS/Views/TableListView/ProjectCodeListView.m @@ -10,14 +10,18 @@ #import "ODRefreshControl.h" #import "Coding_NetAPIManager.h" #import "ProjectCodeListCell.h" +#import "ProjectCodeListSearchCell.h" #import "CodeBranchTagButton.h" +#import "QBImagePickerController.h" -@interface ProjectCodeListView () +@interface ProjectCodeListView () @property (nonatomic, strong) Project *curProject; @property (nonatomic , strong) CodeTree *myCodeTree; @property (nonatomic, strong) UITableView *myTableView; @property (nonatomic, strong) ODRefreshControl *myRefreshControl; @property (strong, nonatomic) CodeBranchTagButton *branchTagButton; +@property (strong, nonatomic) UISearchBar *mySearchBar; +@property (strong, nonatomic) NSArray *searchedFileList; @end @implementation ProjectCodeListView @@ -30,7 +34,7 @@ - (id)initWithFrame:(CGRect)frame project:(Project *)project andCodeTree:(CodeTr if (codeTree) { _myCodeTree = codeTree; }else{ - _myCodeTree = [CodeTree codeTreeMaster]; + self.myCodeTree = [CodeTree codeTreeMaster]; } _myTableView = ({ UITableView *tableView = [[UITableView alloc] initWithFrame:self.bounds style:UITableViewStylePlain]; @@ -38,13 +42,25 @@ - (id)initWithFrame:(CGRect)frame project:(Project *)project andCodeTree:(CodeTr tableView.delegate = self; tableView.dataSource = self; [tableView registerClass:[ProjectCodeListCell class] forCellReuseIdentifier:kCellIdentifier_ProjectCodeList]; + [tableView registerClass:[ProjectCodeListSearchCell class] forCellReuseIdentifier:kCellIdentifier_ProjectCodeListSearchCell]; tableView.separatorStyle = UITableViewCellSeparatorStyleNone; [self addSubview:tableView]; [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; - }); + }); + _mySearchBar = ({ + UISearchBar *searchBar = [[UISearchBar alloc] init]; + searchBar.delegate = self; + [searchBar sizeToFit]; + [searchBar setPlaceholder:@"寻找文件"]; + searchBar; + }); + _myTableView.tableHeaderView = _mySearchBar; _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; [_myRefreshControl addTarget:self action:@selector(refresh) forControlEvents:UIControlEventValueChanged]; [self sendRequest]; @@ -52,16 +68,26 @@ - (id)initWithFrame:(CGRect)frame project:(Project *)project andCodeTree:(CodeTr return self; } -- (void)addBranchTagButton{ - CGFloat bottonToolBarHeight = 49.0; +- (void)refreshToQueryData{ + [self refresh]; +} + +- (void)setMyCodeTree:(CodeTree *)myCodeTree{ + _myCodeTree = myCodeTree; + if (self.codeTreeChangedBlock){ + self.codeTreeChangedBlock(_myCodeTree); + } +} + +- (BOOL)isSearching{ + return ![_mySearchBar.text isEmpty]; +} + +- (CodeBranchTagButton *)branchTagButton{ if (!_branchTagButton) { _branchTagButton = ({ CodeBranchTagButton *button = [CodeBranchTagButton buttonWithProject:_curProject andTitleStr:_myCodeTree.ref]; - [self addSubview:button]; - [button mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.right.bottom.equalTo(self); - make.height.mas_equalTo(bottonToolBarHeight); - }]; + button.showingContainerView = self; button; }); } @@ -69,17 +95,13 @@ - (void)addBranchTagButton{ _branchTagButton.selectedBranchTagBlock = ^(NSString *branchTag){ if ([weakSelf.myCodeTree.ref isEqualToString:branchTag]) { return ; - }else if (weakSelf.refChangedBlock){ - weakSelf.refChangedBlock(branchTag); + }else{ + weakSelf.myCodeTree = [CodeTree codeTreeWithRef:branchTag andPath:weakSelf.myCodeTree.path]; + [weakSelf.myTableView reloadData]; + [weakSelf sendRequest]; } - weakSelf.myCodeTree = [CodeTree codeTreeWithRef:branchTag andPath:weakSelf.myCodeTree.path]; - [weakSelf.myTableView reloadData]; - [weakSelf sendRequest]; }; - - [self.myTableView mas_remakeConstraints:^(MASConstraintMaker *make) { - make.edges.equalTo(self).insets(UIEdgeInsetsMake(0, 0, bottonToolBarHeight, 0)); - }]; + return _branchTagButton; } - (void)refresh{ @@ -90,9 +112,9 @@ - (void)refresh{ } - (void)sendRequest{ - if (_myCodeTree.files.count <= 0) { - [self beginLoading]; - } + if (_myCodeTree.files.count <= 0) { + [self beginLoading]; + } __weak typeof(self) weakSelf = self; [[Coding_NetAPIManager sharedManager] request_CodeTree:_myCodeTree withPro:_curProject codeTreeBlock:^(id codeTreeData, NSError *codeTreeError) { @@ -106,37 +128,188 @@ - (void)sendRequest{ if (codeTreeError != nil && codeTreeError.code == 1024) { hasError = YES; } - [weakSelf configBlankPage:EaseBlankPageTypeView hasData:(weakSelf.myCodeTree.files.count > 0) hasError:hasError reloadButtonBlock:^(id sender) { + [weakSelf configBlankPage:EaseBlankPageTypeCode hasData:(weakSelf.myCodeTree.files.count > 0) hasError:hasError reloadButtonBlock:^(id sender) { [weakSelf refresh]; }]; }]; } +#pragma mark ScrollView Delegate +- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{ + if (scrollView == _myTableView) { + [self.mySearchBar resignFirstResponder]; + } +} + #pragma mark Table + +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ + return ([self isSearching] || !self.hideBranchTagButton)? 44.0: 0.0; +} + +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ + if ([self isSearching]) { + UILabel *headerL = [UILabel labelWithSystemFontSize:14 textColorHexString:@"0xB5B5B5"]; + headerL.frame = CGRectMake(0, 0, kScreen_Width, 40); + headerL.backgroundColor = [UIColor whiteColor]; + headerL.textAlignment = NSTextAlignmentCenter; + headerL.text = [NSString stringWithFormat:@"共搜到 %lu 个与 \"%@\" 相关的文件", (unsigned long)self.searchedFileList.count, self.mySearchBar.text]; + [headerL doBorderWidth:.5 color:kColorDDD cornerRadius:0]; + return headerL; + }else{ + return self.hideBranchTagButton? [UIView new]: self.branchTagButton; + } +} + - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ NSInteger row = 0; - if (_myCodeTree && _myCodeTree.files) { + if ([self isSearching]) { + row = self.searchedFileList.count; + }else{ row = _myCodeTree.files.count; } return row; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ - ProjectCodeListCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_ProjectCodeList forIndexPath:indexPath]; - cell.file = [self.myCodeTree.files objectAtIndex:indexPath.row]; - [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; - return cell; + if ([self isSearching]) { + ProjectCodeListSearchCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_ProjectCodeListSearchCell forIndexPath:indexPath]; + cell.treePath = _myCodeTree.path; + cell.searchText = [_mySearchBar.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; + cell.filePath = self.searchedFileList[indexPath.row]; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth hasSectionLine:NO]; + return cell; + }else{ + ProjectCodeListCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_ProjectCodeList forIndexPath:indexPath]; + cell.file = self.myCodeTree.files[indexPath.row]; + [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth hasSectionLine:NO]; + return cell; + } } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ - return [ProjectCodeListCell cellHeight]; + return [self isSearching]? [ProjectCodeListSearchCell cellHeight]: [ProjectCodeListCell cellHeight]; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ [tableView deselectRowAtIndexPath:indexPath animated:YES]; if (_codeTreeFileOfRefBlock) { - CodeTree_File *file = [self.myCodeTree.files objectAtIndex:indexPath.row]; + CodeTree_File *file; + if ([self isSearching]) { + file = [CodeTree_File new]; + file.path = self.searchedFileList[indexPath.row]; + file.mode = @"file"; + }else{ + file = [self.myCodeTree.files objectAtIndex:indexPath.row]; + } _codeTreeFileOfRefBlock(file, _myCodeTree.ref); } } + +#pragma mark UISearchBarDelegate +- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar{ + [_branchTagButton dismissShowingList]; + return YES; +} + +- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{ + [self searchFileWithStr:searchText]; +} + +- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{ + [searchBar resignFirstResponder]; + [self searchFileWithStr:searchBar.text]; +} + +- (void)searchFileWithStr:(NSString *)string{ + if ([string isEmpty]) { + [self.myTableView reloadData]; + }else{ + NSString *strippedStr = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; + if (strippedStr.length > 0) { + [self updateFilteredContentForSearchString:strippedStr]; + } + } +} + +- (void)updateFilteredContentForSearchString:(NSString *)searchString{ + self.searchedFileList = [self.myCodeTree.treeList filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(NSString * _Nullable evaluatedObject, NSDictionary * _Nullable bindings) { + NSString *shortPath = evaluatedObject; + if (_myCodeTree.path.length > 0) { + if ([shortPath hasPrefix:_myCodeTree.path]) { + shortPath = [shortPath substringFromIndex:_myCodeTree.path.length + 1];// '/xxxx' + }else{ + return NO; + } + } + return ([shortPath rangeOfString:searchString options:NSCaseInsensitiveSearch].location != NSNotFound); + }]]; + [self.myTableView reloadData]; +} + +#pragma mark Action +- (void)createFileClicked{ + __weak typeof(self) weakSelf = self; + UIAlertController *alertCtrl = [UIAlertController alertControllerWithTitle:@"创建文本文件" message:@"输入文件名称" preferredStyle:UIAlertControllerStyleAlert]; + UIAlertAction *cancelA = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]; + UIAlertAction *confirmA = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) { + NSString *fileName = alertCtrl.textFields[0].text; + if (![fileName isFileName]) { + [NSObject showHudTipStr:[fileName isEmpty]? @"文件名不能为空": @"文件名不能含有特殊符号"]; + [[BaseViewController presentingVC] presentViewController:alertCtrl animated:YES completion:nil]; + }else{ + [weakSelf goToCreatFileWithName:fileName]; + } + }]; + [alertCtrl addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { + textField.placeholder = @"文件名"; + }]; + [alertCtrl addAction:cancelA]; + [alertCtrl addAction:confirmA]; + [[BaseViewController presentingVC] presentViewController:alertCtrl animated:YES completion:nil]; +} + +- (void)goToCreatFileWithName:(NSString *)fileName{ + CodeFile *codeFile = [CodeFile codeFileToCommitWithRef:_myCodeTree.ref andPath:_myCodeTree.path name:fileName data:@"" message:[NSString stringWithFormat:@"new file %@", fileName] headCommit:_myCodeTree.headCommit]; + __weak typeof(self) weakSelf = self; + [NSObject showHUDQueryStr:@"请稍等..."]; + [[Coding_NetAPIManager sharedManager] request_CreateCodeFile:codeFile withPro:_curProject andBlock:^(id data, NSError *error) { + [NSObject hideHUDQuery]; + if (data) { + [NSObject showHudTipStr:@"创建成功"]; + [weakSelf refresh]; + } + }]; +} + +- (void)uploadImageClicked{ + QBImagePickerController *imagePickerController = [[QBImagePickerController alloc] init]; + imagePickerController.mediaType = QBImagePickerMediaTypeImage; + imagePickerController.delegate = self; + imagePickerController.allowsMultipleSelection = YES; + imagePickerController.maximumNumberOfSelection = 6; + [[BaseViewController presentingVC] presentViewController:imagePickerController animated:YES completion:NULL]; +} + +#pragma mark QBImagePickerControllerDelegate +- (void)qb_imagePickerController:(QBImagePickerController *)imagePickerController didFinishPickingAssets:(NSArray *)assets{ + __weak typeof(self) weakSelf = self; + MBProgressHUD *hud = [NSObject showHUDQueryStr:@"正在上传..."]; + hud.mode = MBProgressHUDModeDeterminateHorizontalBar; + [[Coding_NetAPIManager sharedManager] request_UploadAssets:assets inCodeTree:_myCodeTree withPro:_curProject andBlock:^(id data, NSError *error) { + [NSObject hideHUDQuery]; + if (data) { + [NSObject showHudTipStr:@"上传成功"]; + [weakSelf refresh]; + } + } progerssBlock:^(CGFloat progressValue) { + hud.progress = MAX(0, progressValue-0.05); + }]; + + [[BaseViewController presentingVC] dismissViewControllerAnimated:YES completion:nil]; +} +- (void)qb_imagePickerControllerDidCancel:(QBImagePickerController *)imagePickerController{ + [[BaseViewController presentingVC] dismissViewControllerAnimated:YES completion:nil]; +} + @end diff --git a/Coding_iOS/Views/TableListView/ProjectFolderListView.h b/Coding_iOS/Views/TableListView/ProjectFolderListView.h deleted file mode 100755 index 492754ee4..000000000 --- a/Coding_iOS/Views/TableListView/ProjectFolderListView.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// ProjectFolderListView.h -// Coding_iOS -// -// Created by 王 原闯 on 14/10/29. -// Copyright (c) 2014年 Coding. All rights reserved. -// - -#import -#import "Projects.h" -#import "ProjectFolders.h" - -@interface ProjectFolderListView : UIView -@property (weak, nonatomic) UIViewController *containerVC; -@property (copy, nonatomic) void (^folderInProjectBlock)(ProjectFolders *, ProjectFolder *, Project *); -- (id)initWithFrame:(CGRect)frame project:(Project *)project; -- (void)reloadData; -- (void)refreshToQueryData; -@end diff --git a/Coding_iOS/Views/TableListView/ProjectFolderListView.m b/Coding_iOS/Views/TableListView/ProjectFolderListView.m deleted file mode 100755 index dbb089fde..000000000 --- a/Coding_iOS/Views/TableListView/ProjectFolderListView.m +++ /dev/null @@ -1,215 +0,0 @@ -// -// ProjectFolderListView.m -// Coding_iOS -// -// Created by 王 原闯 on 14/10/29. -// Copyright (c) 2014年 Coding. All rights reserved. -// - -#import "ProjectFolderListView.h" -#import "ODRefreshControl.h" -#import "Coding_NetAPIManager.h" -#import "ProjectFolderListCell.h" -#import "SettingTextViewController.h" -#import "FolderToMoveViewController.h" - -@interface ProjectFolderListView () -@property (nonatomic, strong) Project *curProject; -@property (strong, nonatomic) ProjectFolders *myFolders; -@property (nonatomic, strong) UITableView *myTableView; -@property (nonatomic, strong) ODRefreshControl *myRefreshControl; -@end -@implementation ProjectFolderListView -- (id)initWithFrame:(CGRect)frame project:(Project *)project{ - self = [super initWithFrame:frame]; - if (self) { - // Initialization code - _curProject = project; - _myFolders = [ProjectFolders emptyFolders]; - _myTableView = ({ - UITableView *tableView = [[UITableView alloc] initWithFrame:self.bounds style:UITableViewStylePlain]; - tableView.backgroundColor = [UIColor clearColor]; - tableView.delegate = self; - tableView.dataSource = self; - [tableView registerClass:[ProjectFolderListCell class] forCellReuseIdentifier:kCellIdentifier_ProjectFolderList]; - tableView.separatorStyle = UITableViewCellSeparatorStyleNone; - [self addSubview:tableView]; - [tableView mas_makeConstraints:^(MASConstraintMaker *make) { - make.edges.equalTo(self); - }]; - tableView; - }); - - _myRefreshControl = [[ODRefreshControl alloc] initInScrollView:self.myTableView]; - [_myRefreshControl addTarget:self action:@selector(refresh) forControlEvents:UIControlEventValueChanged]; - [self sendRequest]; - } - return self; -} -- (void)refresh{ - if (_myFolders.isLoading) { - return; - } - [self sendRequest]; -} - -- (void)sendRequest{ - if (_myFolders.list.count <= 0) { - [self beginLoading]; - } - __weak typeof(self) weakSelf = self; - [[Coding_NetAPIManager sharedManager] request_Folders:_myFolders inProject:_curProject andBlock:^(id data, NSError *error) { - [weakSelf.myRefreshControl endRefreshing]; - [weakSelf endLoading]; - if (data) { - weakSelf.myFolders = data; - [weakSelf.myTableView reloadData]; - } - [weakSelf configBlankPage:EaseBlankPageTypeView hasData:(weakSelf.myFolders.list.count > 0) hasError:(error != nil) reloadButtonBlock:^(id sender) { - [weakSelf refresh]; - }]; - }]; -} -- (void)reloadData{ - if (self.myTableView) { - [self.myTableView reloadData]; - } -} -- (void)refreshToQueryData{ - [self refresh]; -} -#pragma mark Table -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ - NSInteger row = 0; - if (_myFolders && _myFolders.list) { - row = _myFolders.list.count; - } - return row; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ - ProjectFolderListCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_ProjectFolderList forIndexPath:indexPath]; - ProjectFolder *folder = [self.myFolders.list objectAtIndex:indexPath.row]; - cell.folder = folder; - [cell setRightUtilityButtons:[self rightButtonsWithObj:folder] WithButtonWidth:[ProjectFolderListCell cellHeight]]; - cell.delegate = self; - [tableView addLineforPlainCell:cell forRowAtIndexPath:indexPath withLeftSpace:kPaddingLeftWidth]; - return cell; -} - -- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ - return [ProjectFolderListCell cellHeight]; -} - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ - [tableView deselectRowAtIndexPath:indexPath animated:YES]; - if (_folderInProjectBlock) { - ProjectFolder *folder = [self.myFolders.list objectAtIndex:indexPath.row]; - _folderInProjectBlock(_myFolders, folder, _curProject); - } -} -#pragma mark Edit Table -- (NSArray *)rightButtonsWithObj:(id)obj{ - NSMutableArray *rightUtilityButtons = [NSMutableArray new]; - if ([obj isKindOfClass:[ProjectFolder class]]) { - ProjectFolder *folder = (ProjectFolder *)obj; - if (![folder isDefaultFolder] && ![folder isShareFolder]) { - if (folder.sub_folders.count <= 0) { - [rightUtilityButtons sw_addUtilityButtonWithColor:kColorDDD icon:[UIImage imageNamed:@"icon_file_cell_move"]]; - } - [rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithHexString:@"0xe6e6e6"] icon:[UIImage imageNamed:@"icon_file_cell_rename"]]; - [rightUtilityButtons sw_addUtilityButtonWithColor:kColorBrandRed icon:[UIImage imageNamed:@"icon_file_cell_delete"]]; - } - } - return rightUtilityButtons; -} -- (BOOL)swipeableTableViewCellShouldHideUtilityButtonsOnSwipe:(SWTableViewCell *)cell{ - return YES; -} -- (BOOL)swipeableTableViewCell:(SWTableViewCell *)cell canSwipeToState:(SWCellState)state{ - NSIndexPath *indexPath = [self.myTableView indexPathForCell:cell]; - if (indexPath.row == 0) { - return NO; - } - return YES; -} - -- (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerRightUtilityButtonWithIndex:(NSInteger)index { - [cell hideUtilityButtonsAnimated:YES]; - NSIndexPath *indexPath = [self.myTableView indexPathForCell:cell]; - ProjectFolder *folder = [self.myFolders.list objectAtIndex:indexPath.row]; - if ([folder isDefaultFolder]) { - [NSObject showHudTipStr:@"‘默认文件夹’不可以编辑"]; - }else{ - NSInteger buttonCount = cell.rightUtilityButtons.count; - if (index == buttonCount - 3) {//移动 - [self moveFolder:folder fromFolder:nil]; - }else if (index == buttonCount - 2) {//重命名 - [self renameFolder:folder]; - }else{//删除 - __weak typeof(self) weakSelf = self; - UIActionSheet *actionSheet = [UIActionSheet bk_actionSheetCustomWithTitle:[NSString stringWithFormat:@"确定要删除文件夹:%@?",folder.name] buttonTitles:nil destructiveTitle:@"确认删除" cancelTitle:@"取消" andDidDismissBlock:^(UIActionSheet *sheet, NSInteger index) { - if (index == 0) { - [weakSelf deleteFolder:folder]; - } - }]; - [actionSheet showInView:self]; - } - } -} -- (void)deleteFolder:(ProjectFolder *)folder{ - __weak typeof(self) weakSelf = self; - [[Coding_NetAPIManager sharedManager] request_DeleteFolder:folder andBlock:^(id data, NSError *error) { - if (data) { - ProjectFolder *originalFolder = (ProjectFolder *)data; - DebugLog(@"删除文件夹成功:%@", originalFolder.name); - - [weakSelf.myFolders.list removeObject:originalFolder]; - [weakSelf.myTableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationNone]; - } - }]; -} -- (void)renameFolder:(ProjectFolder *)folder{ - __weak typeof(self) weakSelf = self; - @weakify(folder); - [SettingTextViewController showSettingFolderNameVCFromVC:nil withTitle:@"重命名文件夹" textValue:folder.name type:SettingTypeFolderName doneBlock:^(NSString *textValue) { - @strongify(folder); - if (![textValue isEqualToString:folder.name]) { - folder.next_name = textValue; - [[Coding_NetAPIManager sharedManager] request_RenameFolder:folder andBlock:^(id data, NSError *error) { - if (data) { - ProjectFolder *originalFolder = (ProjectFolder *)data; - DebugLog(@"重命名文件夹成功:%@", originalFolder.name); - - originalFolder.name = originalFolder.next_name; - [weakSelf.myTableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationNone]; - } - }]; - } - }]; -} - -- (void)moveFolder:(ProjectFolder *)movedFolder fromFolder:(ProjectFolder *)folder{ - if (!self.containerVC) { - return; - } - __weak typeof(self) weakSelf = self; - FolderToMoveViewController *vc = [[FolderToMoveViewController alloc] init]; - vc.isMoveFolder = YES; - vc.fromFolder = folder; - vc.toMovedIdList = @[movedFolder.file_id]; - vc.curProject = self.curProject; - vc.rootFolders = self.myFolders; - vc.curFolder = nil; - vc.moveToFolderBlock = ^(ProjectFolder *curFolder, NSArray *toMovedIdList){ - [[Coding_NetAPIManager sharedManager] request_MoveFolder:toMovedIdList.firstObject toFolder:curFolder inProject:weakSelf.curProject andBlock:^(id data, NSError *error) { - if (data) { - [weakSelf refresh]; - } - }]; - }; - UINavigationController *nav = [[BaseNavigationController alloc] initWithRootViewController:vc]; - [self.containerVC presentViewController:nav animated:YES completion:nil]; -} - -@end diff --git a/Coding_iOS/Views/TableListView/ProjectListView.m b/Coding_iOS/Views/TableListView/ProjectListView.m index 785db5c48..0cd3be9eb 100755 --- a/Coding_iOS/Views/TableListView/ProjectListView.m +++ b/Coding_iOS/Views/TableListView/ProjectListView.m @@ -29,6 +29,8 @@ @interface ProjectListView () @property (strong, nonatomic) UISearchBar *mySearchBar; @property (copy, nonatomic) void(^searchBlock)(); @property (copy, nonatomic) void(^scanBlock)(); + +@property (assign, nonatomic) BOOL isHeaderClosed, isNewerVersionAvailable; @end @implementation ProjectListView static NSString *const kTitleKey = @"kTitleKey"; @@ -71,9 +73,12 @@ - (id)initWithFrame:(CGRect)frame projects:(Projects *)projects block:(ProjectLi tableView.contentInset = insets; tableView.scrollIndicatorInsets = insets; } + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); - if (projects.type < ProjectsTypeToChoose || projects.type == ProjectsTypeAllPublic) { + if ((projects.type < ProjectsTypeToChoose && !kTarget_Enterprise) || projects.type == ProjectsTypeAllPublic) { _mySearchBar = nil; _myTableView.tableHeaderView = nil; }else{ @@ -81,7 +86,9 @@ - (id)initWithFrame:(CGRect)frame projects:(Projects *)projects block:(ProjectLi UISearchBar *searchBar = [[UISearchBar alloc] init]; searchBar.delegate = self; [searchBar sizeToFit]; - [searchBar setPlaceholder:@"项目名称/创建人"]; + [searchBar setPlaceholder:kTarget_Enterprise? @"项目名称/描述": @"项目名称/创建人"]; + [searchBar setPlaceholderColor:kColorDarkA]; + [searchBar setSearchIcon:[UIImage imageNamed:@"icon_search_searchbar"]]; searchBar; }); _myTableView.tableHeaderView = _mySearchBar; @@ -117,6 +124,7 @@ -(void)setUseNewStyle:(BOOL)useNewStyle{ }]; } [_myTableView reloadData]; + [self p_checkIfNewVersionTip]; } - (void)setSearchBlock:(void(^)())searchBlock andScanBlock:(void(^)())scanBlock{ @@ -126,6 +134,8 @@ - (void)setSearchBlock:(void(^)())searchBlock andScanBlock:(void(^)())scanBlock{ _mySearchBar = ({ MainSearchBar *searchBar = [MainSearchBar new]; [searchBar setPlaceholder:@"搜索"]; + [searchBar setPlaceholderColor:kColorDarkA]; + [searchBar setSearchIcon:[UIImage imageNamed:@"icon_search_searchbar"]]; searchBar.delegate = self; [searchBar sizeToFit]; [searchBar.scanBtn addTarget:self action:@selector(scanBtnClicked) forControlEvents:UIControlEventTouchUpInside]; @@ -148,25 +158,42 @@ - (void)setupDataList{ _dataList = [[NSMutableArray alloc] initWithCapacity:2]; } [_dataList removeAllObjects]; - if (_myProjects.type < ProjectsTypeToChoose) { - NSArray *pinList = _myProjects.pinList, *noPinList = _myProjects.noPinList; - if (pinList.count > 0) { - [_dataList addObject:@{kTitleKey : @"常用项目", - kValueKey : pinList}]; - } - if (noPinList.count > 0) { - [_dataList addObject:@{kTitleKey : @"一般项目", - kValueKey : noPinList}]; - } - }else{ - NSMutableArray *list = [self updateFilteredContentForSearchString:self.mySearchBar.text]; - if (list.count > 0) { - [list sortUsingComparator:^NSComparisonResult(Project *obj1, Project *obj2) { - return (obj1.pin.integerValue < obj2.pin.integerValue); - }]; - [_dataList addObject:@{kTitleKey : @"一般项目", - kValueKey : list}]; - } +// if (_myProjects.type < ProjectsTypeToChoose) { +//// NSArray *pinList = _myProjects.pinList, *noPinList = _myProjects.noPinList; +//// if (pinList.count > 0) { +//// [_dataList addObject:@{kTitleKey : @"常用项目", +//// kValueKey : pinList}]; +//// } +//// if (noPinList.count > 0) { +//// [_dataList addObject:@{kTitleKey : @"一般项目", +//// kValueKey : noPinList}]; +//// } +// NSMutableArray *list = _myProjects.list.mutableCopy; +// if (list.count > 0) { +// [list sortUsingComparator:^NSComparisonResult(Project *obj1, Project *obj2) { +// return (obj1.pin.integerValue < obj2.pin.integerValue); +// }]; +// [_dataList addObject:@{kTitleKey : @"全部项目", +// kValueKey : list}]; +// } +// }else{ +// NSMutableArray *list = [self updateFilteredContentForSearchString:self.mySearchBar.text]; +// if (list.count > 0) { +// [list sortUsingComparator:^NSComparisonResult(Project *obj1, Project *obj2) { +// return (obj1.pin.integerValue < obj2.pin.integerValue); +// }]; +// [_dataList addObject:@{kTitleKey : @"一般项目", +// kValueKey : list}]; +// } +// } +// 特么真搞不清上面那一坨是干嘛的了 + NSMutableArray *list = [self updateFilteredContentForSearchString:self.mySearchBar.text]; + if (list.count > 0) { + [list sortUsingComparator:^NSComparisonResult(Project *obj1, Project *obj2) { + return (obj1.pin.integerValue < obj2.pin.integerValue); + }]; + [_dataList addObject:@{kTitleKey : @"项目", + kValueKey : list}]; } } - (NSString *)titleForSection:(NSUInteger)section{ @@ -181,6 +208,68 @@ - (NSArray *)valueForSection:(NSUInteger)section{ } return nil; } + +- (void)setIsNewerVersionAvailable:(BOOL)isNewerVersionAvailable{ + if (_isNewerVersionAvailable != isNewerVersionAvailable) { + _isNewerVersionAvailable = isNewerVersionAvailable; + [self.myTableView reloadData]; + } +} + +- (void)setIsHeaderClosed:(BOOL)isHeaderClosed{ + _isHeaderClosed = isHeaderClosed; + [self.myTableView reloadData]; +} + +- (void)p_checkIfNewVersionTip{ + if ([self p_needToCheckIfNewVersion]) { + NSString *appStoreCountry = [(NSLocale *)[NSLocale currentLocale] objectForKey:NSLocaleCountryCode]; + if ([appStoreCountry isEqualToString:@"150"]){ + appStoreCountry = @"eu"; + }else if ([[appStoreCountry stringByReplacingOccurrencesOfString:@"[A-Za-z]{2}" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, 2)] length]){ + appStoreCountry = @"us"; + } + __weak typeof(self) weakSelf = self; + NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://itunes.apple.com/%@/lookup?id=%@", appStoreCountry, self.p_appID]] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { + if (!error && data) { + NSDictionary *result = [[NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingOptions)0 error:&error][@"results"] lastObject]; + NSString *latestVersion = result[@"version"]; + NSString *minimumSupportedOSVersion = result[@"minimumOsVersion"]; + if (latestVersion && minimumSupportedOSVersion) { + BOOL osVersionSupported = ([[UIDevice currentDevice].systemVersion compare:minimumSupportedOSVersion options:NSNumericSearch] != NSOrderedAscending); + BOOL isNewerVersionAvailable = ([kVersion_Coding compare:latestVersion options:NSNumericSearch] == NSOrderedAscending); + dispatch_async(dispatch_get_main_queue(), ^{ + weakSelf.isNewerVersionAvailable = (osVersionSupported && isNewerVersionAvailable); + }); + } + } + }]; + [task resume]; + } +} + +- (NSString *)p_appID{ + return kTarget_Enterprise? @"1191398741": @"923676989"; +} + +- (BOOL)p_needToCheckIfNewVersion{ + return (!_isHeaderClosed && + (_useNewStyle && _myProjects.type == ProjectsTypeAll) && + !self.isNewerVersionAvailable); +} + +- (BOOL)p_needToShowVersionTip{ + return (!_isHeaderClosed && + (_useNewStyle && _myProjects.type == ProjectsTypeAll) && + self.isNewerVersionAvailable); +} + +- (BOOL)p_needToShowHeaderTip{ + return (!_isHeaderClosed && + (_useNewStyle && _myProjects.type == ProjectsTypeAll) && + (self.isNewerVersionAvailable || ![NSObject isPrivateCloud].boolValue)); +} + - (void)refreshUI{ [_myTableView reloadData]; [self refreshFirst]; @@ -191,6 +280,8 @@ - (void)refreshToQueryData{ - (void)refresh{ if (!_myProjects.isLoading) { [self sendRequest]; + + [self p_checkIfNewVersionTip]; } } - (void)refreshFirst{ @@ -233,6 +324,8 @@ - (void)sendRequest{ blankPageType = EaseBlankPageTypeProject_ALL; break; case ProjectsTypeCreated: + case ProjectsTypeCreatedPrivate: + case ProjectsTypeCreatedPublic: blankPageType = EaseBlankPageTypeProject_CREATE; break; case ProjectsTypeJoined: @@ -268,6 +361,82 @@ - (void)sendRequest{ - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return [_dataList count]; } + +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ + if ([self p_needToShowHeaderTip]) { + static UILabel *tipL; + if (!tipL) { + tipL = [UILabel labelWithFont:[UIFont systemFontOfSize:12] textColor:[UIColor colorWithHexString:@"0x136BFB"]]; + tipL.numberOfLines = 0; + } + tipL.attributedText = [self p_headerTipStr]; + return [tipL sizeThatFits:CGSizeMake(kScreen_Width - 40 * 1, CGFLOAT_MAX)].height + 16; + } else { + return 0; + } +} + +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ + if ([self p_needToShowHeaderTip]) { + UIView *headerV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, 40)]; + headerV.backgroundColor = [UIColor colorWithHexString:@"0xECF9FF"]; + __weak typeof(self) weakSelf = self; + UIButton *closeBtn = [UIButton new]; + [closeBtn setImage:[UIImage imageNamed:@"button_tip_close"] forState:UIControlStateNormal]; + [closeBtn bk_addEventHandler:^(id sender) { + weakSelf.isHeaderClosed = YES; + } forControlEvents:UIControlEventTouchUpInside]; + [headerV addSubview:closeBtn]; + [closeBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.right.equalTo(headerV); + make.width.mas_equalTo(40); + make.height.mas_equalTo(36); // 文字单行显示时的高度 + }]; +// UIImageView *noticeV = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"button_tip_notice"]]; +// noticeV.contentMode = UIViewContentModeCenter; +// [headerV addSubview:noticeV]; +// [noticeV mas_makeConstraints:^(MASConstraintMaker *make) { +// make.top.bottom.left.equalTo(headerV); +// make.width.mas_equalTo(0); +// }]; + UILabel *tipL = [UILabel labelWithFont:[UIFont systemFontOfSize:12] textColor:[UIColor colorWithHexString:@"0x136BFB"]]; + tipL.numberOfLines = 0; + tipL.userInteractionEnabled = YES; + tipL.attributedText = [self p_headerTipStr]; + if ([self p_needToShowVersionTip]) { + [tipL bk_whenTapped:^{ + [[UIApplication sharedApplication] openURL:[NSURL URLWithString:kAppUrl]]; + }]; + } + [headerV addSubview:tipL]; + [tipL mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(headerV).mas_offset(3); + make.left.equalTo(headerV).offset(15); + make.right.equalTo(closeBtn.mas_left); + }]; + return headerV; + } else { + return nil; + } +} + +- (NSAttributedString *)p_headerTipStr{ + if ([self p_needToShowHeaderTip]) { + NSString *tipStr; + if ([self p_needToShowVersionTip]) { + tipStr = kTarget_Enterprise? @"立即升级最新 CODING 企业版客户端": @"立即升级最新 Coding 客户端"; + } else { + tipStr = @"温馨提示:出于实际使用场景限制的考虑,该 App 不再进行更多新功能开发,建议您前往 PC 端网页版体验更完整的产品功能。"; + } + NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; + paragraphStyle.lineSpacing = 6; + NSDictionary *attributes = @{NSParagraphStyleAttributeName: paragraphStyle}; + return [[NSAttributedString alloc] initWithString:tipStr attributes:attributes]; + } else { + return nil; + } +} + - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return [[self valueForSection:section] count]; } @@ -388,6 +557,10 @@ - (NSMutableArray *)updateFilteredContentForSearchString:(NSString *)searchStrin // strip out all the leading and trailing spaces NSString *strippedStr = [searchString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; + if (strippedStr.length <= 0) { + return searchResults; + } + // break up the search terms (separated by spaces) NSArray *searchItems = nil; if (strippedStr.length > 0) @@ -415,7 +588,7 @@ - (NSMutableArray *)updateFilteredContentForSearchString:(NSString *)searchStrin [searchItemsPredicate addObject:finalPredicate]; // owner_user_name field matching - lhs = [NSExpression expressionForKeyPath:@"owner_user_name"]; + lhs = [NSExpression expressionForKeyPath:kTarget_Enterprise? @"description_mine": @"owner_user_name"]; rhs = [NSExpression expressionForConstantValue:searchString]; finalPredicate = [NSComparisonPredicate predicateWithLeftExpression:lhs diff --git a/Coding_iOS/Views/TableListView/ProjectTaskListView.h b/Coding_iOS/Views/TableListView/ProjectTaskListView.h index d13facced..8e8848575 100755 --- a/Coding_iOS/Views/TableListView/ProjectTaskListView.h +++ b/Coding_iOS/Views/TableListView/ProjectTaskListView.h @@ -13,10 +13,18 @@ typedef void(^ProjectTaskBlock)(ProjectTaskListView *taskListView, Task *task); @interface ProjectTaskListView : UIView +@property (nonatomic, strong) NSString *keyword; +@property (nonatomic, strong) NSString *status; //任务状态,进行中的为1,已完成的为2 +@property (nonatomic, strong) NSString *label; //任务标签 +@property (nonatomic, strong) NSString *project_id; +@property (nonatomic, strong) NSString *userId; +@property (nonatomic, assign) TaskRoleType role; -- (id)initWithFrame:(CGRect)frame tasks:(Tasks *)tasks block:(ProjectTaskBlock)block tabBarHeight:(CGFloat)tabBarHeight; + +- (id)initWithFrame:(CGRect)frame tasks:(Tasks *)tasks project_id:(NSString *)project_id keyword:(NSString *)keyword status:(NSString *)status label:(NSString *)label userId:(NSString *)userId role:(TaskRoleType )role block:(ProjectTaskBlock)block tabBarHeight:(CGFloat)tabBarHeight; - (void)setTasks:(Tasks *)tasks; - (void)refreshToQueryData; - (void)tabBarItemClicked; - (void)reloadData; +- (void)refresh; @end diff --git a/Coding_iOS/Views/TableListView/ProjectTaskListView.m b/Coding_iOS/Views/TableListView/ProjectTaskListView.m index 142aa68e7..700c57b32 100755 --- a/Coding_iOS/Views/TableListView/ProjectTaskListView.m +++ b/Coding_iOS/Views/TableListView/ProjectTaskListView.m @@ -18,7 +18,7 @@ @interface ProjectTaskListView () @property (copy, nonatomic) ProjectTaskBlock block; @property (strong, nonatomic) UITableView *myTableView; @property (strong, nonatomic) ODRefreshControl *myRefreshControl; - +@property (nonatomic, assign) NSInteger page; @end @implementation ProjectTaskListView @@ -39,12 +39,21 @@ - (void)reloadData{ } } -- (id)initWithFrame:(CGRect)frame tasks:(Tasks *)tasks block:(ProjectTaskBlock)block tabBarHeight:(CGFloat)tabBarHeight{ +- (id)initWithFrame:(CGRect)frame tasks:(Tasks *)tasks project_id:(NSString *)project_id keyword:(NSString *)keyword status:(NSString *)status label:(NSString *)label userId:(NSString *)userId role:(TaskRoleType )role block:(ProjectTaskBlock)block tabBarHeight:(CGFloat)tabBarHeight{ self = [super initWithFrame:frame]; if (self) { // Initialization code _myTasks = tasks; _block = block; + _page = 1; + + self.project_id = project_id; + self.keyword = keyword; + self.status = status; + self.label = label; + self.userId = userId; + self.role = role; + _myTableView = ({ UITableView *tableView = [[UITableView alloc] initWithFrame:self.bounds style:UITableViewStylePlain]; @@ -62,6 +71,9 @@ - (id)initWithFrame:(CGRect)frame tasks:(Tasks *)tasks block:(ProjectTaskBlock)b tableView.contentInset = insets; tableView.scrollIndicatorInsets = insets; } + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); @@ -82,6 +94,8 @@ - (id)initWithFrame:(CGRect)frame tasks:(Tasks *)tasks block:(ProjectTaskBlock)b - (void)setTasks:(Tasks *)tasks{ if (_myTasks != tasks) { + self.userId = tasks.owner.id.stringValue; + self.project_id = tasks.project.id.stringValue; self.myTasks = tasks; [_myTableView reloadData]; [_myTableView.infiniteScrollingView stopAnimating]; @@ -106,6 +120,7 @@ - (void)refresh{ if (_myTasks.isLoading) { return; } + _page = 1; _myTasks.willLoadMore = NO; [self sendRequest]; } @@ -115,6 +130,7 @@ - (void)refreshMore{ [_myTableView.infiniteScrollingView stopAnimating]; return; } + _page++; _myTasks.willLoadMore = YES; [self sendRequest]; } @@ -124,7 +140,8 @@ - (void)sendRequest{ [self beginLoading]; } __weak typeof(self) weakSelf = self; - [[Coding_NetAPIManager sharedManager] request_ProjectTaskList_WithObj:_myTasks andBlock:^(Tasks *data, NSError *error) { + + [[Coding_NetAPIManager sharedManager] request_tasks_searchWithUserId:_userId role:_role project_id:_project_id keyword:_keyword status:_status label:_label page:_page andBlock:^(Tasks *data, NSError *error) { [weakSelf endLoading]; [weakSelf.myRefreshControl endRefreshing]; [weakSelf.myTableView.infiniteScrollingView stopAnimating]; @@ -136,6 +153,7 @@ - (void)sendRequest{ [weakSelf configBlankPage:EaseBlankPageTypeTask hasData:(weakSelf.myTasks.list.count > 0) hasError:(error != nil) reloadButtonBlock:^(id sender) { [weakSelf refresh]; }]; + }]; } @@ -223,7 +241,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath #pragma mark TableViewHeader - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ - return 20; + return 15; } - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ diff --git a/Coding_iOS/Views/TableListView/ProjectTasksView.h b/Coding_iOS/Views/TableListView/ProjectTasksView.h index 021ec5d9b..4278a798c 100755 --- a/Coding_iOS/Views/TableListView/ProjectTasksView.h +++ b/Coding_iOS/Views/TableListView/ProjectTasksView.h @@ -14,7 +14,18 @@ @interface ProjectTasksView : UIView + +@property (nonatomic, strong) NSString *keyword; +@property (nonatomic, strong) NSString *status; //任务状态,进行中的为1,已完成的为2 +@property (nonatomic, strong) NSString *label; //任务标签 +@property (nonatomic, strong) NSString *userId; +@property (nonatomic, assign) TaskRoleType role; +@property (nonatomic, strong) NSString *project_id; +@property (nonatomic, copy) void(^selctUserBlock)(NSString *owner); + - (id)initWithFrame:(CGRect)frame project:(Project *)project block:(ProjectTaskBlock)block defaultIndex:(NSInteger)index; - (void)refreshToQueryData; - (ProjectMember *)selectedMember; + +- (void)refresh; @end diff --git a/Coding_iOS/Views/TableListView/ProjectTasksView.m b/Coding_iOS/Views/TableListView/ProjectTasksView.m index 3c2a1b5fe..65d7276c7 100755 --- a/Coding_iOS/Views/TableListView/ProjectTasksView.m +++ b/Coding_iOS/Views/TableListView/ProjectTasksView.m @@ -20,6 +20,7 @@ @interface ProjectTasksView () @property (strong, nonatomic) XTSegmentControl *mySegmentControl; @property (strong, nonatomic) iCarousel *myCarousel; + @end @implementation ProjectTasksView @@ -29,6 +30,8 @@ - (id)initWithFrame:(CGRect)frame project:(Project *)project block:(ProjectTaskB if (self) { // Initialization code _myProject = project; + _role = TaskRoleTypeAll; + self.project_id = project.id.stringValue; _block = block; _myProTksDict = [[NSMutableDictionary alloc] initWithCapacity:1]; _myMemberList = [[NSMutableArray alloc] initWithObjects:[ProjectMember member_All], nil]; @@ -68,6 +71,7 @@ - (id)initWithFrame:(CGRect)frame project:(Project *)project block:(ProjectTaskB } }]; } + return self; } - (void)refreshToQueryData{ @@ -96,9 +100,13 @@ - (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index ProjectTaskListView *listView = (ProjectTaskListView *)view; if (listView) { + [self assignmentWithlistView:listView]; [listView setTasks:curTasks]; }else{ - listView = [[ProjectTaskListView alloc] initWithFrame:carousel.bounds tasks:curTasks block:_block tabBarHeight:0]; + if (_role == TaskRoleTypeOwner) { + _role = TaskRoleTypeAll; + } + listView = [[ProjectTaskListView alloc] initWithFrame:carousel.bounds tasks:curTasks project_id:_project_id keyword:_keyword status:_status label:_label userId:curTasks.owner.id.stringValue role:_role block:_block tabBarHeight:0]; } [listView setSubScrollsToTop:(index == carousel.currentItemIndex)]; return listView; @@ -116,9 +124,39 @@ - (void)carouselCurrentItemIndexDidChange:(iCarousel *)carousel{ if (_mySegmentControl) { _mySegmentControl.currentIndex = carousel.currentItemIndex; } + NSInteger index = carousel.currentItemIndex; + NSString *userId = nil; + if (index != 0) { + userId = ((ProjectMember *)_myMemberList[index]).user_id.stringValue; + } + _userId = userId; + if (_selctUserBlock) { + _selctUserBlock(_userId); + } + [self refresh]; + [carousel.visibleItemViews enumerateObjectsUsingBlock:^(UIView *obj, NSUInteger idx, BOOL *stop) { [obj setSubScrollsToTop:(obj == carousel.currentItemView)]; }]; } +- (void)assignmentWithlistView:(ProjectTaskListView *)listView { + listView.keyword = self.keyword; + listView.status = self.status; + listView.label = self.label; + listView.userId = self.userId; + listView.role = self.role; + listView.project_id = _project_id; +} + +- (void)refresh { + ProjectTaskListView *listView = (ProjectTaskListView *)self.myCarousel.currentItemView; + [self assignmentWithlistView:listView]; + [listView refresh]; + +} + + + + @end diff --git a/Coding_iOS/Views/TableListView/ProjectTopicListView.m b/Coding_iOS/Views/TableListView/ProjectTopicListView.m index 39f750718..2ffca9c50 100755 --- a/Coding_iOS/Views/TableListView/ProjectTopicListView.m +++ b/Coding_iOS/Views/TableListView/ProjectTopicListView.m @@ -48,6 +48,9 @@ - (id)initWithFrame:(CGRect)frame [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); diff --git a/Coding_iOS/Views/TableListView/ShopOrderListView.m b/Coding_iOS/Views/TableListView/ShopOrderListView.m index 2fb836b54..d4df2441c 100644 --- a/Coding_iOS/Views/TableListView/ShopOrderListView.m +++ b/Coding_iOS/Views/TableListView/ShopOrderListView.m @@ -11,11 +11,14 @@ #import "ODRefreshControl.h" #import "UIScrollView+SVInfiniteScrolling.h" #import "Coding_NetAPIManager.h" +#import "EAPayViewController.h" + +#import + +@interface ShopOrderListView () + +@property (strong, nonatomic) NSArray *dataSource; -@interface ShopOrderListView () -{ - NSArray *_dataSource; -} @property (nonatomic, strong) UITableView *myTableView; @property (nonatomic, strong) ShopOderCell *currentOrderCell; @@ -35,14 +38,17 @@ - (instancetype)initWithFrame:(CGRect)frame withOder:(ShopOrderModel *)order tableView.backgroundColor = kColorTableSectionBg; tableView.delegate = self; tableView.dataSource = self; - tableView.estimatedRowHeight = 690/2; +// tableView.estimatedRowHeight = 690/2; [tableView registerClass:[ShopOderCell class] forCellReuseIdentifier:@"ShopOderCell"]; tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; - tableView.separatorColor = [UIColor colorWithHexString:@"0xC8C8C8"]; + tableView.separatorColor = kColorDDD; [self addSubview:tableView]; [tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self); }]; + tableView.estimatedRowHeight = 0; + tableView.estimatedSectionHeaderHeight = 0; + tableView.estimatedSectionFooterHeight = 0; tableView; }); @@ -92,9 +98,11 @@ - (void)reloadData - (void)refresh { - [self.myRefreshControl endRefreshing]; - -// [self loadData]; + if (_myOrder.isLoading) { + return; + } + _myOrder.willLoadMore = NO; + [self sendRequest]; } - (void)refreshMore @@ -104,60 +112,34 @@ - (void)refreshMore return; } _myOrder.willLoadMore = YES; + _myOrder.page = @(_myOrder.page.intValue +1); [self sendRequest]; } - (void)sendRequest { -// __weak typeof(self) weakSelf = self; -// [[Coding_NetAPIManager sharedManager] request_Comments_WithProjectTpoic:self. andBlock:^(id data, NSError *error) { -// [weakSelf.refreshControl endRefreshing]; -// [weakSelf.myTableView.infiniteScrollingView stopAnimating]; -// if (data) { -// [weakSelf.curTopic configWithComments:data]; -// weakSelf.myTableView.showsInfiniteScrolling = weakSelf.curTopic.canLoadMore; -// } -// [weakSelf.myTableView reloadData]; -// }]; - __weak typeof(self) weakSelf = self; - _myOrder.page = @(_myOrder.page.intValue +1); [[Coding_NetAPIManager sharedManager] request_shop_OrderListWithOrder:_myOrder andBlock:^(id data, NSError *error) { [weakSelf.myRefreshControl endRefreshing]; [weakSelf endLoading]; [weakSelf.myTableView.infiniteScrollingView stopAnimating]; - if (data) { - _dataSource = [_myOrder getDataSourceByOrderType]; + + weakSelf.dataSource = [weakSelf.myOrder getDataSourceByOrderType]; + if (weakSelf.myTableView.contentOffset.y < 0) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [weakSelf.myTableView reloadData]; + }); + }else{ [weakSelf.myTableView reloadData]; } -// [weakSelf configBlankPage:EaseBlankPageTypeTopic hasData:(weakSelf.myOrder.dateSource.count > 0) hasError:(error != nil) reloadButtonBlock:^(id sender) { -// [weakSelf refresh]; -// }]; - }]; - } -//- (void)loadData -//{ -// __weak typeof(self) weakSelf = self; -// -// [[Coding_NetAPIManager sharedManager] request_shop_OrderListWithOrder:_myOrder andBlock:^(id data, NSError *error) { -// [weakSelf.myRefreshControl endRefreshing]; -// [weakSelf endLoading]; -// [weakSelf.myTableView.infiniteScrollingView stopAnimating]; -// if (data) { -// _dataSource = [_myOrder getDataSourceByOrderType]; -// [weakSelf.myTableView reloadData]; -// } -// [weakSelf configBlankPage:EaseBlankPageTypeTopic hasData:(weakSelf.myOrder.dateSource.count > 0) hasError:(error != nil) reloadButtonBlock:^(id sender) { -// [weakSelf refresh]; -// }]; -// -// }]; +//- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{//sendRequest 中刷新,会跳帧 +// self.dataSource = [self.myOrder getDataSourceByOrderType]; +// [self.myTableView reloadData]; //} - #pragma mark Table M - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView @@ -195,14 +177,42 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N ShopOrder *item = [_dataSource objectAtIndex:indexPath.section]; ShopOderCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ShopOderCell" forIndexPath:indexPath]; + __weak typeof(self) weakSelf = self; + cell.deleteActionBlock = ^{ + [weakSelf deleteOrder:item]; + }; + cell.payActionBlock = ^{ + [weakSelf payOrder:item]; + }; [cell configViewWithModel:item]; return cell; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ [tableView deselectRowAtIndexPath:indexPath animated:YES]; -// ShopOrder *item = [_dataSource objectAtIndex:indexPath.row]; - +} + +- (void)deleteOrder:(ShopOrder *)order{ + __weak typeof(self) weakSelf = self; + [[UIAlertController ea_actionSheetCustomWithTitle:@"确定要取消此订单吗?" buttonTitles:nil destructiveTitle:@"确定取消" cancelTitle:@"取消" andDidDismissBlock:^(UIAlertAction *action, NSInteger index) { + if (index == 0) { + [NSObject showHUDQueryStr:@"正在取消订单"]; + [[Coding_NetAPIManager sharedManager] request_shop_deleteOrder:order.orderNo andBlock:^(id data, NSError *error) { + [NSObject hideHUDQuery]; + if (data) { + [NSObject showHudTipStr:@"订单已取消"]; + [weakSelf.myOrder.dateSource removeObject:order]; + [weakSelf reloadData]; + } + }]; + } + }] showInView:self]; +} + +- (void)payOrder:(ShopOrder *)order{ + EAPayViewController *vc = [EAPayViewController new]; + vc.shopOrder = order; + [BaseViewController goToVC:vc]; } - (void)dealloc diff --git a/Coding_iOS/Views/TableListView/WikiMenuListView.h b/Coding_iOS/Views/TableListView/WikiMenuListView.h new file mode 100644 index 000000000..5fb17ca6b --- /dev/null +++ b/Coding_iOS/Views/TableListView/WikiMenuListView.h @@ -0,0 +1,18 @@ +// +// WikiMenuListView.h +// Coding_Enterprise_iOS +// +// Created by Ease on 2017/4/5. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import +#import "EAWiki.h" + +@interface WikiMenuListView : UIView +@property (copy, nonatomic) void(^selectedWikiBlock)(EAWiki *wiki); + +- (void)setWikiList:(NSArray *)wikiList selectedWiki:(EAWiki *)selectedWiki; +- (void)show; +- (void)dismiss; +@end diff --git a/Coding_iOS/Views/TableListView/WikiMenuListView.m b/Coding_iOS/Views/TableListView/WikiMenuListView.m new file mode 100644 index 000000000..f7b21b9eb --- /dev/null +++ b/Coding_iOS/Views/TableListView/WikiMenuListView.m @@ -0,0 +1,162 @@ +// +// WikiMenuListView.m +// Coding_Enterprise_iOS +// +// Created by Ease on 2017/4/5. +// Copyright © 2017年 Coding. All rights reserved. +// +#define kWikiMenuListView_LeftPadding 30 + +#import "WikiMenuListView.h" +#import "WikiMenuListCell.h" + +@interface WikiMenuListView () +@property (strong, nonatomic) NSArray *wikiList; +@property (strong, nonatomic) EAWiki *selectedWiki; + +@property (strong, nonatomic) UIView *contentView; +@property (strong, nonatomic) UITableView *myTableView; +@end + +@implementation WikiMenuListView + +- (instancetype)init{ + self = [super init]; + if (self) { + self.frame = kScreen_Bounds; + _contentView = [[UIView alloc] initWithFrame:CGRectMake(-(self.width - kWikiMenuListView_LeftPadding), 0, self.width - kWikiMenuListView_LeftPadding, self.height)]; + _contentView.backgroundColor = [UIColor whiteColor]; + [self addSubview:_contentView]; + //Nav + CGFloat navHeight = 64.0; + UIView *navV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, _contentView.width, navHeight)]; + [navV addLineUp:NO andDown:YES]; + navV.clipsToBounds = YES; + UILabel *navL = [UILabel labelWithFont:[UIFont systemFontOfSize:kNavTitleFontSize] textColor:kColorNavTitle]; + navL.text = @"目录"; + [navV addSubview:navL]; + [navL mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(navV); + make.bottom.equalTo(navV).offset(-10); + }]; + [_contentView addSubview:navV]; + [navV mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.left.right.equalTo(_contentView); + make.height.mas_equalTo(navHeight); + }]; + //TableView + _myTableView = ({ + UITableView *tableView = [[UITableView alloc] init]; + tableView.backgroundColor = [UIColor clearColor]; + tableView.delegate = self; + tableView.dataSource = self; + [tableView registerClass:[WikiMenuListCell class] forCellReuseIdentifier:kCellIdentifier_WikiMenuListCellLavel(0)]; + tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + [_contentView addSubview:tableView]; + [tableView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(_contentView).insets(UIEdgeInsetsMake(navHeight, 0, 0, 0)); + }]; + tableView; + }); + //PanGesture + UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)]; + [_contentView addGestureRecognizer:pan]; + //RACObserve + __weak typeof(self) weakSelf = self; + [RACObserve(self.contentView, frame) subscribeNext:^(NSValue *frameV) { + CGFloat alpha = 0.3; + alpha *= fabs(CGRectGetMinX(frameV.CGRectValue) + _contentView.width)/_contentView.width; + weakSelf.backgroundColor = [UIColor colorWithWhite:0 alpha:alpha]; + }]; + //Tap + UIView *tapV = [UIView new]; + [self addSubview:tapV]; + [tapV mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.right.bottom.equalTo(self); + make.width.mas_equalTo(kWikiMenuListView_LeftPadding); + }]; + [tapV bk_whenTapped:^{ + [weakSelf dismiss]; + }]; + + } + return self; +} + +- (void)setWikiList:(NSArray *)wikiList selectedWiki:(EAWiki *)selectedWiki{ + _wikiList = wikiList; + _selectedWiki = selectedWiki; + + [_myTableView reloadData]; +} + +- (void)handlePanGesture:(UIPanGestureRecognizer*)pan{ + if (pan.state == UIGestureRecognizerStateChanged) { + CGPoint diffP = [pan translationInView:_contentView]; + CGFloat contentX = MIN(diffP.x, 0); + _contentView.x = contentX; + }else if (pan.state == UIGestureRecognizerStateEnded) { + CGPoint velocity = [pan velocityInView:_contentView]; + if (velocity.x < 0) { + [self dismiss]; + }else{ + [self show]; + } + } +} + +- (void)show{ + [kKeyWindow addSubview:self]; + NSTimeInterval duration = .3 * (fabs(_contentView.x)/_contentView.width); + [UIView animateWithDuration:duration animations:^{ + _contentView.x = 0; + }]; +} + +- (void)dismiss{ + NSTimeInterval duration = .3 * (fabs(_contentView.x + _contentView.width)/_contentView.width); + [UIView animateWithDuration:duration animations:^{ + _contentView.x = -_contentView.width; + } completion:^(BOOL finished) { + [self removeFromSuperview]; + }]; +} + +#pragma mark Table +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + return _wikiList.count; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ + return [WikiMenuListCell cellHeightWithObj:_wikiList[indexPath.row]]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + WikiMenuListCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_WikiMenuListCellLavel(0) forIndexPath:indexPath]; + [cell setCurWiki:_wikiList[indexPath.row] selectedWiki:_selectedWiki]; + __weak typeof(self) weakSelf = self; + cell.expandBlock = ^(EAWiki *wiki){ + wiki.isExpanded = !wiki.isExpanded; + [weakSelf.myTableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; + }; + cell.selectedWikiBlock = ^(EAWiki *wiki){ + [weakSelf handleSelectedWiki:wiki]; + }; + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + [self handleSelectedWiki:_wikiList[indexPath.row]]; +} + +- (void)handleSelectedWiki:(EAWiki *)wiki{ + _selectedWiki = wiki; + if (_selectedWikiBlock) { + _selectedWikiBlock(wiki); + } + [self dismiss]; +} + + +@end diff --git a/Coding_iOS/Views/TagsScrollView.h b/Coding_iOS/Views/TagsScrollView.h new file mode 100644 index 000000000..7ea128b02 --- /dev/null +++ b/Coding_iOS/Views/TagsScrollView.h @@ -0,0 +1,15 @@ +// +// TagsScrollView.h +// Coding_iOS +// +// Created by 张达棣 on 16/11/29. +// Copyright © 2016年 Coding. All rights reserved. +// + +#import + +@interface TagsScrollView : UIScrollView + +@property (nonatomic, copy) NSString *tags; + +@end diff --git a/Coding_iOS/Views/TagsScrollView.m b/Coding_iOS/Views/TagsScrollView.m new file mode 100644 index 000000000..a2aebc84d --- /dev/null +++ b/Coding_iOS/Views/TagsScrollView.m @@ -0,0 +1,82 @@ +// +// TagsScrollView.h +// Coding_iOS +// +// Created by 张达棣 on 16/11/29. +// Copyright © 2016年 Coding. All rights reserved. +// + + +#import "TagsScrollView.h" +#import "UIView+SDAutoLayout.h" + +@interface TagsScrollView () +@property (nonatomic, strong) NSMutableArray *signatureLabelArray; +@end + +@implementation TagsScrollView + + + +#pragma mark - 生命周期方法 + +- (instancetype)init { + self = [super init]; + if (self) { + [self creatView]; + } + return self; +} + +- (void)awakeFromNib { + [super awakeFromNib]; + [self creatView]; +} + +#pragma mark - 外部方法 + +#pragma makr - 消息 + +#pragma mark - 系统委托 + +#pragma mark - 自定义委托 + +#pragma mark - 响应方法 + +#pragma mark - 私有方法 + +- (void)creatView { + _signatureLabelArray = [NSMutableArray array]; + self.showsHorizontalScrollIndicator = NO; +} + +#pragma mark - get/set方法 + +- (void)setTags:(NSString *)tags { + _tags = tags; + + NSArray *signatureArray = [tags componentsSeparatedByString:@","]; + for (int i = 0; i < signatureArray.count; i++) { + UILabel *_signatureLabel; + if (i < _signatureLabelArray.count) { + _signatureLabel = _signatureLabelArray[i]; + [_signatureLabel removeFromSuperview]; + } else { + _signatureLabel = [[UILabel alloc] init]; + _signatureLabel.textColor = [UIColor colorWithRGBHex:0x76808e]; + _signatureLabel.cornerRadius = 2; + _signatureLabel.backgroundColor = [UIColor colorWithRGBHex:0xf2f4f6]; + _signatureLabel.font = [UIFont systemFontOfSize:12]; + [_signatureLabelArray addObject:_signatureLabel]; + } + _signatureLabel.text = [NSString stringWithFormat:@" %@ ", signatureArray[i]]; + [self addSubview:_signatureLabel]; + _signatureLabel.sd_layout.centerYEqualToView(self).heightIs(self.frame.size.height); + [_signatureLabel setSingleLineAutoResizeWithMaxWidth:300]; + } + [self setupAutoWidthFlowItems:[_signatureLabelArray copy] withPerRowItemsCount:_signatureLabelArray.count verticalMargin:0 horizontalMargin:8]; + [self setupAutoContentSizeWithRightView:_signatureLabelArray[_signatureLabelArray.count - 1] rightMargin:4]; + +} + +@end diff --git a/Coding_iOS/Views/TaskSelectionView.h b/Coding_iOS/Views/TaskSelectionView.h new file mode 100644 index 000000000..48c11f221 --- /dev/null +++ b/Coding_iOS/Views/TaskSelectionView.h @@ -0,0 +1,25 @@ +// +// TaskSelectionView.h +// Coding_iOS +// +// Created by 张达棣 on 16/12/4. +// Copyright © 2016年 Coding. All rights reserved. +// + +#import + +@interface TaskSelectionView : UIView + +@property (assign) BOOL showStatus; +@property (nonatomic , copy) void (^clickBlock)(NSInteger selectNum); +@property (nonatomic , copy) void (^closeBlock)(); +@property (nonatomic, strong) NSArray *items; +- (instancetype)initWithFrame:(CGRect)frame items:(NSArray *)items; +//将菜单显示到某个视图上 +- (void)showMenuAtView:(UIView *)containerView; +//取消视图 +- (void)dismissMenu; +- (void)refreshMenuDate; + + +@end diff --git a/Coding_iOS/Views/TaskSelectionView.m b/Coding_iOS/Views/TaskSelectionView.m new file mode 100644 index 000000000..e7e45a70a --- /dev/null +++ b/Coding_iOS/Views/TaskSelectionView.m @@ -0,0 +1,176 @@ +// +// TaskSelectionView.m +// Coding_iOS +// +// Created by 张达棣 on 16/12/4. +// Copyright © 2016年 Coding. All rights reserved. +// + +#define kfirstRowNum 3 + +#import "TaskSelectionView.h" +#import "XHRealTimeBlur.h" +#import "Coding_NetAPIManager.h" +#import "ProjectCount.h" +#import "Projects.h" +#import "pop.h" +#import "TaskSelectionCell.h" + +@interface TaskSelectionView() +@property (nonatomic, strong) XHRealTimeBlur *realTimeBlur; +@property (nonatomic, strong) UITableView *tableview; +@property (nonatomic, strong) ProjectCount *pCount; +@property (nonatomic, assign) NSInteger selectNum; //选中数据 + +@end + +@implementation TaskSelectionView + +- (id)initWithFrame:(CGRect)frame items:(NSArray *)items { + self = [super initWithFrame:frame]; + if (self) { + // Initialization code + self.items = items; + self.pCount=[ProjectCount new]; + self.showStatus= NO; + [self setup]; + } + return self; +} + +- (void)refreshMenuDate +{ + __weak typeof(self) weakSelf = self; + [[Coding_NetAPIManager sharedManager] request_ProjectsCatergoryAndCounts_WithObj:_pCount andBlock:^(ProjectCount *data, NSError *error) { + if (data) { + [weakSelf.pCount configWithProjects:data]; + [weakSelf.tableview reloadData]; + } + if(error) + { + NSLog(@"get count error"); + } + }]; +} + +// 设置属性 +- (void)setup { + self.backgroundColor = [UIColor clearColor]; + + _realTimeBlur = [[XHRealTimeBlur alloc] initWithFrame:self.bounds]; + _realTimeBlur.clipsToBounds = YES; + _realTimeBlur.blurStyle = XHBlurStyleTranslucentWhite; + _realTimeBlur.showDuration = 0.1; + _realTimeBlur.disMissDuration = 0.2; + typeof(self) __weak weakSelf = self; + + _realTimeBlur.willShowBlurViewcomplted = ^(void) { + POPBasicAnimation *alphaAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewAlpha]; + alphaAnimation.fromValue = @0.0; + alphaAnimation.toValue = @1.0; + alphaAnimation.duration = 0.3f; + [weakSelf.tableview pop_addAnimation:alphaAnimation forKey:@"alphaAnimationS"]; + }; + + _realTimeBlur.willDismissBlurViewCompleted = ^(void) { + POPBasicAnimation *alphaAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewAlpha]; + alphaAnimation.fromValue = @1.0; + alphaAnimation.toValue = @0.0; + alphaAnimation.duration = 0.2f; + [weakSelf.tableview pop_addAnimation:alphaAnimation forKey:@"alphaAnimationE"]; + }; + + _realTimeBlur.didDismissBlurViewCompleted = ^(BOOL finished) { + [weakSelf removeFromSuperview]; + }; + + + _realTimeBlur.hasTapGestureEnable = YES; + + _tableview = ({ + UITableView *tableview=[[UITableView alloc] initWithFrame:self.bounds]; + tableview.backgroundColor=[UIColor clearColor]; + tableview.delegate=self; + tableview.dataSource=self; + [tableview registerClass:[TaskSelectionCell class] forCellReuseIdentifier:kCellIdentifier_TaskSelectionCell]; + tableview.tableFooterView=[UIView new]; + tableview.separatorStyle=UITableViewCellSeparatorStyleNone; + tableview.estimatedRowHeight = 0; + tableview.estimatedSectionHeaderHeight = 0; + tableview.estimatedSectionFooterHeight = 0; + tableview; + }); + [self addSubview:_tableview]; + _tableview.contentInset=UIEdgeInsetsMake(15, 0,0,0); + + + int contentHeight=100; + if ((kScreen_Height-64)>contentHeight) { + UIView *contentView=[[UIView alloc] initWithFrame:CGRectMake(0,64+contentHeight , kScreen_Width, kScreen_Height-64-contentHeight)]; + contentView.backgroundColor=[UIColor clearColor]; + [self addSubview:contentView]; + UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didClickedContentView:)]; + [contentView addGestureRecognizer:tapGestureRecognizer]; + } +} + +#pragma mark -- event & action +- (void)showMenuAtView:(UIView *)containerView { + _showStatus= YES; + [containerView addSubview:self]; + [_realTimeBlur showBlurViewAtView:self]; + [_tableview reloadData]; +} + +- (void)dismissMenu +{ + UIView *presentView=[[[UIApplication sharedApplication].keyWindow rootViewController] view]; + if ([[presentView.subviews firstObject] isMemberOfClass:NSClassFromString(@"RDVTabBar")]) { + [presentView bringSubviewToFront:[presentView.subviews firstObject]]; + } + _showStatus= NO; + [_realTimeBlur disMiss]; +} + + +#pragma mark -- uitableviewdelegate & datasource +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + return _items.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + TaskSelectionCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier_TaskSelectionCell forIndexPath:indexPath]; + cell.title = _items[indexPath.row]; + cell.isSel = indexPath.row==_selectNum; + + return cell; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ + return ((indexPath.row==0)&&(indexPath.section==1))||((indexPath.row==0)&&(indexPath.section==2))?30.5:50; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + _selectNum=indexPath.row; + [self dismissMenu]; + _clickBlock(indexPath.row); + [tableView deselectRowAtIndexPath:indexPath animated:YES]; +} + +- (void)didClickedContentView:(UIGestureRecognizer *)sender { + _closeBlock(); +} + + +- (void)setItems:(NSArray *)items { + _items = items; + [_tableview reloadData]; +} + +@end diff --git a/Coding_iOS/Views/UIMessageInputView/UIMessageInputView.h b/Coding_iOS/Views/UIMessageInputView/UIMessageInputView.h index c59e72316..c57ebaffa 100755 --- a/Coding_iOS/Views/UIMessageInputView/UIMessageInputView.h +++ b/Coding_iOS/Views/UIMessageInputView/UIMessageInputView.h @@ -43,6 +43,7 @@ typedef NS_ENUM(NSInteger, UIMessageInputViewState) { - (BOOL)notAndBecomeFirstResponder; - (BOOL)isAndResignFirstResponder; - (BOOL)isCustomFirstResponder; +- (CGFloat)heightWithSafeArea; @end @protocol UIMessageInputViewDelegate diff --git a/Coding_iOS/Views/UIMessageInputView/UIMessageInputView.m b/Coding_iOS/Views/UIMessageInputView/UIMessageInputView.m index d33902c1a..5e1f530f0 100755 --- a/Coding_iOS/Views/UIMessageInputView/UIMessageInputView.m +++ b/Coding_iOS/Views/UIMessageInputView/UIMessageInputView.m @@ -53,7 +53,6 @@ @interface UIMessageInputView () 0.1) { + if (fabs(oldheightToBottom - newheightToBottom) > 1.0) { DebugLog(@"heightToBottom-----:%.2f", newheightToBottom); if (oldheightToBottom > newheightToBottom) {//降下去的时候保存 [self saveInputStr]; @@ -83,6 +82,13 @@ - (void)setFrame:(CGRect)frame{ } } +- (void)p_setY:(CGFloat)y{ + if (ABS(kScreen_Height - CGRectGetHeight(self.frame) - y) < 1.0) { + y -= kSafeArea_Bottom; + } + [self setY:y]; +} + - (void)setInputState:(UIMessageInputViewState)inputState{ if (_inputState != inputState) { _inputState = inputState; @@ -160,6 +166,15 @@ - (id)initWithFrame:(CGRect)frame _curProject = nil; UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(didPan:)]; [self addGestureRecognizer:panGesture]; + //补个底色背景 + UIView *bottomV = [UIView new]; + bottomV.backgroundColor = self.backgroundColor; + [self addSubview:bottomV]; + [bottomV mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(kSafeArea_Bottom + kKeyboardView_Height); + make.top.equalTo(self.mas_bottom); + make.left.right.equalTo(self); + }]; } return self; } @@ -287,7 +302,7 @@ - (void)prepareToShow{ if ([self superview] == kKeyWindow) { return; } - [self setY:kScreen_Height]; + [self p_setY:kScreen_Height]; [kKeyWindow addSubview:self]; [kKeyWindow addSubview:_emojiKeyboardView]; [kKeyWindow addSubview:_addKeyboardView]; @@ -296,7 +311,7 @@ - (void)prepareToShow{ if (_isAlwaysShow && ![self isCustomFirstResponder]) { [UIView animateWithDuration:0.25 animations:^{ - [self setY:kScreen_Height - CGRectGetHeight(self.frame)]; + [self p_setY:kScreen_Height - CGRectGetHeight(self.frame)]; }]; } } @@ -306,7 +321,7 @@ - (void)prepareToDismiss{ } [self isAndResignFirstResponder]; [UIView animateWithDuration:0.25 delay:0.0 options:UIViewAnimationOptionTransitionFlipFromBottom animations:^{ - [self setY:kScreen_Height]; + [self p_setY:kScreen_Height]; } completion:^(BOOL finished) { [_emojiKeyboardView removeFromSuperview]; [_addKeyboardView removeFromSuperview]; @@ -331,9 +346,9 @@ - (BOOL)isAndResignFirstResponder{ [_addKeyboardView setY:kScreen_Height]; [_voiceKeyboardView setY:kScreen_Height]; if (self.isAlwaysShow) { - [self setY:kScreen_Height- CGRectGetHeight(self.frame)]; + [self p_setY:kScreen_Height- CGRectGetHeight(self.frame)]; }else{ - [self setY:kScreen_Height]; + [self p_setY:kScreen_Height]; } } completion:^(BOOL finished) { self.inputState = UIMessageInputViewStateSystem; @@ -353,6 +368,10 @@ - (BOOL)isCustomFirstResponder{ return ([_inputTextView isFirstResponder] || self.inputState == UIMessageInputViewStateAdd || self.inputState == UIMessageInputViewStateEmotion || self.inputState == UIMessageInputViewStateVoice); } +- (CGFloat)heightWithSafeArea{ + return CGRectGetHeight(self.frame) + kSafeArea_Bottom; +} + + (instancetype)messageInputViewWithType:(UIMessageInputViewContentType)type{ return [self messageInputViewWithType:type placeHolder:nil]; } @@ -394,7 +413,7 @@ - (void)customUIWithType:(UIMessageInputViewContentType)type{ hasAddBtn = YES; hasPhotoBtn = NO; showBigEmotion = YES; - hasVoiceBtn = YES; + hasVoiceBtn = [NSObject isPrivateCloud].boolValue? NO: YES; } break; case UIMessageInputViewContentTypeTopic: @@ -524,14 +543,6 @@ - (void)customUIWithType:(UIMessageInputViewContentType)type{ [_voiceButton setImage:[UIImage imageNamed:@"keyboard_voice"] forState:UIControlStateNormal]; [_voiceButton addTarget:self action:@selector(voiceButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:_voiceButton]; - - if ([[FunctionTipsManager shareManager] needToTip:kFunctionTipStr_VoiceMessage]) { - _voiceRedpointView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 7, 7)]; - _voiceRedpointView.center = CGPointMake(31, 5); - _voiceRedpointView.backgroundColor = [UIColor colorWithRGBHex:0xf75288]; - _voiceRedpointView.layer.cornerRadius = _voiceRedpointView.frame.size.width/2; - [_voiceButton addSubview:_voiceRedpointView]; - } } _voiceButton.hidden = !hasVoiceBtn; @@ -659,26 +670,17 @@ - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPa // 显示大图 int count = (int)_mediaList.count; NSMutableArray *photos = [NSMutableArray arrayWithCapacity:count]; - - ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init]; for (int i = 0; i 0.1) { - [self setY:endY- CGRectGetHeight(self.frame)]; + if (ABS(kScreen_Height - endY) > 1.0) { + [self p_setY:endY- CGRectGetHeight(self.frame)]; } } completion:^(BOOL finished) { }]; @@ -717,14 +719,14 @@ - (void)emotionButtonClicked:(id)sender{ }else{ self.inputState = UIMessageInputViewStateEmotion; [_inputTextView resignFirstResponder]; - endY = kScreen_Height - kKeyboardView_Height; + endY = kScreen_Height - kKeyboardView_Height - kSafeArea_Bottom; } [UIView animateWithDuration:0.25 delay:0.0f options:UIViewAnimationOptionTransitionFlipFromBottom animations:^{ [_emojiKeyboardView setY:endY]; [_addKeyboardView setY:kScreen_Height]; [_voiceKeyboardView setY:kScreen_Height]; - if (ABS(kScreen_Height - endY) > 0.1) { - [self setY:endY- CGRectGetHeight(self.frame)]; + if (ABS(kScreen_Height - endY) > 1.0) { + [self p_setY:endY- CGRectGetHeight(self.frame)]; } } completion:^(BOOL finished) { }]; @@ -736,12 +738,11 @@ - (void)photoButtonClicked:(id)sender{ } [self isAndResignFirstResponder]; QBImagePickerController *imagePickerController = [[QBImagePickerController alloc] init]; - imagePickerController.filterType = QBImagePickerControllerFilterTypePhotos; + imagePickerController.mediaType = QBImagePickerMediaTypeImage; imagePickerController.delegate = self; imagePickerController.allowsMultipleSelection = YES; imagePickerController.maximumNumberOfSelection = 6; - UINavigationController *navigationController = [[BaseNavigationController alloc] initWithRootViewController:imagePickerController]; - [[BaseViewController presentingVC] presentViewController:navigationController animated:YES completion:^{ + [[BaseViewController presentingVC] presentViewController:imagePickerController animated:YES completion:^{ }]; } @@ -753,24 +754,17 @@ - (void)voiceButtonClicked:(id)sender { } else { self.inputState = UIMessageInputViewStateVoice; [_inputTextView resignFirstResponder]; - endY = kScreen_Height - kKeyboardView_Height; + endY = kScreen_Height - kKeyboardView_Height - kSafeArea_Bottom; } [UIView animateWithDuration:0.25 delay:0.0f options:UIViewAnimationOptionTransitionFlipFromBottom animations:^{ [_voiceKeyboardView setY:endY]; [_emojiKeyboardView setY:kScreen_Height]; [_addKeyboardView setY:kScreen_Height]; - if (ABS(kScreen_Height - endY) > 0.1) { - [self setY:endY- CGRectGetHeight(self.frame)]; + if (ABS(kScreen_Height - endY) > 1.0) { + [self p_setY:endY- CGRectGetHeight(self.frame)]; } } completion:^(BOOL finished) { }]; - - if (_voiceRedpointView) { - [_voiceRedpointView removeFromSuperview]; - self.voiceRedpointView = nil; - - [[FunctionTipsManager shareManager] markTiped:kFunctionTipStr_VoiceMessage]; - } } - (void)arrowButtonClicked:(id)sender { @@ -778,10 +772,10 @@ - (void)arrowButtonClicked:(id)sender { } #pragma mark QBImagePickerControllerDelegate -- (void)qb_imagePickerController:(QBImagePickerController *)imagePickerController didSelectAssets:(NSArray *)assets{ +- (void)qb_imagePickerController:(QBImagePickerController *)imagePickerController didFinishPickingAssets:(NSArray *)assets{ _uploadMediaList = [[NSMutableArray alloc] initWithCapacity:assets.count]; - for (ALAsset *asset in assets) { + for (PHAsset *asset in assets) { [_uploadMediaList addObject:[UIMessageInputView_Media mediaWithAsset:asset urlStr:nil]]; } [self doUploadMediaList]; @@ -811,7 +805,7 @@ - (void)doUploadMediaList{ - (void)doUploadMedia:(UIMessageInputView_Media *)media withIndex:(NSInteger)index{ //保存到app内 - NSString* originalFileName = [[media.curAsset defaultRepresentation] filename]; + NSString* originalFileName = media.curAsset.fileName;; NSString *fileName = [NSString stringWithFormat:@"%@|||%@|||%@", self.curProject.id.stringValue, @"0", originalFileName]; if ([Coding_FileManager writeUploadDataWithName:fileName andAsset:media.curAsset]) { @@ -960,9 +954,9 @@ - (BOOL)textViewShouldEndEditing:(UITextView *)textView{ if (self.inputState == UIMessageInputViewStateSystem) { [UIView animateWithDuration:0.25 delay:0.0f options:UIViewAnimationOptionTransitionFlipFromBottom animations:^{ if (_isAlwaysShow) { - [self setY:kScreen_Height- CGRectGetHeight(self.frame)]; + [self p_setY:kScreen_Height- CGRectGetHeight(self.frame)]; }else{ - [self setY:kScreen_Height]; + [self p_setY:kScreen_Height]; } } completion:^(BOOL finished) { }]; @@ -979,24 +973,13 @@ - (void)keyboardChange:(NSNotification*)aNotification{ CGRect keyboardEndFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; CGFloat keyboardY = keyboardEndFrame.origin.y; - CGFloat selfOriginY = keyboardY == kScreen_Height? self.isAlwaysShow? kScreen_Height - CGRectGetHeight(self.frame): kScreen_Height : keyboardY - CGRectGetHeight(self.frame); -// if (keyboardY == kScreen_Height) { -// if (self.isAlwaysShow) { -// selfOriginY = kScreen_Height- CGRectGetHeight(self.frame); -// }else{ -// selfOriginY = kScreen_Height; -// } -// }else{ -// selfOriginY = keyboardY-CGRectGetHeight(self.frame); -// } + CGFloat selfOriginY = keyboardY+1 > kScreen_Height? self.isAlwaysShow? kScreen_Height - CGRectGetHeight(self.frame): kScreen_Height : keyboardY - CGRectGetHeight(self.frame); if (selfOriginY == self.frame.origin.y) { return; } - - __weak typeof(self) weakSelf = self; void (^endFrameBlock)() = ^(){ - [weakSelf setY:selfOriginY]; + [weakSelf p_setY:selfOriginY]; }; if ([aNotification name] == UIKeyboardWillChangeFrameNotification) { NSTimeInterval animationDuration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; @@ -1014,9 +997,8 @@ - (void)keyboardChange:(NSNotification*)aNotification{ - (void)emojiKeyBoardView:(AGEmojiKeyboardView *)emojiKeyBoardView didUseEmoji:(NSString *)emoji { - NSString *emotion_monkey = [emoji emotionMonkeyName]; + NSString *emotion_monkey = [emoji emotionSpecailName]; if (emotion_monkey) { - emotion_monkey = [NSString stringWithFormat:@" :%@: ", emotion_monkey]; if (_delegate && [_delegate respondsToSelector:@selector(messageInputView:sendBigEmotion:)]) { [self.delegate messageInputView:self sendBigEmotion:emotion_monkey]; } @@ -1034,14 +1016,10 @@ - (void)emojiKeyBoardViewDidPressSendButton:(AGEmojiKeyboardView *)emojiKeyBoard } - (UIImage *)emojiKeyboardView:(AGEmojiKeyboardView *)emojiKeyboardView imageForSelectedCategory:(AGEmojiKeyboardViewCategoryImage)category { - UIImage *img; - if (category == AGEmojiKeyboardViewCategoryImageEmoji) { - img = [UIImage imageNamed:@"keyboard_emotion_emoji"]; - }else if (category == AGEmojiKeyboardViewCategoryImageMonkey){ - img = [UIImage imageNamed:@"keyboard_emotion_monkey"]; - }else{ - img = [UIImage imageNamed:@"keyboard_emotion_monkey_gif"]; - } + UIImage *img = [UIImage imageNamed:(category == AGEmojiKeyboardViewCategoryImageEmoji? @"keyboard_emotion_emoji": + category == AGEmojiKeyboardViewCategoryImageMonkey? @"keyboard_emotion_monkey": + category == AGEmojiKeyboardViewCategoryImageMonkey_Gif? @"keyboard_emotion_monkey_gif": + @"keyboard_emotion_emoji_code")] ?: [UIImage new]; return img; } diff --git a/Coding_iOS/Views/UIMessageInputView/UIMessageInputView_CCell.m b/Coding_iOS/Views/UIMessageInputView/UIMessageInputView_CCell.m index 4e94623f2..05785b864 100644 --- a/Coding_iOS/Views/UIMessageInputView/UIMessageInputView_CCell.m +++ b/Coding_iOS/Views/UIMessageInputView/UIMessageInputView_CCell.m @@ -44,30 +44,11 @@ - (void)setCurMedia:(UIMessageInputView_Media *)curMedia andTotalCount:(NSIntege if (_media != curMedia) { _media = curMedia; - - ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init]; - dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); - dispatch_queue_t queue = dispatch_queue_create("UIMessageInputView_CCellForAsset", DISPATCH_QUEUE_SERIAL); - dispatch_async(queue, ^{ - [assetsLibrary assetForURL:_media.assetURL resultBlock:^(ALAsset *asset) { - _media.curAsset = asset; - dispatch_semaphore_signal(semaphore); - } failureBlock:^(NSError *error) { - _media.curAsset = nil; - dispatch_semaphore_signal(semaphore); - }]; - }); - dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); - - CGImageRef imageRef = nil; - if (totalCount < 3) { - imageRef = _media.curAsset.defaultRepresentation.fullScreenImage; + PHAsset *asset = [PHAsset assetWithLocalIdentifier:_media.assetID]; + if (asset) { + _media.curAsset = asset; + self.imgView.image = asset.loadImage; }else{ - imageRef = _media.curAsset.thumbnail; - } - if (imageRef) { - self.imgView.image = [UIImage imageWithCGImage:imageRef]; - } else { [self.imgView sd_setImageWithURL:[_media.urlStr urlImageWithCodePathResizeToView:self.contentView] placeholderImage:kPlaceholderCodingSquareWidth(55.0) options:SDWebImageRetryFailed| SDWebImageLowPriority| SDWebImageHandleCookies]; } } diff --git a/Coding_iOS/Views/UIMessageInputView/UIMessageInputView_Media.h b/Coding_iOS/Views/UIMessageInputView/UIMessageInputView_Media.h index eff56127f..b2622748f 100644 --- a/Coding_iOS/Views/UIMessageInputView/UIMessageInputView_Media.h +++ b/Coding_iOS/Views/UIMessageInputView/UIMessageInputView_Media.h @@ -16,9 +16,9 @@ typedef NS_ENUM(NSInteger, UIMessageInputView_MediaState) { }; @interface UIMessageInputView_Media : NSObject -@property (strong, nonatomic) ALAsset *curAsset; -@property (strong, nonatomic) NSURL *assetURL; +@property (strong, nonatomic) PHAsset *curAsset; +@property (strong, nonatomic) NSString *assetID; @property (strong, nonatomic) NSString *urlStr; @property (assign, nonatomic) UIMessageInputView_MediaState state; -+ (id)mediaWithAsset:(ALAsset *)asset urlStr:(NSString *)urlStr; ++ (id)mediaWithAsset:(PHAsset *)asset urlStr:(NSString *)urlStr; @end diff --git a/Coding_iOS/Views/UIMessageInputView/UIMessageInputView_Media.m b/Coding_iOS/Views/UIMessageInputView/UIMessageInputView_Media.m index f7810dede..f13bee2f3 100644 --- a/Coding_iOS/Views/UIMessageInputView/UIMessageInputView_Media.m +++ b/Coding_iOS/Views/UIMessageInputView/UIMessageInputView_Media.m @@ -9,10 +9,10 @@ #import "UIMessageInputView_Media.h" @implementation UIMessageInputView_Media -+ (id)mediaWithAsset:(ALAsset *)asset urlStr:(NSString *)urlStr{ ++ (id)mediaWithAsset:(PHAsset *)asset urlStr:(NSString *)urlStr{ UIMessageInputView_Media *media = [[UIMessageInputView_Media alloc] init]; media.curAsset = asset; - media.assetURL = [asset valueForProperty:ALAssetPropertyAssetURL]; + media.assetID = asset.localIdentifier; media.urlStr = urlStr; media.state = urlStr.length > 0? UIMessageInputView_MediaStateUploadSucess: UIMessageInputView_MediaStateInit; return media; diff --git a/Coding_iOS/Views/UserActiveStatusView.h b/Coding_iOS/Views/UserActiveStatusView.h new file mode 100644 index 000000000..9e4d5e507 --- /dev/null +++ b/Coding_iOS/Views/UserActiveStatusView.h @@ -0,0 +1,15 @@ +// +// UserActiveStatusView.h +// Coding_iOS +// +// Created by 张达棣 on 16/11/30. +// Copyright © 2016年 Coding. All rights reserved. +// + +#import + +@interface UserActiveStatusView : UIView +@property (nonatomic, strong) NSString *title; +@property (nonatomic, strong) NSString *details; + +@end diff --git a/Coding_iOS/Views/UserActiveStatusView.m b/Coding_iOS/Views/UserActiveStatusView.m new file mode 100644 index 000000000..034dfa547 --- /dev/null +++ b/Coding_iOS/Views/UserActiveStatusView.m @@ -0,0 +1,74 @@ +// +// UserActiveStatusView.m +// Coding_iOS +// +// Created by 张达棣 on 16/11/30. +// Copyright © 2016年 Coding. All rights reserved. +// + +#import "UserActiveStatusView.h" + +@interface UserActiveStatusView () +@property (nonatomic, strong) UILabel *titleLabel; +@property (nonatomic, strong) UILabel *detailsLabel; + +@end + +@implementation UserActiveStatusView + +#pragma mark - 生命周期方法 + +- (void)awakeFromNib { + [super awakeFromNib]; + [self creatView]; + +} + +- (instancetype)init { + self = [super init]; + if (self) { + [self creatView]; + } + return self; +} + +#pragma mark - 外部方法 + +#pragma makr - 消息 + +#pragma mark - 系统委托 + +#pragma mark - 自定义委托 + +#pragma mark - 响应方法 + +#pragma mark - 私有方法 + +- (void)creatView { + _titleLabel = [[UILabel alloc] init]; + _titleLabel.font = [UIFont systemFontOfSize:17]; + _titleLabel.textAlignment = NSTextAlignmentCenter; + [self addSubview:_titleLabel]; + _titleLabel.sd_layout.leftEqualToView(self).topSpaceToView(self, 8).rightEqualToView(self).heightIs(24); + + _detailsLabel = [[UILabel alloc] init]; + _detailsLabel.font = [UIFont systemFontOfSize:10]; + _detailsLabel.textAlignment = NSTextAlignmentCenter; + _detailsLabel.textColor = [UIColor colorWithRGBHex:0x76808e]; + [self addSubview:_detailsLabel]; + _detailsLabel.sd_layout.leftEqualToView(self).topSpaceToView(_titleLabel, 5).rightEqualToView(self).heightIs(14); +} + +#pragma mark - get/set方法 + +- (void)setTitle:(NSString *)title { + _title = title; + _titleLabel.text = title; +} + +- (void)setDetails:(NSString *)details { + _details = details; + _detailsLabel.text = details; +} + +@end diff --git a/Coding_iOS/Views/WikiHeaderView.h b/Coding_iOS/Views/WikiHeaderView.h new file mode 100644 index 000000000..0b6e166cc --- /dev/null +++ b/Coding_iOS/Views/WikiHeaderView.h @@ -0,0 +1,15 @@ +// +// WikiHeaderView.h +// Coding_Enterprise_iOS +// +// Created by Easeeeeeeeee on 2017/4/7. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import +#import "EAWiki.h" + +@interface WikiHeaderView : UIView +@property (strong, nonatomic) EAWiki *curWiki; +@property (assign, nonatomic) BOOL isForEdit; +@end diff --git a/Coding_iOS/Views/WikiHeaderView.m b/Coding_iOS/Views/WikiHeaderView.m new file mode 100644 index 000000000..5d24da03d --- /dev/null +++ b/Coding_iOS/Views/WikiHeaderView.m @@ -0,0 +1,81 @@ +// +// WikiHeaderView.m +// Coding_Enterprise_iOS +// +// Created by Easeeeeeeeee on 2017/4/7. +// Copyright © 2017年 Coding. All rights reserved. +// + +#import "WikiHeaderView.h" + +@interface WikiHeaderView () +@property (strong, nonatomic) UILabel *titleL, *nameL, *timeL, *versionL; +@end + +@implementation WikiHeaderView + +- (instancetype)init{ + self = [super init]; + if (self) { + self.frame = CGRectMake(0, 0, kScreen_Width, 0); + _titleL = [UILabel labelWithFont:[UIFont systemFontOfSize:17 weight:UIFontWeightMedium] textColor:kColorDark2]; + _nameL = [UILabel labelWithFont:[UIFont systemFontOfSize:12] textColor:kColorDark7]; + _timeL = [UILabel labelWithFont:[UIFont systemFontOfSize:12] textColor:kColorDark7]; + _versionL = [UILabel labelWithFont:[UIFont systemFontOfSize:12] textColor:kColorDark7]; + [self addSubview:_titleL]; + [self addSubview:_nameL]; + [self addSubview:_timeL]; + [self addSubview:_versionL]; + [_titleL mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.top.equalTo(self).offset(kPaddingLeftWidth); + make.right.equalTo(self).offset(-kPaddingLeftWidth); + }]; + [_nameL mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(_titleL); + make.top.equalTo(_titleL.mas_bottom).offset(10); + make.height.mas_equalTo(17); + }]; + [_timeL mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(_nameL.mas_right).offset(10); + make.right.equalTo(_versionL.mas_left).offset(-10); + make.centerY.equalTo(_nameL); + }]; + [_versionL mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(_nameL); + }]; + UIView *lineV = [UIView lineViewWithPointYY:0]; + [self addSubview:lineV]; + [lineV mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(kLine_MinHeight); + make.right.left.equalTo(_titleL); + make.bottom.equalTo(self); + }]; + } + return self; +} + +- (void)setCurWiki:(EAWiki *)curWiki{ + _curWiki = curWiki; + + self.hidden = (_curWiki == nil); + if (!_curWiki) { + self.height = 0; + }else{ + _titleL.text = _curWiki.mdTitle; + _nameL.text = _curWiki.editor.name; + _timeL.text = [NSString stringWithFormat:@"更新于 %@", [_curWiki.updatedAt stringWithFormat:@"MM/dd HH:mm"]]; + _versionL.text = [NSString stringWithFormat:@"当前版本 %@", _curWiki.currentVersion]; + + _nameL.hidden = _timeL.hidden = _versionL.hidden = _isForEdit; + + CGFloat height = [_titleL.text getHeightWithFont:_titleL.font constrainedToSize:CGSizeMake(_titleL.width, kCGGlyphMax)]; + if (_isForEdit) { + height = 15 + height + 15 + 1; + }else{ + height = 15 + height + 10 + 17 + 15 + 1; + } + self.frame = CGRectMake(0, -height, kScreen_Width, height); + } +} + +@end diff --git a/Coding_iOS/images_diff/enterprise/icon_user_monkey/icon_user_monkey@2x.png b/Coding_iOS/images_diff/enterprise/icon_user_monkey/icon_user_monkey@2x.png new file mode 100644 index 000000000..ed53c3b3e Binary files /dev/null and b/Coding_iOS/images_diff/enterprise/icon_user_monkey/icon_user_monkey@2x.png differ diff --git a/Coding_iOS/images_diff/enterprise/icon_user_monkey/icon_user_monkey@3x.png b/Coding_iOS/images_diff/enterprise/icon_user_monkey/icon_user_monkey@3x.png new file mode 100644 index 000000000..468d86760 Binary files /dev/null and b/Coding_iOS/images_diff/enterprise/icon_user_monkey/icon_user_monkey@3x.png differ diff --git a/Coding_iOS/Images/intro_pages/intro_page0_ip4@2x.png b/Coding_iOS/images_diff/enterprise/intro_pages/intro_page0_ip4@2x.png similarity index 100% rename from Coding_iOS/Images/intro_pages/intro_page0_ip4@2x.png rename to Coding_iOS/images_diff/enterprise/intro_pages/intro_page0_ip4@2x.png diff --git a/Coding_iOS/Images/intro_pages/intro_page0_ip5@2x.png b/Coding_iOS/images_diff/enterprise/intro_pages/intro_page0_ip5@2x.png similarity index 100% rename from Coding_iOS/Images/intro_pages/intro_page0_ip5@2x.png rename to Coding_iOS/images_diff/enterprise/intro_pages/intro_page0_ip5@2x.png diff --git a/Coding_iOS/Images/intro_pages/intro_page0_ip6+@3x.png b/Coding_iOS/images_diff/enterprise/intro_pages/intro_page0_ip6+@3x.png similarity index 100% rename from Coding_iOS/Images/intro_pages/intro_page0_ip6+@3x.png rename to Coding_iOS/images_diff/enterprise/intro_pages/intro_page0_ip6+@3x.png diff --git a/Coding_iOS/Images/intro_pages/intro_page0_ip6@2x.png b/Coding_iOS/images_diff/enterprise/intro_pages/intro_page0_ip6@2x.png similarity index 100% rename from Coding_iOS/Images/intro_pages/intro_page0_ip6@2x.png rename to Coding_iOS/images_diff/enterprise/intro_pages/intro_page0_ip6@2x.png diff --git a/Coding_iOS/Images/intro_pages/intro_page1_ip4@2x.png b/Coding_iOS/images_diff/enterprise/intro_pages/intro_page1_ip4@2x.png similarity index 100% rename from Coding_iOS/Images/intro_pages/intro_page1_ip4@2x.png rename to Coding_iOS/images_diff/enterprise/intro_pages/intro_page1_ip4@2x.png diff --git a/Coding_iOS/Images/intro_pages/intro_page1_ip5@2x.png b/Coding_iOS/images_diff/enterprise/intro_pages/intro_page1_ip5@2x.png similarity index 100% rename from Coding_iOS/Images/intro_pages/intro_page1_ip5@2x.png rename to Coding_iOS/images_diff/enterprise/intro_pages/intro_page1_ip5@2x.png diff --git a/Coding_iOS/Images/intro_pages/intro_page1_ip6+@3x.png b/Coding_iOS/images_diff/enterprise/intro_pages/intro_page1_ip6+@3x.png similarity index 100% rename from Coding_iOS/Images/intro_pages/intro_page1_ip6+@3x.png rename to Coding_iOS/images_diff/enterprise/intro_pages/intro_page1_ip6+@3x.png diff --git a/Coding_iOS/Images/intro_pages/intro_page1_ip6@2x.png b/Coding_iOS/images_diff/enterprise/intro_pages/intro_page1_ip6@2x.png similarity index 100% rename from Coding_iOS/Images/intro_pages/intro_page1_ip6@2x.png rename to Coding_iOS/images_diff/enterprise/intro_pages/intro_page1_ip6@2x.png diff --git a/Coding_iOS/Images/intro_pages/intro_page2_ip4@2x.png b/Coding_iOS/images_diff/enterprise/intro_pages/intro_page2_ip4@2x.png similarity index 100% rename from Coding_iOS/Images/intro_pages/intro_page2_ip4@2x.png rename to Coding_iOS/images_diff/enterprise/intro_pages/intro_page2_ip4@2x.png diff --git a/Coding_iOS/Images/intro_pages/intro_page2_ip5@2x.png b/Coding_iOS/images_diff/enterprise/intro_pages/intro_page2_ip5@2x.png similarity index 100% rename from Coding_iOS/Images/intro_pages/intro_page2_ip5@2x.png rename to Coding_iOS/images_diff/enterprise/intro_pages/intro_page2_ip5@2x.png diff --git a/Coding_iOS/Images/intro_pages/intro_page2_ip6+@3x.png b/Coding_iOS/images_diff/enterprise/intro_pages/intro_page2_ip6+@3x.png similarity index 100% rename from Coding_iOS/Images/intro_pages/intro_page2_ip6+@3x.png rename to Coding_iOS/images_diff/enterprise/intro_pages/intro_page2_ip6+@3x.png diff --git a/Coding_iOS/Images/intro_pages/intro_page2_ip6@2x.png b/Coding_iOS/images_diff/enterprise/intro_pages/intro_page2_ip6@2x.png similarity index 100% rename from Coding_iOS/Images/intro_pages/intro_page2_ip6@2x.png rename to Coding_iOS/images_diff/enterprise/intro_pages/intro_page2_ip6@2x.png diff --git a/Coding_iOS/Images/intro_pages/intro_page_selected@2x.png b/Coding_iOS/images_diff/enterprise/intro_pages/intro_page_selected@2x.png similarity index 100% rename from Coding_iOS/Images/intro_pages/intro_page_selected@2x.png rename to Coding_iOS/images_diff/enterprise/intro_pages/intro_page_selected@2x.png diff --git a/Coding_iOS/Images/intro_pages/intro_page_selected@3x.png b/Coding_iOS/images_diff/enterprise/intro_pages/intro_page_selected@3x.png similarity index 100% rename from Coding_iOS/Images/intro_pages/intro_page_selected@3x.png rename to Coding_iOS/images_diff/enterprise/intro_pages/intro_page_selected@3x.png diff --git a/Coding_iOS/Images/intro_pages/intro_page_unselected@2x.png b/Coding_iOS/images_diff/enterprise/intro_pages/intro_page_unselected@2x.png similarity index 100% rename from Coding_iOS/Images/intro_pages/intro_page_unselected@2x.png rename to Coding_iOS/images_diff/enterprise/intro_pages/intro_page_unselected@2x.png diff --git a/Coding_iOS/Images/intro_pages/intro_page_unselected@3x.png b/Coding_iOS/images_diff/enterprise/intro_pages/intro_page_unselected@3x.png similarity index 100% rename from Coding_iOS/Images/intro_pages/intro_page_unselected@3x.png rename to Coding_iOS/images_diff/enterprise/intro_pages/intro_page_unselected@3x.png diff --git a/Coding_iOS/images_diff/enterprise/introduction/dot_dark/intro_dot_dark_selected@2x.png b/Coding_iOS/images_diff/enterprise/introduction/dot_dark/intro_dot_dark_selected@2x.png new file mode 100644 index 000000000..8c4ebfd39 Binary files /dev/null and b/Coding_iOS/images_diff/enterprise/introduction/dot_dark/intro_dot_dark_selected@2x.png differ diff --git a/Coding_iOS/images_diff/enterprise/introduction/dot_dark/intro_dot_dark_selected@3x.png b/Coding_iOS/images_diff/enterprise/introduction/dot_dark/intro_dot_dark_selected@3x.png new file mode 100644 index 000000000..005e31bb7 Binary files /dev/null and b/Coding_iOS/images_diff/enterprise/introduction/dot_dark/intro_dot_dark_selected@3x.png differ diff --git a/Coding_iOS/images_diff/enterprise/introduction/dot_dark/intro_dot_dark_unselected@2x.png b/Coding_iOS/images_diff/enterprise/introduction/dot_dark/intro_dot_dark_unselected@2x.png new file mode 100644 index 000000000..54abeefa1 Binary files /dev/null and b/Coding_iOS/images_diff/enterprise/introduction/dot_dark/intro_dot_dark_unselected@2x.png differ diff --git a/Coding_iOS/images_diff/enterprise/introduction/dot_dark/intro_dot_dark_unselected@3x.png b/Coding_iOS/images_diff/enterprise/introduction/dot_dark/intro_dot_dark_unselected@3x.png new file mode 100644 index 000000000..4111f1317 Binary files /dev/null and b/Coding_iOS/images_diff/enterprise/introduction/dot_dark/intro_dot_dark_unselected@3x.png differ diff --git a/Coding_iOS/images_diff/enterprise/introduction/dot_light/intro_dot_light_selected@2x.png b/Coding_iOS/images_diff/enterprise/introduction/dot_light/intro_dot_light_selected@2x.png new file mode 100644 index 000000000..c7b44a073 Binary files /dev/null and b/Coding_iOS/images_diff/enterprise/introduction/dot_light/intro_dot_light_selected@2x.png differ diff --git a/Coding_iOS/images_diff/enterprise/introduction/dot_light/intro_dot_light_selected@3x.png b/Coding_iOS/images_diff/enterprise/introduction/dot_light/intro_dot_light_selected@3x.png new file mode 100644 index 000000000..86abe27d6 Binary files /dev/null and b/Coding_iOS/images_diff/enterprise/introduction/dot_light/intro_dot_light_selected@3x.png differ diff --git a/Coding_iOS/images_diff/enterprise/introduction/dot_light/intro_dot_light_unselected@2x.png b/Coding_iOS/images_diff/enterprise/introduction/dot_light/intro_dot_light_unselected@2x.png new file mode 100644 index 000000000..9bb05911a Binary files /dev/null and b/Coding_iOS/images_diff/enterprise/introduction/dot_light/intro_dot_light_unselected@2x.png differ diff --git a/Coding_iOS/images_diff/enterprise/introduction/dot_light/intro_dot_light_unselected@3x.png b/Coding_iOS/images_diff/enterprise/introduction/dot_light/intro_dot_light_unselected@3x.png new file mode 100644 index 000000000..3b3642352 Binary files /dev/null and b/Coding_iOS/images_diff/enterprise/introduction/dot_light/intro_dot_light_unselected@3x.png differ diff --git a/Coding_iOS/images_diff/enterprise/introduction/intro_icon_code_down.gif b/Coding_iOS/images_diff/enterprise/introduction/intro_icon_code_down.gif new file mode 100644 index 000000000..fa5426015 Binary files /dev/null and b/Coding_iOS/images_diff/enterprise/introduction/intro_icon_code_down.gif differ diff --git a/Coding_iOS/images_diff/enterprise/introduction/intro_icon_code_up.gif b/Coding_iOS/images_diff/enterprise/introduction/intro_icon_code_up.gif new file mode 100644 index 000000000..58612ce90 Binary files /dev/null and b/Coding_iOS/images_diff/enterprise/introduction/intro_icon_code_up.gif differ diff --git a/Coding_iOS/images_diff/enterprise/introduction/intro_icon_file_down.gif b/Coding_iOS/images_diff/enterprise/introduction/intro_icon_file_down.gif new file mode 100644 index 000000000..38e6d65ae Binary files /dev/null and b/Coding_iOS/images_diff/enterprise/introduction/intro_icon_file_down.gif differ diff --git a/Coding_iOS/images_diff/enterprise/introduction/intro_icon_file_up.gif b/Coding_iOS/images_diff/enterprise/introduction/intro_icon_file_up.gif new file mode 100644 index 000000000..2a99d3fe6 Binary files /dev/null and b/Coding_iOS/images_diff/enterprise/introduction/intro_icon_file_up.gif differ diff --git a/Coding_iOS/images_diff/enterprise/introduction/intro_icon_task_down.gif b/Coding_iOS/images_diff/enterprise/introduction/intro_icon_task_down.gif new file mode 100644 index 000000000..fe6ae190d Binary files /dev/null and b/Coding_iOS/images_diff/enterprise/introduction/intro_icon_task_down.gif differ diff --git a/Coding_iOS/images_diff/enterprise/introduction/intro_icon_task_up.gif b/Coding_iOS/images_diff/enterprise/introduction/intro_icon_task_up.gif new file mode 100644 index 000000000..d4598ca34 Binary files /dev/null and b/Coding_iOS/images_diff/enterprise/introduction/intro_icon_task_up.gif differ diff --git a/Coding_iOS/images_diff/enterprise/introduction/intro_icon_wiki_down.gif b/Coding_iOS/images_diff/enterprise/introduction/intro_icon_wiki_down.gif new file mode 100644 index 000000000..6b6102172 Binary files /dev/null and b/Coding_iOS/images_diff/enterprise/introduction/intro_icon_wiki_down.gif differ diff --git a/Coding_iOS/images_diff/enterprise/introduction/intro_icon_wiki_up.gif b/Coding_iOS/images_diff/enterprise/introduction/intro_icon_wiki_up.gif new file mode 100644 index 000000000..5fc6663e1 Binary files /dev/null and b/Coding_iOS/images_diff/enterprise/introduction/intro_icon_wiki_up.gif differ diff --git a/Coding_iOS/Images/icon_user_monkey@2x.png b/Coding_iOS/images_diff/personal/icon_user_monkey/icon_user_monkey@2x.png similarity index 100% rename from Coding_iOS/Images/icon_user_monkey@2x.png rename to Coding_iOS/images_diff/personal/icon_user_monkey/icon_user_monkey@2x.png diff --git a/Coding_iOS/Images/icon_user_monkey_i6@2x.png b/Coding_iOS/images_diff/personal/icon_user_monkey/icon_user_monkey_i6@2x.png similarity index 100% rename from Coding_iOS/Images/icon_user_monkey_i6@2x.png rename to Coding_iOS/images_diff/personal/icon_user_monkey/icon_user_monkey_i6@2x.png diff --git a/Coding_iOS/Images/icon_user_monkey_i6p@3x.png b/Coding_iOS/images_diff/personal/icon_user_monkey/icon_user_monkey_i6p@3x.png similarity index 100% rename from Coding_iOS/Images/icon_user_monkey_i6p@3x.png rename to Coding_iOS/images_diff/personal/icon_user_monkey/icon_user_monkey_i6p@3x.png diff --git a/Coding_iOS/images_diff/personal/intro_pages/intro_page0_ip4@2x.png b/Coding_iOS/images_diff/personal/intro_pages/intro_page0_ip4@2x.png new file mode 100644 index 000000000..a7880f09a Binary files /dev/null and b/Coding_iOS/images_diff/personal/intro_pages/intro_page0_ip4@2x.png differ diff --git a/Coding_iOS/images_diff/personal/intro_pages/intro_page0_ip5@2x.png b/Coding_iOS/images_diff/personal/intro_pages/intro_page0_ip5@2x.png new file mode 100644 index 000000000..fb49adad5 Binary files /dev/null and b/Coding_iOS/images_diff/personal/intro_pages/intro_page0_ip5@2x.png differ diff --git a/Coding_iOS/images_diff/personal/intro_pages/intro_page0_ip6+@3x.png b/Coding_iOS/images_diff/personal/intro_pages/intro_page0_ip6+@3x.png new file mode 100644 index 000000000..ff62de0ba Binary files /dev/null and b/Coding_iOS/images_diff/personal/intro_pages/intro_page0_ip6+@3x.png differ diff --git a/Coding_iOS/images_diff/personal/intro_pages/intro_page0_ip6@2x.png b/Coding_iOS/images_diff/personal/intro_pages/intro_page0_ip6@2x.png new file mode 100644 index 000000000..79dcaa3a6 Binary files /dev/null and b/Coding_iOS/images_diff/personal/intro_pages/intro_page0_ip6@2x.png differ diff --git a/Coding_iOS/images_diff/personal/intro_pages/intro_page0_ipX@3x.png b/Coding_iOS/images_diff/personal/intro_pages/intro_page0_ipX@3x.png new file mode 100644 index 000000000..79c891b3d Binary files /dev/null and b/Coding_iOS/images_diff/personal/intro_pages/intro_page0_ipX@3x.png differ diff --git a/Coding_iOS/images_diff/personal/intro_pages/intro_page_selected@2x.png b/Coding_iOS/images_diff/personal/intro_pages/intro_page_selected@2x.png new file mode 100644 index 000000000..85d5618af Binary files /dev/null and b/Coding_iOS/images_diff/personal/intro_pages/intro_page_selected@2x.png differ diff --git a/Coding_iOS/images_diff/personal/intro_pages/intro_page_selected@3x.png b/Coding_iOS/images_diff/personal/intro_pages/intro_page_selected@3x.png new file mode 100644 index 000000000..19546fbf6 Binary files /dev/null and b/Coding_iOS/images_diff/personal/intro_pages/intro_page_selected@3x.png differ diff --git a/Coding_iOS/images_diff/personal/intro_pages/intro_page_unselected@2x.png b/Coding_iOS/images_diff/personal/intro_pages/intro_page_unselected@2x.png new file mode 100644 index 000000000..4594a4118 Binary files /dev/null and b/Coding_iOS/images_diff/personal/intro_pages/intro_page_unselected@2x.png differ diff --git a/Coding_iOS/images_diff/personal/intro_pages/intro_page_unselected@3x.png b/Coding_iOS/images_diff/personal/intro_pages/intro_page_unselected@3x.png new file mode 100644 index 000000000..c17cf1750 Binary files /dev/null and b/Coding_iOS/images_diff/personal/intro_pages/intro_page_unselected@3x.png differ diff --git a/Coding_iOS/Images/introduction/intro_dot_selected@2x.png b/Coding_iOS/images_diff/personal/introduction/intro_dot_selected@2x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_dot_selected@2x.png rename to Coding_iOS/images_diff/personal/introduction/intro_dot_selected@2x.png diff --git a/Coding_iOS/Images/introduction/intro_dot_selected@3x.png b/Coding_iOS/images_diff/personal/introduction/intro_dot_selected@3x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_dot_selected@3x.png rename to Coding_iOS/images_diff/personal/introduction/intro_dot_selected@3x.png diff --git a/Coding_iOS/Images/introduction/intro_dot_unselected@2x.png b/Coding_iOS/images_diff/personal/introduction/intro_dot_unselected@2x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_dot_unselected@2x.png rename to Coding_iOS/images_diff/personal/introduction/intro_dot_unselected@2x.png diff --git a/Coding_iOS/Images/introduction/intro_dot_unselected@3x.png b/Coding_iOS/images_diff/personal/introduction/intro_dot_unselected@3x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_dot_unselected@3x.png rename to Coding_iOS/images_diff/personal/introduction/intro_dot_unselected@3x.png diff --git a/Coding_iOS/Images/introduction/intro_icon_0@2x.png b/Coding_iOS/images_diff/personal/introduction/intro_icon_0@2x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_icon_0@2x.png rename to Coding_iOS/images_diff/personal/introduction/intro_icon_0@2x.png diff --git a/Coding_iOS/Images/introduction/intro_icon_0@3x.png b/Coding_iOS/images_diff/personal/introduction/intro_icon_0@3x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_icon_0@3x.png rename to Coding_iOS/images_diff/personal/introduction/intro_icon_0@3x.png diff --git a/Coding_iOS/Images/introduction/intro_icon_1@2x.png b/Coding_iOS/images_diff/personal/introduction/intro_icon_1@2x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_icon_1@2x.png rename to Coding_iOS/images_diff/personal/introduction/intro_icon_1@2x.png diff --git a/Coding_iOS/Images/introduction/intro_icon_1@3x.png b/Coding_iOS/images_diff/personal/introduction/intro_icon_1@3x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_icon_1@3x.png rename to Coding_iOS/images_diff/personal/introduction/intro_icon_1@3x.png diff --git a/Coding_iOS/Images/introduction/intro_icon_2@2x.png b/Coding_iOS/images_diff/personal/introduction/intro_icon_2@2x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_icon_2@2x.png rename to Coding_iOS/images_diff/personal/introduction/intro_icon_2@2x.png diff --git a/Coding_iOS/Images/introduction/intro_icon_2@3x.png b/Coding_iOS/images_diff/personal/introduction/intro_icon_2@3x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_icon_2@3x.png rename to Coding_iOS/images_diff/personal/introduction/intro_icon_2@3x.png diff --git a/Coding_iOS/Images/introduction/intro_icon_3@2x.png b/Coding_iOS/images_diff/personal/introduction/intro_icon_3@2x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_icon_3@2x.png rename to Coding_iOS/images_diff/personal/introduction/intro_icon_3@2x.png diff --git a/Coding_iOS/Images/introduction/intro_icon_3@3x.png b/Coding_iOS/images_diff/personal/introduction/intro_icon_3@3x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_icon_3@3x.png rename to Coding_iOS/images_diff/personal/introduction/intro_icon_3@3x.png diff --git a/Coding_iOS/Images/introduction/intro_icon_4@2x.png b/Coding_iOS/images_diff/personal/introduction/intro_icon_4@2x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_icon_4@2x.png rename to Coding_iOS/images_diff/personal/introduction/intro_icon_4@2x.png diff --git a/Coding_iOS/Images/introduction/intro_icon_4@3x.png b/Coding_iOS/images_diff/personal/introduction/intro_icon_4@3x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_icon_4@3x.png rename to Coding_iOS/images_diff/personal/introduction/intro_icon_4@3x.png diff --git a/Coding_iOS/Images/introduction/intro_icon_5@2x.png b/Coding_iOS/images_diff/personal/introduction/intro_icon_5@2x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_icon_5@2x.png rename to Coding_iOS/images_diff/personal/introduction/intro_icon_5@2x.png diff --git a/Coding_iOS/Images/introduction/intro_icon_5@3x.png b/Coding_iOS/images_diff/personal/introduction/intro_icon_5@3x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_icon_5@3x.png rename to Coding_iOS/images_diff/personal/introduction/intro_icon_5@3x.png diff --git a/Coding_iOS/Images/introduction/intro_icon_6@2x.png b/Coding_iOS/images_diff/personal/introduction/intro_icon_6@2x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_icon_6@2x.png rename to Coding_iOS/images_diff/personal/introduction/intro_icon_6@2x.png diff --git a/Coding_iOS/Images/introduction/intro_icon_6@3x.png b/Coding_iOS/images_diff/personal/introduction/intro_icon_6@3x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_icon_6@3x.png rename to Coding_iOS/images_diff/personal/introduction/intro_icon_6@3x.png diff --git a/Coding_iOS/Images/introduction/intro_tip_0@2x.png b/Coding_iOS/images_diff/personal/introduction/intro_tip_0@2x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_tip_0@2x.png rename to Coding_iOS/images_diff/personal/introduction/intro_tip_0@2x.png diff --git a/Coding_iOS/Images/introduction/intro_tip_0@3x.png b/Coding_iOS/images_diff/personal/introduction/intro_tip_0@3x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_tip_0@3x.png rename to Coding_iOS/images_diff/personal/introduction/intro_tip_0@3x.png diff --git a/Coding_iOS/Images/introduction/intro_tip_1@2x.png b/Coding_iOS/images_diff/personal/introduction/intro_tip_1@2x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_tip_1@2x.png rename to Coding_iOS/images_diff/personal/introduction/intro_tip_1@2x.png diff --git a/Coding_iOS/Images/introduction/intro_tip_1@3x.png b/Coding_iOS/images_diff/personal/introduction/intro_tip_1@3x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_tip_1@3x.png rename to Coding_iOS/images_diff/personal/introduction/intro_tip_1@3x.png diff --git a/Coding_iOS/Images/introduction/intro_tip_2@2x.png b/Coding_iOS/images_diff/personal/introduction/intro_tip_2@2x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_tip_2@2x.png rename to Coding_iOS/images_diff/personal/introduction/intro_tip_2@2x.png diff --git a/Coding_iOS/Images/introduction/intro_tip_2@3x.png b/Coding_iOS/images_diff/personal/introduction/intro_tip_2@3x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_tip_2@3x.png rename to Coding_iOS/images_diff/personal/introduction/intro_tip_2@3x.png diff --git a/Coding_iOS/Images/introduction/intro_tip_3@2x.png b/Coding_iOS/images_diff/personal/introduction/intro_tip_3@2x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_tip_3@2x.png rename to Coding_iOS/images_diff/personal/introduction/intro_tip_3@2x.png diff --git a/Coding_iOS/Images/introduction/intro_tip_3@3x.png b/Coding_iOS/images_diff/personal/introduction/intro_tip_3@3x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_tip_3@3x.png rename to Coding_iOS/images_diff/personal/introduction/intro_tip_3@3x.png diff --git a/Coding_iOS/Images/introduction/intro_tip_4@2x.png b/Coding_iOS/images_diff/personal/introduction/intro_tip_4@2x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_tip_4@2x.png rename to Coding_iOS/images_diff/personal/introduction/intro_tip_4@2x.png diff --git a/Coding_iOS/Images/introduction/intro_tip_4@3x.png b/Coding_iOS/images_diff/personal/introduction/intro_tip_4@3x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_tip_4@3x.png rename to Coding_iOS/images_diff/personal/introduction/intro_tip_4@3x.png diff --git a/Coding_iOS/Images/introduction/intro_tip_5@2x.png b/Coding_iOS/images_diff/personal/introduction/intro_tip_5@2x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_tip_5@2x.png rename to Coding_iOS/images_diff/personal/introduction/intro_tip_5@2x.png diff --git a/Coding_iOS/Images/introduction/intro_tip_5@3x.png b/Coding_iOS/images_diff/personal/introduction/intro_tip_5@3x.png similarity index 100% rename from Coding_iOS/Images/introduction/intro_tip_5@3x.png rename to Coding_iOS/images_diff/personal/introduction/intro_tip_5@3x.png diff --git a/Podfile b/Podfile index 9795f9da7..603d10204 100755 --- a/Podfile +++ b/Podfile @@ -1,32 +1,43 @@ source 'https://github.com/CocoaPods/Specs.git' -platform :ios, '7.0' +platform :ios, '9.0' + +inhibit_all_warnings! target "Coding_iOS" do -pod 'TTTAttributedLabel', '1.10.1' -pod 'RegexKitLite-NoWarning', '1.1.0' -pod 'hpple', '0.2.0' -pod 'MBProgressHUD', '0.9' -pod 'TPKeyboardAvoiding', '1.2.4' -pod 'BlocksKit', '2.2.5' -pod 'ReactiveCocoa', '2.3.1' -pod 'MMMarkdown', '0.3' -pod 'Masonry', '0.5.3' -pod 'NYXImagesKit', '2.3' -pod 'UIImage+BlurredFrame', '0.0.4' -pod 'POP+MCAnimate', '2.0.1' -pod 'PPiAwesomeButton', '1.5.2' -pod 'APParallaxHeader', '0.1.6' -pod 'SDCAlertView', '2.5.2' -pod 'MarqueeLabel', '2.5.0' -pod 'TMCache', '2.1.0' -pod 'iVersion', '1.11.4' -pod 'JazzHands', '2.0.0' -pod 'SSKeychain', '1.2.3' -pod 'UMengSocial', '4.2.3' -#pod 'evernote-cloud-sdk-ios', :git => 'https://github.com/evernote/evernote-cloud-sdk-ios.git', :branch => 'ios7' -pod 'evernote-cloud-sdk-ios', '2.0.2' -pod 'UMengAnalytics', '3.5.10' -pod 'FLEX', '~> 2.0', :configurations => ['Debug'] - -end \ No newline at end of file + pod 'TTTAttributedLabel', '2.0.0' + pod 'RegexKitLite-NoWarning', '1.1.0' + pod 'hpple', '0.2.0' + pod 'MBProgressHUD', '0.9' + pod 'TPKeyboardAvoiding', '1.2.4' + pod 'BlocksKit', '2.2.5' + pod 'ReactiveCocoa', '2.3.1' + pod 'MMMarkdown', '0.3' + pod 'Masonry', '0.5.3' + pod 'SDAutoLayout', '2.1.0' + pod 'NYXImagesKit', '2.3' + pod 'UIImage+BlurredFrame', '0.0.4' + pod 'POP+MCAnimate', '2.0.1' + pod 'PPiAwesomeButton', '1.5.2' + pod 'FontAwesome+iOS', :git => 'https://github.com/alexdrone/ios-fontawesome' + pod 'APParallaxHeader', '0.1.6' + pod 'SDCAlertView', '2.5.2' + pod 'MarqueeLabel', '2.5.0' + pod 'TMCache', '2.1.0' + #pod 'iVersion', '1.11.4' + pod 'JazzHands', '2.0.0' + pod 'SSKeychain', '1.2.3' + #pod 'evernote-cloud-sdk-ios', :git => 'https://github.com/evernote/evernote-cloud-sdk-ios.git', :branch => 'ios7' + pod 'evernote-cloud-sdk-ios', '2.0.2' + pod 'UMengAnalytics', '4.2.4' + pod 'FLEX', '~> 2.0', :configurations => ['Debug'] + + pod 'UMengUShare/Social/WeChat', '6.4.5' + pod 'UMengUShare/Social/QQ', '6.4.5' + pod 'UMengUShare/Social/Sina', '6.4.5' + + target "Coding_Enterprise_iOS" do + + end + +end diff --git a/Podfile.lock b/Podfile.lock index 37fec221b..946ff0a77 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -17,40 +17,39 @@ PODS: - BlocksKit/DynamicDelegate - evernote-cloud-sdk-ios (2.0.2) - FLEX (2.1.1) - - FontAwesome+iOS (0.1.4) + - "FontAwesome+iOS (0.0.1)" - hpple (0.2.0) - - iVersion (1.11.4) - JazzHands (2.0.0) - MarqueeLabel (2.5.0) - Masonry (0.5.3) - MBProgressHUD (0.9) - MMMarkdown (0.3) - NYXImagesKit (2.3) - - pop (1.0.9) - - POP+MCAnimate (2.0.1): + - pop (1.0.10) + - "POP+MCAnimate (2.0.1)": - pop (~> 1.0) - - POP+MCAnimate/Animations (= 2.0.1) - - POP+MCAnimate/Group (= 2.0.1) - - POP+MCAnimate/Internal (= 2.0.1) - - POP+MCAnimate/Shorthand (= 2.0.1) - - POP+MCAnimate/Velocity (= 2.0.1) - - POP+MCAnimate/Animations (2.0.1): + - "POP+MCAnimate/Animations (= 2.0.1)" + - "POP+MCAnimate/Group (= 2.0.1)" + - "POP+MCAnimate/Internal (= 2.0.1)" + - "POP+MCAnimate/Shorthand (= 2.0.1)" + - "POP+MCAnimate/Velocity (= 2.0.1)" + - "POP+MCAnimate/Animations (2.0.1)": - pop (~> 1.0) - - POP+MCAnimate/Group - - POP+MCAnimate/Internal - - POP+MCAnimate/Shorthand - - POP+MCAnimate/Velocity - - POP+MCAnimate/Group (2.0.1): + - "POP+MCAnimate/Group" + - "POP+MCAnimate/Internal" + - "POP+MCAnimate/Shorthand" + - "POP+MCAnimate/Velocity" + - "POP+MCAnimate/Group (2.0.1)": - pop (~> 1.0) - - POP+MCAnimate/Internal (2.0.1): + - "POP+MCAnimate/Internal (2.0.1)": - pop (~> 1.0) - - POP+MCAnimate/Shorthand (2.0.1): + - "POP+MCAnimate/Shorthand (2.0.1)": - pop (~> 1.0) - - POP+MCAnimate/Velocity (2.0.1): + - "POP+MCAnimate/Velocity (2.0.1)": - pop (~> 1.0) - - POP+MCAnimate/Internal + - "POP+MCAnimate/Internal" - PPiAwesomeButton (1.5.2): - - FontAwesome+iOS + - "FontAwesome+iOS" - RBBAnimation (0.4.0) - ReactiveCocoa (2.3.1): - ReactiveCocoa/UI (= 2.3.1) @@ -60,6 +59,7 @@ PODS: - ReactiveCocoa/UI (2.3.1): - ReactiveCocoa/Core - RegexKitLite-NoWarning (1.1.0) + - SDAutoLayout (2.1.0) - SDCAlertView (2.5.2): - RBBAnimation (~> 0.3) - SDCAutoLayout (~> 2.0) @@ -67,65 +67,126 @@ PODS: - SSKeychain (1.2.3) - TMCache (2.1.0) - TPKeyboardAvoiding (1.2.4) - - TTTAttributedLabel (1.10.1) - - UIImage+BlurredFrame (0.0.4) - - UMengAnalytics (3.5.10) - - UMengSocial (4.2.3) + - TTTAttributedLabel (2.0.0) + - "UIImage+BlurredFrame (0.0.4)" + - UMengAnalytics (4.2.4) + - UMengUShare/Core (6.4.5): + - UMengUShare/Network + - UMengUShare/Network (6.4.5) + - UMengUShare/Social/QQ (6.4.5): + - UMengUShare/Core + - UMengUShare/Social/ReducedQQ + - UMengUShare/Social/ReducedQQ (6.4.5): + - UMengUShare/Core + - UMengUShare/Social/ReducedSina (6.4.5): + - UMengUShare/Core + - UMengUShare/Social/ReducedWeChat (6.4.5): + - UMengUShare/Core + - UMengUShare/Social/Sina (6.4.5): + - UMengUShare/Core + - UMengUShare/Social/ReducedSina + - UMengUShare/Social/WeChat (6.4.5): + - UMengUShare/Core + - UMengUShare/Social/ReducedWeChat DEPENDENCIES: - APParallaxHeader (= 0.1.6) - BlocksKit (= 2.2.5) - evernote-cloud-sdk-ios (= 2.0.2) - FLEX (~> 2.0) + - "FontAwesome+iOS (from `https://github.com/alexdrone/ios-fontawesome`)" - hpple (= 0.2.0) - - iVersion (= 1.11.4) - JazzHands (= 2.0.0) - MarqueeLabel (= 2.5.0) - Masonry (= 0.5.3) - MBProgressHUD (= 0.9) - MMMarkdown (= 0.3) - NYXImagesKit (= 2.3) - - POP+MCAnimate (= 2.0.1) + - "POP+MCAnimate (= 2.0.1)" - PPiAwesomeButton (= 1.5.2) - ReactiveCocoa (= 2.3.1) - RegexKitLite-NoWarning (= 1.1.0) + - SDAutoLayout (= 2.1.0) - SDCAlertView (= 2.5.2) - SSKeychain (= 1.2.3) - TMCache (= 2.1.0) - TPKeyboardAvoiding (= 1.2.4) - - TTTAttributedLabel (= 1.10.1) - - UIImage+BlurredFrame (= 0.0.4) - - UMengAnalytics (= 3.5.10) - - UMengSocial (= 4.2.3) + - TTTAttributedLabel (= 2.0.0) + - "UIImage+BlurredFrame (= 0.0.4)" + - UMengAnalytics (= 4.2.4) + - UMengUShare/Social/QQ (= 6.4.5) + - UMengUShare/Social/Sina (= 6.4.5) + - UMengUShare/Social/WeChat (= 6.4.5) + +SPEC REPOS: + https://github.com/cocoapods/specs.git: + - APParallaxHeader + - BlocksKit + - evernote-cloud-sdk-ios + - FLEX + - hpple + - JazzHands + - MarqueeLabel + - Masonry + - MBProgressHUD + - MMMarkdown + - NYXImagesKit + - pop + - "POP+MCAnimate" + - PPiAwesomeButton + - RBBAnimation + - ReactiveCocoa + - RegexKitLite-NoWarning + - SDAutoLayout + - SDCAlertView + - SDCAutoLayout + - SSKeychain + - TMCache + - TPKeyboardAvoiding + - TTTAttributedLabel + - "UIImage+BlurredFrame" + - UMengAnalytics + - UMengUShare + +EXTERNAL SOURCES: + "FontAwesome+iOS": + :git: https://github.com/alexdrone/ios-fontawesome + +CHECKOUT OPTIONS: + "FontAwesome+iOS": + :commit: 3ef4db504ffde636c1f8a5320f1e5b6183f6102c + :git: https://github.com/alexdrone/ios-fontawesome SPEC CHECKSUMS: APParallaxHeader: 854bc48a2487ca12c702f8a236fec0d89cdac5c3 BlocksKit: 7f422b971407001178d181a43b99014ea2591fe6 evernote-cloud-sdk-ios: 7a6e5402b837ea79ef0179caff5ffe7b4f235615 FLEX: 27b768fcae23a313a1eb115076d429180ca9b472 - FontAwesome+iOS: 9070b682a9255ca0fdc34bcfb129ad0ba2b73b87 + "FontAwesome+iOS": c6d3bbd2856b9633028d316d56133d45fb6a6cb0 hpple: 3b765f96fc2cd56ad1a49aef6f7be5cb2aa64b57 - iVersion: 2b6ffe708672cb494ba3cab150a94800c2892e81 JazzHands: 00002e9b1284e7fc1ac6555012e81b8942477242 MarqueeLabel: 6b8ff6915c0536c5099ac30992b7d72f9807df20 Masonry: 9f515466afe48632562342a40a1c224071a1a022 MBProgressHUD: d8e7ea388dc1549a42e0d219067cf5f2c898fb66 MMMarkdown: 13af1af50e5f476f1097797f43ea2bd76c83067a NYXImagesKit: 8163e3335a40eaa173ca5bbbf81fafb57d3947eb - pop: f667631a5108a2e60d9e8797c9b32ddaf2080bce - POP+MCAnimate: a99e209148c602512de487f1160a44bf78572024 + pop: 82ca6b068ce9278fd350fd9dd09482a0ce9492e6 + "POP+MCAnimate": a99e209148c602512de487f1160a44bf78572024 PPiAwesomeButton: 16f7279582fd36f65186b24b83ef876217363eb5 RBBAnimation: 4b2d66f6d993febce63cd564da934985313b9c59 ReactiveCocoa: 3fe9b233ca6db810e86681b5749488564c1179a1 RegexKitLite-NoWarning: 365d208f8187997e33d9de8baeddfc00728596d8 + SDAutoLayout: 8e701d7e6a3ec4fb5571800378e8bb6b6645522d SDCAlertView: f9706c18f456ea87909f8f199704cd28e582ff27 SDCAutoLayout: e6885bb39ab8e2ec2ff84d158f38035f025f7420 SSKeychain: 3f42991739c6c60a9cf1bbd4dff6c0d3694bcf3d TMCache: 95ebcc9b3c7e90fb5fd8fc3036cba3aa781c9bed TPKeyboardAvoiding: 0a40dfbb0af7c8bdae1dd457496dccfd217d85f6 - TTTAttributedLabel: c8f3801a6463b9c9b82b0c84c465fdda9751892a - UIImage+BlurredFrame: ad2f7195c6947ea3117c7d202f75a51958d5061a - UMengAnalytics: 092c24aef47b6ac3c76ad51543f91156a8d7b645 - UMengSocial: 85882abe5b20aa38ad558ece71360e16b5d50909 + TTTAttributedLabel: 8cffe8e127e4e82ff3af1e5386d4cd0ad000b656 + "UIImage+BlurredFrame": ad2f7195c6947ea3117c7d202f75a51958d5061a + UMengAnalytics: ef8d45f94c0e5771dc364cf6a5731d9d3b101da2 + UMengUShare: a5711c54e640b04e3048e931d2b88d50f9cfa55c + +PODFILE CHECKSUM: 8c4d664f01f05a5ddc0837b2a06d36650c4edeeb -COCOAPODS: 0.39.0 +COCOAPODS: 1.6.2 diff --git a/README.md b/README.md index 5fa06a124..ee2842096 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,9 @@ ### Coding_iOS客户端项目介绍 *编译环境:Xcode-Version 8.0 (8A218a)* #### 让项目跑起来先 + +项目里用到了 [CocoaPods](http://cocoapods.org/) 和 [Carthage](https://github.com/Carthage/Carthage),如果没有安装的话,需要先自行安装。 + Clone 代码后,初次执行前,需要双击运行根目录下的`bootstrap`脚本。这个过程涉及到下载依赖,可能会有点久,需耐心等待。 **Tip:由于用到了 submodule,所以必需要把 git 仓库 clone 到本地,而不是只点击‘下载’按钮下载 zip 文件!!!** @@ -12,22 +15,23 @@ Clone 代码后,初次执行前,需要双击运行根目录下的`bootstrap` -####下面介绍一下文件的大概目录先: +#### 下面介绍一下文件的大概目录先: +``` . ├── Coding_iOS │   ├── Models:数据类 │   ├── Views:视图类 - │   │   ├── CCell:所有的CollectionViewCell都在这里 - │   │   ├── Cell:所有的TableViewCell都在这里 - │   │   └── XXX:ListView(项目、动态、任务、讨论、文档、代码)和InputView(用于聊天和评论的输入框) + │   │   ├── CCell:所有的 CollectionViewCell 都在这里 + │   │   ├── Cell:所有的 TableViewCell 都在这里 + │   │   └── XXX:ListView(项目、动态、任务、讨论、文档、代码)和 InputView(用于聊天和评论的输入框) │   ├── Controllers:控制器,对应app中的各个页面 │   │   ├── Login:登录页面 │   │   ├── RootControllers:登录后的根页面 │   │   ├── MeSetting:设置信息页面 │   │   └── XXX:其它页面 - │   ├── Images:app中用到的所有的图片都在这里 + │   ├── Images:app 中用到的所有的图片都在这里 │   ├── Resources:资源文件 - │   ├── Util:一些常用控件和Category、Manager之类 + │   ├── Util:一些常用控件和 Category、Manager 之类 │   │   ├── Common │   │   ├── Manager │   │   ├── OC_Category @@ -53,41 +57,41 @@ Clone 代码后,初次执行前,需要双击运行根目录下的`bootstrap` │      ├── XGPush │      ├── XTSegmentControl │    └── iCarousel - └── Pods:项目使用了[CocoaPods](http://code4app.com/article/cocoapods-install-usage)这个类库管理工具 - + └── Pods:项目使用了 [CocoaPods](http://code4app.com/article/cocoapods-install-usage) 这个类库管理工具 +``` -####再说下项目的启动流程: -在AppDelegate的启动方法中,先设置了一下Appearance的样式,然后根据用户的登录状态选择是去加载登录页面LoginViewController,还是登录后的RootTabViewController页面。 +#### 再说下项目的启动流程: +在 AppDelegate 的启动方法中,先设置了一下 Appearance 的样式,然后根据用户的登录状态选择是去加载登录页面 LoginViewController,还是登录后的 RootTabViewController 页面。 -RootTabViewController继承自第三方库[RDVTabBarController](https://github.com/robbdimitrov/RDVTabBarController)。在RootTabViewController里面依次加载了Project_RootViewController、MyTask_RootViewController、Tweet_RootViewController、Message_RootViewController、Me_RootViewController五个RootViewController,后续的页面跳转都是基于这几个RootViewController引过去的。 +RootTabViewController 继承自第三方库 [RDVTabBarController](https://github.com/robbdimitrov/RDVTabBarController)。在 RootTabViewController 里面依次加载了 Project_RootViewController、MyTask_RootViewController、Tweet_RootViewController、Message_RootViewController、Me_RootViewController 五个 RootViewController,后续的页面跳转都是基于这几个 RootViewController 引过去的。 -####项目里面还有些需要注意的点 - - Coding_NetAPIManager:基本上app的所有请求接口都放在了这里。网络请求使用的是[AFNetworking](https://github.com/AFNetworking/AFNetworking)库,与服务器之间的数据交互格式用的都是json(与[Coding](https://coding.net)使用的api一致)。 +#### 项目里面还有些需要注意的点 + - Coding_NetAPIManager:基本上 app 的所有请求接口都放在了这里。网络请求使用的是 [AFNetworking](https://github.com/AFNetworking/AFNetworking) 库,与服务器之间的数据交互格式用的都是 json(与 [Coding](https://coding.net) 使用的 api 一致)。 - - 关于推送:刚开始是用的[友盟推送](http://www.umeng.com/),后来又改用了[腾讯信鸽](http://xg.qq.com/),因为要兼顾旧版本app的推送,所以服务器是同时保留了两套推送。但是为了确保新版本的app不同时收到双份相同的推送消息,所以当前代码里还存留了友盟的sdk,用于解除推送token与友盟Alias的绑定。 + - 关于推送:刚开始是用的 [友盟推送](http://www.umeng.com/),后来又改用了 [腾讯信鸽](http://xg.qq.com/),因为要兼顾旧版本 app 的推送,所以服务器是同时保留了两套推送。但是为了确保新版本的 app 不同时收到双份相同的推送消息,所以当前代码里还存留了友盟的 sdk,用于解除推送 token 与友盟 Alias 的绑定。 - - 关于ProjectViewController:这个就是进入到某个项目之后的页面,这里包含了项目的动态、任务、讨论、文档、代码、成员各类信息,而且每类信息里面还可能会有新的分类(如‘任务’里面还分有各个成员的任务);这个页面相当的臃肿,我对它们做了拆分,都放在视图类Views目录下面。 首先是把数据列表独立成了对应的XXXListView(如ProjectTaskListView);然后如果需要标签切换的话,会再新建一个XXXsView(如:ProjectTasksView),在这个视图中,上面会放一个切换栏[XTSegmentControl](https://github.com/xushao1990/XTNews)显示各个标签,下面放一个[iCarousel](https://github.com/nicklockwood/iCarousel)可以滑动显示各个标签的内容;最后这些视图都会存储在ProjectViewController的projectContentDict变量里面,根据顶部导航栏选择的类别,去显示或隐藏对应的视图。 + - 关于 ProjectViewController:这个就是进入到某个项目之后的页面,这里包含了项目的动态、任务、讨论、文档、代码、成员各类信息,而且每类信息里面还可能会有新的分类(如‘任务’里面还分有各个成员的任务);这个页面相当的臃肿,我对它们做了拆分,都放在视图类 Views 目录下面。 首先是把数据列表独立成了对应的 XXXListView(如 ProjectTaskListView);然后如果需要标签切换的话,会再新建一个 XXXsView(如:ProjectTasksView),在这个视图中,上面会放一个切换栏 [XTSegmentControl](https://github.com/xushao1990/XTNews) 显示各个标签,下面放一个 [iCarousel](https://github.com/nicklockwood/iCarousel) 可以滑动显示各个标签的内容;最后这些视图都会存储在 ProjectViewController 的 projectContentDict 变量里面,根据顶部导航栏选择的类别,去显示或隐藏对应的视图。 - - 关于UIMessageInputView:这个是私信聊天的输入框。因为这个输入框好多地方都有用到(冒泡、任务、讨论的评论还有私信),所以这个输入框就写成了一个相对独立的控件,并且直接显示在了keyWindow里面而不是某个视图里。这里的表情键盘用的是[AGEmojiKeyboard](https://github.com/ayushgoel/AGEmojiKeyboard)改写了一下。 + - 关于 UIMessageInputView:这个是私信聊天的输入框。因为这个输入框好多地方都有用到(冒泡、任务、讨论的评论还有私信),所以这个输入框就写成了一个相对独立的控件,并且直接显示在了 keyWindow 里面而不是某个视图里。这里的表情键盘用的是 [AGEmojiKeyboard](https://github.com/ayushgoel/AGEmojiKeyboard) 改写了一下。 - - 关于Emoji:这个,[Coding](https://coding.net)站点的emoji都是用的图片,而且服务器是不接受大部分emoji字符的,所以刚开始的时候app一直不能处理emoji表情;又因为没有emoji图片名和emoji code码的对应关系表,所以拖了很久都没能做好转换。直到在github上面找到了[NSStringEmojize](https://github.com/diy/NSStringEmojize)这个项目;试了一下,虽然也不能全部解析,但是大部分表情都能正确显示了,不能更感谢。 + - 关于 Emoji:这个,[Coding](https://coding.net) 站点的 emoji 都是用的图片,而且服务器是不接受大部分 emoji 字符的,所以刚开始的时候 app 一直不能处理 emoji 表情;又因为没有 emoji 图片名和 emoji code 码的对应关系表,所以拖了很久都没能做好转换。直到在 github 上面找到了 [NSStringEmojize](https://github.com/diy/NSStringEmojize) 这个项目;试了一下,虽然也不能全部解析,但是大部分表情都能正确显示了,不能更感谢。 - - 关于如何正确显示冒泡的内容:api返回的数据里面,冒泡内容都是html格式,需要做一下预处理;其实私信、讨论里面的内容也是html。解析html的类名是HtmlMediaItem,它是先用[hpple](https://github.com/topfunky/hpple)对html进行了解析,然后把对应的media元素和对应的位置做一个存储,显示的时候便可以根据需要来显示了。 + - 关于如何正确显示冒泡的内容:api 返回的数据里面,冒泡内容都是 html 格式,需要做一下预处理;其实私信、讨论里面的内容也是 html。解析 html 的类名是 HtmlMediaItem,它是先用 [hpple](https://github.com/topfunky/hpple) 对 html 进行了解析,然后把对应的 media 元素和对应的位置做一个存储,显示的时候便可以根据需要来显示了。 -####最后说下[CocoaPods](http://cocoapods.org/)里面用到的第三方类库 +#### 最后说下 [CocoaPods](http://cocoapods.org/) 里面用到的第三方类库 - [SDWebImage](https://github.com/rs/SDWebImage):图片加载 - - [TTTAttributedLabel](https://github.com/TTTAttributedLabel/TTTAttributedLabel):富文本的label,可点击链接 + - [TTTAttributedLabel](https://github.com/TTTAttributedLabel/TTTAttributedLabel):富文本的 label,可点击链接 - [RegexKitLite](https://github.com/wezm/RegexKitLite):正则表达式 - - [hpple](https://github.com/topfunky/hpple):html解析 - - [MBProgressHUD](https://github.com/jdg/MBProgressHUD):hud提示框 + - [hpple](https://github.com/topfunky/hpple):html 解析 + - [MBProgressHUD](https://github.com/jdg/MBProgressHUD):hud 提示框 - [ODRefreshControl](https://github.com/Sephiroth87/ODRefreshControl):下拉刷新 - [TPKeyboardAvoiding](https://github.com/michaeltyson/TPKeyboardAvoiding):有文字输入时,能根据键盘是否弹出来调整自身显示内容的位置 - [JDStatusBarNotification](https://github.com/jaydee3/JDStatusBarNotification):状态栏提示框 - - [BlocksKit](https://github.com/zwaldowski/BlocksKit):block工具包。将很多需要用delegate实现的方法整合成了block的形式 - - [ReactiveCocoa](https://github.com/ReactiveCocoa/ReactiveCocoa):基于响应式编程思想的oc实践(是个好东西呢) + - [BlocksKit](https://github.com/zwaldowski/BlocksKit):block 工具包。将很多需要用 delegate 实现的方法整合成了 block 的形式 + - [ReactiveCocoa](https://github.com/ReactiveCocoa/ReactiveCocoa):基于响应式编程思想的 oc 实践(是个好东西呢) -####License +#### License Coding is available under the MIT license. See the LICENSE file for more info. diff --git a/bootstrap b/bootstrap index 6f7292456..6d994ee16 100755 --- a/bootstrap +++ b/bootstrap @@ -2,7 +2,7 @@ CMD_PATH=`dirname $0` cd $CMD_PATH cp Coding_iOS/Coding_iOS-Prefix.pch.example Coding_iOS/Coding_iOS-Prefix.pch -git submodule update --init --recursive pod install +carthage update open Coding_iOS.xcworkspace exit 0