Merge remote-tracking branch 'private/release/2.44.0'

This commit is contained in:
Matthew Chen 2019-09-27 11:31:22 -03:00
commit fc77b0fa2d
28 changed files with 512 additions and 358 deletions

View File

@ -81,7 +81,9 @@ def main():
# Looks like this tag was erroneously applied before rebasing.
# After rebasing, HEAD was retagged with 2.41.0.2
'2.41.0.1',
#
# internal builds, not marked as such
'2.44.0.0',
'2.44.0.3'
]
tags_of_concern = [tag for tag in tags_of_concern if tag not in tags_to_ignore]

View File

@ -566,6 +566,7 @@
8809CE8122F534B200D38867 /* CustomKeyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8809CE8022F534B200D38867 /* CustomKeyboard.swift */; };
8809CE8722F8FE6D00D38867 /* AttachmentKeyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8809CE8622F8FE6D00D38867 /* AttachmentKeyboard.swift */; };
8809CE8A22F93C2200D38867 /* RecentPhotoCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8809CE8922F93C2200D38867 /* RecentPhotoCollectionView.swift */; };
880C0FF7233D3F7C00386FB8 /* playPauseButton.json in Resources */ = {isa = PBXBuildFile; fileRef = 880C0FF6233D3F7C00386FB8 /* playPauseButton.json */; };
8810223722DF9C2300A7C44F /* OnboardingAccountLockedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8810223622DF9C2300A7C44F /* OnboardingAccountLockedViewController.swift */; };
8811CF842295D8DA00FF6549 /* VolumeButtons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8811CF832295D8DA00FF6549 /* VolumeButtons.swift */; };
8813F6E12330082900ADEC6A /* AudioWaveformProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88A695BC232C18DF002F7B9B /* AudioWaveformProgressView.swift */; };
@ -584,7 +585,6 @@
88A9729222FA5D4B004B4FBF /* AttachmentFormatPickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88A9729122FA5D4B004B4FBF /* AttachmentFormatPickerView.swift */; };
88A9729422FB4D02004B4FBF /* LocationPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88A9729322FB4D02004B4FBF /* LocationPicker.swift */; };
88BFD4732335C2B3001797D7 /* waveformLoading.json in Resources */ = {isa = PBXBuildFile; fileRef = 88BFD4722335C2B3001797D7 /* waveformLoading.json */; };
88BFD4752335C2DB001797D7 /* playPauseButton.json in Resources */ = {isa = PBXBuildFile; fileRef = 88BFD4742335C2DB001797D7 /* playPauseButton.json */; };
88D1D40222EBB5A100F472C5 /* MessageRequestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88D1D40122EBB5A100F472C5 /* MessageRequestView.swift */; };
88D1D40422EF8A9700F472C5 /* ThreadDetailsInteraction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88D1D40322EF8A9700F472C5 /* ThreadDetailsInteraction.swift */; };
88D1D40622EF8F1100F472C5 /* ThreadDetailsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88D1D40522EF8F1100F472C5 /* ThreadDetailsCell.swift */; };
@ -1373,6 +1373,7 @@
8809CE8422F8DB2D00D38867 /* AttachmentKeyboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentKeyboard.swift; sourceTree = "<group>"; };
8809CE8622F8FE6D00D38867 /* AttachmentKeyboard.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AttachmentKeyboard.swift; sourceTree = "<group>"; };
8809CE8922F93C2200D38867 /* RecentPhotoCollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecentPhotoCollectionView.swift; sourceTree = "<group>"; };
880C0FF6233D3F7C00386FB8 /* playPauseButton.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = playPauseButton.json; sourceTree = "<group>"; };
8810223622DF9C2300A7C44F /* OnboardingAccountLockedViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingAccountLockedViewController.swift; sourceTree = "<group>"; };
8811CF832295D8DA00FF6549 /* VolumeButtons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VolumeButtons.swift; sourceTree = "<group>"; };
881677C422DD2B21007BAF49 /* OWSPinReminderViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OWSPinReminderViewController.swift; sourceTree = "<group>"; };
@ -1392,7 +1393,6 @@
88A9729122FA5D4B004B4FBF /* AttachmentFormatPickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentFormatPickerView.swift; sourceTree = "<group>"; };
88A9729322FB4D02004B4FBF /* LocationPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationPicker.swift; sourceTree = "<group>"; };
88BFD4722335C2B3001797D7 /* waveformLoading.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = waveformLoading.json; sourceTree = "<group>"; };
88BFD4742335C2DB001797D7 /* playPauseButton.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = playPauseButton.json; sourceTree = "<group>"; };
88D1D40122EBB5A100F472C5 /* MessageRequestView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageRequestView.swift; sourceTree = "<group>"; };
88D1D40322EF8A9700F472C5 /* ThreadDetailsInteraction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadDetailsInteraction.swift; sourceTree = "<group>"; };
88D1D40522EF8F1100F472C5 /* ThreadDetailsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadDetailsCell.swift; sourceTree = "<group>"; };
@ -2694,7 +2694,7 @@
88BFD4712335C2A4001797D7 /* Lottie */ = {
isa = PBXGroup;
children = (
88BFD4742335C2DB001797D7 /* playPauseButton.json */,
880C0FF6233D3F7C00386FB8 /* playPauseButton.json */,
88BFD4722335C2B3001797D7 /* waveformLoading.json */,
);
path = Lottie;
@ -3304,9 +3304,9 @@
34330A5A1E7875FB00DF2FB9 /* fontawesome-webfont.ttf in Resources */,
A5509ECA1A69AB8B00ABA4BC /* Main.storyboard in Resources */,
34330A5C1E787A9800DF2FB9 /* dripicons-v2.ttf in Resources */,
880C0FF7233D3F7C00386FB8 /* playPauseButton.json in Resources */,
B6F509971AA53F760068F56A /* Localizable.strings in Resources */,
B66DBF4A19D5BBC8006EA940 /* Images.xcassets in Resources */,
88BFD4752335C2DB001797D7 /* playPauseButton.json in Resources */,
34CF0788203E6B78005C4D61 /* ringback_tone_ansi.caf in Resources */,
34C3C78F2040A4F70000134C /* sonarping.mp3 in Resources */,
34661FB820C1C0D60056EDD6 /* message_sent.aiff in Resources */,

View File

@ -1 +1 @@
{"v":"5.5.2","fr":60,"ip":0,"op":30,"w":24,"h":24,"nm":"lottie-assets2","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Play Outlines 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"t":28,"s":[90]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[14,12,0],"to":[-0.333,0,0],"ti":[0.333,0,0]},{"t":28,"s":[12,12,0]}],"ix":2},"a":{"a":0,"k":[7.25,8.25,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-7,-4],[-7,4],[7,4],[6.888,3.936]],"c":true}]},{"t":28,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-8,-1.969],[-7.984,1.999],[8,1.999],[7.998,-1.997]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[7.25,4.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Play Outlines 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"t":28,"s":[90]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[14,12,0],"to":[-0.333,0,0],"ti":[0.333,0,0]},{"t":28,"s":[12,12,0]}],"ix":2},"a":{"a":0,"k":[7.25,8.25,0],"ix":1},"s":{"a":0,"k":[100,-100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-7,-4],[-7,4],[7,4],[6.888,3.936]],"c":true}]},{"t":28,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-8,-1.969],[-7.984,1.999],[8,1.999],[7.998,-1.997]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[7.25,4.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30,"st":0,"bm":0}],"markers":[]}
{"v":"5.5.9","fr":60,"ip":0,"op":30,"w":28,"h":28,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Play 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"t":28,"s":[90]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[15.111,14,0],"to":[-0.183,0,0],"ti":[0.183,0,0]},{"t":28,"s":[14.011,14,0]}],"ix":2},"a":{"a":0,"k":[0,-5.2,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[{"i":[[0,0],[0,0.825],[0,0],[0,0],[-0.222,-0.002],[0.093,-0.134],[0.153,-0.057],[0,0],[0,0]],"o":[[-0.716,0.414],[0,0],[0,0],[0,0],[0,0.163],[-0.093,0.134],[0,0],[0,0],[0,0]],"v":[[-7.811,5.035],[-9.111,4.287],[-9.111,-5.168],[-9.111,-5.213],[9.111,-5.211],[8.968,-4.754],[8.589,-4.461],[8.581,-4.456],[8.526,-4.424]],"c":true}]},{"t":28,"s":[{"i":[[0,0],[-0.005,0.388],[0,0.202],[-0.4,0.001],[-0.222,-0.002],[0.005,-0.402],[-0.001,-0.198],[-0.001,-0.09],[0.399,0.003]],"o":[[-0.404,0],[0,0],[-0.005,-0.405],[0,0],[0.404,0.001],[0,0.195],[0,0],[-0.001,0.404],[-0.586,-0.004]],"v":[[-9.41,2.811],[-10.003,2.219],[-10.003,-2.587],[-9.404,-3.19],[9.401,-3.188],[10.004,-2.593],[10.003,2.017],[10.003,2.21],[9.409,2.808]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[99.952,100.017],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Play","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"t":28,"s":[90]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[15.111,13.987,0],"to":[-0.183,0,0],"ti":[0.183,0,0]},{"t":28,"s":[14.011,13.987,0]}],"ix":2},"a":{"a":0,"k":[0,5.2,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[{"i":[[0,0],[-0.093,-0.134],[0,-0.163],[0,0],[0,0],[0,0],[-0.716,-0.414],[0,0],[0,0]],"o":[[0.153,0.057],[0.093,0.134],[-0.222,0.002],[0,0],[0,0],[0,-0.825],[0,0],[0,0],[0,0]],"v":[[8.589,4.461],[8.968,4.754],[9.111,5.211],[-9.111,5.213],[-9.111,5.202],[-9.111,-4.287],[-7.811,-5.035],[8.576,4.453],[8.588,4.46]],"c":true}]},{"t":28,"s":[{"i":[[0,0],[-0.001,-0.126],[0.395,0],[0,0],[0,0.392],[0,0],[-0.398,0],[-0.241,0.001],[0,-0.403]],"o":[[0.002,0.152],[0,0.396],[-0.222,0.002],[-0.402,0],[0,-0.1],[0,-0.396],[0,0],[0.397,0],[0.001,0.072]],"v":[[10.01,-1.986],[10.012,2.618],[9.415,3.21],[-9.386,3.208],[-9.987,2.615],[-9.987,-2.191],[-9.389,-2.788],[9.413,-2.788],[10.011,-2.189]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30,"st":0,"bm":0}],"markers":[]}

View File

@ -47,7 +47,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>2.44.0.0</string>
<string>2.44.0.5</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LOGS_EMAIL</key>

View File

@ -63,8 +63,12 @@ class AudioMessageView: UIStackView {
addArrangedSubview(topLabel)
}
// TODO: Adjust the animation speed once we get the final animation
playPauseAnimation.animationSpeed = 2
// TODO: There is a bug with Lottie where animations lag when there are a lot
// of other things happening on screen. Since this animation generally plays
// when the progress bar / waveform is rendering we speed up the playback to
// address some of the lag issues. Once this is fixed we should update lottie
// and remove this check. https://github.com/airbnb/lottie-ios/issues/1034
playPauseAnimation.animationSpeed = 3
playPauseAnimation.backgroundBehavior = .forceFinish
playPauseAnimation.contentMode = .scaleAspectFit
playPauseAnimation.autoSetDimensions(to: CGSize(square: animationSize))
@ -150,7 +154,7 @@ class AudioMessageView: UIStackView {
private static var labelFont: UIFont = .ows_dynamicTypeCaption2
private static var waveformHeight: CGFloat = 35
private static var vMargin: CGFloat = 4
private var animationSize: CGFloat = 30
private var animationSize: CGFloat = 28
private var iconSize: CGFloat = 24
private var hMargin: CGFloat = 0
private var hSpacing: CGFloat = 12

View File

@ -14,6 +14,12 @@
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSUInteger, ViewOnceMessageType) {
ViewOnceMessageType_Unknown = 0,
ViewOnceMessageType_Photo,
ViewOnceMessageType_Video,
};
@interface OWSMessageViewOnceView ()
@property (nonatomic) OWSBubbleView *bubbleView;
@ -81,7 +87,7 @@ NS_ASSUME_NONNULL_BEGIN
self.senderNameContainer = [UIView new];
self.senderNameContainer.layoutMargins = UIEdgeInsetsMake(0, 0, self.senderNameBottomSpacing, 0);
[self.senderNameContainer addSubview:self.senderNameLabel];
[self.senderNameLabel ows_autoPinToSuperviewMargins];
[self.senderNameLabel autoPinEdgesToSuperviewMargins];
self.iconView = [UIImageView new];
[self.iconView setContentHuggingHigh];
@ -405,6 +411,27 @@ NS_ASSUME_NONNULL_BEGIN
// Do nothing.
}
- (ViewOnceMessageType)viewOnceMessageType
{
if (self.viewItem.attachmentStream == nil) {
// The attachment doesn't exist for outgoing
// messages so we'd need to store the content type if
// we wanted to distinguish between photo and video
// For incoming messages viewed messages, it doesn't matter
// because we show generic "View" text, regardless of the
// content type
return ViewOnceMessageType_Unknown;
}
if (self.viewItem.attachmentStream.isVideo) {
return ViewOnceMessageType_Video;
} else {
OWSAssertDebug(self.viewItem.attachmentStream.isImage || self.viewItem.attachmentStream.isAnimated);
return ViewOnceMessageType_Photo;
}
}
#pragma mark - Subviews
- (void)configureLabel
@ -435,9 +462,18 @@ NS_ASSUME_NONNULL_BEGIN
self.label.text = CommonStrings.retryButton;
break;
case ViewOnceMessageState_IncomingAvailable:
self.label.text = NSLocalizedString(@"PER_MESSAGE_EXPIRATION_TAP_TO_VIEW",
@"Label for view-once messages indicating that "
@"user can tap to view the message's contents.");
switch (self.viewOnceMessageType) {
case ViewOnceMessageType_Photo:
self.label.text = MessageStrings.viewOnceViewPhoto;
break;
case ViewOnceMessageType_Video:
self.label.text = MessageStrings.viewOnceViewVideo;
break;
case ViewOnceMessageType_Unknown:
OWSFailDebug(@"unexpected viewOnceMessageType for IncomingFailed.");
self.label.text = MessageStrings.viewOnceViewPhoto;
break;
}
break;
case ViewOnceMessageState_OutgoingFailed:
self.label.text = CommonStrings.retryButton;

View File

@ -3529,13 +3529,20 @@ typedef enum : NSUInteger {
[groupThread fireAvatarChangedNotification];
NSData *_Nullable groupAvatarData;
if (newGroupModel.groupImage) {
NSData *data = UIImagePNGRepresentation(newGroupModel.groupImage);
_Nullable id<DataSource> dataSource = [DataSourceValue dataSourceWithData:data fileExtension:@"png"];
groupAvatarData = UIImagePNGRepresentation(newGroupModel.groupImage);
OWSAssertDebug(groupAvatarData.length > 0);
}
_Nullable id<DataSource> groupAvatarDataSource;
if (groupAvatarData.length > 0) {
groupAvatarDataSource = [DataSourceValue dataSourceWithData:groupAvatarData fileExtension:@"png"];
}
if (groupAvatarDataSource != nil) {
// DURABLE CLEANUP - currently one caller uses the completion handler to delete the tappable error message
// which causes this code to be called. Once we're more aggressive about durable sending retry,
// we could get rid of this "retryable tappable error message".
[self.messageSender sendTemporaryAttachment:dataSource
[self.messageSender sendTemporaryAttachment:groupAvatarDataSource
contentType:OWSMimeTypeImagePng
inMessage:message
success:^{

View File

@ -990,7 +990,8 @@ NSString *NSStringForViewOnceMessageState(ViewOnceMessageState cellType)
return;
} else if ([mediaAttachment isKindOfClass:[TSAttachmentStream class]]) {
TSAttachmentStream *attachmentStream = (TSAttachmentStream *)mediaAttachment;
if (attachmentStream.isValidVisualMedia && (attachmentStream.isImage || attachmentStream.isAnimated)) {
if (attachmentStream.isValidVisualMedia
&& (attachmentStream.isImage || attachmentStream.isAnimated || attachmentStream.isVideo)) {
self.messageCellType = OWSMessageCellType_ViewOnce;
self.viewOnceMessageState = ViewOnceMessageState_IncomingAvailable;
self.attachmentStream = attachmentStream;

View File

@ -333,6 +333,10 @@ NS_ASSUME_NONNULL_BEGIN
actionBlock:^{
[DebugUIMessages sendMessages:1 toAllMembersOfGroup:groupThread];
}]];
[items addObject:[OWSTableItem itemWithTitle:@"Send Group Info Request"
actionBlock:^{
[DebugUIMessages requestGroupInfoForGroupThread:groupThread];
}]];
}
return [OWSTableSection sectionWithTitle:self.name items:items];
@ -4938,6 +4942,19 @@ typedef OWSContact * (^OWSContactBlock)(SDSAnyWriteTransaction *transaction);
}];
}
+ (void)requestGroupInfoForGroupThread:(TSGroupThread *)groupThread
{
[self writeWithBlock:^(SDSAnyWriteTransaction *_Nonnull transaction) {
for (SignalServiceAddress *address in groupThread.groupModel.groupMembers) {
TSThread *thread = [TSContactThread getOrCreateThreadWithContactAddress:address transaction:transaction];
OWSLogInfo(@"Requesting group info for group thread from: %@", address);
OWSSyncGroupsRequestMessage *syncGroupsRequestMessage =
[[OWSSyncGroupsRequestMessage alloc] initWithThread:thread groupId:groupThread.groupModel.groupId];
[self.messageSenderJobQueue addMessage:syncGroupsRequestMessage.asPreparer transaction:transaction];
}
}];
}
@end
NS_ASSUME_NONNULL_END

View File

@ -9,19 +9,18 @@ import UIKit
class ViewOnceMessageViewController: OWSViewController {
class Content {
enum ContentType {
case stillImage, animatedImage, video
}
let messageId: String
let filePath: String
// The content is an animated image (GIF or WEBP)
// if true, a still image otherwise.
// TODO: We could eventually support video.
let isAnimated: Bool
let type: ContentType
init(messageId: String,
filePath: String,
isAnimated: Bool) {
init(messageId: String, filePath: String, type: ContentType) {
self.messageId = messageId
self.filePath = filePath
self.isAnimated = isAnimated
self.type = type
}
deinit {
@ -132,11 +131,14 @@ class ViewOnceMessageViewController: OWSViewController {
owsFailDebug("Missing content type.")
return
}
let isAnimated: Bool
let viewOnceType: Content.ContentType
if attachmentStream.isAnimated || contentType == OWSMimeTypeImageWebp {
isAnimated = true
viewOnceType = .animatedImage
} else if attachmentStream.isImage {
isAnimated = false
viewOnceType = .stillImage
} else if attachmentStream.isVideo {
viewOnceType = .video
} else {
owsFailDebug("Unexpected content type.")
return
@ -214,9 +216,7 @@ class ViewOnceMessageViewController: OWSViewController {
return
}
content = Content(messageId: messageId,
filePath: tempFilePath,
isAnimated: isAnimated)
content = Content(messageId: messageId, filePath: tempFilePath, type: viewOnceType)
}
return content
}
@ -270,7 +270,8 @@ class ViewOnceMessageViewController: OWSViewController {
private func buildMediaView() -> UIView? {
let filePath = content.filePath
if content.isAnimated {
switch content.type {
case .animatedImage:
guard let image = YYImage(contentsOfFile: filePath) else {
owsFailDebug("Could not load attachment.")
return nil
@ -291,7 +292,7 @@ class ViewOnceMessageViewController: OWSViewController {
animatedImageView.layer.allowsEdgeAntialiasing = true
animatedImageView.image = image
return animatedImageView
} else {
case .stillImage:
guard let image = UIImage(contentsOfFile: filePath) else {
owsFailDebug("Could not load attachment.")
return nil
@ -313,9 +314,66 @@ class ViewOnceMessageViewController: OWSViewController {
imageView.layer.allowsEdgeAntialiasing = true
imageView.image = image
return imageView
case .video:
let videoContainer = UIView()
let videoUrl = URL(fileURLWithPath: content.filePath)
let player = OWSVideoPlayer(url: videoUrl, shouldLoop: true)
self.videoPlayer = player
player.delegate = self
let playerView = VideoPlayerView()
playerView.player = player.avPlayer
videoContainer.addSubview(playerView)
playerView.autoPinEdgesToSuperviewEdges()
let label = UILabel()
label.textColor = Theme.darkThemePrimaryColor
label.font = UIFont.ows_dynamicTypeBody.ows_monospaced()
label.setShadow()
videoContainer.addSubview(label)
label.autoPinEdge(toSuperviewMargin: .top, withInset: 16)
label.autoPinEdge(toSuperviewMargin: .trailing, withInset: 16)
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .positional
formatter.allowedUnits = [.minute, .second ]
formatter.zeroFormattingBehavior = [ .pad ]
let avPlayer = player.avPlayer
self.videoPlayerProgressObserver = avPlayer.addPeriodicTimeObserver(forInterval: CMTime(seconds: 0.1, preferredTimescale: 100), queue: nil) { [weak self] (_) in
guard let item = avPlayer.currentItem else {
owsFailDebug("item was unexpectedly nil")
label.text = "0:00"
return
}
let position = avPlayer.currentTime()
let duration: CMTime = item.asset.duration
let remainingTime = duration - position
let remainingSeconds = CMTimeGetSeconds(remainingTime)
guard let remainingString = formatter.string(from: remainingSeconds) else {
owsFailDebug("unable to format time remaining")
label.text = "0:00"
return
}
label.text = remainingString
}
return videoContainer
}
}
// MARK: Video
var videoPlayerProgressObserver: Any?
var videoPlayer: OWSVideoPlayer?
func setupDatabaseObservation() {
databaseStorage.add(databaseStorageObserver: self)
@ -339,6 +397,7 @@ class ViewOnceMessageViewController: OWSViewController {
super.viewDidAppear(animated)
self.becomeFirstResponder()
self.videoPlayer?.play()
}
public override var preferredStatusBarStyle: UIStatusBarStyle {
@ -419,3 +478,9 @@ extension ViewOnceMessageViewController: SDSDatabaseStorageObserver {
dismissIfRemoved()
}
}
extension ViewOnceMessageViewController: OWSVideoPlayerDelegate {
func videoPlayerDidPlayToCompletion(_ videoPlayer: OWSVideoPlayer) {
// no-op
}
}

View File

@ -1773,10 +1773,13 @@
"PER_MESSAGE_EXPIRATION_NOTIFICATION" = "Disappearing Photo";
/* Label for outgoing view-once messages. */
"PER_MESSAGE_EXPIRATION_OUTGOING_MESSAGE" = "Photo";
"PER_MESSAGE_EXPIRATION_OUTGOING_MESSAGE" = "Media";
/* Label for view-once messages indicating that user can tap to view the message's contents. */
"PER_MESSAGE_EXPIRATION_TAP_TO_VIEW" = "View Photo";
"PER_MESSAGE_EXPIRATION_VIEW_PHOTO" = "View Photo";
/* Label for view-once messages indicating that user can tap to view the message's contents. */
"PER_MESSAGE_EXPIRATION_VIEW_VIDEO" = "View Video";
/* Label for view-once messages indicating that the local user has viewed the message's contents. */
"PER_MESSAGE_EXPIRATION_VIEWED" = "Viewed";

View File

@ -69,11 +69,10 @@ public class AttachmentApprovalViewController: UIPageViewController, UIPageViewC
private var options: AttachmentApprovalViewControllerOptions {
var options = receivedOptions
// For now, only still images can be sent as view-once messages.
if FeatureFlags.viewOnceSending,
attachmentApprovalItemCollection.attachmentApprovalItems.count == 1,
let firstItem = attachmentApprovalItemCollection.attachmentApprovalItems.first,
firstItem.attachment.isValidImage {
firstItem.attachment.isValidImage || firstItem.attachment.isValidVideo {
options.insert(.canToggleViewOnce)
}

View File

@ -64,6 +64,12 @@ public class MessageStrings: NSObject {
@objc
static public let noteToSelf = NSLocalizedString("NOTE_TO_SELF", comment: "Label for 1:1 conversation with yourself.")
@objc
static public let viewOnceViewPhoto = NSLocalizedString("PER_MESSAGE_EXPIRATION_VIEW_PHOTO", comment: "Label for view-once messages indicating that user can tap to view the message's contents.")
@objc
static public let viewOnceViewVideo = NSLocalizedString("PER_MESSAGE_EXPIRATION_VIEW_VIDEO", comment: "Label for view-once messages indicating that user can tap to view the message's contents.")
}
@objc

View File

@ -8,7 +8,7 @@ import AVFoundation
@objc
public class VideoPlayerView: UIView {
@objc
var player: AVPlayer? {
public var player: AVPlayer? {
get {
return playerLayer.player
}

View File

@ -6,7 +6,7 @@ import Foundation
import AVFoundation
@objc
protocol OWSVideoPlayerDelegate: class {
public protocol OWSVideoPlayerDelegate: class {
func videoPlayerDidPlayToCompletion(_ videoPlayer: OWSVideoPlayer)
}
@ -14,15 +14,23 @@ protocol OWSVideoPlayerDelegate: class {
public class OWSVideoPlayer: NSObject {
@objc
let avPlayer: AVPlayer
public let avPlayer: AVPlayer
let audioActivity: AudioActivity
let shouldLoop: Bool
@objc
weak var delegate: OWSVideoPlayerDelegate?
weak public var delegate: OWSVideoPlayerDelegate?
@objc init(url: URL) {
@objc
convenience public init(url: URL) {
self.init(url: url, shouldLoop: false)
}
@objc
public init(url: URL, shouldLoop: Bool) {
self.avPlayer = AVPlayer(url: url)
self.audioActivity = AudioActivity(audioDescription: "[OWSVideoPlayer] url:\(url)", behavior: .playback)
self.shouldLoop = shouldLoop
super.init()
@ -81,6 +89,11 @@ public class OWSVideoPlayer: NSObject {
@objc
private func playerItemDidPlayToCompletion(_ notification: Notification) {
self.delegate?.videoPlayerDidPlayToCompletion(self)
audioSession.endAudioActivity(self.audioActivity)
if shouldLoop {
avPlayer.seek(to: CMTime.zero)
avPlayer.play()
} else {
audioSession.endAudioActivity(self.audioActivity)
}
}
}

View File

@ -228,7 +228,8 @@ message DataMessage {
INITIAL = 0;
MESSAGE_TIMERS = 1;
VIEW_ONCE = 2;
CURRENT = 2;
VIEW_ONCE_VIDEO = 3;
CURRENT = 3;
}
optional string body = 1;

View File

@ -39,7 +39,7 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
- (nullable SSKProtoSyncMessageBuilder *)syncMessageBuilder
- (nullable SSKProtoSyncMessageBuilder *)syncMessageBuilderWithTransaction:(SDSAnyReadTransaction *)transaction
{
SSKProtoSyncMessageBlockedBuilder *blockedBuilder = [SSKProtoSyncMessageBlocked builder];
[blockedBuilder setNumbers:_phoneNumbers];

View File

@ -101,7 +101,7 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssertDebug(SSKFeatureFlags.viewOnceSending);
[dataBuilder setIsViewOnce:YES];
[dataBuilder setRequiredProtocolVersion:(uint32_t)SSKProtos.viewOnceMessagesProtocolVersion];
[dataBuilder setRequiredProtocolVersion:(uint32_t)SSKProtoDataMessageProtocolVersionViewOnceVideo];
NSError *error;
dataMessage = [dataBuilder buildAndReturnError:&error];

View File

@ -1069,13 +1069,13 @@ NSUInteger const TSOutgoingMessageSchemaVersion = 1;
SSKProtoDataMessageBuilder *builder = [SSKProtoDataMessage builder];
[builder setTimestamp:self.timestamp];
NSUInteger requiredProtocolVersion = SSKProtos.initialProtocolVersion;
NSUInteger requiredProtocolVersion = SSKProtoDataMessageProtocolVersionInitial;
if (self.isViewOnceMessage) {
if (SSKFeatureFlags.viewOnceSending) {
[builder setIsViewOnce:YES];
requiredProtocolVersion = SSKProtos.viewOnceMessagesProtocolVersion;
requiredProtocolVersion = SSKProtoDataMessageProtocolVersionViewOnceVideo;
} else {
OWSFailDebug(@"Feature flag not set.");
}

View File

@ -1256,19 +1256,23 @@ NS_ASSUME_NONNULL_BEGIN
// Only send this group update to the requester.
[message updateWithSendingToSingleGroupRecipient:envelope.sourceAddress transaction:transaction];
NSData *_Nullable groupAvatarData;
if (gThread.groupModel.groupImage) {
NSData *_Nullable data = UIImagePNGRepresentation(gThread.groupModel.groupImage);
OWSAssertDebug(data);
if (data) {
_Nullable id<DataSource> dataSource = [DataSourceValue dataSourceWithData:data fileExtension:@"png"];
[self.messageSenderJobQueue addMediaMessage:message
dataSource:dataSource
contentType:OWSMimeTypeImagePng
sourceFilename:nil
caption:nil
albumMessageId:nil
isTemporaryAttachment:YES];
}
groupAvatarData = UIImagePNGRepresentation(gThread.groupModel.groupImage);
OWSAssertDebug(groupAvatarData.length > 0);
}
_Nullable id<DataSource> groupAvatarDataSource;
if (groupAvatarData.length > 0) {
groupAvatarDataSource = [DataSourceValue dataSourceWithData:groupAvatarData fileExtension:@"png"];
}
if (groupAvatarDataSource != nil) {
[self.messageSenderJobQueue addMediaMessage:message
dataSource:groupAvatarDataSource
contentType:OWSMimeTypeImagePng
sourceFilename:nil
caption:nil
albumMessageId:nil
isTemporaryAttachment:YES];
} else {
[self.messageSenderJobQueue addMessage:message.asPreparer transaction:transaction];
}

View File

@ -713,32 +713,32 @@ extension SSKProtoTypingMessage.SSKProtoTypingMessageBuilder {
}
fileprivate class func parseProto(_ proto: SignalServiceProtos_Content) throws -> SSKProtoContent {
var dataMessage: SSKProtoDataMessage? = nil
var dataMessage: SSKProtoDataMessage?
if proto.hasDataMessage {
dataMessage = try SSKProtoDataMessage.parseProto(proto.dataMessage)
}
var syncMessage: SSKProtoSyncMessage? = nil
var syncMessage: SSKProtoSyncMessage?
if proto.hasSyncMessage {
syncMessage = try SSKProtoSyncMessage.parseProto(proto.syncMessage)
}
var callMessage: SSKProtoCallMessage? = nil
var callMessage: SSKProtoCallMessage?
if proto.hasCallMessage {
callMessage = try SSKProtoCallMessage.parseProto(proto.callMessage)
}
var nullMessage: SSKProtoNullMessage? = nil
var nullMessage: SSKProtoNullMessage?
if proto.hasNullMessage {
nullMessage = try SSKProtoNullMessage.parseProto(proto.nullMessage)
}
var receiptMessage: SSKProtoReceiptMessage? = nil
var receiptMessage: SSKProtoReceiptMessage?
if proto.hasReceiptMessage {
receiptMessage = try SSKProtoReceiptMessage.parseProto(proto.receiptMessage)
}
var typingMessage: SSKProtoTypingMessage? = nil
var typingMessage: SSKProtoTypingMessage?
if proto.hasTypingMessage {
typingMessage = try SSKProtoTypingMessage.parseProto(proto.typingMessage)
}
@ -1531,12 +1531,12 @@ extension SSKProtoCallMessageHangup.SSKProtoCallMessageHangupBuilder {
}
fileprivate class func parseProto(_ proto: SignalServiceProtos_CallMessage) throws -> SSKProtoCallMessage {
var offer: SSKProtoCallMessageOffer? = nil
var offer: SSKProtoCallMessageOffer?
if proto.hasOffer {
offer = try SSKProtoCallMessageOffer.parseProto(proto.offer)
}
var answer: SSKProtoCallMessageAnswer? = nil
var answer: SSKProtoCallMessageAnswer?
if proto.hasAnswer {
answer = try SSKProtoCallMessageAnswer.parseProto(proto.answer)
}
@ -1544,12 +1544,12 @@ extension SSKProtoCallMessageHangup.SSKProtoCallMessageHangupBuilder {
var iceUpdate: [SSKProtoCallMessageIceUpdate] = []
iceUpdate = try proto.iceUpdate.map { try SSKProtoCallMessageIceUpdate.parseProto($0) }
var hangup: SSKProtoCallMessageHangup? = nil
var hangup: SSKProtoCallMessageHangup?
if proto.hasHangup {
hangup = try SSKProtoCallMessageHangup.parseProto(proto.hangup)
}
var busy: SSKProtoCallMessageBusy? = nil
var busy: SSKProtoCallMessageBusy?
if proto.hasBusy {
busy = try SSKProtoCallMessageBusy.parseProto(proto.busy)
}
@ -1735,7 +1735,7 @@ extension SSKProtoCallMessage.SSKProtoCallMessageBuilder {
}
fileprivate class func parseProto(_ proto: SignalServiceProtos_DataMessage.Quote.QuotedAttachment) throws -> SSKProtoDataMessageQuoteQuotedAttachment {
var thumbnail: SSKProtoAttachmentPointer? = nil
var thumbnail: SSKProtoAttachmentPointer?
if proto.hasThumbnail {
thumbnail = try SSKProtoAttachmentPointer.parseProto(proto.thumbnail)
}
@ -2982,7 +2982,7 @@ extension SSKProtoDataMessageContactPostalAddress.SSKProtoDataMessageContactPost
}
fileprivate class func parseProto(_ proto: SignalServiceProtos_DataMessage.Contact.Avatar) throws -> SSKProtoDataMessageContactAvatar {
var avatar: SSKProtoAttachmentPointer? = nil
var avatar: SSKProtoAttachmentPointer?
if proto.hasAvatar {
avatar = try SSKProtoAttachmentPointer.parseProto(proto.avatar)
}
@ -3170,7 +3170,7 @@ extension SSKProtoDataMessageContactAvatar.SSKProtoDataMessageContactAvatarBuild
}
fileprivate class func parseProto(_ proto: SignalServiceProtos_DataMessage.Contact) throws -> SSKProtoDataMessageContact {
var name: SSKProtoDataMessageContactName? = nil
var name: SSKProtoDataMessageContactName?
if proto.hasName {
name = try SSKProtoDataMessageContactName.parseProto(proto.name)
}
@ -3184,7 +3184,7 @@ extension SSKProtoDataMessageContactAvatar.SSKProtoDataMessageContactAvatarBuild
var address: [SSKProtoDataMessageContactPostalAddress] = []
address = try proto.address.map { try SSKProtoDataMessageContactPostalAddress.parseProto($0) }
var avatar: SSKProtoDataMessageContactAvatar? = nil
var avatar: SSKProtoDataMessageContactAvatar?
if proto.hasAvatar {
avatar = try SSKProtoDataMessageContactAvatar.parseProto(proto.avatar)
}
@ -3339,7 +3339,7 @@ extension SSKProtoDataMessageContact.SSKProtoDataMessageContactBuilder {
}
let url = proto.url
var image: SSKProtoAttachmentPointer? = nil
var image: SSKProtoAttachmentPointer?
if proto.hasImage {
image = try SSKProtoAttachmentPointer.parseProto(proto.image)
}
@ -3573,6 +3573,7 @@ extension SSKProtoDataMessageSticker.SSKProtoDataMessageStickerBuilder {
case initial = 0
case messageTimers = 1
case viewOnce = 2
case viewOnceVideo = 3
}
private class func SSKProtoDataMessageProtocolVersionWrap(_ value: SignalServiceProtos_DataMessage.ProtocolVersion) -> SSKProtoDataMessageProtocolVersion {
@ -3580,6 +3581,7 @@ extension SSKProtoDataMessageSticker.SSKProtoDataMessageStickerBuilder {
case .initial: return .initial
case .messageTimers: return .messageTimers
case .viewOnce: return .viewOnce
case .viewOnceVideo: return .viewOnceVideo
}
}
@ -3588,6 +3590,7 @@ extension SSKProtoDataMessageSticker.SSKProtoDataMessageStickerBuilder {
case .initial: return .initial
case .messageTimers: return .messageTimers
case .viewOnce: return .viewOnce
case .viewOnceVideo: return .viewOnceVideo
}
}
@ -3860,12 +3863,12 @@ extension SSKProtoDataMessageSticker.SSKProtoDataMessageStickerBuilder {
var attachments: [SSKProtoAttachmentPointer] = []
attachments = try proto.attachments.map { try SSKProtoAttachmentPointer.parseProto($0) }
var group: SSKProtoGroupContext? = nil
var group: SSKProtoGroupContext?
if proto.hasGroup {
group = try SSKProtoGroupContext.parseProto(proto.group)
}
var quote: SSKProtoDataMessageQuote? = nil
var quote: SSKProtoDataMessageQuote?
if proto.hasQuote {
quote = try SSKProtoDataMessageQuote.parseProto(proto.quote)
}
@ -3876,7 +3879,7 @@ extension SSKProtoDataMessageSticker.SSKProtoDataMessageStickerBuilder {
var preview: [SSKProtoDataMessagePreview] = []
preview = try proto.preview.map { try SSKProtoDataMessagePreview.parseProto($0) }
var sticker: SSKProtoDataMessageSticker? = nil
var sticker: SSKProtoDataMessageSticker?
if proto.hasSticker {
sticker = try SSKProtoDataMessageSticker.parseProto(proto.sticker)
}
@ -4831,7 +4834,7 @@ extension SSKProtoSyncMessageSentUnidentifiedDeliveryStatus.SSKProtoSyncMessageS
}
fileprivate class func parseProto(_ proto: SignalServiceProtos_SyncMessage.Sent) throws -> SSKProtoSyncMessageSent {
var message: SSKProtoDataMessage? = nil
var message: SSKProtoDataMessage?
if proto.hasMessage {
message = try SSKProtoDataMessage.parseProto(proto.message)
}
@ -5055,7 +5058,7 @@ extension SSKProtoSyncMessageContacts.SSKProtoSyncMessageContactsBuilder {
}
fileprivate class func parseProto(_ proto: SignalServiceProtos_SyncMessage.Groups) throws -> SSKProtoSyncMessageGroups {
var blob: SSKProtoAttachmentPointer? = nil
var blob: SSKProtoAttachmentPointer?
if proto.hasBlob {
blob = try SSKProtoAttachmentPointer.parseProto(proto.blob)
}
@ -6285,22 +6288,22 @@ extension SSKProtoSyncMessageViewOnceOpen.SSKProtoSyncMessageViewOnceOpenBuilder
}
fileprivate class func parseProto(_ proto: SignalServiceProtos_SyncMessage) throws -> SSKProtoSyncMessage {
var sent: SSKProtoSyncMessageSent? = nil
var sent: SSKProtoSyncMessageSent?
if proto.hasSent {
sent = try SSKProtoSyncMessageSent.parseProto(proto.sent)
}
var contacts: SSKProtoSyncMessageContacts? = nil
var contacts: SSKProtoSyncMessageContacts?
if proto.hasContacts {
contacts = try SSKProtoSyncMessageContacts.parseProto(proto.contacts)
}
var groups: SSKProtoSyncMessageGroups? = nil
var groups: SSKProtoSyncMessageGroups?
if proto.hasGroups {
groups = try SSKProtoSyncMessageGroups.parseProto(proto.groups)
}
var request: SSKProtoSyncMessageRequest? = nil
var request: SSKProtoSyncMessageRequest?
if proto.hasRequest {
request = try SSKProtoSyncMessageRequest.parseProto(proto.request)
}
@ -6308,17 +6311,17 @@ extension SSKProtoSyncMessageViewOnceOpen.SSKProtoSyncMessageViewOnceOpenBuilder
var read: [SSKProtoSyncMessageRead] = []
read = try proto.read.map { try SSKProtoSyncMessageRead.parseProto($0) }
var blocked: SSKProtoSyncMessageBlocked? = nil
var blocked: SSKProtoSyncMessageBlocked?
if proto.hasBlocked {
blocked = try SSKProtoSyncMessageBlocked.parseProto(proto.blocked)
}
var verified: SSKProtoVerified? = nil
var verified: SSKProtoVerified?
if proto.hasVerified {
verified = try SSKProtoVerified.parseProto(proto.verified)
}
var configuration: SSKProtoSyncMessageConfiguration? = nil
var configuration: SSKProtoSyncMessageConfiguration?
if proto.hasConfiguration {
configuration = try SSKProtoSyncMessageConfiguration.parseProto(proto.configuration)
}
@ -6326,7 +6329,7 @@ extension SSKProtoSyncMessageViewOnceOpen.SSKProtoSyncMessageViewOnceOpenBuilder
var stickerPackOperation: [SSKProtoSyncMessageStickerPackOperation] = []
stickerPackOperation = try proto.stickerPackOperation.map { try SSKProtoSyncMessageStickerPackOperation.parseProto($0) }
var viewOnceOpen: SSKProtoSyncMessageViewOnceOpen? = nil
var viewOnceOpen: SSKProtoSyncMessageViewOnceOpen?
if proto.hasViewOnceOpen {
viewOnceOpen = try SSKProtoSyncMessageViewOnceOpen.parseProto(proto.viewOnceOpen)
}
@ -7017,7 +7020,7 @@ extension SSKProtoGroupContextMember.SSKProtoGroupContextMemberBuilder {
}
let id = proto.id
var avatar: SSKProtoAttachmentPointer? = nil
var avatar: SSKProtoAttachmentPointer?
if proto.hasAvatar {
avatar = try SSKProtoAttachmentPointer.parseProto(proto.avatar)
}
@ -7407,12 +7410,12 @@ extension SSKProtoContactDetailsAvatar.SSKProtoContactDetailsAvatarBuilder {
}
fileprivate class func parseProto(_ proto: SignalServiceProtos_ContactDetails) throws -> SSKProtoContactDetails {
var avatar: SSKProtoContactDetailsAvatar? = nil
var avatar: SSKProtoContactDetailsAvatar?
if proto.hasAvatar {
avatar = try SSKProtoContactDetailsAvatar.parseProto(proto.avatar)
}
var verified: SSKProtoVerified? = nil
var verified: SSKProtoVerified?
if proto.hasVerified {
verified = try SSKProtoVerified.parseProto(proto.verified)
}
@ -7904,7 +7907,7 @@ extension SSKProtoGroupDetailsMember.SSKProtoGroupDetailsMemberBuilder {
}
let id = proto.id
var avatar: SSKProtoGroupDetailsAvatar? = nil
var avatar: SSKProtoGroupDetailsAvatar?
if proto.hasAvatar {
avatar = try SSKProtoGroupDetailsAvatar.parseProto(proto.avatar)
}
@ -8195,7 +8198,7 @@ extension SSKProtoPackSticker.SSKProtoPackStickerBuilder {
}
fileprivate class func parseProto(_ proto: SignalServiceProtos_Pack) throws -> SSKProtoPack {
var cover: SSKProtoPackSticker? = nil
var cover: SSKProtoPackSticker?
if proto.hasCover {
cover = try SSKProtoPackSticker.parseProto(proto.cover)
}

View File

@ -9,23 +9,10 @@ public class SSKProtos: NSObject {
private override init() {}
@objc
public class var initialProtocolVersion: Int {
return SignalServiceProtos_DataMessage.ProtocolVersion.initial.rawValue
}
@objc
public class var perMessageExpirationProtocolVersion: Int {
return SignalServiceProtos_DataMessage.ProtocolVersion.messageTimers.rawValue
}
@objc
public class var viewOnceMessagesProtocolVersion: Int {
return SignalServiceProtos_DataMessage.ProtocolVersion.viewOnce.rawValue
}
@objc
public class var currentProtocolVersion: Int {
// Our proto wrappers don't handle enum aliases, so we have one non-generated
// wrapper for the "current" protocol version.
return SignalServiceProtos_DataMessage.ProtocolVersion.current.rawValue
}
}

File diff suppressed because it is too large Load Diff

View File

@ -155,7 +155,9 @@ public class SDSDatabaseStorage: SDSTransactable {
// crash if we can't read the DB.
do {
return try GRDBDatabaseStorageAdapter(baseDir: type(of: self).baseDir())
return try Bench(title: "Creating GRDB storage") {
return try GRDBDatabaseStorageAdapter(baseDir: type(of: self).baseDir())
}
} catch {
owsFail("\(error)")
}
@ -188,8 +190,10 @@ public class SDSDatabaseStorage: SDSTransactable {
}
}
let yapPrimaryStorage = OWSPrimaryStorage()
return YAPDBStorageAdapter(storage: yapPrimaryStorage)
return Bench(title: "Creating YDB storage") {
let yapPrimaryStorage = OWSPrimaryStorage()
return YAPDBStorageAdapter(storage: yapPrimaryStorage)
}
}
// MARK: -

View File

@ -179,7 +179,12 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssertDebug(self->_cachedFileUrl != nil);
}
NSURL *srcUrl = self.dataUrl;
NSURL *_Nullable srcUrl = self.dataUrl;
if (srcUrl == nil) {
*error = OWSErrorMakeAssertionError(@"Missing data URL.");
success = NO;
return;
}
self.isConsumed = YES;
success = [NSFileManager.defaultManager moveItemAtURL:srcUrl
toURL:dstUrl

View File

@ -65,7 +65,7 @@ public enum ExperienceUpgradeId: String {
@objc
public func markAsSeen(experienceUpgrade: ExperienceUpgrade, transaction: SDSAnyWriteTransaction) {
Logger.info("marking experience upgrade as seen")
experienceUpgrade.anyInsert(transaction: transaction)
experienceUpgrade.anyUpsert(transaction: transaction)
}
@objc

View File

@ -18,7 +18,7 @@ extension FeatureBuild {
}
}
let build: FeatureBuild = OWSIsDebugBuild() ? .dev : .beta
let build: FeatureBuild = OWSIsDebugBuild() ? .dev : .qa
// MARK: -
@ -90,10 +90,7 @@ public class FeatureFlags: NSObject {
@objc
public static var storageMode: StorageMode {
if CurrentAppContext().isRunningTests {
// We should be running the tests using both .ydbTests or .grdbTests.
return .grdbTests
} else if build.includes(.dev) {
return .grdbThrowawayIfMigrating
return .ydbTests
} else {
return .ydb
}

View File

@ -19,7 +19,7 @@
<key>CFBundleShortVersionString</key>
<string>2.44.0</string>
<key>CFBundleVersion</key>
<string>2.44.0.0</string>
<string>2.44.0.5</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>NSAppTransportSecurity</key>