git.iko.soy/dashared/GDproject
on master help sign in
Worked on messages: infoVC is almost perfect, CGAffineTransform is done, whole design-beauty-style is left thought..
b65cc45Darya Rednikina
GDproject.xcodeproj/project.pbxproj+16−4
@@ -19,6 +19,7 @@
19 1261BB93227B364C003898CF /* ChannelViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1261BB92227B364C003898CF /* ChannelViewController.swift */; };
19 1261BB93227B364C003898CF /* ChannelViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1261BB92227B364C003898CF /* ChannelViewController.swift */; };
20 1261BB95227B3991003898CF /* AddToChannelVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1261BB94227B3991003898CF /* AddToChannelVC.swift */; };
20 1261BB95227B3991003898CF /* AddToChannelVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1261BB94227B3991003898CF /* AddToChannelVC.swift */; };
21 1261BB9E227B793D003898CF /* ChatInfoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1261BB9D227B793D003898CF /* ChatInfoViewController.swift */; };
21 1261BB9E227B793D003898CF /* ChatInfoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1261BB9D227B793D003898CF /* ChatInfoViewController.swift */; };
22+ 12758257227F1401001F291F /* DialogViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12758256227F1401001F291F /* DialogViewController.swift */; };
22 1288B5CE221F1158002BE6B1 /* DataStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1288B5CD221F1158002BE6B1 /* DataStorage.swift */; };
23 1288B5CE221F1158002BE6B1 /* DataStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1288B5CD221F1158002BE6B1 /* DataStorage.swift */; };
23 1291BE2D2221312D009D3F23 /* ChannelsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1291BE2C2221312C009D3F23 /* ChannelsCoordinator.swift */; };
24 1291BE2D2221312D009D3F23 /* ChannelsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1291BE2C2221312C009D3F23 /* ChannelsCoordinator.swift */; };
24 1291BE342221569B009D3F23 /* TabbarCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1291BE332221569B009D3F23 /* TabbarCoordinator.swift */; };
25 1291BE342221569B009D3F23 /* TabbarCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1291BE332221569B009D3F23 /* TabbarCoordinator.swift */; };
@@ -26,8 +27,8 @@
26 129320042279B4270035C7B3 /* MessagesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 129320032279B4270035C7B3 /* MessagesViewController.swift */; };
27 129320042279B4270035C7B3 /* MessagesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 129320032279B4270035C7B3 /* MessagesViewController.swift */; };
27 129320072279B5690035C7B3 /* MessagesCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 129320062279B5690035C7B3 /* MessagesCoordinator.swift */; };
28 129320072279B5690035C7B3 /* MessagesCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 129320062279B5690035C7B3 /* MessagesCoordinator.swift */; };
28 129320092279C3B50035C7B3 /* PeopleToWriteViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 129320082279C3B50035C7B3 /* PeopleToWriteViewController.swift */; };
29 129320092279C3B50035C7B3 /* PeopleToWriteViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 129320082279C3B50035C7B3 /* PeopleToWriteViewController.swift */; };
29− 1293200B2279D02D0035C7B3 /* DialogViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1293200A2279D02D0035C7B3 /* DialogViewController.swift */; };
30 1293200D2279D7310035C7B3 /* CompletionTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1293200C2279D7310035C7B3 /* CompletionTree.swift */; };
30 1293200D2279D7310035C7B3 /* CompletionTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1293200C2279D7310035C7B3 /* CompletionTree.swift */; };
31+ 1298810B227F13840032ACA3 /* DialogCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1298810A227F13840032ACA3 /* DialogCell.swift */; };
31 12BA4B9B224101A400DF93D7 /* ApplicationCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12BA4B9A224101A400DF93D7 /* ApplicationCoordinator.swift */; };
32 12BA4B9B224101A400DF93D7 /* ApplicationCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12BA4B9A224101A400DF93D7 /* ApplicationCoordinator.swift */; };
32 12BA4B9D224101E700DF93D7 /* BaseCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12BA4B9C224101E700DF93D7 /* BaseCoordinator.swift */; };
33 12BA4B9D224101E700DF93D7 /* BaseCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12BA4B9C224101E700DF93D7 /* BaseCoordinator.swift */; };
33 12BA4B9F224102B700DF93D7 /* LogInCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12BA4B9E224102B700DF93D7 /* LogInCoordinator.swift */; };
34 12BA4B9F224102B700DF93D7 /* LogInCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12BA4B9E224102B700DF93D7 /* LogInCoordinator.swift */; };
@@ -113,6 +114,7 @@
113 1261BB92227B364C003898CF /* ChannelViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelViewController.swift; sourceTree = "<group>"; };
114 1261BB92227B364C003898CF /* ChannelViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelViewController.swift; sourceTree = "<group>"; };
114 1261BB94227B3991003898CF /* AddToChannelVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddToChannelVC.swift; sourceTree = "<group>"; };
115 1261BB94227B3991003898CF /* AddToChannelVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddToChannelVC.swift; sourceTree = "<group>"; };
115 1261BB9D227B793D003898CF /* ChatInfoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatInfoViewController.swift; sourceTree = "<group>"; };
116 1261BB9D227B793D003898CF /* ChatInfoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatInfoViewController.swift; sourceTree = "<group>"; };
117+ 12758256227F1401001F291F /* DialogViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DialogViewController.swift; sourceTree = "<group>"; };
116 1288B5CD221F1158002BE6B1 /* DataStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataStorage.swift; sourceTree = "<group>"; };
118 1288B5CD221F1158002BE6B1 /* DataStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataStorage.swift; sourceTree = "<group>"; };
117 1291BE2C2221312C009D3F23 /* ChannelsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelsCoordinator.swift; sourceTree = "<group>"; };
119 1291BE2C2221312C009D3F23 /* ChannelsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelsCoordinator.swift; sourceTree = "<group>"; };
118 1291BE332221569B009D3F23 /* TabbarCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabbarCoordinator.swift; sourceTree = "<group>"; };
120 1291BE332221569B009D3F23 /* TabbarCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabbarCoordinator.swift; sourceTree = "<group>"; };
@@ -120,8 +122,8 @@
120 129320032279B4270035C7B3 /* MessagesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagesViewController.swift; sourceTree = "<group>"; };
122 129320032279B4270035C7B3 /* MessagesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagesViewController.swift; sourceTree = "<group>"; };
121 129320062279B5690035C7B3 /* MessagesCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagesCoordinator.swift; sourceTree = "<group>"; };
123 129320062279B5690035C7B3 /* MessagesCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagesCoordinator.swift; sourceTree = "<group>"; };
122 129320082279C3B50035C7B3 /* PeopleToWriteViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = PeopleToWriteViewController.swift; path = GDproject/Controller/Messages/PeopleToWriteViewController.swift; sourceTree = SOURCE_ROOT; };
124 129320082279C3B50035C7B3 /* PeopleToWriteViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = PeopleToWriteViewController.swift; path = GDproject/Controller/Messages/PeopleToWriteViewController.swift; sourceTree = SOURCE_ROOT; };
123− 1293200A2279D02D0035C7B3 /* DialogViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = DialogViewController.swift; path = GDproject/Controller/Messages/DialogViewController.swift; sourceTree = SOURCE_ROOT; };
124 1293200C2279D7310035C7B3 /* CompletionTree.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompletionTree.swift; sourceTree = "<group>"; };
125 1293200C2279D7310035C7B3 /* CompletionTree.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompletionTree.swift; sourceTree = "<group>"; };
126+ 1298810A227F13840032ACA3 /* DialogCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DialogCell.swift; sourceTree = "<group>"; };
125 12BA4B9A224101A400DF93D7 /* ApplicationCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationCoordinator.swift; sourceTree = "<group>"; };
127 12BA4B9A224101A400DF93D7 /* ApplicationCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationCoordinator.swift; sourceTree = "<group>"; };
126 12BA4B9C224101E700DF93D7 /* BaseCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseCoordinator.swift; sourceTree = "<group>"; };
128 12BA4B9C224101E700DF93D7 /* BaseCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseCoordinator.swift; sourceTree = "<group>"; };
127 12BA4B9E224102B700DF93D7 /* LogInCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogInCoordinator.swift; sourceTree = "<group>"; };
129 12BA4B9E224102B700DF93D7 /* LogInCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogInCoordinator.swift; sourceTree = "<group>"; };
@@ -225,12 +227,21 @@
225 children = (
227 children = (
226 1261BB9D227B793D003898CF /* ChatInfoViewController.swift */,
228 1261BB9D227B793D003898CF /* ChatInfoViewController.swift */,
227 129320082279C3B50035C7B3 /* PeopleToWriteViewController.swift */,
229 129320082279C3B50035C7B3 /* PeopleToWriteViewController.swift */,
228− 1293200A2279D02D0035C7B3 /* DialogViewController.swift */,
230+ 1298810C227F138C0032ACA3 /* Dialog */,
229 129320032279B4270035C7B3 /* MessagesViewController.swift */,
231 129320032279B4270035C7B3 /* MessagesViewController.swift */,
230 );
232 );
231 path = Messages;
233 path = Messages;
232 sourceTree = "<group>";
234 sourceTree = "<group>";
233 };
235 };
236+ 1298810C227F138C0032ACA3 /* Dialog */ = {
237+ isa = PBXGroup;
238+ children = (
239+ 12758256227F1401001F291F /* DialogViewController.swift */,
240+ 1298810A227F13840032ACA3 /* DialogCell.swift */,
241+ );
242+ path = Dialog;
243+ sourceTree = "<group>";
244+ };
234 12E36D8F221424EA006FCDD7 = {
245 12E36D8F221424EA006FCDD7 = {
235 isa = PBXGroup;
246 isa = PBXGroup;
236 children = (
247 children = (
@@ -425,10 +436,10 @@
425 12DB7FDF221877160096878E /* InviteViewController.swift in Sources */,
436 12DB7FDF221877160096878E /* InviteViewController.swift in Sources */,
426 121A8972226B1EAC005EE599 /* TagsSuggestionController.swift in Sources */,
437 121A8972226B1EAC005EE599 /* TagsSuggestionController.swift in Sources */,
427 1293200D2279D7310035C7B3 /* CompletionTree.swift in Sources */,
438 1293200D2279D7310035C7B3 /* CompletionTree.swift in Sources */,
428− 1293200B2279D02D0035C7B3 /* DialogViewController.swift in Sources */,
429 12E36DCA22144635006FCDD7 /* NewPostViewController.swift in Sources */,
439 12E36DCA22144635006FCDD7 /* NewPostViewController.swift in Sources */,
430 1261BB9E227B793D003898CF /* ChatInfoViewController.swift in Sources */,
440 1261BB9E227B793D003898CF /* ChatInfoViewController.swift in Sources */,
431 12E36D9E221424EA006FCDD7 /* NewsController.swift in Sources */,
441 12E36D9E221424EA006FCDD7 /* NewsController.swift in Sources */,
442+ 1298810B227F13840032ACA3 /* DialogCell.swift in Sources */,
432 12E36DCC22144725006FCDD7 /* PostViewCell.swift in Sources */,
443 12E36DCC22144725006FCDD7 /* PostViewCell.swift in Sources */,
433 123E37A5221F1B3200F6E42A /* LogInViewController.swift in Sources */,
444 123E37A5221F1B3200F6E42A /* LogInViewController.swift in Sources */,
434 125BD57F22171D73008A3575 /* Extentions.swift in Sources */,
445 125BD57F22171D73008A3575 /* Extentions.swift in Sources */,
@@ -439,6 +450,7 @@
439 1291BE2D2221312D009D3F23 /* ChannelsCoordinator.swift in Sources */,
450 1291BE2D2221312D009D3F23 /* ChannelsCoordinator.swift in Sources */,
440 12E36DD122148122006FCDD7 /* FullPostController.swift in Sources */,
451 12E36DD122148122006FCDD7 /* FullPostController.swift in Sources */,
441 129320042279B4270035C7B3 /* MessagesViewController.swift in Sources */,
452 129320042279B4270035C7B3 /* MessagesViewController.swift in Sources */,
453+ 12758257227F1401001F291F /* DialogViewController.swift in Sources */,
442 1288B5CE221F1158002BE6B1 /* DataStorage.swift in Sources */,
454 1288B5CE221F1158002BE6B1 /* DataStorage.swift in Sources */,
443 12BA4B9F224102B700DF93D7 /* LogInCoordinator.swift in Sources */,
455 12BA4B9F224102B700DF93D7 /* LogInCoordinator.swift in Sources */,
444 12F3D6B22241097B00A69214 /* ProfileCoordinator.swift in Sources */,
456 12F3D6B22241097B00A69214 /* ProfileCoordinator.swift in Sources */,
GDproject/Base.lproj/Main.storyboard+38−75
@@ -619,12 +619,28 @@
619 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
619 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
620 <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
620 <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
621 <prototypes>
621 <prototypes>
622− <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" id="bgd-9d-SmR">
622+ <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" reuseIdentifier="cell3" textLabel="8Ad-wM-No8" detailTextLabel="QHM-V8-CWk" style="IBUITableViewCellStyleSubtitle" id="bgd-9d-SmR">
623 <rect key="frame" x="0.0" y="28" width="375" height="44"/>
623 <rect key="frame" x="0.0" y="28" width="375" height="44"/>
624 <autoresizingMask key="autoresizingMask"/>
624 <autoresizingMask key="autoresizingMask"/>
625 <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="bgd-9d-SmR" id="9W4-bO-4MN">
625 <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="bgd-9d-SmR" id="9W4-bO-4MN">
626 <rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
626 <rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
627 <autoresizingMask key="autoresizingMask"/>
627 <autoresizingMask key="autoresizingMask"/>
628+ <subviews>
629+ <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="8Ad-wM-No8">
630+ <rect key="frame" x="16" y="5" width="33.5" height="20.5"/>
631+ <autoresizingMask key="autoresizingMask"/>
632+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
633+ <nil key="textColor"/>
634+ <nil key="highlightedColor"/>
635+ </label>
636+ <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="hfhhfhh" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="QHM-V8-CWk">
637+ <rect key="frame" x="16" y="25.5" width="44.5" height="14.5"/>
638+ <autoresizingMask key="autoresizingMask"/>
639+ <fontDescription key="fontDescription" type="system" pointSize="12"/>
640+ <nil key="textColor"/>
641+ <nil key="highlightedColor"/>
642+ </label>
643+ </subviews>
628 </tableViewCellContentView>
644 </tableViewCellContentView>
629 </tableViewCell>
645 </tableViewCell>
630 </prototypes>
646 </prototypes>
@@ -641,84 +657,31 @@
641 <!--Chat Info View Controller-->
657 <!--Chat Info View Controller-->
642 <scene sceneID="1br-Xg-fR9">
658 <scene sceneID="1br-Xg-fR9">
643 <objects>
659 <objects>
644− <tableViewController id="Rfd-Hp-Qqv" customClass="ChatInfoViewController" customModule="GDproject" customModuleProvider="target" sceneMemberID="viewController">
660+ <tableViewController storyboardIdentifier="ChatInfoViewController" id="Rfd-Hp-Qqv" customClass="ChatInfoViewController" customModule="GDproject" customModuleProvider="target" sceneMemberID="viewController">
645− <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="grouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="Rvg-ok-cnE">
661+ <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="Rvg-ok-cnE">
646 <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
662 <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
647 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
663 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
648 <color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
664 <color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
649− <sections>
665+ <prototypes>
650− <tableViewSection headerTitle="Title" id="EwY-Ph-im0">
651− <cells>
652− <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" id="hl5-Uc-R53">
666+ <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="cell" textLabel="EdJ-of-2FG" style="IBUITableViewCellStyleDefault" id="hl5-Uc-R53">
653− <rect key="frame" x="0.0" y="55.5" width="375" height="44"/>
667+ <rect key="frame" x="0.0" y="55.5" width="375" height="44"/>
654− <autoresizingMask key="autoresizingMask"/>
668+ <autoresizingMask key="autoresizingMask"/>
655− <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="hl5-Uc-R53" id="Oy5-4e-dPI">
669+ <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="hl5-Uc-R53" id="Oy5-4e-dPI">
656− <rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
670+ <rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
657− <autoresizingMask key="autoresizingMask"/>
671+ <autoresizingMask key="autoresizingMask"/>
658− </tableViewCellContentView>
672+ <subviews>
659− </tableViewCell>
660− </cells>
661− </tableViewSection>
662− <tableViewSection headerTitle="Opportunities" id="FhP-ZG-Wz1">
663− <cells>
664− <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="q4L-ZD-zVb" style="IBUITableViewCellStyleDefault" id="lrc-b1-1JB">
665− <rect key="frame" x="0.0" y="155.5" width="375" height="44"/>
666− <autoresizingMask key="autoresizingMask"/>
667− <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="lrc-b1-1JB" id="4YN-xu-f78">
668− <rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
669− <autoresizingMask key="autoresizingMask"/>
670− <subviews>
671− <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Leave chat" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="q4L-ZD-zVb">
673+ <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="EdJ-of-2FG">
672− <rect key="frame" x="16" y="0.0" width="343" height="43.5"/>
674+ <rect key="frame" x="16" y="0.0" width="343" height="43.5"/>
673− <autoresizingMask key="autoresizingMask"/>
674− <fontDescription key="fontDescription" type="system" pointSize="17"/>
675− <color key="textColor" red="1" green="0.14913141730000001" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
676− <nil key="highlightedColor"/>
677− </label>
678− </subviews>
679− </tableViewCellContentView>
680− </tableViewCell>
681− </cells>
682− </tableViewSection>
683− <tableViewSection headerTitle="Actions" id="oLK-Mz-9rh">
684− <cells>
685− <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="mO7-R4-T0a" style="IBUITableViewCellStyleDefault" id="6N5-8b-glu">
686− <rect key="frame" x="0.0" y="255.5" width="375" height="44"/>
687− <autoresizingMask key="autoresizingMask"/>
688− <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="6N5-8b-glu" id="pKT-jH-Ur5">
689− <rect key="frame" x="0.0" y="0.0" width="341" height="43.5"/>
690− <autoresizingMask key="autoresizingMask"/>
691− <subviews>
692− <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Show participants" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="mO7-R4-T0a">
693− <rect key="frame" x="16" y="0.0" width="324" height="43.5"/>
694− <autoresizingMask key="autoresizingMask"/>
695− <fontDescription key="fontDescription" type="system" pointSize="17"/>
696− <nil key="textColor"/>
697− <nil key="highlightedColor"/>
698− </label>
699− </subviews>
700− </tableViewCellContentView>
701− </tableViewCell>
702− <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="fXd-wg-rwW" style="IBUITableViewCellStyleDefault" id="VQR-WR-KA7">
703− <rect key="frame" x="0.0" y="299.5" width="375" height="44"/>
704− <autoresizingMask key="autoresizingMask"/>
705− <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="VQR-WR-KA7" id="mkm-sp-LKZ">
706− <rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
707 <autoresizingMask key="autoresizingMask"/>
675 <autoresizingMask key="autoresizingMask"/>
708− <subviews>
709− <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Add participants" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="fXd-wg-rwW">
710− <rect key="frame" x="16" y="0.0" width="343" height="43.5"/>
711− <autoresizingMask key="autoresizingMask"/>
712− <fontDescription key="fontDescription" type="system" pointSize="17"/>
676+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
713− <nil key="textColor"/>
677+ <nil key="textColor"/>
714− <nil key="highlightedColor"/>
678+ <nil key="highlightedColor"/>
715− </label>
679+ </label>
716− </subviews>
680+ </subviews>
717− </tableViewCellContentView>
681+ </tableViewCellContentView>
718− </tableViewCell>
682+ </tableViewCell>
719− </cells>
683+ </prototypes>
720− </tableViewSection>
721− </sections>
684+ <sections/>
722 <connections>
685 <connections>
723 <outlet property="dataSource" destination="Rfd-Hp-Qqv" id="ThC-G8-che"/>
686 <outlet property="dataSource" destination="Rfd-Hp-Qqv" id="ThC-G8-che"/>
724 <outlet property="delegate" destination="Rfd-Hp-Qqv" id="1WG-zg-Ahf"/>
687 <outlet property="delegate" destination="Rfd-Hp-Qqv" id="1WG-zg-Ahf"/>
GDproject/Constants.swift+2
@@ -65,5 +65,7 @@ let dialogViewController = "DialogViewController"
65
65
66let tagsSuggestionController = "TagsSuggestionController"
66let tagsSuggestionController = "TagsSuggestionController"
67
67
68+let chatInfoViewController = "ChatInfoViewController"
69+
68let blueSystemColor = UIColor(red: 0, green: 137/255, blue: 249/255, alpha: 0.5)
70let blueSystemColor = UIColor(red: 0, green: 137/255, blue: 249/255, alpha: 0.5)
69
71
GDproject/Controller/ News and channels/ChannelViewController.swift+3−2
@@ -53,7 +53,7 @@ class ChannelViewController: UITableViewController, UpdatableName, UpdatableChan
53 super.viewWillAppear(animated)
53 super.viewWillAppear(animated)
54 tableView.reloadData()
54 tableView.reloadData()
55 }
55 }
56− // TODO: update channel
56+
57 override func viewWillDisappear(_ animated: Bool) {
57 override func viewWillDisappear(_ animated: Bool) {
58
58
59 defer {
59 defer {
@@ -147,7 +147,8 @@ class ChannelViewController: UITableViewController, UpdatableName, UpdatableChan
147
147
148 override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath)
148 override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath)
149 {
149 {
150− if editingStyle == UITableViewCell.EditingStyle.delete {
150+ if editingStyle == UITableViewCell.EditingStyle.delete
151+ {
151 if indexPath.section == 1 {
152 if indexPath.section == 1 {
152 channel?.people.remove(at: indexPath.row-1)
153 channel?.people.remove(at: indexPath.row-1)
153 } else {
154 } else {
GDproject/Controller/ News and channels/NewsController.swift+1
@@ -53,6 +53,7 @@ class NewsController: UIViewController, UISearchControllerDelegate, UpdateableWi
53 updater.delegate = self
53 updater.delegate = self
54 searchController = UISearchController(searchResultsController: updater)
54 searchController = UISearchController(searchResultsController: updater)
55
55
56+ navigationController?.navigationBar.prefersLargeTitles = true
56 navigationItem.title = "Loading ..."
57 navigationItem.title = "Loading ..."
57 tableView.refreshControl = refreshContr
58 tableView.refreshControl = refreshContr
58 // Configure Refresh Control
59 // Configure Refresh Control
GDproject/Controller/ News and channels/PostViewCell.swift+3−2
@@ -8,7 +8,6 @@
8
8
9import UIKit
9import UIKit
10import Cartography
10import Cartography
11−import MarkdownKit
12import TinyConstraints
11import TinyConstraints
13
12
14class PostViewCell: UITableViewCell
13class PostViewCell: UITableViewCell
@@ -182,7 +181,9 @@ class PostViewCell: UITableViewCell
182 }
181 }
183
182
184 @objc func displayProfile(){
183 @objc func displayProfile(){
185− onUserDisplay?(post!.authorId)
184+ if let id = post?.authorId {
185+ onUserDisplay?(id)
186+ }
186 }
187 }
187
188
188 @objc func setAnonymousChannel(on button: UIButton){
189 @objc func setAnonymousChannel(on button: UIButton){
GDproject/Controller/Coordinators/MessagesCoordinator.swift+11−2
@@ -32,14 +32,23 @@ class MessagesCoordinator: BaseCoordinator {
32 vc.onUserDisplayList = { [weak vc, unowned self] in
32 vc.onUserDisplayList = { [weak vc, unowned self] in
33
33
34 let newVC = self.storyboard.instantiateViewController(withIdentifier: peopleToWriteVC) as! PeopleToWriteViewController
34 let newVC = self.storyboard.instantiateViewController(withIdentifier: peopleToWriteVC) as! PeopleToWriteViewController
35+
36+// newVC.whatToDoWithSelection = {
37+//
38+// }
39+
35 vc?.navigationController?.pushViewController(newVC, animated: true)
40 vc?.navigationController?.pushViewController(newVC, animated: true)
36 }
41 }
37
42
38− vc.onDialogDisplay = { [weak vc, unowned self] _ in
43+ vc.onDialogDisplay = { [weak vc, unowned self] in
39 let newVC = self.storyboard.instantiateViewController(withIdentifier: dialogVC) as! DialogViewController
44 let newVC = self.storyboard.instantiateViewController(withIdentifier: dialogVC) as! DialogViewController
40− //newVC.currentDialog = $0
45+ newVC.dialog = $0.dialog
46+ newVC.users = $0.users
41 vc?.navigationController?.pushViewController(newVC, animated: true)
47 vc?.navigationController?.pushViewController(newVC, animated: true)
42 }
48 }
49+
50+
51+
43 navigationController?.viewControllers = [vc]
52 navigationController?.viewControllers = [vc]
44 }
53 }
45}
54}
GDproject/Controller/Messages/ChatInfoViewController.swift+203−57
@@ -8,87 +8,233 @@
8
8
9import UIKit
9import UIKit
10
10
11−
12/// Class for displaying chat info
11/// Class for displaying chat info
13///
12///
14class ChatInfoViewController: UITableViewController {
13class ChatInfoViewController: UITableViewController {
15
14
15+ enum PersonStatus{
16+ case admin
17+ case ordinary
18+ }
19+
20+ weak var delegate: UpdatableGroup?
21+
22+ var groupChat: Model.Group? {
23+ didSet{
24+ if let groupChat = groupChat {
25+ usersArray = groupChat.users.map { $0.key }
26+ }
27+ }
28+ }
29+
30+ var usersArray: [Int] = [] {
31+ didSet {
32+ tableView.reloadData()
33+ }
34+ }
35+
36+ var users: [Int: Model.Users] = [:]
37+
38+ func canIEditThisChat() -> PersonStatus
39+ {
40+ let myId = UserDefaults.standard.integer(forKey: UserDefaultsKeys.id.rawValue)
41+
42+ if let groupChatUserPermission = groupChat?.users[myId]?.isAdmin {
43+ return groupChatUserPermission ? .admin : .ordinary
44+ }
45+
46+ return .ordinary
47+ }
48+
49+ var myPermissions: PersonStatus = .ordinary
50+
51+
16
52
17 override func viewDidLoad() {
53 override func viewDidLoad() {
18 super.viewDidLoad()
54 super.viewDidLoad()
19
55
20− // Uncomment the following line to preserve selection between presentations
56+ tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
21− // self.clearsSelectionOnViewWillAppear = false
57+ myPermissions = canIEditThisChat()
22−
58+ tableView.reloadData()
23− // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
59+
60+ switch myPermissions {
61+ case .admin:
24− // self.navigationItem.rightBarButtonItem = self.editButtonItem
62+ navigationItem.rightBarButtonItem = self.editButtonItem
63+ default:
64+ return
65+ }
25 }
66 }
26
67
27 // MARK: - Table view data source
68 // MARK: - Table view data source
28
69
29 override func numberOfSections(in tableView: UITableView) -> Int {
70 override func numberOfSections(in tableView: UITableView) -> Int {
30− // #warning Incomplete implementation, return the number of sections
71+ return 3
31− return 0
32 }
72 }
33
73
34 override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
74 override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
35− // #warning Incomplete implementation, return the number of rows
75+ switch section {
36− return 0
76+ case 0:
77+ return 1
78+ case 1:
79+ return 1
80+ default:
81+ return usersArray.count + (myPermissions == .ordinary ? 0 : 1)
82+ }
37 }
83 }
38
84
39− /*
85+
40− override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
86+ override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
87+ {
41− let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
88+ let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
42−
89+
43− // Configure the cell...
90+ if indexPath.row == 0 {
91+ switch indexPath.section {
92+ case 0:
93+ cell.textLabel?.text = groupChat!.name
94+ return cell
95+ case 1:
96+ cell.textLabel?.text = "Leave chat"
97+ cell.textLabel?.textColor = #colorLiteral(red: 1, green: 0.1491314173, blue: 0, alpha: 1)
98+ return cell
99+ default:
100+ switch myPermissions{
101+ case .admin:
102+ cell.textLabel?.text = "Add participants"
103+ cell.accessoryType = .disclosureIndicator
104+ case .ordinary:
105+ cell.textLabel?.text = name(for: users[usersArray[indexPath.row]])
106+ }
107+ return cell
108+ }
109+ }
110+
111+ switch myPermissions{
112+ case .admin:
113+ cell.textLabel?.text = name(for: users[usersArray[indexPath.row-1]])
114+ case .ordinary:
115+ cell.textLabel?.text = name(for: users[usersArray[indexPath.row]])
116+ }
44
117
45 return cell
118 return cell
46 }
119 }
47− */
120+
48−
121+ private func name(for user: Model.Users?) -> String {
49− /*
50− // Override to support conditional editing of the table view.
51− override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
52− // Return false if you do not want the specified item to be editable.
53− return true
122+ return "👤 \(user!.fullName())"
54 }
123 }
55− */
124+
56−
57− /*
58− // Override to support editing the table view.
59− override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
125+ override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
60− if editingStyle == .delete {
126+ {
61− // Delete the row from the data source
127+ switch section {
62− tableView.deleteRows(at: [indexPath], with: .fade)
128+ case 0:
63− } else if editingStyle == .insert {
129+ return "Title"
64− // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
130+ case 1:
131+ return "Opportunities"
132+ default:
133+ return "Participants"
65− }
134+ }
66− }
67− */
68−
69− /*
70− // Override to support rearranging the table view.
71− override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
72−
73 }
135 }
74− */
136+
75−
137+
76− /*
138+ func editName(for cell: UITableViewCell){
77− // Override to support conditional rearranging of the table view.
139+ let alert = UIAlertController(title: "Вы уверены?", message: "Название:", preferredStyle: .alert)
140+
141+ let action1 = UIAlertAction(title: "Oтмена", style: .cancel, handler: nil)
142+
143+ alert.addTextField { [weak self] (tf) in
144+ tf.textColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
145+ tf.text = self?.groupChat?.name
146+ }
147+
148+ let action2 = UIAlertAction(title: "OK", style: .default) { [unowned self] _ in
149+ let name = alert.textFields?.first?.text
150+ cell.textLabel?.text = name
151+ self.groupChat?.name = name!
152+ Model.updateGroupChat(with: self.groupChat!)
153+ self.delegate?.updateGroup(with: self.groupChat!)
154+ }
155+
156+ alert.addAction(action1)
157+ alert.addAction(action2)
158+
159+ present(alert, animated: true, completion: nil)
160+ }
161+ override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
162+ {
163+ guard let groupChat = groupChat else {
164+ return
165+ }
166+
167+ guard let cell = tableView.cellForRow(at: indexPath) else {
168+ return
169+ }
170+
171+ if indexPath.row == 0 {
172+ switch indexPath.section{
173+ case 0:
174+ switch myPermissions{
175+ case .admin:
176+ editName(for: cell)
177+ default:
178+ break
179+ }
180+ case 1:
181+ Model.leaveGroupChat(id: groupChat.id) {
182+ [weak self] in
183+ self?.navigationController?.popViewController(animated: true)
184+ }
185+ default:
186+ showUserChoiceVC()
187+ }
188+ }
189+ }
190+
191+ func showUserChoiceVC()
192+ {
193+ let vc = storyboard?.instantiateViewController(withIdentifier: peopleToWriteVC) as! PeopleToWriteViewController
194+
195+ vc.whatToDoWithSelection = { [weak self, weak vc] mapa in
196+
197+ mapa.forEach { self?.users[$0.key] = Model.Channels.fullPeopleDict[$0.key] }
198+ mapa.forEach { self?.groupChat?.users[$0.key] = $0.value }
199+ vc?.navigationController?.popViewController(animated: true)
200+ }
201+
202+ navigationController?.pushViewController(vc, animated: true)
203+ }
204+
78− override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
205+ override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath)
79− // Return false if you do not want the item to be re-orderable.
206+ {
207+ if editingStyle == UITableViewCell.EditingStyle.delete {
208+ groupChat?.users[usersArray[indexPath.row-1]] = nil
209+ }
210+
211+ tableView.reloadData()
212+ }
213+
214+ override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
215+ if indexPath.row == 0 {
216+ return false
217+ }
218+
80 return true
219 return true
81 }
220 }
82− */
221+
83−
222+ /// update chatInfo
84− /*
223+ override func viewWillDisappear(_ animated: Bool) {
85− // MARK: - Navigation
224+
86−
225+ defer {
87− // In a storyboard-based application, you will often want to do a little preparation before navigation
226+ super.viewWillDisappear(animated)
88− override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
227+ }
89− // Get the new view controller using segue.destination.
228+
90− // Pass the selected object to the new view controller.
229+ guard let _ = self.navigationController?.viewControllers.lastIndex(of: self) else {
230+ switch myPermissions {
231+ case .ordinary:
232+ return
233+ case .admin:
234+ Model.updateGroupChat(with: groupChat!)
235+ delegate?.updateGroup(with: groupChat!)
236+ }
237+ return
238+ }
91 }
239 }
92− */
93−
94}
240}
GDproject/Controller/Messages/Dialog/DialogCell.swiftnew file+93
@@ -0,0 +1,93 @@
1+//
2+// DialogCell.swift
3+// GDproject
4+//
5+// Created by cstore on 05/05/2019.
6+// Copyright © 2019 drHSE. All rights reserved.
7+//
8+
9+import UIKit
10+import TinyConstraints
11+import MarkdownKit
12+
13+class DialogCell: UITableViewCell {
14+
15+ let nameLabel: UIButton = {
16+ let button = UIButton()
17+ button.setTitleColor(.black, for: .normal)
18+ button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)
19+ button.addTarget(self, action: #selector(displayProfile), for: .touchUpInside)
20+ button.contentHorizontalAlignment = UIControl.ContentHorizontalAlignment.left
21+ return button
22+ }()
23+
24+ @objc func displayProfile()
25+ {
26+ if let id = self.user?.id{
27+ onUserDisplay?(id)
28+ }
29+ }
30+ var onUserDisplay: ((Int)->())?
31+
32+ let fullNameLabel: UILabel = {
33+ let label = UILabel()
34+ label.textColor = #colorLiteral(red: 0.3333333433, green: 0.3333333433, blue: 0.3333333433, alpha: 1)
35+ label.text = "Богомазова Вероника Львовна"
36+ label.font = UIFont.systemFont(ofSize: 12)
37+ return label
38+ }()
39+
40+ let timeLabel: UILabel = {
41+ let label = UILabel()
42+ label.font = UIFont.systemFont(ofSize: 12)
43+ label.textColor = #colorLiteral(red: 0.6000000238, green: 0.6000000238, blue: 0.6000000238, alpha: 1)
44+ return label
45+ }()
46+
47+ func createTextView(with text: NSAttributedString, _ isSelectable: Bool) -> UITextView
48+ {
49+ let textView = UITextView()
50+ textView.isScrollEnabled = false
51+ textView.isEditable = false
52+
53+ if isSelectable {
54+ textView.isSelectable = true
55+ } else {
56+ textView.isUserInteractionEnabled = false
57+ }
58+
59+ textView.attributedText = text
60+ return textView
61+ }
62+
63+ override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?)
64+ {
65+ super.init(style: style, reuseIdentifier: reuseIdentifier)
66+ }
67+
68+ required init?(coder aDecoder: NSCoder)
69+ {
70+ fatalError("init(coder:) has not been implemented")
71+ }
72+
73+ var user: Model.Users? {
74+ didSet{
75+ nameLabel.setTitle(user!.fullName(), for: .normal)
76+ }
77+ }
78+
79+ func fill(with markdownText: NSAttributedString, byUser: Model.Users)
80+ {
81+ // important
82+ contentView.subviews.forEach({ $0.removeFromSuperview() })
83+
84+ self.user = byUser
85+ let textView = createTextView(with: markdownText, true)
86+
87+ self.contentView.addSubview(nameLabel)
88+ self.contentView.addSubview(textView)
89+ nameLabel.edgesToSuperview(excluding: .bottom, insets: .top(8) + .left(8))
90+ textView.edgesToSuperview(excluding: .top, insets: .right(8) + .left(8) + .bottom(8))
91+ textView.topToBottom(of: nameLabel)
92+ }
93+}
GDproject/Controller/Messages/Dialog/DialogViewController.swiftnew file+145
@@ -0,0 +1,145 @@
1+//
2+// DialogViewController.swift
3+// GDproject
4+//
5+// Created by cstore on 01/05/2019.
6+// Copyright © 2019 drHSE. All rights reserved.
7+//
8+
9+import UIKit
10+
11+protocol UpdatableGroup:class {
12+ func updateGroup(with group: Model.Group)
13+}
14+
15+class DialogViewController: UITableViewController, UpdatableGroup {
16+
17+ func updateGroup(with group: Model.Group){
18+ self.groupChat?.group = group
19+ setTitleForGroup(groupChat: groupChat!)
20+ }
21+
22+ let cellId = "cell3"
23+ var onInfoShow: (()->())?
24+
25+ var dialog: Model.Dialog? {
26+ didSet{
27+ switch dialog! {
28+ case .groupChat(let chat):
29+ self.groupChat = chat
30+ case .userChat(let chat):
31+ self.userChat = chat
32+ }
33+ }
34+ }
35+
36+ var groupChat: Model.GroupChat?
37+ var userChat: Model.UserChat?
38+
39+ var users: [Int: Model.Users]?
40+
41+ var groupId: Int?
42+
43+ var cellData: [PostCellData] = [] {
44+ didSet {
45+ print(cellData)
46+ tableView.reloadData()
47+ }
48+ }
49+
50+ override func viewDidLoad() {
51+ super.viewDidLoad()
52+
53+ tabBarController?.tabBar.isHidden = true
54+ navigationItem.largeTitleDisplayMode = .never
55+
56+ tableView.register(DialogCell.self, forCellReuseIdentifier: cellId)
57+ tableView.transform = CGAffineTransform(scaleX: 1, y: -1)
58+ tableView.contentInsetAdjustmentBehavior = .never
59+ tableView.contentOffset = CGPoint(x: 0, y: -30)
60+
61+ if let groupChat = groupChat {
62+ setTitleForGroup(groupChat: groupChat)
63+ } else if let userChat = userChat{
64+ setTitleForChat(userChat: userChat)
65+ }
66+ }
67+
68+ func setTitleForChat(userChat: Model.UserChat){
69+ navigationItem.title = "🌌 \(users![userChat.user]!.fullName())"
70+ }
71+
72+ func setTitleForGroup(groupChat: Model.GroupChat){
73+ navigationItem.title = "🌌 \(groupChat.group.id) \(groupChat.group.name)"
74+ navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Info", style: .plain, target: self, action: #selector(moveToInfoVC))
75+ }
76+
77+ @objc func moveToInfoVC(){
78+ let vc = storyboard?.instantiateViewController(withIdentifier: chatInfoViewController) as! ChatInfoViewController
79+
80+ vc.delegate = self
81+ vc.users = users!
82+
83+ if let groupChat = groupChat {
84+ vc.groupChat = groupChat.group
85+ }
86+
87+ navigationController?.pushViewController(vc, animated: true)
88+ }
89+
90+ var currentMessagesInChat: [Model.LastMessage]? {
91+ didSet {
92+ if let currentMessagesInChat = currentMessagesInChat {
93+ cellData = currentMessagesInChat.map { PostCellData(attributedData: PostCellData.create(with: [$0.body])) }
94+ }
95+ }
96+ }
97+
98+ // MARK: - Table view data source
99+
100+ override func numberOfSections(in tableView: UITableView) -> Int {
101+ return 1
102+ }
103+
104+ override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
105+ return cellData.count
106+ }
107+
108+ override func viewWillAppear(_ animated: Bool) {
109+ super.viewWillAppear(animated)
110+
111+ if let dialog = dialog {
112+ getMessages(for: dialog)
113+ }
114+ }
115+
116+ func getMessages(for dialog: Model.Dialog){
117+ switch dialog {
118+ case .groupChat(let groupChat):
119+ Model.getMessagesFor(typeOfChat: Model.Dialog.groupChat(groupChat), chat: groupChat.group.id)
120+ { [unowned self] in
121+ self.currentMessagesInChat = $0
122+ }
123+ case .userChat(let userChat):
124+ Model.getMessagesFor(typeOfChat: Model.Dialog.userChat(userChat), chat: userChat.user)
125+ { [unowned self] in
126+ self.currentMessagesInChat = $0
127+ }
128+ }
129+ }
130+
131+ override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
132+ {
133+ let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! DialogCell
134+
135+ //In cellForRowAtIndexPath
136+ cell.transform = CGAffineTransform(scaleX: 1, y: -1)
137+
138+ if let author = currentMessagesInChat?[indexPath.row].author, let user = users?[author]
139+ {
140+ cell.fill(with: cellData[indexPath.row].attributedData, byUser: user)
141+ }
142+
143+ return cell
144+ }
145+}
GDproject/Controller/Messages/DialogViewController.swiftdeleted−67
@@ -1,67 +0,0 @@
1−//
2−// DialogViewController.swift
3−// GDproject
4−//
5−// Created by cstore on 01/05/2019.
6−// Copyright © 2019 drHSE. All rights reserved.
7−//
8−
9−import UIKit
10−
11−class DialogViewController: UITableViewController {
12−
13− var onInfoShow: (()->())?
14− var group: Model.Group?
15−
16− override func viewDidLoad() {
17− super.viewDidLoad()
18−
19− tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
20−
21− if let id = group {
22− navigationItem.title = "🌌 \(id.id) \(id.name)"
23− navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Info", style: .plain, target: self, action: #selector(moveToInfoVC))
24− }
25− }
26−
27−
28− @objc func moveToInfoVC(){
29−
30− }
31−
32− var currentMessagesInChat: [Model.LastMessage]? {
33− didSet {
34− tableView.reloadData()
35− }
36− }
37−
38− // MARK: - Table view data source
39−
40− override func numberOfSections(in tableView: UITableView) -> Int {
41− return 1
42− }
43−
44− override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
45− return currentMessagesInChat?.count ?? 0
46− }
47−
48− override func viewWillAppear(_ animated: Bool) {
49− super.viewWillAppear(animated)
50−
51− if let group = group {
52− Model.getMessagesForGroupChat(chat: group.id) { [unowned self] in
53− self.currentMessagesInChat = $0
54− }
55− }
56− }
57−
58− override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
59− {
60− let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
61−
62− cell.detailTextLabel?.text = currentMessagesInChat![indexPath.row].body.markdown
63− cell.textLabel?.text = "\(currentMessagesInChat![indexPath.row].author)"
64−
65− return cell
66− }
67−}
GDproject/Controller/Messages/MessagesViewController.swift+11−6
@@ -12,14 +12,17 @@ class MessagesViewController: UITableViewController {
12
12
13 // curreent Active which can be displayed
13 // curreent Active which can be displayed
14 var currentActiveDialogs: [Model.Dialog] = [] {
14 var currentActiveDialogs: [Model.Dialog] = [] {
15− didSet{
15+ didSet {
16 tableView.reloadData()
16 tableView.reloadData()
17 }
17 }
18 }
18 }
19
19
20+ // curreent users
21+ var users: [Int: Model.Users] = [:]
22+
20 var onUserDisplayList: (()->())?
23 var onUserDisplayList: (()->())?
21
24
22− var onDialogDisplay: ((Model.Dialog)->())?
25+ var onDialogDisplay: (((dialog: Model.Dialog, users: [Int:Model.Users]))->())?
23
26
24 let searchC = UISearchController(searchResultsController: nil)
27 let searchC = UISearchController(searchResultsController: nil)
25
28
@@ -42,9 +45,10 @@ class MessagesViewController: UITableViewController {
42
45
43 override func viewWillAppear(_ animated: Bool) {
46 override func viewWillAppear(_ animated: Bool) {
44 super.viewWillAppear(animated)
47 super.viewWillAppear(animated)
45−
48+ tabBarController?.tabBar.isHidden = false
46 Model.getChatAll { [weak self] in
49 Model.getChatAll { [weak self] in
47− self?.currentActiveDialogs = $0
50+ self?.currentActiveDialogs = $0.0
51+ self?.users = $0.1
48 }
52 }
49 }
53 }
50
54
@@ -67,7 +71,7 @@ class MessagesViewController: UITableViewController {
67 cell.textLabel?.text = group.group.name
71 cell.textLabel?.text = group.group.name
68 cell.detailTextLabel?.text = group.lastMessage.body.markdown
72 cell.detailTextLabel?.text = group.lastMessage.body.markdown
69 case .userChat(let userChat):
73 case .userChat(let userChat):
70− cell.textLabel?.text = "\(userChat.user)"
74+ cell.textLabel?.text = "\(users[userChat.user]!)"
71 cell.detailTextLabel?.text = userChat.lastMessage.body.markdown
75 cell.detailTextLabel?.text = userChat.lastMessage.body.markdown
72 }
76 }
73
77
@@ -75,6 +79,7 @@ class MessagesViewController: UITableViewController {
75 }
79 }
76
80
77 override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
81 override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
78− onDialogDisplay?(currentActiveDialogs[indexPath.row])
82+ let tuple = (currentActiveDialogs[indexPath.row],users)
83+ onDialogDisplay?(tuple)
79 }
84 }
80}
85}
GDproject/Controller/Messages/PeopleToWriteViewController.swift+6−14
@@ -10,7 +10,8 @@ import UIKit
10
10
11class PeopleToWriteViewController: UITableViewController {
11class PeopleToWriteViewController: UITableViewController {
12
12
13− // TODO: - edit button when it's used for selection
13+ // TODO: - edit button when it's used for selection
14+ var whatToDoWithSelection: (([Int: Model.UserPermission])->())?
14
15
15 let searchC = UISearchController(searchResultsController: nil)
16 let searchC = UISearchController(searchResultsController: nil)
16
17
@@ -23,7 +24,9 @@ class PeopleToWriteViewController: UITableViewController {
23
24
24 tableView.isEditing = true
25 tableView.isEditing = true
25 self.navigationItem.title = "People"
26 self.navigationItem.title = "People"
27+
26− self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .compose, target: self, action: #selector(newMessage))
28+ self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(newMessage))
29+
27 self.navigationItem.largeTitleDisplayMode = .never
30 self.navigationItem.largeTitleDisplayMode = .never
28 self.navigationItem.searchController = searchC
31 self.navigationItem.searchController = searchC
29 self.navigationItem.hidesSearchBarWhenScrolling = false
32 self.navigationItem.hidesSearchBarWhenScrolling = false
@@ -32,15 +35,12 @@ class PeopleToWriteViewController: UITableViewController {
32 override func setEditing(_ editing: Bool, animated: Bool) {
35 override func setEditing(_ editing: Bool, animated: Bool) {
33 super.setEditing(true, animated: animated)
36 super.setEditing(true, animated: animated)
34 }
37 }
35− // MARK: - Table view data source
36
38
37 override func numberOfSections(in tableView: UITableView) -> Int {
39 override func numberOfSections(in tableView: UITableView) -> Int {
38− // #warning Incomplete implementation, return the number of sections
39 return 1
40 return 1
40 }
41 }
41
42
42 override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
43 override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
43− // #warning Incomplete implementation, return the number of rows
44 return users.count
44 return users.count
45 }
45 }
46
46
@@ -62,15 +62,7 @@ class PeopleToWriteViewController: UITableViewController {
62 {
62 {
63 if chosenUsers.count != 0
63 if chosenUsers.count != 0
64 {
64 {
65− navigationController?.popViewController(animated: false)
65+ whatToDoWithSelection?(chosenUsers)
66− var group = Model.Group(users: chosenUsers, name: "Untitled", id: 0)
67−
68− Model.createGroupChat(from: group) { [unowned self] (id) in
69− let vc = self.storyboard?.instantiateViewController(withIdentifier: dialogViewController) as! DialogViewController
70− group.id = id
71− vc.group = group
72− self.navigationController?.pushViewController(vc, animated: true)
73− }
74 }
66 }
75 }
67 }
76}
68}
GDproject/Simple model/Model.swift+51−11
@@ -40,7 +40,7 @@ class Model{
40 static let channelsDeleteURL = URL(string: "\(baseUrl)/channels/delete")!
40 static let channelsDeleteURL = URL(string: "\(baseUrl)/channels/delete")!
41 static let channelsGetAnonURL = URL(string: "\(baseUrl)/channels/getAnonymous")!
41 static let channelsGetAnonURL = URL(string: "\(baseUrl)/channels/getAnonymous")!
42 static let complexURL = URL(string: "\(baseUrl)/complex")!
42 static let complexURL = URL(string: "\(baseUrl)/complex")!
43− static let hashTagTreeURL = URL(string: "\(baseUrl)/tagCompletions")!
43+ static let hashTagTreeURL = URL(string: "\(baseUrl)/tags/completions")!
44 static let createGroupChatURL = URL(string: "\(baseUrl)/chats/createGroupChat")!
44 static let createGroupChatURL = URL(string: "\(baseUrl)/chats/createGroupChat")!
45 static let chatsGetAllURL = URL(string: "\(baseUrl)/chats/getAll")!
45 static let chatsGetAllURL = URL(string: "\(baseUrl)/chats/getAll")!
46 static let getGroupChatURL = URL(string: "\(baseUrl)/chats/getGroupChat")!
46 static let getGroupChatURL = URL(string: "\(baseUrl)/chats/getGroupChat")!
@@ -48,7 +48,7 @@ class Model{
48 static let updateGroupChatURL = URL(string: "\(baseUrl)/chats/updateGroupChat")!
48 static let updateGroupChatURL = URL(string: "\(baseUrl)/chats/updateGroupChat")!
49 static let messagesGetGroupChatURL = URL(string: "\(baseUrl)/messages/get/groupChat")! //r
49 static let messagesGetGroupChatURL = URL(string: "\(baseUrl)/messages/get/groupChat")! //r
50 static let messagesSendURL = URL(string: "\(baseUrl)/messages/send")!
50 static let messagesSendURL = URL(string: "\(baseUrl)/messages/send")!
51− static let messagesUserChatURL = URL(string: "\(baseUrl)/messages/userChat")!
51+ static let messagesGetUserChatURL = URL(string: "\(baseUrl)/messages/get/userChat")!
52
52
53
53
54 struct QueryPosts<T: Codable>: Codable {
54 struct QueryPosts<T: Codable>: Codable {
@@ -559,7 +559,7 @@ class Model{
559 }
559 }
560 }
560 }
561
561
562− static func getChatAll(limit: Int = 10, exclusiveFrom: Int? = nil, request: [Int] = [], completion: @escaping (([Dialog])->()))
562+ static func getChatAll(limit: Int = 10, exclusiveFrom: Int? = nil, request: [Int] = [], completion: @escaping ((([Dialog],[Int:Model.Users]))->()))
563 {
563 {
564 let req = GeneralRequest<[Int]>(limit: limit, exclusiveFrom: exclusiveFrom, request: request)
564 let req = GeneralRequest<[Int]>(limit: limit, exclusiveFrom: exclusiveFrom, request: request)
565 var request = URLRequest(url: chatsGetAllURL)
565 var request = URLRequest(url: chatsGetAllURL)
@@ -573,8 +573,7 @@ class Model{
573 guard let json = response.data else { return }
573 guard let json = response.data else { return }
574 let dialogs = try! decoder.decode(QueryPosts<Dialog>.self, from: json)
574 let dialogs = try! decoder.decode(QueryPosts<Dialog>.self, from: json)
575
575
576− print(dialogs.response)
577− completion(dialogs.response)
576+ completion((dialogs.response,dialogs.users))
578 }
577 }
579 }
578 }
580
579
@@ -624,6 +623,12 @@ class Model{
624 var users: [Int: UserPermission]
623 var users: [Int: UserPermission]
625 var name: String
624 var name: String
626 var id: Int
625 var id: Int
626+
627+ init(users: [Int: UserPermission] = [:], name: String = "", id: Int) {
628+ self.id = id
629+ self.users = users
630+ self.name = name
631+ }
627 }
632 }
628
633
629 struct UserPermission: Codable {
634 struct UserPermission: Codable {
@@ -734,16 +739,23 @@ class Model{
734 }
739 }
735 }
740 }
736
741
737− static func getMessagesForGroupChat(chat id: Int, exclusiveFrom: Int? = nil, limit l: Int = 10, direction: String = "backward", completion: @escaping (([LastMessage])->()))
742+ static func getMessagesFor(typeOfChat: Model.Dialog, chat id: Int, exclusiveFrom: Int? = nil, limit l: Int = 10, direction: String = "backward", completion: @escaping (([LastMessage])->()))
738 {
743 {
739 let req = GeneralRequest<Int>(direction: direction, limit: l, exclusiveFrom: exclusiveFrom, request: id)
744 let req = GeneralRequest<Int>(direction: direction, limit: l, exclusiveFrom: exclusiveFrom, request: id)
745+ var request: URLRequest?
740
746
747+ switch typeOfChat {
748+ case .groupChat:
741− var request = URLRequest(url: messagesGetGroupChatURL)
749+ request = URLRequest(url: messagesGetGroupChatURL)
742− request.httpMethod = "POST"
750+ case .userChat:
743− request.httpBody = try? JSONEncoder().encode(req)
751+ request = URLRequest(url: messagesGetUserChatURL)
744− request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
752+ }
745
753
754+ request!.httpMethod = "POST"
755+ request!.httpBody = try? JSONEncoder().encode(req)
756+ request!.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
757+
746− AF.request(request).response { (response) in
758+ AF.request(request!).response { (response) in
747
759
748 isValidTocken?(response.response?.statusCode ?? 498)
760 isValidTocken?(response.response?.statusCode ?? 498)
749
761
@@ -753,4 +765,32 @@ class Model{
753 completion(messages)
765 completion(messages)
754 }
766 }
755 }
767 }
768+
769+ static func leaveGroupChat(id: Int, completion: @escaping (()->()))
770+ {
771+ var request = URLRequest(url: leaveGroupChatURL)
772+ request.httpMethod = "POST"
773+ request.httpBody = "\(id)".data(using: .utf8)
774+ request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
775+
776+ AF.request(request).response { (response) in
777+ isValidTocken?(response.response?.statusCode ?? 498)
778+ }
779+
780+ completion()
781+ }
782+
783+ static func updateGroupChat(with group: Model.Group)
784+ {
785+ var request = URLRequest(url: updateGroupChatURL)
786+ request.httpMethod = "POST"
787+ request.httpBody = try? JSONEncoder().encode(group)
788+ request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
789+
790+ AF.request(request).response { (response) in
791+ isValidTocken?(response.response?.statusCode ?? 498)
792+ }
793+
794+ // completion()
795+ }
756}
796}