Fix RTL bubbles in conversation and message detail view
// FREEBIE
This commit is contained in:
parent
b2a38323b1
commit
e2445e6ed2
@ -140,6 +140,7 @@
|
||||
4520D8D51D417D8E00123472 /* Photos.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4520D8D41D417D8E00123472 /* Photos.framework */; };
|
||||
4521C3C01F59F3BA00B4C582 /* TextFieldHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4521C3BF1F59F3BA00B4C582 /* TextFieldHelper.swift */; };
|
||||
4521C3C11F59F3BA00B4C582 /* TextFieldHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4521C3BF1F59F3BA00B4C582 /* TextFieldHelper.swift */; };
|
||||
4523149C1F7D7F81003A428C /* OWSMessagesBubbleImageFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4523149B1F7D7F81003A428C /* OWSMessagesBubbleImageFactory.swift */; };
|
||||
452C468F1E427E200087B011 /* OutboundCallInitiator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 452C468E1E427E200087B011 /* OutboundCallInitiator.swift */; };
|
||||
452C46901E427E200087B011 /* OutboundCallInitiator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 452C468E1E427E200087B011 /* OutboundCallInitiator.swift */; };
|
||||
452D1EE81DCA90D100A57EC4 /* MesssagesBubblesSizeCalculatorTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 452D1EE71DCA90D100A57EC4 /* MesssagesBubblesSizeCalculatorTest.swift */; };
|
||||
@ -604,6 +605,7 @@
|
||||
452037D01EE84975004E4CDF /* DebugUISessionState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUISessionState.m; sourceTree = "<group>"; };
|
||||
4520D8D41D417D8E00123472 /* Photos.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Photos.framework; path = System/Library/Frameworks/Photos.framework; sourceTree = SDKROOT; };
|
||||
4521C3BF1F59F3BA00B4C582 /* TextFieldHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldHelper.swift; sourceTree = "<group>"; };
|
||||
4523149B1F7D7F81003A428C /* OWSMessagesBubbleImageFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSMessagesBubbleImageFactory.swift; sourceTree = "<group>"; };
|
||||
4526BD481CA61C8D00166BC8 /* OWSMessageEditing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSMessageEditing.h; sourceTree = "<group>"; };
|
||||
452C468E1E427E200087B011 /* OutboundCallInitiator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OutboundCallInitiator.swift; sourceTree = "<group>"; };
|
||||
452D1EE71DCA90D100A57EC4 /* MesssagesBubblesSizeCalculatorTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MesssagesBubblesSizeCalculatorTest.swift; path = Models/MesssagesBubblesSizeCalculatorTest.swift; sourceTree = "<group>"; };
|
||||
@ -1173,6 +1175,7 @@
|
||||
45E2E91F1E153B3D00457AA0 /* Strings.swift */,
|
||||
34B3F8331E8DF1700035BE1A /* ViewControllers */,
|
||||
76EB052B18170B33006006FC /* Views */,
|
||||
4523149B1F7D7F81003A428C /* OWSMessagesBubbleImageFactory.swift */,
|
||||
);
|
||||
name = UserInterface;
|
||||
sourceTree = "<group>";
|
||||
@ -2277,6 +2280,7 @@
|
||||
45666EC91D994C0D008FE134 /* OWSGroupAvatarBuilder.m in Sources */,
|
||||
3471B1DA1EB7C63600F6AEC8 /* NewNonContactConversationViewController.m in Sources */,
|
||||
34B3F87C1E8DF1700035BE1A /* FingerprintViewController.m in Sources */,
|
||||
4523149C1F7D7F81003A428C /* OWSMessagesBubbleImageFactory.swift in Sources */,
|
||||
45638BDC1F3DD0D400128435 /* DebugUICalling.swift in Sources */,
|
||||
76EB058218170B33006006FC /* Environment.m in Sources */,
|
||||
450449391F45EE7D002D1ADA /* NSString+OWS.m in Sources */,
|
||||
|
||||
51
Signal/src/OWSMessagesBubbleImageFactory.swift
Normal file
51
Signal/src/OWSMessagesBubbleImageFactory.swift
Normal file
@ -0,0 +1,51 @@
|
||||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@objc
|
||||
class OWSMessagesBubbleImageFactory: NSObject {
|
||||
|
||||
let jsqFactory = JSQMessagesBubbleImageFactory()!
|
||||
|
||||
var isRTL: Bool {
|
||||
return UIView().isRTL()
|
||||
}
|
||||
|
||||
var incoming: JSQMessagesBubbleImage {
|
||||
let color = UIColor.jsq_messageBubbleLightGray()!
|
||||
return incoming(color: color)
|
||||
}
|
||||
|
||||
var outgoing: JSQMessagesBubbleImage {
|
||||
let color = UIColor.ows_materialBlue()
|
||||
return outgoing(color: color)
|
||||
}
|
||||
|
||||
var currentlyOutgoing: JSQMessagesBubbleImage {
|
||||
let color = UIColor.ows_fadedBlue()
|
||||
return outgoing(color: color)
|
||||
}
|
||||
|
||||
var outgoingFailed: JSQMessagesBubbleImage {
|
||||
let color = UIColor.gray
|
||||
return outgoing(color: color)
|
||||
}
|
||||
|
||||
func outgoing(color: UIColor) -> JSQMessagesBubbleImage {
|
||||
if isRTL {
|
||||
return jsqFactory.incomingMessagesBubbleImage(with: color)
|
||||
} else {
|
||||
return jsqFactory.outgoingMessagesBubbleImage(with: color)
|
||||
}
|
||||
}
|
||||
|
||||
func incoming(color: UIColor) -> JSQMessagesBubbleImage {
|
||||
if isRTL {
|
||||
return jsqFactory.outgoingMessagesBubbleImage(with: color)
|
||||
} else {
|
||||
return jsqFactory.incomingMessagesBubbleImage(with: color)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5,7 +5,6 @@
|
||||
#import "AppSettingsViewController.h"
|
||||
#import "AttachmentSharing.h"
|
||||
#import "ContactTableViewCell.h"
|
||||
#import "ConversationViewController.h"
|
||||
#import "DateUtil.h"
|
||||
#import "DebugUIPage.h"
|
||||
#import "Environment.h"
|
||||
@ -44,6 +43,7 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <JSQMessagesViewController/JSQMediaItem.h>
|
||||
#import <JSQMessagesViewController/JSQMessagesBubbleImage.h>
|
||||
#import <JSQMessagesViewController/JSQMessagesBubbleImageFactory.h>
|
||||
#import <JSQMessagesViewController/JSQMessagesMediaViewBubbleImageMasker.h>
|
||||
#import <JSQMessagesViewController/UIColor+JSQMessages.h>
|
||||
#import <JSQSystemSoundPlayer.h>
|
||||
|
||||
@ -4,6 +4,8 @@
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface UIColor (OWS)
|
||||
|
||||
+ (UIColor *)ows_signalBrandBlueColor;
|
||||
@ -26,3 +28,5 @@
|
||||
- (UIColor *)blendWithColor:(UIColor *)otherColor alpha:(CGFloat)alpha;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@ -6,6 +6,8 @@
|
||||
#import "OWSMath.h"
|
||||
#import "UIColor+OWS.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@implementation UIColor (OWS)
|
||||
|
||||
+ (UIColor *)ows_signalBrandBlueColor
|
||||
@ -154,3 +156,5 @@
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
#import <JSQMessagesViewController/JSQMessagesViewController.h>
|
||||
|
||||
@class TSThread;
|
||||
@class JSQMessagesBubbleImage;
|
||||
|
||||
extern NSString *const ConversationViewControllerDidAppearNotification;
|
||||
|
||||
@ -24,11 +23,4 @@ extern NSString *const ConversationViewControllerDidAppearNotification;
|
||||
- (void)peekSetup;
|
||||
- (void)popped;
|
||||
|
||||
#pragma mark shared bubble styles
|
||||
|
||||
+ (JSQMessagesBubbleImage *)outgoingBubbleImageData;
|
||||
+ (JSQMessagesBubbleImage *)incomingBubbleImageData;
|
||||
+ (JSQMessagesBubbleImage *)currentlyOutgoingBubbleImageData;
|
||||
+ (JSQMessagesBubbleImage *)outgoingMessageFailedImageData;
|
||||
|
||||
@end
|
||||
|
||||
@ -259,6 +259,11 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
|
||||
@property (nonatomic) YapDatabaseConnection *uiDatabaseConnection;
|
||||
@property (nonatomic) YapDatabaseViewMappings *messageMappings;
|
||||
|
||||
@property (nonatomic) JSQMessagesBubbleImage *outgoingBubbleImageData;
|
||||
@property (nonatomic) JSQMessagesBubbleImage *incomingBubbleImageData;
|
||||
@property (nonatomic) JSQMessagesBubbleImage *currentlyOutgoingBubbleImageData;
|
||||
@property (nonatomic) JSQMessagesBubbleImage *outgoingMessageFailedImageData;
|
||||
|
||||
@property (nonatomic) MPMoviePlayerController *videoPlayer;
|
||||
@property (nonatomic) AVAudioRecorder *audioRecorder;
|
||||
@property (nonatomic) OWSAudioAttachmentPlayer *audioAttachmentPlayer;
|
||||
@ -1536,75 +1541,13 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
|
||||
self.collectionView.collectionViewLayout.messageBubbleLeftRightMargin = 80.0f;
|
||||
}
|
||||
|
||||
// Bubbles
|
||||
self.collectionView.collectionViewLayout.bubbleSizeCalculator = [OWSMessagesBubblesSizeCalculator new];
|
||||
}
|
||||
|
||||
+ (JSQMessagesBubbleImageFactory *)sharedBubbleImageFactory
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
static JSQMessagesBubbleImageFactory *bubbleImageFactory;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
bubbleImageFactory = [JSQMessagesBubbleImageFactory new];
|
||||
});
|
||||
|
||||
return bubbleImageFactory;
|
||||
}
|
||||
|
||||
+ (JSQMessagesBubbleImage *)outgoingBubbleImageData
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
static JSQMessagesBubbleImage *bubbleImage;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
bubbleImage =
|
||||
[[self sharedBubbleImageFactory] outgoingMessagesBubbleImageWithColor:[UIColor ows_materialBlueColor]];
|
||||
});
|
||||
|
||||
return bubbleImage;
|
||||
}
|
||||
|
||||
+ (JSQMessagesBubbleImage *)incomingBubbleImageData
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
static JSQMessagesBubbleImage *bubbleImage;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
bubbleImage = [[self sharedBubbleImageFactory]
|
||||
incomingMessagesBubbleImageWithColor:[UIColor jsq_messageBubbleLightGrayColor]];
|
||||
});
|
||||
|
||||
return bubbleImage;
|
||||
}
|
||||
|
||||
+ (JSQMessagesBubbleImage *)currentlyOutgoingBubbleImageData
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
static JSQMessagesBubbleImage *bubbleImage;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
bubbleImage =
|
||||
[[self sharedBubbleImageFactory] outgoingMessagesBubbleImageWithColor:[UIColor ows_fadedBlueColor]];
|
||||
});
|
||||
|
||||
return bubbleImage;
|
||||
}
|
||||
|
||||
+ (JSQMessagesBubbleImage *)outgoingMessageFailedImageData
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
static JSQMessagesBubbleImage *bubbleImage;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
bubbleImage = [[self sharedBubbleImageFactory] outgoingMessagesBubbleImageWithColor:[UIColor grayColor]];
|
||||
});
|
||||
|
||||
return bubbleImage;
|
||||
OWSMessagesBubbleImageFactory *bubbleFactory = [OWSMessagesBubbleImageFactory new];
|
||||
self.incomingBubbleImageData = bubbleFactory.incoming;
|
||||
self.outgoingBubbleImageData = bubbleFactory.outgoing;
|
||||
self.currentlyOutgoingBubbleImageData = bubbleFactory.currentlyOutgoing;
|
||||
self.outgoingMessageFailedImageData = bubbleFactory.outgoingFailed;
|
||||
}
|
||||
|
||||
#pragma mark - Identity
|
||||
@ -1886,19 +1829,19 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
|
||||
TSOutgoingMessage *outgoingMessage = (TSOutgoingMessage *)message;
|
||||
switch (outgoingMessage.messageState) {
|
||||
case TSOutgoingMessageStateUnsent:
|
||||
return [[self class] outgoingMessageFailedImageData];
|
||||
return self.outgoingMessageFailedImageData;
|
||||
case TSOutgoingMessageStateAttemptingOut:
|
||||
return [[self class] currentlyOutgoingBubbleImageData];
|
||||
return self.currentlyOutgoingBubbleImageData;
|
||||
case TSOutgoingMessageStateSent_OBSOLETE:
|
||||
case TSOutgoingMessageStateDelivered_OBSOLETE:
|
||||
OWSFail(@"%@ Obsolete message state.", self.tag);
|
||||
return [[self class] outgoingBubbleImageData];
|
||||
return self.outgoingBubbleImageData;
|
||||
case TSOutgoingMessageStateSentToService:
|
||||
return [[self class] outgoingBubbleImageData];
|
||||
return self.outgoingBubbleImageData;
|
||||
}
|
||||
}
|
||||
|
||||
return [[self class] incomingBubbleImageData];
|
||||
return self.incomingBubbleImageData;
|
||||
}
|
||||
|
||||
- (id<JSQMessageAvatarImageDataSource>)collectionView:(JSQMessagesCollectionView *)collectionView
|
||||
|
||||
@ -24,6 +24,8 @@ class MessageMetadataViewController: OWSViewController {
|
||||
|
||||
let databaseConnection: YapDatabaseConnection
|
||||
|
||||
let bubbleFactory = OWSMessagesBubbleImageFactory()
|
||||
|
||||
var message: TSMessage
|
||||
|
||||
var mediaMessageView: MediaMessageView?
|
||||
@ -280,16 +282,18 @@ class MessageMetadataViewController: OWSViewController {
|
||||
bodyLabel.numberOfLines = 10
|
||||
bodyLabel.lineBreakMode = .byWordWrapping
|
||||
|
||||
let bubbleImageData = isIncoming ? ConversationViewController.incomingBubbleImageData() : ConversationViewController.outgoingBubbleImageData()
|
||||
let bubbleImageData = isIncoming ? bubbleFactory.incoming : bubbleFactory.outgoing
|
||||
|
||||
let leadingMargin: CGFloat = isIncoming ? 15 : 10
|
||||
let trailingMargin: CGFloat = isIncoming ? 10 : 15
|
||||
|
||||
let bubbleView = UIImageView(image: bubbleImageData!.messageBubbleImage)
|
||||
let bubbleView = UIImageView(image: bubbleImageData.messageBubbleImage)
|
||||
|
||||
bubbleView.layer.cornerRadius = 10
|
||||
bubbleView.addSubview(bodyLabel)
|
||||
bodyLabel.autoPinLeadingToSuperView(withMargin: leadingMargin)
|
||||
bodyLabel.autoPinTrailingToSuperView(withMargin: trailingMargin)
|
||||
|
||||
bodyLabel.autoPinEdge(toSuperviewEdge: .leading, withInset: leadingMargin)
|
||||
bodyLabel.autoPinEdge(toSuperviewEdge: .trailing, withInset: trailingMargin)
|
||||
bodyLabel.autoPinHeightToSuperview(withMargin: 10)
|
||||
|
||||
// Try to hug content both horizontally and vertically, but *prefer* wide and short, to narrow and tall.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user