mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-30 13:16:58 +02:00
RoomViewController: Show contextual menu toolbar on long press.
This commit is contained in:
@@ -123,7 +123,7 @@
|
||||
|
||||
#import "Riot-Swift.h"
|
||||
|
||||
@interface RoomViewController () <UISearchBarDelegate, UIGestureRecognizerDelegate, RoomTitleViewTapGestureDelegate, RoomParticipantsViewControllerDelegate, MXKRoomMemberDetailsViewControllerDelegate, ContactsTableViewControllerDelegate, MXServerNoticesDelegate>
|
||||
@interface RoomViewController () <UISearchBarDelegate, UIGestureRecognizerDelegate, RoomTitleViewTapGestureDelegate, RoomParticipantsViewControllerDelegate, MXKRoomMemberDetailsViewControllerDelegate, ContactsTableViewControllerDelegate, MXServerNoticesDelegate, RoomContextualMenuViewControllerDelegate>
|
||||
{
|
||||
// The expanded header
|
||||
ExpandedRoomTitleView *expandedHeader;
|
||||
@@ -213,6 +213,10 @@
|
||||
MXServerNotices *serverNotices;
|
||||
}
|
||||
|
||||
@property (nonatomic, weak) IBOutlet UIView *overlayContainerView;
|
||||
|
||||
@property (nonatomic, strong) RoomContextualMenuPresenter *roomContextualMenuPresenter;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RoomViewController
|
||||
@@ -404,6 +408,8 @@
|
||||
[self refreshRoomInputToolbar];
|
||||
}
|
||||
|
||||
self.roomContextualMenuPresenter = [RoomContextualMenuPresenter new];
|
||||
|
||||
// Observe user interface theme change.
|
||||
kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
@@ -589,6 +595,9 @@
|
||||
{
|
||||
[super viewDidDisappear:animated];
|
||||
|
||||
// Hide contextual menu if needed
|
||||
[self hideContextualMenuAnimated:NO];
|
||||
|
||||
// Reset visible room id
|
||||
[AppDelegate theDelegate].visibleRoomId = nil;
|
||||
|
||||
@@ -936,6 +945,8 @@
|
||||
- (void)updateRoomInputToolbarViewClassIfNeeded
|
||||
{
|
||||
Class roomInputToolbarViewClass = RoomInputToolbarView.class;
|
||||
|
||||
BOOL shouldDismissContextualMenu = NO;
|
||||
|
||||
// Check the user has enough power to post message
|
||||
if (self.roomDataSource.roomState)
|
||||
@@ -950,10 +961,12 @@
|
||||
if (isRoomObsolete || isResourceLimitExceeded)
|
||||
{
|
||||
roomInputToolbarViewClass = nil;
|
||||
shouldDismissContextualMenu = YES;
|
||||
}
|
||||
else if (!canSend)
|
||||
{
|
||||
roomInputToolbarViewClass = DisabledRoomInputToolbarView.class;
|
||||
shouldDismissContextualMenu = YES;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -961,6 +974,12 @@
|
||||
if (self.isRoomPreview)
|
||||
{
|
||||
roomInputToolbarViewClass = nil;
|
||||
shouldDismissContextualMenu = YES;
|
||||
}
|
||||
|
||||
if (shouldDismissContextualMenu)
|
||||
{
|
||||
[self hideContextualMenuAnimated:NO];
|
||||
}
|
||||
|
||||
// Change inputToolbarView class only if given class is different from current one
|
||||
@@ -978,7 +997,7 @@
|
||||
|
||||
if ([self.inputToolbarView isKindOfClass:RoomInputToolbarView.class])
|
||||
{
|
||||
height = ((RoomInputToolbarView*)self.inputToolbarView).mainToolbarMinHeightConstraint.constant;
|
||||
height = ((RoomInputToolbarView*)self.inputToolbarView).mainToolbarHeightConstraint.constant;
|
||||
}
|
||||
else if ([self.inputToolbarView isKindOfClass:DisabledRoomInputToolbarView.class])
|
||||
{
|
||||
@@ -1485,6 +1504,14 @@
|
||||
[UIView setAnimationsEnabled:YES];
|
||||
}
|
||||
|
||||
- (void)handleLongPressFromCell:(id<MXKCellRendering>)cell withTappedEvent:(MXEvent*)event
|
||||
{
|
||||
if (event && !customizedRoomDataSource.selectedEventId)
|
||||
{
|
||||
[self showContextualMenuForEvent:event cell:cell animated:YES];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Hide/Show expanded header
|
||||
|
||||
- (void)showExpandedHeader:(BOOL)isVisible
|
||||
@@ -1552,6 +1579,9 @@
|
||||
mainNavigationController.navigationBar.translucent = isVisible;
|
||||
self.navigationController.navigationBar.translucent = isVisible;
|
||||
|
||||
// Hide contextual menu if needed
|
||||
[self hideContextualMenuAnimated:YES];
|
||||
|
||||
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseIn
|
||||
animations:^{
|
||||
|
||||
@@ -2030,9 +2060,6 @@
|
||||
[self selectEventWithId:tappedEvent.eventId];
|
||||
}
|
||||
}
|
||||
|
||||
// Force table refresh
|
||||
[self dataSource:self.roomDataSource didCellChange:nil];
|
||||
}
|
||||
else if ([actionIdentifier isEqualToString:kMXKRoomBubbleCellTapOnOverlayContainer])
|
||||
{
|
||||
@@ -2073,9 +2100,6 @@
|
||||
// Highlight this event in displayed message
|
||||
[self selectEventWithId:((MXKRoomBubbleTableViewCell*)cell).bubbleData.attachment.eventId];
|
||||
}
|
||||
|
||||
// Force table refresh
|
||||
[self dataSource:self.roomDataSource didCellChange:nil];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2105,6 +2129,11 @@
|
||||
|
||||
[self.roomDataSource collapseRoomBubble:((MXKRoomBubbleTableViewCell*)cell).bubbleData collapsed:YES];
|
||||
}
|
||||
else if ([actionIdentifier isEqualToString:kMXKRoomBubbleCellLongPressOnEvent])
|
||||
{
|
||||
MXEvent *tappedEvent = userInfo[kMXKRoomBubbleCellEventKey];
|
||||
[self handleLongPressFromCell:cell withTappedEvent:tappedEvent];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Keep default implementation for other actions
|
||||
@@ -2213,24 +2242,6 @@
|
||||
}]];
|
||||
}
|
||||
}
|
||||
|
||||
if (level == 0)
|
||||
{
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_copy", @"Vector", nil)
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
typeof(self) self = weakSelf;
|
||||
|
||||
[self cancelEventSelection];
|
||||
|
||||
[[UIPasteboard generalPasteboard] setString:selectedComponent.textMessage];
|
||||
}
|
||||
|
||||
}]];
|
||||
}
|
||||
|
||||
if (level == 0)
|
||||
{
|
||||
@@ -2323,42 +2334,6 @@
|
||||
}]];
|
||||
}
|
||||
|
||||
if (attachment.type != MXKAttachmentTypeSticker)
|
||||
{
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_copy", @"Vector", nil)
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
typeof(self) self = weakSelf;
|
||||
|
||||
[self cancelEventSelection];
|
||||
|
||||
[self startActivityIndicator];
|
||||
|
||||
[attachment copy:^{
|
||||
|
||||
__strong __typeof(weakSelf)self = weakSelf;
|
||||
[self stopActivityIndicator];
|
||||
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
__strong __typeof(weakSelf)self = weakSelf;
|
||||
[self stopActivityIndicator];
|
||||
|
||||
//Alert user
|
||||
[[AppDelegate theDelegate] showErrorAsAlert:error];
|
||||
|
||||
}];
|
||||
|
||||
// Start animation in case of download during attachment preparing
|
||||
[roomBubbleTableViewCell startProgressUI];
|
||||
}
|
||||
|
||||
}]];
|
||||
}
|
||||
|
||||
// Check status of the selected event
|
||||
if (selectedEvent.sentState == MXEventSentStatePreparing ||
|
||||
selectedEvent.sentState == MXEventSentStateEncrypting ||
|
||||
@@ -2733,7 +2708,7 @@
|
||||
if (weakSelf)
|
||||
{
|
||||
typeof(self) self = weakSelf;
|
||||
[self cancelEventSelection];
|
||||
[self hideContextualMenuAnimated:YES];
|
||||
}
|
||||
|
||||
}]];
|
||||
@@ -2843,10 +2818,8 @@
|
||||
else if (url && urlItemInteractionValue)
|
||||
{
|
||||
// Fallback case for external links
|
||||
|
||||
// TODO: Use UITextItemInteraction enum when minimum deployement target will be iOS 10
|
||||
switch (urlItemInteractionValue.integerValue) {
|
||||
case 0: //UITextItemInteractionInvokeDefaultAction
|
||||
case UITextItemInteractionInvokeDefaultAction:
|
||||
{
|
||||
[[UIApplication sharedApplication] vc_open:url completionHandler:^(BOOL success) {
|
||||
if (!success)
|
||||
@@ -2857,10 +2830,13 @@
|
||||
shouldDoAction = NO;
|
||||
}
|
||||
break;
|
||||
case 1: //UITextItemInteractionPresentActions
|
||||
// Long press on link, let MXKRoomBubbleTableViewCell UITextView present the default contextual menu.
|
||||
case UITextItemInteractionPresentActions:
|
||||
{
|
||||
// Long press on link, present room contextual menu.
|
||||
shouldDoAction = NO;
|
||||
}
|
||||
break;
|
||||
case 2: //UITextItemInteractionPreview
|
||||
case UITextItemInteractionPreview:
|
||||
// Force touch on link, let MXKRoomBubbleTableViewCell UITextView use default peek and pop behavior.
|
||||
break;
|
||||
default:
|
||||
@@ -2879,10 +2855,19 @@
|
||||
- (void)selectEventWithId:(NSString*)eventId
|
||||
{
|
||||
BOOL shouldEnableReplyMode = [self.roomDataSource canReplyToEventWithId:eventId];
|
||||
|
||||
[self selectEventWithId:eventId enableReplyMode:shouldEnableReplyMode showTimestamp:YES];
|
||||
}
|
||||
|
||||
[self setInputToolBarSendMode: shouldEnableReplyMode ? RoomInputToolbarViewSendModeReply : RoomInputToolbarViewSendModeSend];
|
||||
|
||||
- (void)selectEventWithId:(NSString*)eventId enableReplyMode:(BOOL)enableReplyMode showTimestamp:(BOOL)showTimestamp
|
||||
{
|
||||
[self setInputToolBarSendMode: enableReplyMode ? RoomInputToolbarViewSendModeReply : RoomInputToolbarViewSendModeSend];
|
||||
|
||||
customizedRoomDataSource.showBubbleDateTimeOnSelection = showTimestamp;
|
||||
customizedRoomDataSource.selectedEventId = eventId;
|
||||
|
||||
// Force table refresh
|
||||
[self dataSource:self.roomDataSource didCellChange:nil];
|
||||
}
|
||||
|
||||
- (void)cancelEventSelection
|
||||
@@ -2895,6 +2880,7 @@
|
||||
currentAlert = nil;
|
||||
}
|
||||
|
||||
customizedRoomDataSource.showBubbleDateTimeOnSelection = YES;
|
||||
customizedRoomDataSource.selectedEventId = nil;
|
||||
|
||||
// Force table refresh
|
||||
@@ -4976,5 +4962,169 @@
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Contextual Menu
|
||||
|
||||
- (NSArray<RoomContextualMenuItem*>*)contextualMenuItemsForEvent:(MXEvent*)event andCell:(id<MXKCellRendering>)cell
|
||||
{
|
||||
NSString *eventId = event.eventId;
|
||||
MXKRoomBubbleTableViewCell *roomBubbleTableViewCell = (MXKRoomBubbleTableViewCell *)cell;
|
||||
MXKAttachment *attachment = roomBubbleTableViewCell.bubbleData.attachment;
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
// Copy action
|
||||
|
||||
RoomContextualMenuItem *copyMenuItem = [[RoomContextualMenuItem alloc] initWithMenuAction:RoomContextualMenuActionCopy];
|
||||
copyMenuItem.isEnabled = !attachment || attachment.type != MXKAttachmentTypeSticker;
|
||||
copyMenuItem.action = ^{
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
if (!attachment)
|
||||
{
|
||||
NSArray *components = roomBubbleTableViewCell.bubbleData.bubbleComponents;
|
||||
MXKRoomBubbleComponent *selectedComponent;
|
||||
for (selectedComponent in components)
|
||||
{
|
||||
if ([selectedComponent.event.eventId isEqualToString:event.eventId])
|
||||
{
|
||||
break;
|
||||
}
|
||||
selectedComponent = nil;
|
||||
}
|
||||
NSString *textMessage = selectedComponent.textMessage;
|
||||
|
||||
[UIPasteboard generalPasteboard].string = textMessage;
|
||||
|
||||
[self hideContextualMenuAnimated:YES];
|
||||
}
|
||||
else if (attachment.type != MXKAttachmentTypeSticker)
|
||||
{
|
||||
[self hideContextualMenuAnimated:YES completion:^{
|
||||
[self startActivityIndicator];
|
||||
|
||||
[attachment copy:^{
|
||||
|
||||
[self stopActivityIndicator];
|
||||
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
[self stopActivityIndicator];
|
||||
|
||||
//Alert user
|
||||
[[AppDelegate theDelegate] showErrorAsAlert:error];
|
||||
}];
|
||||
|
||||
// Start animation in case of download during attachment preparing
|
||||
[roomBubbleTableViewCell startProgressUI];
|
||||
}];
|
||||
}
|
||||
};
|
||||
|
||||
// Reply action
|
||||
|
||||
RoomContextualMenuItem *replyMenuItem = [[RoomContextualMenuItem alloc] initWithMenuAction:RoomContextualMenuActionReply];
|
||||
replyMenuItem.isEnabled = [self.roomDataSource canReplyToEventWithId:eventId];
|
||||
replyMenuItem.action = ^{
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self hideContextualMenuAnimated:YES cancelEventSelection:NO completion:nil];
|
||||
[self selectEventWithId:eventId enableReplyMode:YES showTimestamp:NO];
|
||||
};
|
||||
|
||||
// Edit action
|
||||
|
||||
RoomContextualMenuItem *editMenuItem = [[RoomContextualMenuItem alloc] initWithMenuAction:RoomContextualMenuActionEdit];
|
||||
// TODO: Handle edit action
|
||||
editMenuItem.isEnabled = NO;
|
||||
|
||||
// More action
|
||||
|
||||
RoomContextualMenuItem *moreMenuItem = [[RoomContextualMenuItem alloc] initWithMenuAction:RoomContextualMenuActionMore];
|
||||
moreMenuItem.action = ^{
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
[self showEditButtonAlertMenuForEvent:event inCell:cell level:0];
|
||||
};
|
||||
|
||||
// Actions list
|
||||
|
||||
NSArray<RoomContextualMenuItem*> *actionItems = @[
|
||||
copyMenuItem,
|
||||
replyMenuItem,
|
||||
editMenuItem,
|
||||
moreMenuItem
|
||||
];
|
||||
|
||||
return actionItems;
|
||||
}
|
||||
|
||||
- (void)showContextualMenuForEvent:(MXEvent*)event cell:(id<MXKCellRendering>)cell animated:(BOOL)animated
|
||||
{
|
||||
if (self.roomContextualMenuPresenter.isPresenting)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
[self selectEventWithId:event.eventId enableReplyMode:NO showTimestamp:NO];
|
||||
|
||||
NSArray<RoomContextualMenuItem*>* contextualMenuItems = [self contextualMenuItemsForEvent:event andCell:cell];
|
||||
|
||||
RoomContextualMenuViewController *roomContextualMenuViewController = [RoomContextualMenuViewController instantiateWith:contextualMenuItems];
|
||||
roomContextualMenuViewController.delegate = self;
|
||||
|
||||
[self.roomContextualMenuPresenter presentWithRoomContextualMenuViewController:roomContextualMenuViewController
|
||||
from:self
|
||||
on:self.overlayContainerView
|
||||
animated:YES
|
||||
completion:^{
|
||||
[self contextualMenuAnimationCompletionAfterBeingShown:YES];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)hideContextualMenuAnimated:(BOOL)animated
|
||||
{
|
||||
[self hideContextualMenuAnimated:animated completion:nil];
|
||||
}
|
||||
|
||||
- (void)hideContextualMenuAnimated:(BOOL)animated completion:(void(^)(void))completion
|
||||
{
|
||||
[self hideContextualMenuAnimated:animated cancelEventSelection:YES completion:completion];
|
||||
}
|
||||
|
||||
- (void)hideContextualMenuAnimated:(BOOL)animated cancelEventSelection:(BOOL)cancelEventSelection completion:(void(^)(void))completion
|
||||
{
|
||||
if (!self.roomContextualMenuPresenter.isPresenting)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (cancelEventSelection)
|
||||
{
|
||||
[self cancelEventSelection];
|
||||
}
|
||||
|
||||
[self.roomContextualMenuPresenter hideContextualMenuWithAnimated:animated completion:^{
|
||||
[self contextualMenuAnimationCompletionAfterBeingShown:NO];
|
||||
|
||||
if (completion)
|
||||
{
|
||||
completion();
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)contextualMenuAnimationCompletionAfterBeingShown:(BOOL)isShown
|
||||
{
|
||||
self.inputToolbarView.editable = !isShown;
|
||||
self.bubblesTableView.scrollsToTop = !isShown;
|
||||
self.overlayContainerView.userInteractionEnabled = isShown;
|
||||
}
|
||||
|
||||
#pragma mark - RoomContextualMenuViewControllerDelegate
|
||||
|
||||
- (void)roomContextualMenuViewControllerDidTapBackgroundOverlay:(RoomContextualMenuViewController *)viewController
|
||||
{
|
||||
[self hideContextualMenuAnimated:YES];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@@ -21,6 +21,7 @@
|
||||
<outlet property="jumpToLastUnreadBannerSeparatorView" destination="knN-q1-QkJ" id="hHJ-c8-QfN"/>
|
||||
<outlet property="jumpToLastUnreadButton" destination="ISb-UT-u0O" id="fs0-sQ-lRe"/>
|
||||
<outlet property="jumpToLastUnreadLabel" destination="S1q-B4-Df3" id="McV-gv-bUa"/>
|
||||
<outlet property="overlayContainerView" destination="gt1-EO-UVY" id="5q6-pW-UyZ"/>
|
||||
<outlet property="previewHeaderContainer" destination="54r-18-K1g" id="Klt-RV-V1E"/>
|
||||
<outlet property="previewHeaderContainerHeightConstraint" destination="goj-GZ-IkD" id="GbA-T9-kiL"/>
|
||||
<outlet property="resetReadMarkerButton" destination="c4g-BY-xOo" id="KuR-hH-rz1"/>
|
||||
@@ -130,7 +131,7 @@
|
||||
<constraint firstItem="ISb-UT-u0O" firstAttribute="centerY" secondItem="Vlz-UJ-Jz8" secondAttribute="centerY" id="w7t-WC-VjP"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XX4-n6-hCm" userLabel="Activities Container">
|
||||
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XX4-n6-hCm" userLabel="Activities Container">
|
||||
<rect key="frame" x="0.0" y="606" width="375" height="20"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="RoomVCActivitiesContainer"/>
|
||||
@@ -146,10 +147,15 @@
|
||||
<constraint firstAttribute="height" constant="41" id="5eD-Fm-RDb"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="gt1-EO-UVY">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="RoomVCView"/>
|
||||
<constraints>
|
||||
<constraint firstItem="gt1-EO-UVY" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="0Gc-VV-1ao"/>
|
||||
<constraint firstAttribute="trailing" secondItem="BGD-sd-SQR" secondAttribute="trailing" id="0la-ok-MBr"/>
|
||||
<constraint firstItem="S6r-bo-jxw" firstAttribute="width" secondItem="BGD-sd-SQR" secondAttribute="width" id="3Mr-fA-bfF"/>
|
||||
<constraint firstItem="nLd-BP-JAE" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="4Q7-hr-rqi"/>
|
||||
@@ -160,12 +166,15 @@
|
||||
<constraint firstItem="XX4-n6-hCm" firstAttribute="bottom" secondItem="nLd-BP-JAE" secondAttribute="top" id="QO8-nF-xys"/>
|
||||
<constraint firstItem="XX4-n6-hCm" firstAttribute="width" secondItem="iN0-l3-epB" secondAttribute="width" id="WhE-lH-ZtR"/>
|
||||
<constraint firstItem="BGD-sd-SQR" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="X14-4s-uGM"/>
|
||||
<constraint firstItem="gt1-EO-UVY" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="XGH-fF-BKB"/>
|
||||
<constraint firstAttribute="trailing" secondItem="nLd-BP-JAE" secondAttribute="trailing" id="YAu-gd-ItG"/>
|
||||
<constraint firstItem="S6r-bo-jxw" firstAttribute="centerX" secondItem="BGD-sd-SQR" secondAttribute="centerX" id="a2s-5o-q2d"/>
|
||||
<constraint firstItem="gt1-EO-UVY" firstAttribute="bottom" secondItem="nLd-BP-JAE" secondAttribute="bottom" id="acJ-g8-R7x"/>
|
||||
<constraint firstItem="XX4-n6-hCm" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="csl-KT-4s9"/>
|
||||
<constraint firstItem="54r-18-K1g" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="ghf-co-a4t"/>
|
||||
<constraint firstItem="BGD-sd-SQR" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="haP-Kv-OLI"/>
|
||||
<constraint firstAttribute="bottom" secondItem="nLd-BP-JAE" secondAttribute="bottom" id="kQ6-Cg-FMi"/>
|
||||
<constraint firstAttribute="trailing" secondItem="gt1-EO-UVY" secondAttribute="trailing" id="qmd-M4-phm"/>
|
||||
<constraint firstItem="uK2-9a-rZj" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="u8r-eN-1g8"/>
|
||||
<constraint firstItem="S6r-bo-jxw" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="xYa-gT-4x0"/>
|
||||
<constraint firstItem="uK2-9a-rZj" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="y6b-JK-CF5"/>
|
||||
@@ -174,7 +183,7 @@
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="cancel" width="32" height="32"/>
|
||||
<image name="jump_to_unread" width="48" height="48"/>
|
||||
<image name="cancel" width="20" height="20"/>
|
||||
<image name="jump_to_unread" width="30" height="30"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
Reference in New Issue
Block a user