mirror of
https://github.com/vector-im/element-ios.git
synced 2024-09-29 15:52:40 +00:00
Merge pull request #28 from vector-im/room_photo_selection
Room photo selection Improve the room settings page -> add the room photo management -> display if a room is public or private -> enable / disable the room notification Else Improve the room naming.
This commit is contained in:
commit
27690a4333
20 changed files with 1125 additions and 70 deletions
|
@ -25,9 +25,15 @@
|
|||
717928481C03852C00407D96 /* TableViewCellWithLabelAndLargeTextView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 717928411C03852C00407D96 /* TableViewCellWithLabelAndLargeTextView.xib */; };
|
||||
717928491C03852C00407D96 /* TableViewCellWithLabelAndTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 717928431C03852C00407D96 /* TableViewCellWithLabelAndTextField.m */; };
|
||||
7179284A1C03852C00407D96 /* TableViewCellWithLabelAndTextField.xib in Resources */ = {isa = PBXBuildFile; fileRef = 717928441C03852C00407D96 /* TableViewCellWithLabelAndTextField.xib */; };
|
||||
71B2A3BB1C2013DC00472061 /* TableViewCellWithLabelAndMXKImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 71B2A3B91C2013DC00472061 /* TableViewCellWithLabelAndMXKImageView.m */; };
|
||||
71B2A3BC1C2013DC00472061 /* TableViewCellWithLabelAndMXKImageView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 71B2A3BA1C2013DC00472061 /* TableViewCellWithLabelAndMXKImageView.xib */; };
|
||||
71B2A3C01C203C7100472061 /* TableViewCellWithLabelAndSwitch.m in Sources */ = {isa = PBXBuildFile; fileRef = 71B2A3BE1C203C7100472061 /* TableViewCellWithLabelAndSwitch.m */; };
|
||||
71B2A3C11C203C7100472061 /* TableViewCellWithLabelAndSwitch.xib in Resources */ = {isa = PBXBuildFile; fileRef = 71B2A3BF1C203C7100472061 /* TableViewCellWithLabelAndSwitch.xib */; };
|
||||
71C5F2951C074ACC004C094B /* RoomSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 71C5F2941C074ACC004C094B /* RoomSettingsViewController.m */; };
|
||||
71EBE66D1C04C4D300E7D953 /* RoomActivitiesView.m in Sources */ = {isa = PBXBuildFile; fileRef = 71EBE66B1C04C4D300E7D953 /* RoomActivitiesView.m */; };
|
||||
71EBE66E1C04C4D300E7D953 /* RoomActivitiesView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 71EBE66C1C04C4D300E7D953 /* RoomActivitiesView.xib */; };
|
||||
71F7F5151C218D8900E7ED8F /* RecentCellData.m in Sources */ = {isa = PBXBuildFile; fileRef = 71F7F5141C218D8900E7ED8F /* RecentCellData.m */; };
|
||||
71F7F5181C22CC7500E7ED8F /* MXRoom+Vector.m in Sources */ = {isa = PBXBuildFile; fileRef = 71F7F5171C22CC7500E7ED8F /* MXRoom+Vector.m */; };
|
||||
F001D7621B8207C000A162C3 /* RoomInputToolbarView.m in Sources */ = {isa = PBXBuildFile; fileRef = F001D75C1B8207C000A162C3 /* RoomInputToolbarView.m */; };
|
||||
F001D7631B8207C000A162C3 /* RoomInputToolbarView.xib in Resources */ = {isa = PBXBuildFile; fileRef = F001D75D1B8207C000A162C3 /* RoomInputToolbarView.xib */; };
|
||||
F001D76C1B821E4F00A162C3 /* MediaPickerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F001D76B1B821E4F00A162C3 /* MediaPickerViewController.m */; };
|
||||
|
@ -188,12 +194,22 @@
|
|||
717928421C03852C00407D96 /* TableViewCellWithLabelAndTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TableViewCellWithLabelAndTextField.h; path = TableViewCell/TableViewCellWithLabelAndTextField.h; sourceTree = "<group>"; };
|
||||
717928431C03852C00407D96 /* TableViewCellWithLabelAndTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TableViewCellWithLabelAndTextField.m; path = TableViewCell/TableViewCellWithLabelAndTextField.m; sourceTree = "<group>"; };
|
||||
717928441C03852C00407D96 /* TableViewCellWithLabelAndTextField.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = TableViewCellWithLabelAndTextField.xib; path = TableViewCell/TableViewCellWithLabelAndTextField.xib; sourceTree = "<group>"; };
|
||||
71B2A3B81C2013DC00472061 /* TableViewCellWithLabelAndMXKImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TableViewCellWithLabelAndMXKImageView.h; path = TableViewCell/TableViewCellWithLabelAndMXKImageView.h; sourceTree = "<group>"; };
|
||||
71B2A3B91C2013DC00472061 /* TableViewCellWithLabelAndMXKImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TableViewCellWithLabelAndMXKImageView.m; path = TableViewCell/TableViewCellWithLabelAndMXKImageView.m; sourceTree = "<group>"; };
|
||||
71B2A3BA1C2013DC00472061 /* TableViewCellWithLabelAndMXKImageView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = TableViewCellWithLabelAndMXKImageView.xib; path = TableViewCell/TableViewCellWithLabelAndMXKImageView.xib; sourceTree = "<group>"; };
|
||||
71B2A3BD1C203C7100472061 /* TableViewCellWithLabelAndSwitch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TableViewCellWithLabelAndSwitch.h; path = TableViewCell/TableViewCellWithLabelAndSwitch.h; sourceTree = "<group>"; };
|
||||
71B2A3BE1C203C7100472061 /* TableViewCellWithLabelAndSwitch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TableViewCellWithLabelAndSwitch.m; path = TableViewCell/TableViewCellWithLabelAndSwitch.m; sourceTree = "<group>"; };
|
||||
71B2A3BF1C203C7100472061 /* TableViewCellWithLabelAndSwitch.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = TableViewCellWithLabelAndSwitch.xib; path = TableViewCell/TableViewCellWithLabelAndSwitch.xib; sourceTree = "<group>"; };
|
||||
71C5F2931C074ACC004C094B /* RoomSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RoomSettingsViewController.h; sourceTree = "<group>"; };
|
||||
71C5F2941C074ACC004C094B /* RoomSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RoomSettingsViewController.m; sourceTree = "<group>"; };
|
||||
71C5F2991C077007004C094B /* VectorDesignValues.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VectorDesignValues.h; sourceTree = "<group>"; };
|
||||
71EBE66A1C04C4D300E7D953 /* RoomActivitiesView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RoomActivitiesView.h; path = RoomActivitiesView/RoomActivitiesView.h; sourceTree = "<group>"; };
|
||||
71EBE66B1C04C4D300E7D953 /* RoomActivitiesView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RoomActivitiesView.m; path = RoomActivitiesView/RoomActivitiesView.m; sourceTree = "<group>"; };
|
||||
71EBE66C1C04C4D300E7D953 /* RoomActivitiesView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = RoomActivitiesView.xib; path = RoomActivitiesView/RoomActivitiesView.xib; sourceTree = "<group>"; };
|
||||
71F7F5131C218D8900E7ED8F /* RecentCellData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecentCellData.h; sourceTree = "<group>"; };
|
||||
71F7F5141C218D8900E7ED8F /* RecentCellData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RecentCellData.m; sourceTree = "<group>"; };
|
||||
71F7F5161C22CC7500E7ED8F /* MXRoom+Vector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MXRoom+Vector.h"; sourceTree = "<group>"; };
|
||||
71F7F5171C22CC7500E7ED8F /* MXRoom+Vector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MXRoom+Vector.m"; sourceTree = "<group>"; };
|
||||
9B179239B79688A61A3F465F /* libPods-Vector.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Vector.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F001D75B1B8207C000A162C3 /* RoomInputToolbarView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RoomInputToolbarView.h; sourceTree = "<group>"; };
|
||||
F001D75C1B8207C000A162C3 /* RoomInputToolbarView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RoomInputToolbarView.m; sourceTree = "<group>"; };
|
||||
|
@ -402,9 +418,15 @@
|
|||
7179283C1C03852C00407D96 /* TableViewCellSeparator.h */,
|
||||
7179283D1C03852C00407D96 /* TableViewCellSeparator.m */,
|
||||
7179283E1C03852C00407D96 /* TableViewCellSeparator.xib */,
|
||||
71B2A3BD1C203C7100472061 /* TableViewCellWithLabelAndSwitch.h */,
|
||||
71B2A3BE1C203C7100472061 /* TableViewCellWithLabelAndSwitch.m */,
|
||||
71B2A3BF1C203C7100472061 /* TableViewCellWithLabelAndSwitch.xib */,
|
||||
7179283F1C03852C00407D96 /* TableViewCellWithLabelAndLargeTextView.h */,
|
||||
717928401C03852C00407D96 /* TableViewCellWithLabelAndLargeTextView.m */,
|
||||
717928411C03852C00407D96 /* TableViewCellWithLabelAndLargeTextView.xib */,
|
||||
71B2A3B81C2013DC00472061 /* TableViewCellWithLabelAndMXKImageView.h */,
|
||||
71B2A3B91C2013DC00472061 /* TableViewCellWithLabelAndMXKImageView.m */,
|
||||
71B2A3BA1C2013DC00472061 /* TableViewCellWithLabelAndMXKImageView.xib */,
|
||||
717928421C03852C00407D96 /* TableViewCellWithLabelAndTextField.h */,
|
||||
717928431C03852C00407D96 /* TableViewCellWithLabelAndTextField.m */,
|
||||
717928441C03852C00407D96 /* TableViewCellWithLabelAndTextField.xib */,
|
||||
|
@ -514,6 +536,8 @@
|
|||
F00C47881BFF854400DBABC9 /* RoomList */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
71F7F5131C218D8900E7ED8F /* RecentCellData.h */,
|
||||
71F7F5141C218D8900E7ED8F /* RecentCellData.m */,
|
||||
F00C47891BFF854400DBABC9 /* RecentsDataSource.h */,
|
||||
F00C478A1BFF854400DBABC9 /* RecentsDataSource.m */,
|
||||
);
|
||||
|
@ -697,6 +721,8 @@
|
|||
F0C34CB51C17145F00C36F09 /* Categories */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
71F7F5161C22CC7500E7ED8F /* MXRoom+Vector.h */,
|
||||
71F7F5171C22CC7500E7ED8F /* MXRoom+Vector.m */,
|
||||
F0C34CB61C17145F00C36F09 /* MXKRoomBubbleTableViewCell+Vector.h */,
|
||||
F0C34CB71C17145F00C36F09 /* MXKRoomBubbleTableViewCell+Vector.m */,
|
||||
);
|
||||
|
@ -858,6 +884,7 @@
|
|||
F02528D91C11B6FC00E1FE1B /* camera_play.png in Resources */,
|
||||
F0D2D9881C197DCB007B8C96 /* RoomIncomingTextMsgBubbleCell.xib in Resources */,
|
||||
F02529001C11B6FC00E1FE1B /* settings_icon.png in Resources */,
|
||||
71B2A3BC1C2013DC00472061 /* TableViewCellWithLabelAndMXKImageView.xib in Resources */,
|
||||
F02528D81C11B6FC00E1FE1B /* camera_picture.png in Resources */,
|
||||
F02528E01C11B6FC00E1FE1B /* create_room.png in Resources */,
|
||||
F02528DF1C11B6FC00E1FE1B /* camera_video.png in Resources */,
|
||||
|
@ -890,6 +917,7 @@
|
|||
F0C34B641C15C28300C36F09 /* RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.xib in Resources */,
|
||||
F02528D61C11B6FC00E1FE1B /* camera_capture@2x.png in Resources */,
|
||||
71046D601C0C86C600DCA984 /* RoomTitleViewWithTopic.xib in Resources */,
|
||||
71B2A3C11C203C7100472061 /* TableViewCellWithLabelAndSwitch.xib in Resources */,
|
||||
F02528D51C11B6FC00E1FE1B /* camera_capture.png in Resources */,
|
||||
F02528EA1C11B6FC00E1FE1B /* low_priority_icon@2x.png in Resources */,
|
||||
F02528EE1C11B6FC00E1FE1B /* mute_icon@3x.png in Resources */,
|
||||
|
@ -1022,6 +1050,7 @@
|
|||
F094AA051B78E3D400B1FBBF /* empty.mm in Sources */,
|
||||
F0A1CD221B9F4BBA00F9C15C /* RoomParticipantsViewController.m in Sources */,
|
||||
F001D76C1B821E4F00A162C3 /* MediaPickerViewController.m in Sources */,
|
||||
71F7F5151C218D8900E7ED8F /* RecentCellData.m in Sources */,
|
||||
F084DAAE1BB57BD100B4C530 /* AuthInputsEmailIdentityBasedView.m in Sources */,
|
||||
71352D591C10569F001D50B0 /* AvatarGenerator.m in Sources */,
|
||||
717928471C03852C00407D96 /* TableViewCellWithLabelAndLargeTextView.m in Sources */,
|
||||
|
@ -1030,6 +1059,7 @@
|
|||
7165A25B1C05CD42003635D7 /* SegmentedViewController.m in Sources */,
|
||||
F094AA321B78E42600B1FBBF /* GlobalNotificationSettingsViewController.m in Sources */,
|
||||
F094A9A81B78D8F000B1FBBF /* main.m in Sources */,
|
||||
71B2A3C01C203C7100472061 /* TableViewCellWithLabelAndSwitch.m in Sources */,
|
||||
F00C47861BFF77C800DBABC9 /* RecentTableViewCell.m in Sources */,
|
||||
F0DD7D881B7B507100C4BE02 /* RoomCreationStep2ViewController.m in Sources */,
|
||||
71352D651C10A265001D50B0 /* Contact.m in Sources */,
|
||||
|
@ -1039,6 +1069,7 @@
|
|||
F094AA351B78E42600B1FBBF /* RecentsViewController.m in Sources */,
|
||||
F08BE09E1B87025B00C480FB /* EventFormatter.m in Sources */,
|
||||
F05895001B8B7E6600B73E85 /* RoomBubbleCellData.m in Sources */,
|
||||
71F7F5181C22CC7500E7ED8F /* MXRoom+Vector.m in Sources */,
|
||||
F0D2D9831C197DCB007B8C96 /* RoomIncomingAttachmentBubbleCell.m in Sources */,
|
||||
F0C34B611C15C28300C36F09 /* RoomOutgoingAttachmentBubbleCell.m in Sources */,
|
||||
71C5F2951C074ACC004C094B /* RoomSettingsViewController.m in Sources */,
|
||||
|
@ -1048,6 +1079,7 @@
|
|||
F08BE0A21B87064000C480FB /* RoomDataSource.m in Sources */,
|
||||
716FDC8A1C186A3A001034CB /* InviteRecentTableViewCell.m in Sources */,
|
||||
F0C34CB31C16269D00C36F09 /* RoomIncomingTextMsgWithPaginationTitleBubbleCell.m in Sources */,
|
||||
71B2A3BB1C2013DC00472061 /* TableViewCellWithLabelAndMXKImageView.m in Sources */,
|
||||
F0D2D9851C197DCB007B8C96 /* RoomIncomingAttachmentWithoutSenderInfoBubbleCell.m in Sources */,
|
||||
71046D5E1C0C639300DCA984 /* RoomTitleViewWithTopic.m in Sources */,
|
||||
F0C34B631C15C28300C36F09 /* RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.m in Sources */,
|
||||
|
|
|
@ -132,12 +132,17 @@
|
|||
|
||||
// Room Details
|
||||
"room_details_title" = "Room Details";
|
||||
"room_details_mute_notifs" = "Mute notifications";
|
||||
"room_details_photo" = "Photo";
|
||||
"room_details_room_name" = "Room Name";
|
||||
"room_details_topic" = "Topic";
|
||||
"room_details_people" = "People";
|
||||
"room_details_settings" = "Settings";
|
||||
"room_details_fail_to_update_topic" = "Fail to update the topic";
|
||||
"room_details_fail_to_update_room_name" = "Fail to update the room name";
|
||||
"room_details_with_updates" = "The updates will be lost : are you sure to leave ?";
|
||||
"room_details_room_is_public" = "This room is public";
|
||||
"room_details_room_is_private" = "This room is private";
|
||||
|
||||
"notification_settings_global_notification_settings" = "Global Notification Settings";
|
||||
|
||||
|
@ -157,4 +162,11 @@
|
|||
"public_room_section_title" = "Public Rooms (at %@):";
|
||||
"bug_report_prompt" = "The application has crashed last time. Would you like to submit a crash report?";
|
||||
"rage_shake_prompt" = "You seem to be shaking the phone in frustration. Would you like to submit a bug report?";
|
||||
"camera_access_not_granted" = "Vector doesn't have permission to use Camera, please change privacy settings";
|
||||
"camera_access_not_granted" = "Vector doesn't have permission to use Camera, please change privacy settings";
|
||||
|
||||
// room display name
|
||||
"room_displayname_invite_from" = "Invite from %@";
|
||||
"room_displayname_room_invite" = "Room Invite";
|
||||
"room_displayname_two_members" = "%@ and %@";
|
||||
"room_displayname_more_than_two_members" = "%@ and %u others";
|
||||
|
||||
|
|
58
Vector/Categories/MXRoom+Vector.h
Normal file
58
Vector/Categories/MXRoom+Vector.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <MatrixKit/MatrixKit.h>
|
||||
|
||||
/**
|
||||
Define a `MXRoom` category at Vector level.
|
||||
*/
|
||||
@interface MXRoom (Vector)
|
||||
|
||||
/**
|
||||
Returns YES if there is an push rule to disable the notifications for this room.
|
||||
*/
|
||||
@property(nonatomic, readonly) BOOL areRoomNotificationsMuted;
|
||||
|
||||
/**
|
||||
Returns YES if the oneself user is a moderator i.e. he is allowed to update the room name or the avatar..
|
||||
*/
|
||||
@property(nonatomic, readonly) BOOL isModerator;
|
||||
|
||||
/**
|
||||
Returns the vector displayname.
|
||||
*/
|
||||
@property(nonatomic, readonly) NSString* vectorDisplayname;
|
||||
|
||||
/**
|
||||
Toggle a room rule notifications.
|
||||
|
||||
@param mute YES to disable room notification
|
||||
@return the dedicated push rule
|
||||
*/
|
||||
- (void)toggleRoomNotifications:(BOOL)mute;
|
||||
|
||||
/**
|
||||
Set the room avatar in the dedicated MXKImageView.
|
||||
The vector style implies to use in order :
|
||||
1 - the default avatar if there is one
|
||||
2 - the member avatar for < 3 members rooms
|
||||
3 - the first later of the room name.
|
||||
|
||||
@param mxkImageView the destinated MXKImageView.
|
||||
*/
|
||||
- (void)setRoomAvatarImageIn:(MXKImageView*)mxkImageView;
|
||||
|
||||
@end
|
373
Vector/Categories/MXRoom+Vector.m
Normal file
373
Vector/Categories/MXRoom+Vector.m
Normal file
|
@ -0,0 +1,373 @@
|
|||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXRoom+Vector.h"
|
||||
|
||||
#import "AvatarGenerator.h"
|
||||
|
||||
@interface MXRoom ()
|
||||
|
||||
// create property for the extensions
|
||||
|
||||
// rule events observer
|
||||
@property id notificationCenterDidFailObserver;
|
||||
@property id notificationCenterDidUpdateObserver;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MXRoom (Vector)
|
||||
|
||||
/**
|
||||
Returns the room rule notifition.
|
||||
|
||||
@return the dedicated push rule
|
||||
*/
|
||||
- (MXPushRule*)getRoomPushRule
|
||||
{
|
||||
NSArray* rules = self.mxSession.notificationCenter.rules.global.room;
|
||||
|
||||
// sanity checks
|
||||
if (rules)
|
||||
{
|
||||
for(MXPushRule* rule in rules)
|
||||
{
|
||||
// the rule id is the room Id
|
||||
// it is the server trick to avoid duplicated rule on the same room.
|
||||
if ([rule.ruleId isEqualToString:self.state.roomId])
|
||||
{
|
||||
return rule;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL)areRoomNotificationsMuted
|
||||
{
|
||||
MXPushRule* rule = [self getRoomPushRule];
|
||||
|
||||
if (rule)
|
||||
{
|
||||
for (MXPushRuleAction *ruleAction in rule.actions)
|
||||
{
|
||||
if (ruleAction.actionType == MXPushRuleActionTypeDontNotify)
|
||||
{
|
||||
return rule.enabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)isModerator
|
||||
{
|
||||
// Check whether the user has enough power to rename the room or update the avatar
|
||||
MXRoomPowerLevels *powerLevels = [self.state powerLevels];
|
||||
|
||||
NSUInteger userPowerLevel = [powerLevels powerLevelOfUserWithUserID:self.mxSession.myUser.userId];
|
||||
|
||||
return (userPowerLevel >= [powerLevels minimumPowerLevelForSendingEventAsStateEvent:kMXEventTypeStringRoomName]);
|
||||
}
|
||||
|
||||
- (void)toggleRoomNotifications:(BOOL)mute
|
||||
{
|
||||
BOOL isNotified = ![self areRoomNotificationsMuted];
|
||||
|
||||
// check if the state is already in the right state
|
||||
if (isNotified == !mute)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MXNotificationCenter* notificationCenter = self.mxSession.notificationCenter;
|
||||
MXPushRule* rule = [self getRoomPushRule];
|
||||
|
||||
if (!mute)
|
||||
{
|
||||
// let the other notification rules manage the pushes.
|
||||
[notificationCenter removeRule:rule];
|
||||
}
|
||||
else
|
||||
{
|
||||
// user does not want to have push
|
||||
|
||||
// if there is no rule
|
||||
if (!rule)
|
||||
{
|
||||
// add one
|
||||
[notificationCenter addRoomRule:self.state.roomId
|
||||
notify:NO
|
||||
sound:NO
|
||||
highlight:NO];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// check if the user did not define one
|
||||
BOOL hasDontNotifyRule = NO;
|
||||
|
||||
for (MXPushRuleAction *ruleAction in rule.actions)
|
||||
{
|
||||
if (ruleAction.actionType == MXPushRuleActionTypeDontNotify)
|
||||
{
|
||||
hasDontNotifyRule = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if the user defined one, use it
|
||||
if (hasDontNotifyRule)
|
||||
{
|
||||
[notificationCenter enableRule:rule isEnabled:YES];
|
||||
}
|
||||
else
|
||||
{
|
||||
__weak typeof(self) weakSelf = self;
|
||||
|
||||
// if the user defined a room rule
|
||||
// the rule is deleted before adding new one
|
||||
|
||||
id localNotificationCenterDidUpdateObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXNotificationCenterDidUpdateRules object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
||||
|
||||
MXPushRule* rule = [self getRoomPushRule];
|
||||
|
||||
// check if the rule has been deleted
|
||||
// there is no way to know if the notif is really for this rule..
|
||||
if (!rule)
|
||||
{
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
|
||||
if (strongSelf.notificationCenterDidUpdateObserver)
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:strongSelf.notificationCenterDidUpdateObserver];
|
||||
strongSelf.notificationCenterDidUpdateObserver = nil;
|
||||
}
|
||||
|
||||
if (strongSelf.notificationCenterDidFailObserver)
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:strongSelf.notificationCenterDidUpdateObserver];
|
||||
strongSelf.notificationCenterDidUpdateObserver = nil;
|
||||
}
|
||||
|
||||
// add one dedicated rule
|
||||
[notificationCenter addRoomRule:self.state.roomId
|
||||
notify:NO
|
||||
sound:NO
|
||||
highlight:NO];
|
||||
}
|
||||
}];
|
||||
|
||||
id localNotificationCenterDidFailObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXNotificationCenterDidFailRulesUpdate object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
||||
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
|
||||
if (strongSelf.notificationCenterDidUpdateObserver)
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:strongSelf.notificationCenterDidUpdateObserver];
|
||||
strongSelf.notificationCenterDidUpdateObserver = nil;
|
||||
}
|
||||
|
||||
if (strongSelf.notificationCenterDidFailObserver)
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:strongSelf.notificationCenterDidUpdateObserver];
|
||||
strongSelf.notificationCenterDidUpdateObserver = nil;
|
||||
}
|
||||
}];
|
||||
|
||||
self.notificationCenterDidUpdateObserver = localNotificationCenterDidUpdateObserver;
|
||||
self.notificationCenterDidFailObserver = localNotificationCenterDidFailObserver;
|
||||
|
||||
// remove the rule notification
|
||||
// the notifications are used to tell
|
||||
[notificationCenter removeRule:rule];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setRoomAvatarImageIn:(MXKImageView*)mxkImageView
|
||||
{
|
||||
NSString* roomAvatarUrl = self.state.avatar;
|
||||
|
||||
// detect if it is a room with no more than 2 members (i.e. an alone or a 1:1 chat)
|
||||
if (!roomAvatarUrl)
|
||||
{
|
||||
NSString* myUserId = self.mxSession.myUser.userId;
|
||||
|
||||
NSArray* members = self.state.members;
|
||||
|
||||
if (members.count < 3)
|
||||
{
|
||||
// use the member avatar only it is an active member
|
||||
for (MXRoomMember *roomMember in members)
|
||||
{
|
||||
if ((MXMembershipJoin == roomMember.membership) && ((members.count == 1) || ![roomMember.userId isEqualToString:myUserId]))
|
||||
{
|
||||
roomAvatarUrl = roomMember.avatarUrl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UIImage* avatarImage = [AvatarGenerator generateRoomAvatar:self];
|
||||
|
||||
if (roomAvatarUrl)
|
||||
{
|
||||
mxkImageView.enableInMemoryCache = YES;
|
||||
|
||||
[mxkImageView setImageURL:[self.mxSession.matrixRestClient urlOfContentThumbnail:roomAvatarUrl toFitViewSize:mxkImageView.frame.size withMethod:MXThumbnailingMethodCrop] withType:nil andImageOrientation:UIImageOrientationUp previewImage:avatarImage];
|
||||
}
|
||||
else
|
||||
{
|
||||
mxkImageView.image = avatarImage;
|
||||
}
|
||||
|
||||
mxkImageView.contentMode = UIViewContentModeScaleAspectFill;
|
||||
}
|
||||
|
||||
- (NSString *)vectorDisplayname
|
||||
{
|
||||
// this algo is the one defined in
|
||||
// https://github.com/matrix-org/matrix-js-sdk/blob/develop/lib/models/room.js#L617
|
||||
// calculateRoomName(room, userId)
|
||||
|
||||
MXRoomState* roomState = self.state;
|
||||
|
||||
if (roomState.name.length > 0)
|
||||
{
|
||||
return roomState.name;
|
||||
}
|
||||
|
||||
NSString *alias = roomState.canonicalAlias;
|
||||
|
||||
if (!alias)
|
||||
{
|
||||
// For rooms where canonical alias is not defined, we use the 1st alias as a workaround
|
||||
NSArray *aliases = roomState.aliases;
|
||||
|
||||
if (aliases.count)
|
||||
{
|
||||
alias = [aliases[0] copy];
|
||||
}
|
||||
}
|
||||
|
||||
if (alias)
|
||||
{
|
||||
return alias;
|
||||
}
|
||||
|
||||
NSString* myUserId = self.mxSession.myUser.userId;
|
||||
|
||||
NSArray* members = roomState.members;
|
||||
NSMutableArray* othersActiveMembers = [[NSMutableArray alloc] init];
|
||||
NSMutableArray* activeMembers = [[NSMutableArray alloc] init];
|
||||
|
||||
for(MXRoomMember* member in members)
|
||||
{
|
||||
if (member.membership != MXMembershipLeave)
|
||||
{
|
||||
if (![member.userId isEqualToString:myUserId])
|
||||
{
|
||||
[othersActiveMembers addObject:member];
|
||||
}
|
||||
|
||||
[activeMembers addObject:member];
|
||||
}
|
||||
}
|
||||
|
||||
// sort the members by their creation (oldest first)
|
||||
othersActiveMembers = [[othersActiveMembers sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
|
||||
|
||||
uint64_t originServerTs1 = 0;
|
||||
uint64_t originServerTs2 = 0;
|
||||
|
||||
MXRoomMember* member1 = (MXRoomMember*)obj1;
|
||||
MXRoomMember* member2 = (MXRoomMember*)obj2;
|
||||
|
||||
if (member1.originalEvent)
|
||||
{
|
||||
originServerTs1 = member1.originalEvent.originServerTs;
|
||||
}
|
||||
|
||||
if (member2.originalEvent)
|
||||
{
|
||||
originServerTs2 = member2.originalEvent.originServerTs;
|
||||
}
|
||||
|
||||
if (originServerTs1 == originServerTs2)
|
||||
{
|
||||
return NSOrderedSame;
|
||||
}
|
||||
else
|
||||
{
|
||||
return originServerTs1 > originServerTs2 ? NSOrderedDescending : NSOrderedAscending;
|
||||
}
|
||||
}] mutableCopy];
|
||||
|
||||
|
||||
NSString* displayName = @"";
|
||||
|
||||
// TODO: Localisation
|
||||
if (othersActiveMembers.count == 0)
|
||||
{
|
||||
if (activeMembers.count == 1)
|
||||
{
|
||||
MXRoomMember* member = [activeMembers objectAtIndex:0];
|
||||
|
||||
if (member.membership == MXMembershipInvite)
|
||||
{
|
||||
if (member.originalEvent.sender)
|
||||
{
|
||||
// extract who invited us to the room
|
||||
displayName = [NSString stringWithFormat:NSLocalizedStringFromTable(@"room_displayname_invite_from", @"Vector", nil), [roomState memberName:member.originalEvent.sender]];
|
||||
}
|
||||
else
|
||||
{
|
||||
displayName = NSLocalizedStringFromTable(@"room_displayname_room_invite", @"Vector", nil);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
displayName = myUserId;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (othersActiveMembers.count == 1)
|
||||
{
|
||||
MXRoomMember* member = [othersActiveMembers objectAtIndex:0];
|
||||
|
||||
displayName = [roomState memberName:member.userId];
|
||||
}
|
||||
else if (othersActiveMembers.count == 2)
|
||||
{
|
||||
MXRoomMember* member1 = [othersActiveMembers objectAtIndex:0];
|
||||
MXRoomMember* member2 = [othersActiveMembers objectAtIndex:1];
|
||||
|
||||
displayName = [NSString stringWithFormat:NSLocalizedStringFromTable(@"room_displayname_two_members", @"Vector", nil), [roomState memberName:member1.userId], [roomState memberName:member2.userId]];
|
||||
}
|
||||
else
|
||||
{
|
||||
MXRoomMember* member = [othersActiveMembers objectAtIndex:0];
|
||||
displayName = [NSString stringWithFormat:NSLocalizedStringFromTable(@"room_displayname_more_than_two_members", @"Vector", nil), [roomState memberName:member.userId], othersActiveMembers.count - 1];
|
||||
}
|
||||
|
||||
return displayName;
|
||||
}
|
||||
|
||||
@end
|
26
Vector/Model/RoomList/RecentCellData.h
Normal file
26
Vector/Model/RoomList/RecentCellData.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <MatrixSDK/MatrixSDK.h>
|
||||
|
||||
#import "MXKRecentCellData.h"
|
||||
/**
|
||||
`RecentCellData` is Vector cuustomized MXKRecentCellData` cell.
|
||||
*/
|
||||
@interface RecentCellData : MXKRecentCellData
|
||||
|
||||
@end
|
32
Vector/Model/RoomList/RecentCellData.m
Normal file
32
Vector/Model/RoomList/RecentCellData.m
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "RecentCellData.h"
|
||||
|
||||
#import "MXRoom+Vector.h"
|
||||
|
||||
@implementation RecentCellData
|
||||
// trick to hide the mother class property as it is readonly one.
|
||||
// self.roomDisplayname returns this value instead of the mother class.
|
||||
@synthesize roomDisplayname;
|
||||
|
||||
- (void)update
|
||||
{
|
||||
[super update];
|
||||
roomDisplayname = self.roomDataSource.room.vectorDisplayname;
|
||||
}
|
||||
|
||||
@end
|
|
@ -22,6 +22,10 @@
|
|||
|
||||
#import "InviteRecentTableViewCell.h"
|
||||
|
||||
#import "MXRoom+Vector.h"
|
||||
|
||||
#import "RecentCellData.h"
|
||||
|
||||
@interface RecentsDataSource()
|
||||
{
|
||||
NSMutableArray* invitesCellDataArray;
|
||||
|
@ -62,10 +66,15 @@
|
|||
sectionsCount = 0;
|
||||
|
||||
roomTagsListenerByUserId = [[NSMutableDictionary alloc] init];
|
||||
|
||||
// Set default data and view classes
|
||||
[self registerCellDataClass:RecentCellData.class forCellIdentifier:kMXKRecentCellIdentifier];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
|
||||
- (void)removeMatrixSession:(MXSession*)matrixSession
|
||||
{
|
||||
[super removeMatrixSession:matrixSession];
|
||||
|
@ -109,6 +118,28 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (BOOL)isRoomNotifiedAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
MXRoom* room = [self getRoomAtIndexPath:indexPath];
|
||||
|
||||
if (room)
|
||||
{
|
||||
return !room.areRoomNotificationsMuted;
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)muteRoomNotifications:(BOOL)mute atIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
MXRoom* room = [self getRoomAtIndexPath:indexPath];
|
||||
|
||||
// sanity check
|
||||
if (room)
|
||||
{
|
||||
[room toggleRoomNotifications:mute];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)refreshRoomsSectionsAndReload
|
||||
{
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
#import "AvatarGenerator.h"
|
||||
|
||||
#import "MXRoom+Vector.h"
|
||||
|
||||
@implementation AvatarGenerator
|
||||
|
||||
static NSMutableDictionary *imageByKeyDict = nil;
|
||||
|
@ -156,7 +158,7 @@ static UILabel* backgroundLabel = nil;
|
|||
|
||||
// if the displayname is the userID
|
||||
// skip the @
|
||||
if (!displayname && [text hasPrefix:@"@"])
|
||||
if (!displayname && ([text hasPrefix:@"@"] || [text hasPrefix:@"#"]))
|
||||
{
|
||||
text = [text substringFromIndex:1];
|
||||
}
|
||||
|
@ -176,7 +178,7 @@ static UILabel* backgroundLabel = nil;
|
|||
*/
|
||||
+ (UIImage*)generateRoomAvatar:(MXRoom*)room
|
||||
{
|
||||
NSString* displayName = room.state.displayname;
|
||||
NSString* displayName = room.vectorDisplayname;
|
||||
NSString* roomId = room.state.roomId;
|
||||
|
||||
// the selected color is based on the roomId
|
||||
|
@ -184,7 +186,7 @@ static UILabel* backgroundLabel = nil;
|
|||
NSString* text = displayName;
|
||||
|
||||
// ignore the first #
|
||||
if ([text hasPrefix:@"#"])
|
||||
if ([text hasPrefix:@"#"] || [text hasPrefix:@"@"])
|
||||
{
|
||||
text = [text substringFromIndex:1];
|
||||
}
|
||||
|
|
|
@ -325,11 +325,18 @@ static NSMutableDictionary* backgroundByImageNameDict;
|
|||
- (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
NSMutableArray* actions = [[NSMutableArray alloc] init];
|
||||
|
||||
MXRoom* room = [self.dataSource getRoomAtIndexPath:indexPath];
|
||||
|
||||
if (room)
|
||||
{
|
||||
NSArray* invitedRooms = room.mxSession.invitedRooms;
|
||||
|
||||
// display no action for the invited room
|
||||
if (invitedRooms && ([invitedRooms indexOfObject:room] != NSNotFound))
|
||||
{
|
||||
return actions;
|
||||
}
|
||||
|
||||
NSString* title = @" ";
|
||||
|
||||
// pushes settings
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
|
||||
#import <MatrixKit/MatrixKit.h>
|
||||
|
||||
@interface RoomSettingsViewController : MXKRoomSettingsViewController<UITextViewDelegate>
|
||||
#import "MediaPickerViewController.h"
|
||||
|
||||
@interface RoomSettingsViewController : MXKRoomSettingsViewController<UITextViewDelegate, MediaPickerViewControllerDelegate>
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -16,19 +16,32 @@
|
|||
|
||||
#import "RoomSettingsViewController.h"
|
||||
|
||||
#import <Photos/Photos.h>
|
||||
#import <MediaPlayer/MediaPlayer.h>
|
||||
|
||||
#import "TableViewCellWithLabelAndTextField.h"
|
||||
#import "TableViewCellWithLabelAndLargeTextView.h"
|
||||
#import "TableViewCellWithLabelAndMXKImageView.h"
|
||||
#import "TableViewCellWithLabelAndSwitch.h"
|
||||
|
||||
#import "TableViewCellSeparator.h"
|
||||
|
||||
#import "RageShakeManager.h"
|
||||
|
||||
#import "VectorDesignValues.h"
|
||||
|
||||
#import "AvatarGenerator.h"
|
||||
|
||||
#import "MXRoom+Vector.h"
|
||||
|
||||
#define ROOM_SECTION 0
|
||||
|
||||
#define ROOM_SECTION_NAME 0
|
||||
#define ROOM_SECTION_TOPIC 1
|
||||
#define ROOM_SECTION_COUNT 2
|
||||
#define ROOM_SECTION_PHOTO 0
|
||||
#define ROOM_SECTION_NAME 1
|
||||
#define ROOM_SECTION_TOPIC 2
|
||||
#define ROOM_SECTION_PRIV_PUB 3
|
||||
#define ROOM_SECTION_MUTE_NOTIFICATIONS 4
|
||||
#define ROOM_SECTION_COUNT 5
|
||||
|
||||
#define ROOM_TOPIC_CELL_HEIGHT 99
|
||||
|
||||
|
@ -48,6 +61,15 @@
|
|||
UIActivityIndicatorView* updatingSpinner;
|
||||
|
||||
MXKAlert *currentAlert;
|
||||
|
||||
// listen to more events than the mother class
|
||||
id extraEventsListener;
|
||||
|
||||
// picker
|
||||
MediaPickerViewController* mediaPicker;
|
||||
|
||||
// switches
|
||||
UISwitch *roomNotifSwitch;
|
||||
}
|
||||
@end
|
||||
|
||||
|
@ -93,6 +115,8 @@
|
|||
[super viewWillAppear:animated];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didMXSessionStateChange:) name:kMXSessionStateDidChangeNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didUpdateRules:) name:kMXNotificationCenterDidUpdateRules object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didAccountUserInfoDidChange:) name:kMXKAccountUserInfoDidChangeNotification object:nil];
|
||||
}
|
||||
|
||||
- (void)viewWillDisappear:(BOOL)animated
|
||||
|
@ -101,6 +125,8 @@
|
|||
|
||||
[self dismissFirstResponder];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionStateDidChangeNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMXNotificationCenterDidUpdateRules object:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMXKAccountUserInfoDidChangeNotification object:nil];
|
||||
}
|
||||
|
||||
// this method is called when the viewcontroller is displayed inside another one.
|
||||
|
@ -150,16 +176,19 @@
|
|||
|
||||
- (void)showUpdatingSpinner
|
||||
{
|
||||
self.tableView.userInteractionEnabled = NO;
|
||||
|
||||
// Add a spinner
|
||||
updatingSpinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
|
||||
updatingSpinner.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin);
|
||||
updatingSpinner.backgroundColor = [UIColor colorWithRed:0.8 green:0.8 blue:0.8 alpha:1.0];
|
||||
updatingSpinner.hidesWhenStopped = NO;
|
||||
[updatingSpinner startAnimating];
|
||||
updatingSpinner.center = self.view.center;
|
||||
[self.view addSubview:updatingSpinner];
|
||||
if (!updatingSpinner)
|
||||
{
|
||||
self.tableView.userInteractionEnabled = NO;
|
||||
|
||||
// Add a spinner
|
||||
updatingSpinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
|
||||
updatingSpinner.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin);
|
||||
updatingSpinner.backgroundColor = [UIColor colorWithRed:0.8 green:0.8 blue:0.8 alpha:1.0];
|
||||
updatingSpinner.hidesWhenStopped = NO;
|
||||
[updatingSpinner startAnimating];
|
||||
updatingSpinner.center = self.view.center;
|
||||
[self.view addSubview:updatingSpinner];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)hideUpdatingSpinner
|
||||
|
@ -232,10 +261,38 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (void)didUpdateRules:(NSNotification *)notif
|
||||
{
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
|
||||
- (void)didAccountUserInfoDidChange:(NSNotification *)notif
|
||||
{
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
|
||||
- (IBAction)onCancel:(id)sender
|
||||
{
|
||||
// warn if there is a pending update ?
|
||||
[self.navigationController popViewControllerAnimated:YES];
|
||||
// if there are some updated fields
|
||||
if (updatedItemsDict && (updatedItemsDict.count > 0))
|
||||
{
|
||||
// ensure that the user understands that the updates will be lost if
|
||||
MXKAlert* alert = [[MXKAlert alloc] initWithTitle:nil message:NSLocalizedStringFromTable(@"room_details_with_updates", @"Vector", nil) style:MXKAlertStyleAlert];
|
||||
|
||||
[alert addActionWithTitle:NSLocalizedStringFromTable(@"cancel", @"Vector", nil) style:MXKAlertActionStyleCancel handler:^(MXKAlert *alert) {
|
||||
[self.navigationController popViewControllerAnimated:YES];
|
||||
}];
|
||||
|
||||
[alert addActionWithTitle:NSLocalizedStringFromTable(@"save", @"Vector", nil) style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) {
|
||||
[self onSave:nil];
|
||||
}];
|
||||
|
||||
[alert showInViewController:self];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self.navigationController popViewControllerAnimated:YES];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onSaveFailed:(NSString*)message withKey:(NSString*)key
|
||||
|
@ -274,9 +331,60 @@
|
|||
|
||||
- (IBAction)onSave:(id)sender
|
||||
{
|
||||
[self showUpdatingSpinner];
|
||||
|
||||
// check if there is some update
|
||||
if (mxRoomState && updatedItemsDict && (updatedItemsDict.count > 0))
|
||||
{
|
||||
if ([updatedItemsDict objectForKey:@"ROOM_SECTION_PHOTO"])
|
||||
{
|
||||
// Retrieve the current picture and make sure its orientation is up
|
||||
UIImage *updatedPicture = [MXKTools forceImageOrientationUp:[updatedItemsDict objectForKey:@"ROOM_SECTION_PHOTO"]];
|
||||
|
||||
// Upload picture
|
||||
MXKMediaLoader *uploader = [MXKMediaManager prepareUploaderWithMatrixSession:mxRoom.mxSession initialRange:0 andRange:1.0];
|
||||
|
||||
[uploader uploadData:UIImageJPEGRepresentation(updatedPicture, 0.5) filename:nil mimeType:@"image/jpeg" success:^(NSString *url)
|
||||
{
|
||||
[updatedItemsDict removeObjectForKey:@"ROOM_SECTION_PHOTO"];
|
||||
[updatedItemsDict setObject:url forKey:@"ROOM_SECTION_PHOTO_URL"];
|
||||
|
||||
[self onSave:nil];
|
||||
} failure:^(NSError *error)
|
||||
{
|
||||
NSLog(@"[Vector RoomSettingsViewController] Failed to upload image: %@", error);
|
||||
[updatedItemsDict removeObjectForKey:@"ROOM_SECTION_PHOTO"];
|
||||
[self onSave:nil];
|
||||
}];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ([updatedItemsDict objectForKey:@"ROOM_SECTION_PHOTO_URL"])
|
||||
{
|
||||
__weak typeof(self) weakSelf = self;
|
||||
|
||||
NSString* photoUrl = [updatedItemsDict objectForKey:@"ROOM_SECTION_PHOTO_URL"];
|
||||
|
||||
[mxRoom setAvatar:photoUrl success:^{
|
||||
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
[strongSelf->updatedItemsDict removeObjectForKey:@"ROOM_SECTION_PHOTO_URL"];
|
||||
[strongSelf onSave:nil];
|
||||
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
NSLog(@"[Vector RoomSettingsViewController] Failed to update the room avatar %@", error);
|
||||
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
[strongSelf->updatedItemsDict removeObjectForKey:@"ROOM_SECTION_PHOTO_URL"];
|
||||
[strongSelf onSave:nil];
|
||||
|
||||
}];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// has a new room name
|
||||
if ([updatedItemsDict objectForKey:@"ROOM_SECTION_NAME"])
|
||||
{
|
||||
|
@ -284,7 +392,6 @@
|
|||
|
||||
if (![newName isEqualToString:mxRoomState.name])
|
||||
{
|
||||
[self showUpdatingSpinner];
|
||||
__weak typeof(self) weakSelf = self;
|
||||
|
||||
pendingOperation = [mxRoom setName:newName success:^{
|
||||
|
@ -319,7 +426,6 @@
|
|||
|
||||
if (![newTopic isEqualToString:mxRoomState.topic])
|
||||
{
|
||||
[self showUpdatingSpinner];
|
||||
__weak typeof(self) weakSelf = self;
|
||||
|
||||
pendingOperation = [mxRoom setTopic:newTopic success:^{
|
||||
|
@ -348,6 +454,15 @@
|
|||
}
|
||||
}
|
||||
|
||||
if ([updatedItemsDict objectForKey:@"ROOM_SECTION_MUTE_NOTIFICATIONS"])
|
||||
{
|
||||
[mxRoom toggleRoomNotifications:roomNotifSwitch.on];
|
||||
[updatedItemsDict removeObjectForKey:@"ROOM_SECTION_MUTE_NOTIFICATIONS"];
|
||||
[self onSave:nil];
|
||||
}
|
||||
|
||||
[self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0);
|
||||
|
||||
[self hideUpdatingSpinner];
|
||||
|
||||
[self.navigationController popViewControllerAnimated:YES];
|
||||
|
@ -430,7 +545,63 @@
|
|||
// retrieve row as a ROOM_SECTION_XX index
|
||||
row = (row - 1) / 2;
|
||||
|
||||
if (row == ROOM_SECTION_TOPIC)
|
||||
if (row == ROOM_SECTION_MUTE_NOTIFICATIONS)
|
||||
{
|
||||
TableViewCellWithLabelAndSwitch *roomNotifCell = [tableView dequeueReusableCellWithIdentifier:[TableViewCellWithLabelAndSwitch defaultReuseIdentifier]];
|
||||
|
||||
if (!roomNotifCell)
|
||||
{
|
||||
roomNotifCell = [[TableViewCellWithLabelAndSwitch alloc] init];
|
||||
[roomNotifCell.mxkSwitch addTarget:self action:@selector(onSwitchUpdate:) forControlEvents:UIControlEventValueChanged];
|
||||
roomNotifCell.mxkSwitch.onTintColor = VECTOR_GREEN_COLOR;
|
||||
}
|
||||
|
||||
roomNotifCell.mxkLabel.text = NSLocalizedStringFromTable(@"room_details_mute_notifs", @"Vector", nil);
|
||||
roomNotifSwitch = roomNotifCell.mxkSwitch;
|
||||
|
||||
if (updatedItemsDict && [updatedItemsDict objectForKey:@"ROOM_SECTION_MUTE_NOTIFICATIONS"])
|
||||
{
|
||||
roomNotifSwitch.on = ((NSNumber*)[updatedItemsDict objectForKey:@"ROOM_SECTION_MUTE_NOTIFICATIONS"]).boolValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
roomNotifSwitch.on = mxRoom.areRoomNotificationsMuted;
|
||||
}
|
||||
|
||||
cell = roomNotifCell;
|
||||
}
|
||||
else if (row == ROOM_SECTION_PHOTO)
|
||||
{
|
||||
TableViewCellWithLabelAndMXKImageView *roomPhotoCell = [tableView dequeueReusableCellWithIdentifier:[TableViewCellWithLabelAndMXKImageView defaultReuseIdentifier]];
|
||||
|
||||
if (!roomPhotoCell)
|
||||
{
|
||||
roomPhotoCell = [[TableViewCellWithLabelAndMXKImageView alloc] init];
|
||||
|
||||
// tap on avatar to update it
|
||||
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onRoomAvatarTap:)];
|
||||
[roomPhotoCell.mxkImageView addGestureRecognizer:tap];
|
||||
}
|
||||
|
||||
roomPhotoCell.mxkLabel.text = NSLocalizedStringFromTable(@"room_details_photo", @"Vector", nil);
|
||||
|
||||
if (updatedItemsDict && [updatedItemsDict objectForKey:@"ROOM_SECTION_PHOTO"])
|
||||
{
|
||||
roomPhotoCell.mxkImageView.image = (UIImage*)[updatedItemsDict objectForKey:@"ROOM_SECTION_PHOTO"];
|
||||
}
|
||||
else
|
||||
{
|
||||
[mxRoom setRoomAvatarImageIn:roomPhotoCell.mxkImageView];
|
||||
roomPhotoCell.mxkImageView.alpha = mxRoom.isModerator ? 1.0f : 0.5f;
|
||||
}
|
||||
|
||||
[roomPhotoCell.mxkImageView.layer setCornerRadius:roomPhotoCell.mxkImageView.frame.size.width / 2];
|
||||
roomPhotoCell.mxkImageView.clipsToBounds = YES;
|
||||
roomPhotoCell.userInteractionEnabled = mxRoom.isModerator;
|
||||
|
||||
cell = roomPhotoCell;
|
||||
}
|
||||
else if (row == ROOM_SECTION_TOPIC)
|
||||
{
|
||||
TableViewCellWithLabelAndLargeTextView *roomTopicCell = [tableView dequeueReusableCellWithIdentifier:[TableViewCellWithLabelAndLargeTextView defaultReuseIdentifier]];
|
||||
|
||||
|
@ -460,8 +631,8 @@
|
|||
roomTopicCell.mxkTextView.delegate = self;
|
||||
|
||||
// disable the edition if the user cannoy update it
|
||||
roomTopicCell.mxkTextView.editable = isSuperUser;
|
||||
roomTopicCell.mxkTextView.textColor = isSuperUser ? [UIColor blackColor] : [UIColor lightGrayColor];
|
||||
roomTopicCell.mxkTextView.editable = mxRoom.isModerator;
|
||||
roomTopicCell.mxkTextView.textColor = mxRoom.isModerator ? [UIColor blackColor] : [UIColor lightGrayColor];
|
||||
|
||||
cell = roomTopicCell;
|
||||
}
|
||||
|
@ -492,13 +663,28 @@
|
|||
nameTextField = roomNameCell.mxkTextField;
|
||||
|
||||
// disable the edition if the user cannoy update it
|
||||
roomNameCell.editable = isSuperUser;
|
||||
roomNameCell.mxkTextField.textColor = isSuperUser ? [UIColor blackColor] : [UIColor lightGrayColor];
|
||||
roomNameCell.editable = mxRoom.isModerator;
|
||||
roomNameCell.mxkTextField.textColor = mxRoom.isModerator ? [UIColor blackColor] : [UIColor lightGrayColor];
|
||||
|
||||
|
||||
// Add a "textFieldDidChange" notification method to the text field control.
|
||||
[roomNameCell.mxkTextField addTarget:self action:@selector(onTextFieldUpdate:) forControlEvents:UIControlEventEditingChanged];
|
||||
}
|
||||
else if (row == ROOM_SECTION_PRIV_PUB)
|
||||
{
|
||||
TableViewCellWithLabelAndTextField *privPublicCell = [tableView dequeueReusableCellWithIdentifier:[TableViewCellWithLabelAndTextField defaultReuseIdentifier]];
|
||||
|
||||
if (!privPublicCell)
|
||||
{
|
||||
privPublicCell = [[TableViewCellWithLabelAndTextField alloc] init];
|
||||
}
|
||||
|
||||
privPublicCell.mxkTextField.userInteractionEnabled = NO;
|
||||
privPublicCell.mxkTextField.text = @"";
|
||||
privPublicCell.mxkLabel.text = mxRoom.state.isPublic ? NSLocalizedStringFromTable(@"room_details_room_is_public", @"Vector", nil) : NSLocalizedStringFromTable(@"room_details_room_is_private", @"Vector", nil);
|
||||
|
||||
cell = privPublicCell;
|
||||
}
|
||||
}
|
||||
|
||||
return cell;
|
||||
|
@ -509,14 +695,124 @@
|
|||
if (self.tableView == aTableView)
|
||||
{
|
||||
[self dismissFirstResponder];
|
||||
|
||||
if (indexPath.section == ROOM_SECTION)
|
||||
{
|
||||
NSUInteger row = indexPath.row;
|
||||
|
||||
// the even views are the line separator
|
||||
if ((row % 2) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// retrieve row as a ROOM_SECTION_XX index
|
||||
row = (row - 1) / 2;
|
||||
|
||||
if (row == ROOM_SECTION_PHOTO)
|
||||
{
|
||||
[self onRoomAvatarTap:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
|
||||
#pragma mark - MediaPickerViewController Delegate
|
||||
|
||||
- (void)dismissMediaPicker
|
||||
{
|
||||
if (scrollView == self.tableView)
|
||||
if (mediaPicker)
|
||||
{
|
||||
[self dismissFirstResponder];
|
||||
[mediaPicker withdrawViewControllerAnimated:YES completion:nil];
|
||||
mediaPicker = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mediaPickerController:(MediaPickerViewController *)mediaPickerController didSelectImage:(UIImage*)image withURL:(NSURL *)imageURL
|
||||
{
|
||||
[self dismissMediaPicker];
|
||||
|
||||
if (image)
|
||||
{
|
||||
[self getNavigationItem].rightBarButtonItem.enabled = YES;
|
||||
|
||||
NSMutableDictionary* dict = [self getUpdatedItemsDict];
|
||||
[dict setObject:image forKey:@"ROOM_SECTION_PHOTO"];
|
||||
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mediaPickerController:(MediaPickerViewController *)mediaPickerController didSelectVideo:(NSURL*)videoURL isCameraRecording:(BOOL)isCameraRecording
|
||||
{
|
||||
// this method should not be called
|
||||
[self dismissMediaPicker];
|
||||
}
|
||||
|
||||
- (void)mediaPickerController:(MediaPickerViewController *)mediaPickerController didSelectAssets:(NSArray *)assets
|
||||
{
|
||||
if (assets.count > 0)
|
||||
{
|
||||
PHAsset* asset = [assets objectAtIndex:0];
|
||||
PHContentEditingInputRequestOptions *editOptions = [[PHContentEditingInputRequestOptions alloc] init];
|
||||
|
||||
[asset requestContentEditingInputWithOptions:editOptions
|
||||
completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
|
||||
|
||||
if (contentEditingInput.mediaType == PHAssetMediaTypeImage)
|
||||
{
|
||||
// Here the fullSizeImageURL is related to a local file path
|
||||
NSData *data = [NSData dataWithContentsOfURL:contentEditingInput.fullSizeImageURL];
|
||||
UIImage *image = [UIImage imageWithData:data];
|
||||
|
||||
if (image)
|
||||
{
|
||||
[self getNavigationItem].rightBarButtonItem.enabled = YES;
|
||||
|
||||
NSMutableDictionary* dict = [self getUpdatedItemsDict];
|
||||
[dict setObject:image forKey:@"ROOM_SECTION_PHOTO"];
|
||||
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
[self dismissMediaPicker];
|
||||
}
|
||||
|
||||
#pragma mark - actions
|
||||
|
||||
- (void)onRoomAvatarTap:(UITapGestureRecognizer *)recognizer
|
||||
{
|
||||
mediaPicker = [MediaPickerViewController mediaPickerViewController];
|
||||
mediaPicker.mediaTypes = @[(NSString *)kUTTypeImage];
|
||||
mediaPicker.multipleSelections = NO;
|
||||
mediaPicker.selectionButtonCustomLabel = NSLocalizedStringFromTable(@"media_picker_attach", @"Vector", nil);
|
||||
mediaPicker.delegate = self;
|
||||
UINavigationController *navigationController = [UINavigationController new];
|
||||
[navigationController pushViewController:mediaPicker animated:NO];
|
||||
|
||||
[self presentViewController:navigationController animated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void)onSwitchUpdate:(UISwitch*)uiSwitch
|
||||
{
|
||||
if (uiSwitch == roomNotifSwitch)
|
||||
{
|
||||
NSMutableDictionary* dict = [self getUpdatedItemsDict];
|
||||
|
||||
if (roomNotifSwitch.on == mxRoom.areRoomNotificationsMuted)
|
||||
{
|
||||
[dict removeObjectForKey:@"ROOM_SECTION_MUTE_NOTIFICATIONS"];
|
||||
}
|
||||
else
|
||||
{
|
||||
[dict setObject:[NSNumber numberWithBool:roomNotifSwitch.on] forKey:@"ROOM_SECTION_MUTE_NOTIFICATIONS"];
|
||||
}
|
||||
|
||||
[self getNavigationItem].rightBarButtonItem.enabled = (dict.count != 0);
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
|
||||
#import "AvatarGenerator.h"
|
||||
|
||||
#import <Photos/Photos.h>
|
||||
#import <MediaPlayer/MediaPlayer.h>
|
||||
|
||||
#define SETTINGS_SECTION_SIGN_OUT_INDEX 0
|
||||
#define SETTINGS_SECTION_USER_SETTINGS_INDEX 1
|
||||
#define SETTINGS_SECTION_NOTIFICATIONS_SETTINGS_INDEX 2
|
||||
|
@ -1001,7 +1004,26 @@
|
|||
|
||||
- (void)mediaPickerController:(MediaPickerViewController *)mediaPickerController didSelectAssets:(NSArray *)assets
|
||||
{
|
||||
// this method should not be called
|
||||
if (assets.count > 0)
|
||||
{
|
||||
PHAsset* asset = [assets objectAtIndex:0];
|
||||
PHContentEditingInputRequestOptions *editOptions = [[PHContentEditingInputRequestOptions alloc] init];
|
||||
|
||||
[asset requestContentEditingInputWithOptions:editOptions
|
||||
completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
|
||||
|
||||
if (contentEditingInput.mediaType == PHAssetMediaTypeImage)
|
||||
{
|
||||
// Here the fullSizeImageURL is related to a local file path
|
||||
NSData *data = [NSData dataWithContentsOfURL:contentEditingInput.fullSizeImageURL];
|
||||
UIImage *image = [UIImage imageWithData:data];
|
||||
|
||||
newAvatarImage = image;
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
[self dismissMediaPicker];
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
|
||||
#import "VectorDesignValues.h"
|
||||
|
||||
#import "MXRoom+Vector.h"
|
||||
|
||||
@implementation RecentTableViewCell
|
||||
|
||||
#pragma mark - Class methods
|
||||
|
@ -78,44 +80,8 @@
|
|||
}
|
||||
|
||||
self.roomAvatar.backgroundColor = [UIColor clearColor];
|
||||
|
||||
MXRoom* room = roomCellData.roomDataSource.room;
|
||||
|
||||
NSString* roomAvatarUrl = room.state.avatar;
|
||||
|
||||
// detect if it is a room with no more than 2 members (i.e. an alone or a 1:1 chat)
|
||||
if (!roomAvatarUrl)
|
||||
{
|
||||
NSString* myUserId = room.mxSession.myUser.userId;
|
||||
|
||||
NSArray* members = room.state.members;
|
||||
|
||||
if (members.count < 3)
|
||||
{
|
||||
// use the member avatar only it is an active member
|
||||
for (MXRoomMember *roomMember in members)
|
||||
{
|
||||
if ((MXMembershipJoin == roomMember.membership) && ((members.count == 1) || ![roomMember.userId isEqualToString:myUserId]))
|
||||
{
|
||||
roomAvatarUrl = roomMember.avatarUrl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UIImage* avatarImage = [AvatarGenerator generateRoomAvatar:room];
|
||||
|
||||
if (roomAvatarUrl)
|
||||
{
|
||||
self.roomAvatar.enableInMemoryCache = YES;
|
||||
|
||||
[self.roomAvatar setImageURL:[roomCellData.roomDataSource.mxSession.matrixRestClient urlOfContentThumbnail:roomAvatarUrl toFitViewSize:self.roomAvatar.frame.size withMethod:MXThumbnailingMethodCrop] withType:nil andImageOrientation:UIImageOrientationUp previewImage:avatarImage];
|
||||
}
|
||||
else
|
||||
{
|
||||
self.roomAvatar.image = avatarImage;
|
||||
}
|
||||
[roomCellData.roomDataSource.room setRoomAvatarImageIn:self.roomAvatar];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
#import "VectorDesignValues.h"
|
||||
|
||||
#import "MXRoom+Vector.h"
|
||||
|
||||
@implementation RoomTitleViewWithTopic
|
||||
|
||||
- (void)refreshDisplay
|
||||
|
@ -26,7 +28,7 @@
|
|||
|
||||
if (self.mxRoom)
|
||||
{
|
||||
NSString* roomName = self.displayNameTextField.text;
|
||||
NSString* roomName = self.mxRoom.vectorDisplayname;
|
||||
|
||||
if (roomName)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <MatrixSDK/MatrixSDK.h>
|
||||
|
||||
#import "MXKTableViewCell.h"
|
||||
#import "MXKImageView.h"
|
||||
|
||||
@interface TableViewCellWithLabelAndMXKImageView : MXKTableViewCell
|
||||
|
||||
@property (strong, nonatomic) IBOutlet UILabel *mxkLabel;
|
||||
@property (strong, nonatomic) IBOutlet MXKImageView *mxkImageView;
|
||||
|
||||
@end
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "TableViewCellWithLabelAndMXKImageView.h"
|
||||
|
||||
@implementation TableViewCellWithLabelAndMXKImageView
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9060" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9051"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="aCf-VI-ocb" customClass="TableViewCellWithLabelAndMXKImageView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="aCf-VI-ocb" id="Eg5-vl-rni">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="43"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Xx4-AP-OQs">
|
||||
<rect key="frame" x="10" y="11" width="544" height="21"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="7Ts-eR-MZV" userLabel="Mxk ImageView" customClass="MXKImageView">
|
||||
<rect key="frame" x="560" y="5" width="34" height="34"/>
|
||||
<animations/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="34" id="Ejk-bJ-0MB"/>
|
||||
<constraint firstAttribute="height" constant="34" id="m9S-XK-OTa"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<animations/>
|
||||
<constraints>
|
||||
<constraint firstItem="Xx4-AP-OQs" firstAttribute="leading" secondItem="Eg5-vl-rni" secondAttribute="leading" constant="10" id="Wih-ke-1dd"/>
|
||||
<constraint firstItem="7Ts-eR-MZV" firstAttribute="leading" secondItem="Xx4-AP-OQs" secondAttribute="trailing" constant="6" id="fSB-ec-jkJ"/>
|
||||
<constraint firstAttribute="centerY" secondItem="Xx4-AP-OQs" secondAttribute="centerY" id="v6O-QC-moW"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<animations/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="7Ts-eR-MZV" secondAttribute="trailing" constant="6" id="JNP-da-JzI"/>
|
||||
<constraint firstItem="7Ts-eR-MZV" firstAttribute="centerY" secondItem="aCf-VI-ocb" secondAttribute="centerY" id="lgB-TU-fX3"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<outlet property="mxkImageView" destination="7Ts-eR-MZV" id="fP1-hq-oEh"/>
|
||||
<outlet property="mxkLabel" destination="Xx4-AP-OQs" id="Va7-zb-8uX"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
</objects>
|
||||
</document>
|
24
Vector/Views/TableViewCell/TableViewCellWithLabelAndSwitch.h
Normal file
24
Vector/Views/TableViewCell/TableViewCellWithLabelAndSwitch.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKTableViewCell.h"
|
||||
|
||||
@interface TableViewCellWithLabelAndSwitch : MXKTableViewCell
|
||||
|
||||
@property (strong, nonatomic) IBOutlet UILabel *mxkLabel;
|
||||
@property (strong, nonatomic) IBOutlet UISwitch *mxkSwitch;
|
||||
|
||||
@end
|
22
Vector/Views/TableViewCell/TableViewCellWithLabelAndSwitch.m
Normal file
22
Vector/Views/TableViewCell/TableViewCellWithLabelAndSwitch.m
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "TableViewCellWithLabelAndSwitch.h"
|
||||
|
||||
@implementation TableViewCellWithLabelAndSwitch
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9060" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9051"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="aCf-VI-ocb" customClass="TableViewCellWithLabelAndSwitch">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="aCf-VI-ocb" id="Eg5-vl-rni">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="43"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9dA-E8-w3v">
|
||||
<rect key="frame" x="543" y="6" width="51" height="31"/>
|
||||
<animations/>
|
||||
</switch>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Xx4-AP-OQs">
|
||||
<rect key="frame" x="8" y="11" width="527" height="21"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<animations/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="Xx4-AP-OQs" secondAttribute="bottom" constant="11" id="2wi-Xu-jlr"/>
|
||||
<constraint firstItem="9dA-E8-w3v" firstAttribute="top" secondItem="Eg5-vl-rni" secondAttribute="top" constant="6" id="7fZ-Vc-PCU"/>
|
||||
<constraint firstItem="Xx4-AP-OQs" firstAttribute="top" secondItem="Eg5-vl-rni" secondAttribute="top" constant="11" id="WhC-iv-1UK"/>
|
||||
<constraint firstItem="Xx4-AP-OQs" firstAttribute="leading" secondItem="Eg5-vl-rni" secondAttribute="leading" constant="8" id="Wih-ke-1dd"/>
|
||||
<constraint firstAttribute="bottom" secondItem="9dA-E8-w3v" secondAttribute="bottom" constant="6" id="efV-Gs-ip0"/>
|
||||
<constraint firstItem="9dA-E8-w3v" firstAttribute="leading" secondItem="Xx4-AP-OQs" secondAttribute="trailing" constant="8" id="hms-8a-BYd"/>
|
||||
<constraint firstAttribute="trailing" secondItem="9dA-E8-w3v" secondAttribute="trailing" constant="8" id="oN3-Ph-hS5"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<animations/>
|
||||
<connections>
|
||||
<outlet property="mxkLabel" destination="Xx4-AP-OQs" id="jTM-zE-gtP"/>
|
||||
<outlet property="mxkSwitch" destination="9dA-E8-w3v" id="sko-Dh-EsF"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
</objects>
|
||||
</document>
|
Loading…
Reference in a new issue