mirror of
https://github.com/vector-im/element-ios.git
synced 2024-09-28 23:32:41 +00:00
Merge pull request #4265 from vector-im/voip_jitsi_remover
Voip Jitsi Widget Remover
This commit is contained in:
commit
c1e99196b2
30 changed files with 818 additions and 145 deletions
|
@ -11,6 +11,8 @@ Changes to be released in next version
|
|||
* SettingsVC: Show / hide NSFW and decrypted content options from build settings (#4290).
|
||||
* RoomVC: Tweaked Scroll to Bottom FAB button (#4272).
|
||||
* DesignKit: Introduce a new framework to manage design components.
|
||||
* Add Jitsi widget remove banner for privileged users.
|
||||
* Update "Jump to unread" banner to a pill style button.
|
||||
|
||||
🐛 Bugfix
|
||||
* RoomVC: Avoid navigation to integration management using integration popup with settings set to integration disabled (#4261).
|
||||
|
|
BIN
Riot/Assets/Images.xcassets/Room/Activities/new_close.imageset/Close.png
vendored
Normal file
BIN
Riot/Assets/Images.xcassets/Room/Activities/new_close.imageset/Close.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 370 B |
BIN
Riot/Assets/Images.xcassets/Room/Activities/new_close.imageset/Close@2x.png
vendored
Normal file
BIN
Riot/Assets/Images.xcassets/Room/Activities/new_close.imageset/Close@2x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 509 B |
BIN
Riot/Assets/Images.xcassets/Room/Activities/new_close.imageset/Close@3x.png
vendored
Normal file
BIN
Riot/Assets/Images.xcassets/Room/Activities/new_close.imageset/Close@3x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 772 B |
26
Riot/Assets/Images.xcassets/Room/Activities/new_close.imageset/Contents.json
vendored
Normal file
26
Riot/Assets/Images.xcassets/Room/Activities/new_close.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "Close.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "Close@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "Close@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"template-rendering-intent" : "template"
|
||||
}
|
||||
}
|
26
Riot/Assets/Images.xcassets/Room/Activities/room_scroll_up.imageset/Contents.json
vendored
Normal file
26
Riot/Assets/Images.xcassets/Room/Activities/room_scroll_up.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "Up.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "Up@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "Up@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"template-rendering-intent" : "original"
|
||||
}
|
||||
}
|
BIN
Riot/Assets/Images.xcassets/Room/Activities/room_scroll_up.imageset/Up.png
vendored
Normal file
BIN
Riot/Assets/Images.xcassets/Room/Activities/room_scroll_up.imageset/Up.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 609 B |
BIN
Riot/Assets/Images.xcassets/Room/Activities/room_scroll_up.imageset/Up@2x.png
vendored
Normal file
BIN
Riot/Assets/Images.xcassets/Room/Activities/room_scroll_up.imageset/Up@2x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1,015 B |
BIN
Riot/Assets/Images.xcassets/Room/Activities/room_scroll_up.imageset/Up@3x.png
vendored
Normal file
BIN
Riot/Assets/Images.xcassets/Room/Activities/room_scroll_up.imageset/Up@3x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
|
@ -1,23 +1,26 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "cancel.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "cancel@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "cancel@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"template-rendering-intent" : "template"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -313,7 +313,8 @@ Tap the + to start adding people.";
|
|||
"room_member_power_level_short_custom" = "Custom";
|
||||
|
||||
// Chat
|
||||
"room_jump_to_first_unread" = "Jump to first unread message";
|
||||
"room_slide_to_end_group_call" = "Slide to end the call for everyone";
|
||||
"room_jump_to_first_unread" = "Jump to unread";
|
||||
"room_accessiblity_scroll_to_bottom" = "Scroll to bottom";
|
||||
"room_new_message_notification" = "%d new message";
|
||||
"room_new_messages_notification" = "%d new messages";
|
||||
|
|
|
@ -64,4 +64,16 @@ extension UIView {
|
|||
self.accessibilityTraits.insert(.notEnabled)
|
||||
}
|
||||
}
|
||||
|
||||
@objc func vc_addShadow(withColor color: UIColor, offset: CGSize, radius: CGFloat, opacity: CGFloat) {
|
||||
layer.shadowColor = color.cgColor
|
||||
layer.shadowOpacity = Float(opacity)
|
||||
layer.shadowRadius = radius
|
||||
layer.shadowOffset = offset
|
||||
}
|
||||
|
||||
@objc func vc_removeShadow() {
|
||||
layer.shadowColor = UIColor.clear.cgColor
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -105,7 +105,9 @@ internal enum Asset {
|
|||
internal static let actionSticker = ImageAsset(name: "action_sticker")
|
||||
internal static let error = ImageAsset(name: "error")
|
||||
internal static let errorMessageTick = ImageAsset(name: "error_message_tick")
|
||||
internal static let newClose = ImageAsset(name: "new_close")
|
||||
internal static let roomActivitiesRetry = ImageAsset(name: "room_activities_retry")
|
||||
internal static let roomScrollUp = ImageAsset(name: "room_scroll_up")
|
||||
internal static let scrolldown = ImageAsset(name: "scrolldown")
|
||||
internal static let scrolldownDark = ImageAsset(name: "scrolldown_dark")
|
||||
internal static let sendingMessageTick = ImageAsset(name: "sending_message_tick")
|
||||
|
|
|
@ -2930,7 +2930,7 @@ internal enum VectorL10n {
|
|||
internal static var roomJoinGroupCall: String {
|
||||
return VectorL10n.tr("Vector", "room_join_group_call")
|
||||
}
|
||||
/// Jump to first unread message
|
||||
/// Jump to unread
|
||||
internal static var roomJumpToFirstUnread: String {
|
||||
return VectorL10n.tr("Vector", "room_jump_to_first_unread")
|
||||
}
|
||||
|
@ -3390,6 +3390,10 @@ internal enum VectorL10n {
|
|||
internal static var roomResourceUsageLimitReachedMessageContact3: String {
|
||||
return VectorL10n.tr("Vector", "room_resource_usage_limit_reached_message_contact_3")
|
||||
}
|
||||
/// Slide to end the call for everyone
|
||||
internal static var roomSlideToEndGroupCall: String {
|
||||
return VectorL10n.tr("Vector", "room_slide_to_end_group_call")
|
||||
}
|
||||
/// Invite members
|
||||
internal static var roomTitleInviteMembers: String {
|
||||
return VectorL10n.tr("Vector", "room_title_invite_members")
|
||||
|
|
|
@ -165,7 +165,7 @@ class CallPresenter: NSObject {
|
|||
})
|
||||
}
|
||||
|
||||
if let jitsiVC = jitsiVC, jitsiVC.widget.widgetId == widget.widgetId {
|
||||
if let jitsiVC = jitsiVC {
|
||||
if jitsiVC.widget.widgetId == widget.widgetId {
|
||||
self.presentCallVC(jitsiVC)
|
||||
} else {
|
||||
|
@ -610,7 +610,11 @@ class CallPresenter: NSObject {
|
|||
return
|
||||
}
|
||||
|
||||
presentCallVC(callVC)
|
||||
if callVC == pipCallVC {
|
||||
exitPipCallVC(callVC)
|
||||
} else {
|
||||
presentCallVC(callVC)
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
|
@ -644,7 +648,11 @@ class CallPresenter: NSObject {
|
|||
return
|
||||
}
|
||||
|
||||
presentCallVC(jitsiVC)
|
||||
if jitsiVC == pipCallVC {
|
||||
exitPipCallVC(jitsiVC)
|
||||
} else {
|
||||
presentCallVC(jitsiVC)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Call Screens
|
||||
|
|
|
@ -94,6 +94,9 @@ import DesignKit
|
|||
/// Color to tint the search background image
|
||||
var matrixSearchBackgroundImageTintColor: UIColor { get }
|
||||
|
||||
/// Color to use in shadows. Should be contrast to `backgroundColor`.
|
||||
var shadowColor: UIColor { get }
|
||||
|
||||
// MARK: - Customisation methods
|
||||
|
||||
|
||||
|
|
|
@ -155,6 +155,9 @@ NSString *const kThemeServiceDidChangeThemeNotification = @"kThemeServiceDidChan
|
|||
|
||||
// Define the UISearchBar cancel button color
|
||||
[[UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setTitleTextAttributes:@{ NSForegroundColorAttributeName : self.theme.tintColor } forState: UIControlStateNormal];
|
||||
|
||||
[[UIStackView appearanceWhenContainedInInstancesOfClasses:@[[UINavigationBar class]]] setSpacing:-7];
|
||||
[[UIStackView appearanceWhenContainedInInstancesOfClasses:@[[UINavigationBar class]]] setDistribution:UIStackViewDistributionEqualCentering];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -88,6 +88,8 @@ class DarkTheme: NSObject, Theme {
|
|||
var matrixSearchBackgroundImageTintColor: UIColor = UIColor(rgb: 0x7E7E7E)
|
||||
var secondaryCircleButtonBackgroundColor: UIColor = UIColor(rgb: 0xE3E8F0)
|
||||
|
||||
var shadowColor: UIColor = UIColor(rgb: 0xFFFFFF)
|
||||
|
||||
var messageTickColor: UIColor = .white
|
||||
|
||||
func applyStyle(onTabBar tabBar: UITabBar) {
|
||||
|
|
|
@ -98,6 +98,8 @@ class DefaultTheme: NSObject, Theme {
|
|||
|
||||
var secondaryCircleButtonBackgroundColor: UIColor = UIColor(rgb: 0xE3E8F0)
|
||||
|
||||
var shadowColor: UIColor = UIColor(rgb: 0x000000)
|
||||
|
||||
func applyStyle(onTabBar tabBar: UITabBar) {
|
||||
tabBar.unselectedItemTintColor = self.tabBarUnselectedItemTintColor
|
||||
tabBar.tintColor = self.tintColor
|
||||
|
|
|
@ -233,10 +233,15 @@ class DialpadViewController: UIViewController {
|
|||
theme.applyStyle(onNavigationBar: navigationBar)
|
||||
}
|
||||
|
||||
titleLabel.textColor = theme.noticeSecondaryColor
|
||||
if theme.identifier == ThemeIdentifier.light.rawValue {
|
||||
titleLabel.textColor = theme.noticeSecondaryColor
|
||||
closeButton.setBackgroundImage(Asset.Images.closeButton.image.vc_tintedImage(usingColor: theme.tabBarUnselectedItemTintColor), for: .normal)
|
||||
} else {
|
||||
titleLabel.textColor = theme.baseTextSecondaryColor
|
||||
closeButton.setBackgroundImage(Asset.Images.closeButton.image.vc_tintedImage(usingColor: theme.baseTextSecondaryColor), for: .normal)
|
||||
}
|
||||
phoneNumberTextField.textColor = theme.textPrimaryColor
|
||||
lineView.backgroundColor = theme.lineBreakColor
|
||||
closeButton.setBackgroundImage(Asset.Images.closeButton.image.vc_tintedImage(usingColor: theme.tabBarUnselectedItemTintColor), for: .normal)
|
||||
|
||||
updateThemesOfAllButtons(in: digitsStackView, with: theme)
|
||||
}
|
||||
|
|
|
@ -31,9 +31,9 @@ class DialpadActionButton: DialpadButton {
|
|||
switch type {
|
||||
case .backspace:
|
||||
backgroundColor = .clear
|
||||
tintColor = theme.noticeSecondaryColor
|
||||
tintColor = theme.colors.tertiaryContent
|
||||
case .call:
|
||||
backgroundColor = theme.tintColor
|
||||
backgroundColor = theme.colors.accent
|
||||
tintColor = .white
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,16 +47,18 @@ extern NSNotificationName const RoomGroupCallTileTappedNotification;
|
|||
|
||||
// The jump to last unread banner
|
||||
@property (weak, nonatomic) IBOutlet UIView *jumpToLastUnreadBannerContainer;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *jumpToLastUnreadBannerContainerTopConstraint;
|
||||
@property (weak, nonatomic) IBOutlet UIView *jumpToLastUnreadBanner;
|
||||
@property (weak, nonatomic) IBOutlet UIImageView *jumpToLastUnreadImageView;
|
||||
@property (weak, nonatomic) IBOutlet UIButton *jumpToLastUnreadButton;
|
||||
@property (weak, nonatomic) IBOutlet UILabel *jumpToLastUnreadLabel;
|
||||
@property (weak, nonatomic) IBOutlet UIButton *resetReadMarkerButton;
|
||||
@property (weak, nonatomic) IBOutlet UIView *jumpToLastUnreadBannerSeparatorView;
|
||||
@property (weak, nonatomic) IBOutlet UIView *inputBackgroundView;
|
||||
@property (weak, nonatomic) IBOutlet UIButton *scrollToBottomButton;
|
||||
@property (weak, nonatomic) IBOutlet BadgeLabel *scrollToBottomBadgeLabel;
|
||||
|
||||
// Remove Jitsi widget container
|
||||
@property (weak, nonatomic) IBOutlet UIView *removeJitsiWidgetContainer;
|
||||
|
||||
/**
|
||||
Preview data for a room invitation received by email, or a link to a room.
|
||||
*/
|
||||
|
|
|
@ -135,7 +135,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
@interface RoomViewController () <UISearchBarDelegate, UIGestureRecognizerDelegate, UIScrollViewAccessibilityDelegate, RoomTitleViewTapGestureDelegate, RoomParticipantsViewControllerDelegate, MXKRoomMemberDetailsViewControllerDelegate, ContactsTableViewControllerDelegate, MXServerNoticesDelegate, RoomContextualMenuViewControllerDelegate,
|
||||
ReactionsMenuViewModelCoordinatorDelegate, EditHistoryCoordinatorBridgePresenterDelegate, MXKDocumentPickerPresenterDelegate, EmojiPickerCoordinatorBridgePresenterDelegate,
|
||||
ReactionHistoryCoordinatorBridgePresenterDelegate, CameraPresenterDelegate, MediaPickerCoordinatorBridgePresenterDelegate,
|
||||
RoomDataSourceDelegate, RoomCreationModalCoordinatorBridgePresenterDelegate, RoomInfoCoordinatorBridgePresenterDelegate, DialpadViewControllerDelegate>
|
||||
RoomDataSourceDelegate, RoomCreationModalCoordinatorBridgePresenterDelegate, RoomInfoCoordinatorBridgePresenterDelegate, DialpadViewControllerDelegate, RemoveJitsiWidgetViewDelegate>
|
||||
{
|
||||
|
||||
// The preview header
|
||||
|
@ -220,6 +220,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
}
|
||||
|
||||
@property (nonatomic, weak) IBOutlet UIView *overlayContainerView;
|
||||
@property (nonatomic, strong) RemoveJitsiWidgetView *removeJitsiWidgetView;
|
||||
|
||||
|
||||
@property (nonatomic, strong) RoomContextualMenuViewController *roomContextualMenuViewController;
|
||||
|
@ -387,6 +388,8 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
[self vc_removeBackTitle];
|
||||
|
||||
[self setupRemoveJitsiWidgetRemoveView];
|
||||
|
||||
// Replace the default input toolbar view.
|
||||
// Note: this operation will force the layout of subviews. That is why cell view classes must be registered before.
|
||||
[self updateRoomInputToolbarViewClassIfNeeded];
|
||||
|
@ -455,11 +458,11 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
self.activityIndicator.backgroundColor = ThemeService.shared.theme.overlayBackgroundColor;
|
||||
|
||||
[self.removeJitsiWidgetView updateWithTheme:ThemeService.shared.theme];
|
||||
|
||||
// Prepare jump to last unread banner
|
||||
self.jumpToLastUnreadBannerContainer.backgroundColor = ThemeService.shared.theme.backgroundColor;
|
||||
self.jumpToLastUnreadImageView.tintColor = ThemeService.shared.theme.textPrimaryColor;
|
||||
self.jumpToLastUnreadImageView.tintColor = ThemeService.shared.theme.tintColor;
|
||||
self.jumpToLastUnreadLabel.textColor = ThemeService.shared.theme.textPrimaryColor;
|
||||
self.jumpToLastUnreadBannerSeparatorView.backgroundColor = ThemeService.shared.theme.lineBreakColor;
|
||||
|
||||
self.previewHeaderContainer.backgroundColor = ThemeService.shared.theme.headerBackgroundColor;
|
||||
|
||||
|
@ -473,23 +476,31 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
[self.bubblesTableView reloadData];
|
||||
}
|
||||
|
||||
self.scrollToBottomButton.layer.shadowColor = [UIColor blackColor].CGColor;
|
||||
self.scrollToBottomButton.layer.shadowOpacity = 0.2;
|
||||
self.scrollToBottomButton.layer.shadowRadius = 6;
|
||||
self.scrollToBottomButton.layer.shadowOffset = CGSizeMake(0, 4);
|
||||
[self.scrollToBottomButton vc_addShadowWithColor:ThemeService.shared.theme.shadowColor
|
||||
offset:CGSizeMake(0, 4)
|
||||
radius:6
|
||||
opacity:0.2];
|
||||
|
||||
self.inputBackgroundView.backgroundColor = [ThemeService.shared.theme.backgroundColor colorWithAlphaComponent:0.98];
|
||||
|
||||
if ([ThemeService.shared.themeId isEqualToString:@"light"])
|
||||
if (ThemeService.shared.isCurrentThemeDark)
|
||||
{
|
||||
[self.scrollToBottomButton setImage:[UIImage imageNamed:@"scrolldown_dark"] forState:UIControlStateNormal];
|
||||
|
||||
self.jumpToLastUnreadBanner.backgroundColor = ThemeService.shared.theme.colors.navigation;
|
||||
[self.jumpToLastUnreadBanner vc_removeShadow];
|
||||
self.resetReadMarkerButton.tintColor = ThemeService.shared.theme.colors.quarterlyContent;
|
||||
}
|
||||
else
|
||||
{
|
||||
[self.scrollToBottomButton setImage:[UIImage imageNamed:@"scrolldown"] forState:UIControlStateNormal];
|
||||
}
|
||||
else if ([ThemeService.shared.themeId isEqualToString:@"dark"] || [ThemeService.shared.themeId isEqualToString:@"black"])
|
||||
{
|
||||
[self.scrollToBottomButton setImage:[UIImage imageNamed:@"scrolldown_dark"] forState:UIControlStateNormal];
|
||||
}
|
||||
else if (@available(iOS 12.0, *) && ThemeService.shared.theme.userInterfaceStyle == UIUserInterfaceStyleDark) {
|
||||
[self.scrollToBottomButton setImage:[UIImage imageNamed:@"scrolldown_dark"] forState:UIControlStateNormal];
|
||||
|
||||
self.jumpToLastUnreadBanner.backgroundColor = ThemeService.shared.theme.colors.background;
|
||||
[self.jumpToLastUnreadBanner vc_addShadowWithColor:ThemeService.shared.theme.shadowColor
|
||||
offset:CGSizeMake(0, 4)
|
||||
radius:8
|
||||
opacity:0.1];
|
||||
self.resetReadMarkerButton.tintColor = ThemeService.shared.theme.colors.tertiaryContent;
|
||||
}
|
||||
|
||||
self.scrollToBottomBadgeLabel.badgeColor = ThemeService.shared.theme.tintColor;
|
||||
|
@ -518,6 +529,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
// Refresh the room title view
|
||||
[self refreshRoomTitle];
|
||||
|
||||
// refresh remove Jitsi widget view
|
||||
[self refreshRemoveJitsiWidgetView];
|
||||
|
||||
// Refresh tool bar if the room data source is set.
|
||||
if (self.roomDataSource)
|
||||
{
|
||||
|
@ -732,15 +746,12 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
self.previewHeaderContainerHeightConstraint.constant = frame.origin.y + frame.size.height;
|
||||
|
||||
self.bubblesTableViewTopConstraint.constant = self.previewHeaderContainerHeightConstraint.constant - self.bubblesTableView.mxk_adjustedContentInset.top;
|
||||
self.jumpToLastUnreadBannerContainerTopConstraint.constant = self.previewHeaderContainerHeightConstraint.constant;
|
||||
}
|
||||
else
|
||||
{
|
||||
// In non expanded header mode, the navigation bar is opaque
|
||||
// The table view must not display behind it
|
||||
self.edgesForExtendedLayout = UIRectEdgeLeft | UIRectEdgeBottom | UIRectEdgeRight;
|
||||
|
||||
self.jumpToLastUnreadBannerContainerTopConstraint.constant = self.bubblesTableView.mxk_adjustedContentInset.top; // no expanded
|
||||
}
|
||||
|
||||
// stay at the bottom if already was
|
||||
|
@ -1396,6 +1407,29 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
#pragma mark - Internals
|
||||
|
||||
- (UIBarButtonItem *)videoCallBarButtonItem
|
||||
{
|
||||
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"video_call"]
|
||||
style:UIBarButtonItemStylePlain
|
||||
target:self
|
||||
action:@selector(onVideoCallPressed:)];
|
||||
item.accessibilityLabel = NSLocalizedStringFromTable(@"room_accessibility_video_call", @"Vector", nil);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
- (void)setupRemoveJitsiWidgetRemoveView
|
||||
{
|
||||
self.removeJitsiWidgetView = [RemoveJitsiWidgetView instantiate];
|
||||
self.removeJitsiWidgetView.delegate = self;
|
||||
|
||||
[self.removeJitsiWidgetContainer vc_addSubViewMatchingParent:self.removeJitsiWidgetView];
|
||||
|
||||
self.removeJitsiWidgetContainer.hidden = YES;
|
||||
|
||||
[self refreshRemoveJitsiWidgetView];
|
||||
}
|
||||
|
||||
- (void)forceLayoutRefresh
|
||||
{
|
||||
// Sanity check: check whether the table view data source is set.
|
||||
|
@ -1467,70 +1501,84 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
if (self.roomDataSource.isLive)
|
||||
{
|
||||
rightBarButtonItems = [NSMutableArray new];
|
||||
BOOL hasCustomJoinButton = NO;
|
||||
|
||||
UIEdgeInsets itemInsets = UIEdgeInsetsMake(0, -5, 0, 5);
|
||||
if (self.supportCallOption)
|
||||
{
|
||||
if (self.roomDataSource.room.summary.membersCount.joined == 2 && self.roomDataSource.room.isDirect)
|
||||
{
|
||||
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"voice_call_hangon_icon"] style:UIBarButtonItemStylePlain target:self action:@selector(onVoiceCallPressed:)];
|
||||
item.accessibilityLabel = NSLocalizedStringFromTable(@"room_accessibility_call", @"Vector", nil);
|
||||
item.imageInsets = UIEdgeInsetsMake(0, -5, 0, 5);
|
||||
item.enabled = !self.isCallActive;
|
||||
[rightBarButtonItems addObject:item];
|
||||
}
|
||||
|
||||
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"video_call"] style:UIBarButtonItemStylePlain target:self action:@selector(onVideoCallPressed:)];
|
||||
item.imageInsets = rightBarButtonItems.count ? UIEdgeInsetsMake(0, 10, 0, -10) : itemInsets;
|
||||
item.accessibilityLabel = NSLocalizedStringFromTable(@"room_accessibility_video_call", @"Vector", nil);
|
||||
if (self.roomDataSource.room.summary.membersCount.joined == 2 && self.roomDataSource.room.isDirect)
|
||||
{
|
||||
// Matrix call
|
||||
item.enabled = !self.isCallActive;
|
||||
// voice call button for Matrix call
|
||||
UIBarButtonItem *itemVoice = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"voice_call_hangon_icon"]
|
||||
style:UIBarButtonItemStylePlain
|
||||
target:self
|
||||
action:@selector(onVoiceCallPressed:)];
|
||||
itemVoice.accessibilityLabel = NSLocalizedStringFromTable(@"room_accessibility_call", @"Vector", nil);
|
||||
itemVoice.enabled = !self.isCallActive;
|
||||
[rightBarButtonItems addObject:itemVoice];
|
||||
|
||||
// video call button for Matrix call
|
||||
UIBarButtonItem *itemVideo = [self videoCallBarButtonItem];
|
||||
itemVideo.enabled = !self.isCallActive;
|
||||
[rightBarButtonItems addObject:itemVideo];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Jitsi call
|
||||
// video call button for Jitsi call
|
||||
if (self.isCallActive)
|
||||
{
|
||||
JitsiViewController *jitsiVC = [AppDelegate theDelegate].callPresenter.jitsiVC;
|
||||
if ([jitsiVC.widget.roomId isEqualToString:self.roomDataSource.roomId])
|
||||
{
|
||||
// show a disabled call button
|
||||
UIBarButtonItem *item = [self videoCallBarButtonItem];
|
||||
item.enabled = NO;
|
||||
[rightBarButtonItems addObject:item];
|
||||
}
|
||||
else
|
||||
{
|
||||
// show Join button
|
||||
CallTileActionButton *button = [CallTileActionButton new];
|
||||
[button setImage:[UIImage imageNamed:@"call_video_icon"] forState:UIControlStateNormal];
|
||||
[button setTitle:NSLocalizedStringFromTable(@"room_join_group_call", @"Vector", nil) forState:UIControlStateNormal];
|
||||
[button setImage:[UIImage imageNamed:@"call_video_icon"]
|
||||
forState:UIControlStateNormal];
|
||||
[button setTitle:NSLocalizedStringFromTable(@"room_join_group_call", @"Vector", nil)
|
||||
forState:UIControlStateNormal];
|
||||
[button addTarget:self
|
||||
action:@selector(onVideoCallPressed:)
|
||||
forControlEvents:UIControlEventTouchUpInside];
|
||||
button.contentEdgeInsets = UIEdgeInsetsMake(4, 12, 4, 12);
|
||||
item.customView = button;
|
||||
item.enabled = YES;
|
||||
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:button];
|
||||
item.accessibilityLabel = NSLocalizedStringFromTable(@"room_accessibility_video_call", @"Vector", nil);
|
||||
[rightBarButtonItems addObject:item];
|
||||
|
||||
hasCustomJoinButton = YES;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// show a video call button
|
||||
// item will still be enabled, and when tapped an alert will be displayed to the user
|
||||
UIBarButtonItem *item = [self videoCallBarButtonItem];
|
||||
if (!self.canEditJitsiWidget)
|
||||
{
|
||||
item.image = [[UIImage imageNamed:@"video_call"] vc_withAlpha:0.3];
|
||||
}
|
||||
// item will still be enabled, and when tapped an alert will be displayed to the user
|
||||
item.enabled = YES;
|
||||
[rightBarButtonItems addObject:item];
|
||||
}
|
||||
}
|
||||
[rightBarButtonItems addObject:item];
|
||||
itemInsets = UIEdgeInsetsMake(0, 20, 0, -20);
|
||||
}
|
||||
|
||||
if ([self widgetsCount:NO])
|
||||
{
|
||||
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"integrations_icon"] style:UIBarButtonItemStylePlain target:self action:@selector(onIntegrationsPressed:)];
|
||||
item.imageInsets = itemInsets;
|
||||
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"integrations_icon"]
|
||||
style:UIBarButtonItemStylePlain
|
||||
target:self
|
||||
action:@selector(onIntegrationsPressed:)];
|
||||
item.accessibilityLabel = NSLocalizedStringFromTable(@"room_accessibility_integrations", @"Vector", nil);
|
||||
if (hasCustomJoinButton)
|
||||
{
|
||||
item.imageInsets = UIEdgeInsetsMake(0, -5, 0, -5);
|
||||
item.landscapeImagePhoneInsets = UIEdgeInsetsMake(0, -5, 0, -5);
|
||||
}
|
||||
[rightBarButtonItems addObject:item];
|
||||
}
|
||||
|
||||
|
@ -2075,7 +2123,6 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
animations:^{
|
||||
|
||||
self.bubblesTableViewTopConstraint.constant = 0;
|
||||
self.jumpToLastUnreadBannerContainerTopConstraint.constant = self.bubblesTableView.mxk_adjustedContentInset.top;
|
||||
|
||||
// Force to render the view
|
||||
[self forceLayoutRefresh];
|
||||
|
@ -2194,7 +2241,6 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
animations:^{
|
||||
|
||||
self.bubblesTableViewTopConstraint.constant = self.previewHeaderContainerHeightConstraint.constant - self.bubblesTableView.mxk_adjustedContentInset.top;
|
||||
self.jumpToLastUnreadBannerContainerTopConstraint.constant = self.previewHeaderContainerHeightConstraint.constant;
|
||||
|
||||
previewHeader.roomAvatar.alpha = 1;
|
||||
|
||||
|
@ -4431,17 +4477,20 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
- (void)listenWidgetNotifications
|
||||
{
|
||||
MXWeakify(self);
|
||||
|
||||
kMXKWidgetManagerDidUpdateWidgetObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kWidgetManagerDidUpdateWidgetNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
Widget *widget = notif.object;
|
||||
if (widget.mxSession == self.roomDataSource.mxSession
|
||||
&& [widget.roomId isEqualToString:customizedRoomDataSource.roomId])
|
||||
&& [widget.roomId isEqualToString:self->customizedRoomDataSource.roomId])
|
||||
{
|
||||
// Jitsi conference widget existence is shown in the bottom bar
|
||||
// Update the bar
|
||||
[self refreshActivitiesViewDisplay];
|
||||
[self refreshRoomInputToolbar];
|
||||
// Call button update
|
||||
[self refreshRoomTitle];
|
||||
// Remove Jitsi widget view update
|
||||
[self refreshRemoveJitsiWidgetView];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
@ -4489,8 +4538,6 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
[roomActivitiesView removeGestureRecognizer:roomActivitiesView.gestureRecognizers[0]];
|
||||
}
|
||||
|
||||
Widget *jitsiWidget = [customizedRoomDataSource jitsiWidget];
|
||||
|
||||
if ([self.roomDataSource.mxSession.syncError.errcode isEqualToString:kMXErrCodeStringResourceLimitExceeded])
|
||||
{
|
||||
self.activitiesViewExpanded = YES;
|
||||
|
@ -5092,6 +5139,32 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
}
|
||||
}
|
||||
|
||||
- (void)refreshRemoveJitsiWidgetView
|
||||
{
|
||||
if (self.roomDataSource.isLive && !self.roomDataSource.isPeeking)
|
||||
{
|
||||
Widget *jitsiWidget = [customizedRoomDataSource jitsiWidget];
|
||||
|
||||
if (jitsiWidget && self.canEditJitsiWidget)
|
||||
{
|
||||
[self.removeJitsiWidgetView reset];
|
||||
self.removeJitsiWidgetContainer.hidden = NO;
|
||||
self.removeJitsiWidgetView.delegate = self;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.removeJitsiWidgetContainer.hidden = YES;
|
||||
self.removeJitsiWidgetView.delegate = nil;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[self.removeJitsiWidgetView reset];
|
||||
self.removeJitsiWidgetContainer.hidden = YES;
|
||||
self.removeJitsiWidgetView.delegate = self;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)refreshJumpToLastUnreadBannerDisplay
|
||||
{
|
||||
// This banner is only displayed when the room timeline is in live (and no peeking).
|
||||
|
@ -6050,4 +6123,37 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
self.roomInfoCoordinatorBridgePresenter = nil;
|
||||
}
|
||||
|
||||
#pragma mark - RemoveJitsiWidgetViewDelegate
|
||||
|
||||
- (void)removeJitsiWidgetViewDidCompleteSliding:(RemoveJitsiWidgetView *)view
|
||||
{
|
||||
view.delegate = nil;
|
||||
Widget *jitsiWidget = [customizedRoomDataSource jitsiWidget];
|
||||
|
||||
[self startActivityIndicator];
|
||||
|
||||
// close the widget
|
||||
MXWeakify(self);
|
||||
|
||||
[[WidgetManager sharedManager] closeWidget:jitsiWidget.widgetId
|
||||
inRoom:self.roomDataSource.room
|
||||
success:^{
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
[self stopActivityIndicator];
|
||||
// we can wait for kWidgetManagerDidUpdateWidgetNotification, but we want to be faster
|
||||
self.removeJitsiWidgetContainer.hidden = YES;
|
||||
self.removeJitsiWidgetView.delegate = nil;
|
||||
|
||||
// end active call if exists
|
||||
if ([[AppDelegate theDelegate].callPresenter.jitsiVC.widget.widgetId isEqualToString:jitsiWidget.widgetId])
|
||||
{
|
||||
[[AppDelegate theDelegate].callPresenter endActiveJitsiCall];
|
||||
}
|
||||
} failure:^(NSError *error) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
[self showJitsiErrorAsAlert:error];
|
||||
[self stopActivityIndicator];
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -15,15 +15,15 @@
|
|||
<outlet property="bubblesTableViewBottomConstraint" destination="1SD-y2-oTg" id="n8D-hT-eqt"/>
|
||||
<outlet property="bubblesTableViewTopConstraint" destination="bFw-dg-qEr" id="KxM-H0-h2y"/>
|
||||
<outlet property="inputBackgroundView" destination="Xt7-83-dQh" id="xoG-eb-zFB"/>
|
||||
<outlet property="jumpToLastUnreadBannerContainer" destination="S6r-bo-jxw" id="Ady-Eh-4E0"/>
|
||||
<outlet property="jumpToLastUnreadBannerContainerTopConstraint" destination="5eM-eJ-khq" id="b1J-aM-ZcT"/>
|
||||
<outlet property="jumpToLastUnreadBannerSeparatorView" destination="knN-q1-QkJ" id="hHJ-c8-QfN"/>
|
||||
<outlet property="jumpToLastUnreadButton" destination="ISb-UT-u0O" id="fs0-sQ-lRe"/>
|
||||
<outlet property="jumpToLastUnreadImageView" destination="Vlz-UJ-Jz8" id="8iM-Go-SqC"/>
|
||||
<outlet property="jumpToLastUnreadBanner" destination="S6r-bo-jxw" id="FSS-Be-E15"/>
|
||||
<outlet property="jumpToLastUnreadBannerContainer" destination="S6H-Az-RCM" id="YlI-fu-OpT"/>
|
||||
<outlet property="jumpToLastUnreadButton" destination="1bj-1n-LgM" id="vB7-oE-h7O"/>
|
||||
<outlet property="jumpToLastUnreadImageView" destination="Vlz-UJ-Jz8" id="r53-4l-Ld7"/>
|
||||
<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="removeJitsiWidgetContainer" destination="hB3-nR-MVR" id="Fbu-c2-Qys"/>
|
||||
<outlet property="resetReadMarkerButton" destination="c4g-BY-xOo" id="KuR-hH-rz1"/>
|
||||
<outlet property="roomActivitiesContainer" destination="XX4-n6-hCm" id="uD0-ab-8s8"/>
|
||||
<outlet property="roomActivitiesContainerHeightConstraint" destination="E8v-l2-8eV" id="ebD-oV-ttx"/>
|
||||
|
@ -55,76 +55,86 @@
|
|||
<constraint firstAttribute="height" constant="368" id="goj-GZ-IkD"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="S6r-bo-jxw">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" translatesAutoresizingMaskIntoConstraints="NO" id="fmF-ad-erE">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="0.0"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ISb-UT-u0O">
|
||||
<rect key="frame" x="5" y="0.0" width="51" height="44"/>
|
||||
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="hB3-nR-MVR">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="54"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="44" id="XgY-bC-cpU"/>
|
||||
<constraint firstAttribute="height" constant="54" id="QJx-Yo-mCC"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<action selector="onButtonPressed:" destination="-1" eventType="touchUpInside" id="7pe-19-Zxc"/>
|
||||
</connections>
|
||||
</button>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="scrollup" translatesAutoresizingMaskIntoConstraints="NO" id="Vlz-UJ-Jz8">
|
||||
<rect key="frame" x="13" y="7" width="30" height="30"/>
|
||||
</view>
|
||||
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="S6H-Az-RCM">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="76"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="S6r-bo-jxw">
|
||||
<rect key="frame" x="93" y="16" width="189.5" height="44"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="room_scroll_up" translatesAutoresizingMaskIntoConstraints="NO" id="Vlz-UJ-Jz8">
|
||||
<rect key="frame" x="14" y="10" width="24" height="24"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="24" id="JCI-mP-w3F"/>
|
||||
<constraint firstAttribute="width" secondItem="Vlz-UJ-Jz8" secondAttribute="height" multiplier="1:1" id="gEk-9p-KUO"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Jump to unread" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="S1q-B4-Df3">
|
||||
<rect key="frame" x="42" y="13" width="107.5" height="18"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1bj-1n-LgM">
|
||||
<rect key="frame" x="0.0" y="0.0" width="143.5" height="44"/>
|
||||
<connections>
|
||||
<action selector="onButtonPressed:" destination="-1" eventType="touchUpInside" id="bNQ-wp-3le"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="c4g-BY-xOo">
|
||||
<rect key="frame" x="143.5" y="0.0" width="44" height="44"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="44" id="2YD-H9-DyP"/>
|
||||
<constraint firstAttribute="width" secondItem="c4g-BY-xOo" secondAttribute="height" multiplier="1:1" id="DG6-tf-YUj"/>
|
||||
</constraints>
|
||||
<inset key="imageEdgeInsets" minX="14" minY="14" maxX="14" maxY="14"/>
|
||||
<state key="normal" image="new_close"/>
|
||||
<connections>
|
||||
<action selector="onButtonPressed:" destination="-1" eventType="touchUpInside" id="8by-6v-ZGR"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<color key="backgroundColor" systemColor="systemGray6Color"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="1bj-1n-LgM" secondAttribute="bottom" id="06E-yF-opV"/>
|
||||
<constraint firstAttribute="height" constant="44" id="7TA-9m-DJm"/>
|
||||
<constraint firstItem="S1q-B4-Df3" firstAttribute="leading" secondItem="Vlz-UJ-Jz8" secondAttribute="trailing" constant="4" id="Aer-yt-Ipv"/>
|
||||
<constraint firstItem="c4g-BY-xOo" firstAttribute="leading" secondItem="S1q-B4-Df3" secondAttribute="trailing" constant="-6" id="Iqm-Q5-jWz"/>
|
||||
<constraint firstItem="Vlz-UJ-Jz8" firstAttribute="centerY" secondItem="S6r-bo-jxw" secondAttribute="centerY" id="Oyl-YW-LyY"/>
|
||||
<constraint firstAttribute="trailing" secondItem="1bj-1n-LgM" secondAttribute="trailing" constant="46" id="SbE-4d-jky"/>
|
||||
<constraint firstItem="S1q-B4-Df3" firstAttribute="centerY" secondItem="S6r-bo-jxw" secondAttribute="centerY" id="YEJ-zl-raJ"/>
|
||||
<constraint firstItem="1bj-1n-LgM" firstAttribute="leading" secondItem="S6r-bo-jxw" secondAttribute="leading" id="ZEh-qn-hpl"/>
|
||||
<constraint firstAttribute="trailing" secondItem="c4g-BY-xOo" secondAttribute="trailing" constant="2" id="f9h-zF-Kj7"/>
|
||||
<constraint firstItem="1bj-1n-LgM" firstAttribute="top" secondItem="S6r-bo-jxw" secondAttribute="top" id="g2R-SU-q9s"/>
|
||||
<constraint firstItem="c4g-BY-xOo" firstAttribute="centerY" secondItem="S6r-bo-jxw" secondAttribute="centerY" id="q7f-Lx-2kO"/>
|
||||
<constraint firstItem="Vlz-UJ-Jz8" firstAttribute="leading" secondItem="S6r-bo-jxw" secondAttribute="leading" constant="14" id="rya-xy-hDd"/>
|
||||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
|
||||
<integer key="value" value="22"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="30" id="JCI-mP-w3F"/>
|
||||
<constraint firstAttribute="width" secondItem="Vlz-UJ-Jz8" secondAttribute="height" multiplier="1:1" id="gEk-9p-KUO"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="S1q-B4-Df3">
|
||||
<rect key="frame" x="56" y="22" width="0.0" height="0.0"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="c4g-BY-xOo">
|
||||
<rect key="frame" x="335" y="0.0" width="44" height="44"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="44" id="2YD-H9-DyP"/>
|
||||
<constraint firstAttribute="width" secondItem="c4g-BY-xOo" secondAttribute="height" multiplier="1:1" id="DG6-tf-YUj"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<action selector="onButtonPressed:" destination="-1" eventType="touchUpInside" id="8by-6v-ZGR"/>
|
||||
</connections>
|
||||
</button>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="cancel" translatesAutoresizingMaskIntoConstraints="NO" id="TYG-1i-OrY">
|
||||
<rect key="frame" x="347" y="12" width="20" height="20"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="20" id="2Nx-YU-skd"/>
|
||||
<constraint firstAttribute="width" secondItem="TYG-1i-OrY" secondAttribute="height" multiplier="1:1" id="jBy-Ex-gBc"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="knN-q1-QkJ" userLabel="Separator View">
|
||||
<rect key="frame" x="0.0" y="43" width="375" height="1"/>
|
||||
<color key="backgroundColor" red="0.93725490199999995" green="0.93725490199999995" blue="0.95686274510000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="1" id="8k7-fr-b8R"/>
|
||||
<constraint firstAttribute="height" constant="1" id="G1Q-g6-4kp"/>
|
||||
<constraint firstItem="S6r-bo-jxw" firstAttribute="centerX" secondItem="S6H-Az-RCM" secondAttribute="centerX" id="2eL-aC-qst"/>
|
||||
<constraint firstItem="S6r-bo-jxw" firstAttribute="centerY" secondItem="S6H-Az-RCM" secondAttribute="centerY" id="Bdj-uB-YN7"/>
|
||||
<constraint firstAttribute="height" constant="76" id="YE8-fe-fJ9"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="44" id="7TA-9m-DJm"/>
|
||||
<constraint firstItem="ISb-UT-u0O" firstAttribute="trailing" secondItem="S1q-B4-Df3" secondAttribute="trailing" id="ABS-rW-2Up"/>
|
||||
<constraint firstItem="knN-q1-QkJ" firstAttribute="leading" secondItem="S6r-bo-jxw" secondAttribute="leading" id="DL5-gC-Y2y"/>
|
||||
<constraint firstAttribute="bottom" secondItem="knN-q1-QkJ" secondAttribute="bottom" id="HrB-BI-pbX"/>
|
||||
<constraint firstItem="Vlz-UJ-Jz8" firstAttribute="centerY" secondItem="S6r-bo-jxw" secondAttribute="centerY" id="Oyl-YW-LyY"/>
|
||||
<constraint firstItem="c4g-BY-xOo" firstAttribute="centerY" secondItem="TYG-1i-OrY" secondAttribute="centerY" id="PY6-yg-tuv"/>
|
||||
<constraint firstAttribute="trailing" secondItem="knN-q1-QkJ" secondAttribute="trailing" id="RFO-8F-wd7"/>
|
||||
<constraint firstItem="S1q-B4-Df3" firstAttribute="centerY" secondItem="S6r-bo-jxw" secondAttribute="centerY" id="YEJ-zl-raJ"/>
|
||||
<constraint firstItem="ISb-UT-u0O" firstAttribute="leading" secondItem="S6r-bo-jxw" secondAttribute="leading" constant="5" id="Znj-wf-lOm"/>
|
||||
<constraint firstAttribute="trailing" secondItem="TYG-1i-OrY" secondAttribute="trailing" constant="8" id="bcg-1X-Ujo"/>
|
||||
<constraint firstItem="TYG-1i-OrY" firstAttribute="centerY" secondItem="S6r-bo-jxw" secondAttribute="centerY" id="dr9-xy-Nhj"/>
|
||||
<constraint firstItem="Vlz-UJ-Jz8" firstAttribute="leading" secondItem="S6r-bo-jxw" secondAttribute="leading" constant="13" id="rya-xy-hDd"/>
|
||||
<constraint firstItem="S1q-B4-Df3" firstAttribute="leading" secondItem="S6r-bo-jxw" secondAttribute="leading" constant="56" id="t7w-84-xaw"/>
|
||||
<constraint firstItem="c4g-BY-xOo" firstAttribute="centerX" secondItem="TYG-1i-OrY" secondAttribute="centerX" id="tXP-dn-3bC"/>
|
||||
<constraint firstItem="ISb-UT-u0O" firstAttribute="centerY" secondItem="Vlz-UJ-Jz8" secondAttribute="centerY" id="w7t-WC-VjP"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</stackView>
|
||||
<button opaque="NO" alpha="0.0" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Ih9-EU-BOU" userLabel="scroll Button">
|
||||
<rect key="frame" x="327" y="570" width="32" height="32"/>
|
||||
<state key="normal" image="scrolldown"/>
|
||||
|
@ -168,16 +178,16 @@
|
|||
<accessibility key="accessibilityConfiguration" identifier="RoomVCView"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="BGD-sd-SQR" secondAttribute="bottom" constant="41" id="1SD-y2-oTg"/>
|
||||
<constraint firstItem="S6r-bo-jxw" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="5eM-eJ-khq"/>
|
||||
<constraint firstItem="Xt7-83-dQh" firstAttribute="leading" secondItem="QpJ-1u-4ii" secondAttribute="leading" id="6lr-Tx-pEb"/>
|
||||
<constraint firstItem="QpJ-1u-4ii" firstAttribute="trailing" secondItem="Ih9-EU-BOU" secondAttribute="trailing" constant="16" id="6rq-lR-0sB"/>
|
||||
<constraint firstItem="54r-18-K1g" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="7Ft-EV-Br0"/>
|
||||
<constraint firstItem="gt1-EO-UVY" firstAttribute="leading" secondItem="QpJ-1u-4ii" secondAttribute="leading" id="8Ff-Ot-h3F"/>
|
||||
<constraint firstItem="Xt7-83-dQh" firstAttribute="bottom" secondItem="iN0-l3-epB" secondAttribute="bottom" id="9g2-wm-4M9"/>
|
||||
<constraint firstItem="S6r-bo-jxw" firstAttribute="leading" secondItem="QpJ-1u-4ii" secondAttribute="leading" id="Bcq-e4-B0D"/>
|
||||
<constraint firstItem="fmF-ad-erE" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="DtG-PR-F24"/>
|
||||
<constraint firstItem="BGD-sd-SQR" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="ECb-mP-EOG"/>
|
||||
<constraint firstAttribute="trailing" secondItem="BGD-sd-SQR" secondAttribute="trailing" id="EGD-cX-OGq"/>
|
||||
<constraint firstItem="XX4-n6-hCm" firstAttribute="top" secondItem="Ih9-EU-BOU" secondAttribute="bottom" constant="24" id="GUp-ZU-6h3"/>
|
||||
<constraint firstAttribute="trailing" secondItem="fmF-ad-erE" secondAttribute="trailing" id="JnG-B8-qQf"/>
|
||||
<constraint firstItem="QHs-rM-UU8" firstAttribute="centerX" secondItem="Ih9-EU-BOU" secondAttribute="centerX" id="K8X-wJ-hkh"/>
|
||||
<constraint firstItem="QHs-rM-UU8" firstAttribute="centerY" secondItem="Ih9-EU-BOU" secondAttribute="top" id="KL4-OU-cP6"/>
|
||||
<constraint firstItem="gt1-EO-UVY" firstAttribute="trailing" secondItem="QpJ-1u-4ii" secondAttribute="trailing" id="L9A-P5-xeT"/>
|
||||
|
@ -185,13 +195,13 @@
|
|||
<constraint firstItem="XX4-n6-hCm" firstAttribute="bottom" secondItem="nLd-BP-JAE" secondAttribute="top" id="QO8-nF-xys"/>
|
||||
<constraint firstItem="nLd-BP-JAE" firstAttribute="leading" secondItem="QpJ-1u-4ii" secondAttribute="leading" id="T1Y-r9-bYV"/>
|
||||
<constraint firstItem="XX4-n6-hCm" firstAttribute="trailing" secondItem="QpJ-1u-4ii" secondAttribute="trailing" id="Tij-mR-KZp"/>
|
||||
<constraint firstItem="S6r-bo-jxw" firstAttribute="trailing" secondItem="QpJ-1u-4ii" secondAttribute="trailing" id="VVn-vW-lbm"/>
|
||||
<constraint firstItem="gt1-EO-UVY" firstAttribute="top" secondItem="QpJ-1u-4ii" secondAttribute="top" id="YfN-0Z-0bc"/>
|
||||
<constraint firstItem="54r-18-K1g" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="aR5-rp-1Cp"/>
|
||||
<constraint firstItem="gt1-EO-UVY" firstAttribute="bottom" secondItem="nLd-BP-JAE" secondAttribute="bottom" id="acJ-g8-R7x"/>
|
||||
<constraint firstItem="BGD-sd-SQR" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="bFw-dg-qEr"/>
|
||||
<constraint firstAttribute="bottom" secondItem="nLd-BP-JAE" secondAttribute="bottom" id="omU-sm-3bK"/>
|
||||
<constraint firstItem="nLd-BP-JAE" firstAttribute="trailing" secondItem="QpJ-1u-4ii" secondAttribute="trailing" id="pRw-S0-6WL"/>
|
||||
<constraint firstItem="fmF-ad-erE" firstAttribute="top" secondItem="QpJ-1u-4ii" secondAttribute="top" id="qYq-nb-cu5"/>
|
||||
<constraint firstItem="Xt7-83-dQh" firstAttribute="trailing" secondItem="QpJ-1u-4ii" secondAttribute="trailing" id="tAK-09-gTA"/>
|
||||
<constraint firstAttribute="trailing" secondItem="54r-18-K1g" secondAttribute="trailing" id="wOi-Ih-yfq"/>
|
||||
<constraint firstItem="Xt7-83-dQh" firstAttribute="top" secondItem="XX4-n6-hCm" secondAttribute="top" id="xHx-En-Ppf"/>
|
||||
|
@ -206,11 +216,14 @@
|
|||
</designable>
|
||||
</designables>
|
||||
<resources>
|
||||
<image name="cancel" width="20" height="20"/>
|
||||
<image name="new_close" width="16" height="16"/>
|
||||
<image name="room_scroll_up" width="24" height="24"/>
|
||||
<image name="scrolldown" width="32" height="32"/>
|
||||
<image name="scrollup" width="30" height="30"/>
|
||||
<systemColor name="systemBackgroundColor">
|
||||
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemGray6Color">
|
||||
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
||||
|
|
|
@ -2156,6 +2156,7 @@ NSString *const kRoomSettingsAdvancedE2eEnabledCellViewIdentifier = @"kRoomSetti
|
|||
UITableViewHeaderFooterView *tableViewHeaderFooterView = (UITableViewHeaderFooterView*)view;
|
||||
tableViewHeaderFooterView.textLabel.textColor = ThemeService.shared.theme.textPrimaryColor;
|
||||
tableViewHeaderFooterView.textLabel.font = [UIFont systemFontOfSize:15];
|
||||
tableViewHeaderFooterView.contentView.backgroundColor = ThemeService.shared.theme.headerBackgroundColor;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ extension CallBubbleCellBaseContentView: Themable {
|
|||
paginationLabel.textColor = theme.tintColor
|
||||
paginationSeparatorView.backgroundColor = theme.tintColor
|
||||
|
||||
bgView.backgroundColor = theme.headerBackgroundColor
|
||||
bgView.backgroundColor = theme.colors.tile
|
||||
callerNameLabel.textColor = theme.textPrimaryColor
|
||||
callIconView.tintColor = theme.textTertiaryColor
|
||||
callTypeLabel.textColor = theme.textSecondaryColor
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
//
|
||||
// Copyright 2021 New Vector 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
|
||||
|
||||
class ArrowsAnimationView: UIView {
|
||||
|
||||
private enum Constants {
|
||||
static let numberOfArrows: Int = 3
|
||||
static let arrowSize: CGSize = CGSize(width: 14, height: 14)
|
||||
static let gradientAnimationKey: String = "gradient"
|
||||
static let gradientRatios: [CGFloat] = [1.0, 0.3, 0.2]
|
||||
}
|
||||
|
||||
private var gradientLayer: CAGradientLayer!
|
||||
private lazy var gradientAnimation: CABasicAnimation = {
|
||||
let animation = CABasicAnimation(keyPath: "locations")
|
||||
animation.fromValue = [0.0, 0.0, 0.25]
|
||||
animation.toValue = [0.75, 1.0, 1.0]
|
||||
animation.repeatCount = .infinity
|
||||
animation.duration = 1
|
||||
return animation
|
||||
}()
|
||||
private var theme: Theme = ThemeService.shared().theme
|
||||
private var arrowImageViews: [UIImageView] = []
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
setup()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
setup()
|
||||
}
|
||||
|
||||
private func setup() {
|
||||
let arrowImage = Asset.Images.disclosureIcon.image
|
||||
for i in 0..<Constants.numberOfArrows {
|
||||
let totalSpace = frame.width - CGFloat(Constants.numberOfArrows) * Constants.arrowSize.width
|
||||
let oneSpace = totalSpace / CGFloat(Constants.numberOfArrows - 1)
|
||||
let x = CGFloat(i) * (oneSpace + Constants.arrowSize.width)
|
||||
let y = (frame.height - Constants.arrowSize.height) / 2
|
||||
let imageView = UIImageView(frame: CGRect(origin: CGPoint(x: x, y: y),
|
||||
size: Constants.arrowSize))
|
||||
imageView.contentMode = .scaleAspectFit
|
||||
imageView.tintColor = theme.tabBarUnselectedItemTintColor
|
||||
imageView.image = arrowImage
|
||||
addSubview(imageView)
|
||||
|
||||
arrowImageViews.append(imageView)
|
||||
}
|
||||
|
||||
gradientLayer = CAGradientLayer()
|
||||
gradientLayer.frame = bounds
|
||||
gradientLayer.locations = [0.25, 0.5, 0.75]
|
||||
gradientLayer.startPoint = CGPoint(x: 0, y: 0.5)
|
||||
gradientLayer.endPoint = CGPoint(x: 1, y: 0.5)
|
||||
// this color doesn't have to come from the theme, it's only used as a mask
|
||||
let color = UIColor.black
|
||||
let colors = Constants.gradientRatios.map({ color.withAlphaComponent($0) })
|
||||
gradientLayer.colors = colors.map({ $0.cgColor })
|
||||
|
||||
layer.mask = gradientLayer
|
||||
}
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
gradientLayer.frame = bounds
|
||||
}
|
||||
|
||||
// MARK: - API
|
||||
|
||||
var isAnimating: Bool = false {
|
||||
didSet {
|
||||
if isAnimating {
|
||||
if gradientLayer.animation(forKey: Constants.gradientAnimationKey) == nil {
|
||||
gradientLayer.add(gradientAnimation,
|
||||
forKey: Constants.gradientAnimationKey)
|
||||
}
|
||||
} else {
|
||||
if gradientLayer.animation(forKey: Constants.gradientAnimationKey) != nil {
|
||||
gradientLayer.removeAnimation(forKey: Constants.gradientAnimationKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Themable
|
||||
|
||||
extension ArrowsAnimationView: Themable {
|
||||
|
||||
func update(theme: Theme) {
|
||||
self.theme = theme
|
||||
|
||||
arrowImageViews.forEach({ $0.tintColor = theme.tabBarUnselectedItemTintColor })
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,194 @@
|
|||
//
|
||||
// Copyright 2021 New Vector 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
|
||||
import Reusable
|
||||
|
||||
@objcMembers
|
||||
class RemoveJitsiWidgetView: UIView {
|
||||
|
||||
private enum Constants {
|
||||
static let activationThreshold: CGFloat = 0.5
|
||||
}
|
||||
|
||||
private enum State: Equatable {
|
||||
case notStarted
|
||||
case sliding(percentage: CGFloat)
|
||||
case completed
|
||||
|
||||
static func == (lhs: State, rhs: State) -> Bool {
|
||||
switch (lhs, rhs) {
|
||||
case (.notStarted, .notStarted):
|
||||
return true
|
||||
case (let .sliding(percentage1), let .sliding(percentage2)):
|
||||
return percentage1 == percentage2
|
||||
case (.completed, .completed):
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@IBOutlet private weak var slidingViewLeadingConstraint: NSLayoutConstraint!
|
||||
@IBOutlet private weak var slidingView: UIView!
|
||||
@IBOutlet private weak var slidingViewLabel: UILabel! {
|
||||
didSet {
|
||||
slidingViewLabel.text = VectorL10n.roomSlideToEndGroupCall
|
||||
}
|
||||
}
|
||||
@IBOutlet private weak var arrowsView: ArrowsAnimationView!
|
||||
@IBOutlet private weak var hangupView: UIView!
|
||||
@IBOutlet private weak var hangupImage: UIImageView!
|
||||
@IBOutlet private weak var topSeparatorView: UIView!
|
||||
@IBOutlet private weak var bottomSeparatorView: UIView!
|
||||
|
||||
private var state: State = .notStarted
|
||||
private var theme: Theme = ThemeService.shared().theme
|
||||
|
||||
// MARK - Private
|
||||
|
||||
private func configure(withState state: State) {
|
||||
switch state {
|
||||
case .notStarted:
|
||||
arrowsView.isAnimating = false
|
||||
hangupView.backgroundColor = .clear
|
||||
hangupImage.tintColor = theme.noticeColor
|
||||
slidingViewLeadingConstraint.constant = 0
|
||||
case .sliding(let percentage):
|
||||
arrowsView.isAnimating = true
|
||||
if percentage < Constants.activationThreshold {
|
||||
hangupView.backgroundColor = .clear
|
||||
hangupImage.tintColor = theme.noticeColor
|
||||
} else {
|
||||
hangupView.backgroundColor = theme.noticeColor
|
||||
hangupImage.tintColor = theme.callScreenButtonTintColor
|
||||
}
|
||||
slidingViewLeadingConstraint.constant = percentage * slidingView.frame.width
|
||||
case .completed:
|
||||
arrowsView.isAnimating = false
|
||||
hangupView.backgroundColor = theme.noticeColor
|
||||
hangupImage.tintColor = theme.callScreenButtonTintColor
|
||||
}
|
||||
}
|
||||
|
||||
private func updateState(to newState: State) {
|
||||
guard newState != state else {
|
||||
return
|
||||
}
|
||||
configure(withState: newState)
|
||||
state = newState
|
||||
|
||||
if state == .completed {
|
||||
delegate?.removeJitsiWidgetViewDidCompleteSliding(self)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Touch Handling
|
||||
|
||||
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||
super.touchesBegan(touches, with: event)
|
||||
|
||||
if state == .notStarted {
|
||||
updateState(to: .sliding(percentage: 0))
|
||||
}
|
||||
}
|
||||
|
||||
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||
super.touchesMoved(touches, with: event)
|
||||
|
||||
switch state {
|
||||
case .sliding:
|
||||
if let touch = touches.first {
|
||||
let touchLocation = touch.location(in: self)
|
||||
if frame.contains(touchLocation) {
|
||||
let percentage = touchLocation.x / frame.width
|
||||
updateState(to: .sliding(percentage: percentage))
|
||||
}
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||
super.touchesEnded(touches, with: event)
|
||||
|
||||
switch state {
|
||||
case .sliding(let percentage):
|
||||
if percentage < Constants.activationThreshold {
|
||||
updateState(to: .notStarted)
|
||||
} else {
|
||||
updateState(to: .completed)
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||
super.touchesCancelled(touches, with: event)
|
||||
|
||||
switch state {
|
||||
case .sliding(let percentage):
|
||||
if percentage < Constants.activationThreshold {
|
||||
updateState(to: .notStarted)
|
||||
} else {
|
||||
updateState(to: .completed)
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - API
|
||||
|
||||
weak var delegate: RemoveJitsiWidgetViewDelegate?
|
||||
|
||||
static func instantiate() -> RemoveJitsiWidgetView {
|
||||
let view = RemoveJitsiWidgetView.loadFromNib()
|
||||
view.update(theme: ThemeService.shared().theme)
|
||||
return view
|
||||
}
|
||||
|
||||
func reset() {
|
||||
updateState(to: .notStarted)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - NibLoadable
|
||||
|
||||
extension RemoveJitsiWidgetView: NibLoadable { }
|
||||
|
||||
// MARK: - Themable
|
||||
|
||||
extension RemoveJitsiWidgetView: Themable {
|
||||
|
||||
func update(theme: Theme) {
|
||||
self.theme = theme
|
||||
|
||||
self.backgroundColor = theme.headerBackgroundColor
|
||||
|
||||
slidingViewLabel.textColor = theme.textPrimaryColor
|
||||
arrowsView.update(theme: theme)
|
||||
topSeparatorView.backgroundColor = theme.lineBreakColor
|
||||
bottomSeparatorView.backgroundColor = theme.lineBreakColor
|
||||
|
||||
configure(withState: state)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="iN0-l3-epB" customClass="RemoveJitsiWidgetView" customModule="Riot" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="55"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kKF-lQ-ZyI">
|
||||
<rect key="frame" x="0.0" y="0.0" width="236.5" height="55"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Slide to end the call for everyone " textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dT6-Xr-WEJ">
|
||||
<rect key="frame" x="24" y="0.0" width="202.5" height="55"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="13"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="dT6-Xr-WEJ" secondAttribute="trailing" constant="10" id="EbF-GZ-NzF"/>
|
||||
<constraint firstItem="dT6-Xr-WEJ" firstAttribute="top" secondItem="kKF-lQ-ZyI" secondAttribute="top" id="Qu0-Ik-PYy"/>
|
||||
<constraint firstItem="dT6-Xr-WEJ" firstAttribute="leading" secondItem="kKF-lQ-ZyI" secondAttribute="leading" constant="24" id="aJj-xS-5HE"/>
|
||||
<constraint firstAttribute="bottom" secondItem="dT6-Xr-WEJ" secondAttribute="bottom" id="n5n-Ky-ncI"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bi1-rF-LRz" customClass="ArrowsAnimationView" customModule="Riot" customModuleProvider="target">
|
||||
<rect key="frame" x="236.5" y="0.0" width="50.5" height="55"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="50" id="sKo-iu-uGJ"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="PIa-uP-1J7">
|
||||
<rect key="frame" x="295" y="0.0" width="80" height="55"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="voice_call_hangup_icon" translatesAutoresizingMaskIntoConstraints="NO" id="bWv-EC-L99">
|
||||
<rect key="frame" x="28" y="15.5" width="24" height="24"/>
|
||||
<color key="tintColor" systemColor="systemRedColor"/>
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="bWv-EC-L99" firstAttribute="centerY" secondItem="PIa-uP-1J7" secondAttribute="centerY" id="2Vl-CE-QUT"/>
|
||||
<constraint firstItem="bWv-EC-L99" firstAttribute="centerX" secondItem="PIa-uP-1J7" secondAttribute="centerX" id="9vE-r4-Nje"/>
|
||||
<constraint firstAttribute="width" constant="80" id="NW6-rp-ycN"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Ntn-XH-RxI">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="1"/>
|
||||
<color key="backgroundColor" systemColor="systemGrayColor"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="1" id="yX4-ag-LWD"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bLk-fK-yz0">
|
||||
<rect key="frame" x="0.0" y="54" width="375" height="1"/>
|
||||
<color key="backgroundColor" systemColor="systemGrayColor"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="1" id="LsE-CW-ztj"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
<constraints>
|
||||
<constraint firstItem="PIa-uP-1J7" firstAttribute="bottom" secondItem="vUN-kp-3ea" secondAttribute="bottom" id="41n-Yu-G3I"/>
|
||||
<constraint firstItem="kKF-lQ-ZyI" firstAttribute="bottom" secondItem="vUN-kp-3ea" secondAttribute="bottom" id="Ciw-a7-Pct"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Ntn-XH-RxI" secondAttribute="trailing" id="E9k-gw-h02"/>
|
||||
<constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="bLk-fK-yz0" secondAttribute="trailing" id="ERx-So-ce7"/>
|
||||
<constraint firstAttribute="bottom" secondItem="bLk-fK-yz0" secondAttribute="bottom" id="I42-n7-cBJ"/>
|
||||
<constraint firstItem="bi1-rF-LRz" firstAttribute="bottom" secondItem="vUN-kp-3ea" secondAttribute="bottom" id="Iyl-NN-rCe"/>
|
||||
<constraint firstItem="bLk-fK-yz0" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="Oj8-Jf-cWi"/>
|
||||
<constraint firstItem="PIa-uP-1J7" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="XJo-0J-fte"/>
|
||||
<constraint firstItem="kKF-lQ-ZyI" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="aUb-po-3Dw"/>
|
||||
<constraint firstItem="PIa-uP-1J7" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="trailing" id="fn9-gi-1Fo"/>
|
||||
<constraint firstItem="bi1-rF-LRz" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="gbK-bh-J3T"/>
|
||||
<constraint firstItem="bi1-rF-LRz" firstAttribute="leading" secondItem="kKF-lQ-ZyI" secondAttribute="trailing" priority="750" id="hWc-xf-WTt"/>
|
||||
<constraint firstItem="kKF-lQ-ZyI" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="k9f-Tc-VQw"/>
|
||||
<constraint firstItem="Ntn-XH-RxI" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="lzw-UG-Zeh"/>
|
||||
<constraint firstItem="PIa-uP-1J7" firstAttribute="leading" secondItem="bi1-rF-LRz" secondAttribute="trailing" constant="8" id="sSR-kg-guw"/>
|
||||
<constraint firstItem="Ntn-XH-RxI" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="vJc-3a-yWr"/>
|
||||
</constraints>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<connections>
|
||||
<outlet property="arrowsView" destination="bi1-rF-LRz" id="9NK-yt-cXa"/>
|
||||
<outlet property="bottomSeparatorView" destination="bLk-fK-yz0" id="6Fn-W3-VTa"/>
|
||||
<outlet property="hangupImage" destination="bWv-EC-L99" id="UAz-cI-2ai"/>
|
||||
<outlet property="hangupView" destination="PIa-uP-1J7" id="Qd0-It-bFg"/>
|
||||
<outlet property="slidingView" destination="kKF-lQ-ZyI" id="bLF-Aa-1Oy"/>
|
||||
<outlet property="slidingViewLabel" destination="dT6-Xr-WEJ" id="OSR-IL-92L"/>
|
||||
<outlet property="slidingViewLeadingConstraint" destination="aUb-po-3Dw" id="R7j-74-W4J"/>
|
||||
<outlet property="topSeparatorView" destination="Ntn-XH-RxI" id="nRw-nh-427"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="110.86956521739131" y="-142.96875"/>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="voice_call_hangup_icon" width="24" height="24"/>
|
||||
<systemColor name="systemBackgroundColor">
|
||||
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemGrayColor">
|
||||
<color red="0.55686274509803924" green="0.55686274509803924" blue="0.57647058823529407" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemRedColor">
|
||||
<color red="1" green="0.23137254901960785" blue="0.18823529411764706" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// Copyright 2021 New Vector 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
|
||||
|
||||
@objc
|
||||
protocol RemoveJitsiWidgetViewDelegate: class {
|
||||
|
||||
/// Tells the delegate that the user complete sliding on the view
|
||||
/// - Parameter view: The view instance
|
||||
func removeJitsiWidgetViewDidCompleteSliding(_ view: RemoveJitsiWidgetView)
|
||||
}
|
Loading…
Reference in a new issue