Fix loader

pull/288/head
nielsandriesse 5 years ago
parent ed783e66d4
commit 048f053cec

@ -1,21 +1,22 @@
import Accelerate import Accelerate
@objc(LKVoiceMessageViewDelegate)
protocol VoiceMessageViewDelegate {
func showLoader()
func hideLoader()
}
@objc(LKVoiceMessageView) @objc(LKVoiceMessageView)
final class VoiceMessageView : UIView { final class VoiceMessageView : UIView {
private let voiceMessage: TSAttachment private let voiceMessage: TSAttachment
private let isOutgoing: Bool private let isOutgoing: Bool
private var isAnimating = false
private var volumeSamples: [Float] = [] { didSet { updateShapeLayers() } } private var volumeSamples: [Float] = [] { didSet { updateShapeLayers() } }
private var progress: CGFloat = 0 private var progress: CGFloat = 0
@objc var delegate: VoiceMessageViewDelegate?
@objc var duration: Int = 0 { didSet { updateDurationLabel() } } @objc var duration: Int = 0 { didSet { updateDurationLabel() } }
// MARK: Components // MARK: Components
private lazy var loader: UIView = {
let result = UIView()
result.backgroundColor = Colors.text.withAlphaComponent(0.2)
return result
}()
private lazy var durationLabel: UILabel = { private lazy var durationLabel: UILabel = {
let result = UILabel() let result = UILabel()
result.textColor = Colors.text result.textColor = Colors.text
@ -47,7 +48,6 @@ final class VoiceMessageView : UIView {
self.voiceMessage = voiceMessage self.voiceMessage = voiceMessage
self.isOutgoing = isOutgoing self.isOutgoing = isOutgoing
super.init(frame: CGRect.zero) super.init(frame: CGRect.zero)
initialize()
} }
override init(frame: CGRect) { override init(frame: CGRect) {
@ -58,17 +58,16 @@ final class VoiceMessageView : UIView {
preconditionFailure("Use init(voiceMessage:associatedWith:) instead.") preconditionFailure("Use init(voiceMessage:associatedWith:) instead.")
} }
private func initialize() { @objc func initialize() {
setUpViewHierarchy() setUpViewHierarchy()
if voiceMessage.isDownloaded { if voiceMessage.isDownloaded {
loader.alpha = 0
guard let url = (voiceMessage as? TSAttachmentStream)?.originalMediaURL else { guard let url = (voiceMessage as? TSAttachmentStream)?.originalMediaURL else {
return print("[Loki] Couldn't get URL for voice message.") return print("[Loki] Couldn't get URL for voice message.")
} }
let targetSampleCount = 48 let targetSampleCount = 48
if let cachedVolumeSamples = Storage.getVolumeSamples(for: voiceMessage.uniqueId!), cachedVolumeSamples.count == targetSampleCount { if let cachedVolumeSamples = Storage.getVolumeSamples(for: voiceMessage.uniqueId!), cachedVolumeSamples.count == targetSampleCount {
self.volumeSamples = cachedVolumeSamples self.volumeSamples = cachedVolumeSamples
self.stopAnimating() self.delegate?.hideLoader()
} else { } else {
let voiceMessageID = voiceMessage.uniqueId! let voiceMessageID = voiceMessage.uniqueId!
AudioUtilities.getVolumeSamples(for: url, targetSampleCount: targetSampleCount).done(on: DispatchQueue.main) { [weak self] volumeSamples in AudioUtilities.getVolumeSamples(for: url, targetSampleCount: targetSampleCount).done(on: DispatchQueue.main) { [weak self] volumeSamples in
@ -78,22 +77,20 @@ final class VoiceMessageView : UIView {
Storage.setVolumeSamples(for: voiceMessageID, to: volumeSamples, using: transaction) Storage.setVolumeSamples(for: voiceMessageID, to: volumeSamples, using: transaction)
} }
self.durationLabel.alpha = 1 self.durationLabel.alpha = 1
self.stopAnimating() self.delegate?.hideLoader()
}.catch(on: DispatchQueue.main) { error in }.catch(on: DispatchQueue.main) { error in
print("[Loki] Couldn't sample audio file due to error: \(error).") print("[Loki] Couldn't sample audio file due to error: \(error).")
} }
} }
} else { } else {
durationLabel.alpha = 0 durationLabel.alpha = 0
showLoader() delegate?.showLoader()
} }
} }
private func setUpViewHierarchy() { private func setUpViewHierarchy() {
set(.width, to: 200) set(.width, to: 200)
set(.height, to: VoiceMessageView.contentHeight) set(.height, to: VoiceMessageView.contentHeight)
addSubview(loader)
loader.pin(to: self)
layer.insertSublayer(backgroundShapeLayer, at: 0) layer.insertSublayer(backgroundShapeLayer, at: 0)
layer.insertSublayer(foregroundShapeLayer, at: 1) layer.insertSublayer(foregroundShapeLayer, at: 1)
addSubview(durationLabel) addSubview(durationLabel)
@ -102,27 +99,6 @@ final class VoiceMessageView : UIView {
} }
// MARK: UI & Updating // MARK: UI & Updating
private func showLoader() {
isAnimating = true
loader.alpha = 1
animateLoader()
}
private func animateLoader() {
loader.frame = CGRect(x: 0, y: 0, width: 0, height: VoiceMessageView.contentHeight)
UIView.animate(withDuration: 2) { [weak self] in
self?.loader.frame = CGRect(x: 0, y: 0, width: 200, height: VoiceMessageView.contentHeight)
} completion: { [weak self] _ in
guard let self = self else { return }
if self.isAnimating { self.animateLoader() }
}
}
private func stopAnimating() {
isAnimating = false
loader.alpha = 0
}
override func layoutSubviews() { override func layoutSubviews() {
super.layoutSubviews() super.layoutSubviews()
updateShapeLayers() updateShapeLayers()

@ -20,7 +20,7 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@interface OWSMessageBubbleView () <OWSQuotedMessageViewDelegate, OWSContactShareButtonsViewDelegate> @interface OWSMessageBubbleView () <OWSQuotedMessageViewDelegate, OWSContactShareButtonsViewDelegate, LKVoiceMessageViewDelegate>
@property (nonatomic) OWSBubbleView *bubbleView; @property (nonatomic) OWSBubbleView *bubbleView;
@ -50,6 +50,10 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, nullable) OWSContactShareButtonsView *contactShareButtonsView; @property (nonatomic, nullable) OWSContactShareButtonsView *contactShareButtonsView;
@property (nonatomic) UIView *loader;
@property (nonatomic) BOOL isAnimating;
@end @end
#pragma mark - #pragma mark -
@ -108,6 +112,10 @@ NS_ASSUME_NONNULL_BEGIN
self.linkPreviewView = [[LinkPreviewView alloc] initWithDraftDelegate:nil]; self.linkPreviewView = [[LinkPreviewView alloc] initWithDraftDelegate:nil];
self.footerView = [OWSMessageFooterView new]; self.footerView = [OWSMessageFooterView new];
self.loader = [UIView new];
self.loader.backgroundColor = [LKColors.text colorWithAlphaComponent:0.6f];
self.loader.alpha = 0.0f;
} }
- (OWSMessageTextView *)newTextView - (OWSMessageTextView *)newTextView
@ -414,6 +422,9 @@ NS_ASSUME_NONNULL_BEGIN
addObject:[bodyMediaView autoSetDimension:ALDimensionHeight toSize:bodyMediaSize.CGSizeValue.height]]; addObject:[bodyMediaView autoSetDimension:ALDimensionHeight toSize:bodyMediaSize.CGSizeValue.height]];
} }
[self.bubbleView addSubview:self.loader];
[self.loader autoPinEdgesToSuperviewEdges];
[self insertContactShareButtonsIfNecessary]; [self insertContactShareButtonsIfNecessary];
[self updateBubbleColor]; [self updateBubbleColor];
@ -661,6 +672,34 @@ NS_ASSUME_NONNULL_BEGIN
} }
} }
- (void)showLoader
{
self.isAnimating = YES;
self.loader.alpha = 1.0f;
[self animateLoader];
}
- (void)animateLoader
{
__weak OWSMessageBubbleView *weakSelf = self;
self.loader.frame = CGRectMake(0.0f, 0.0f, 0.0f, self.frame.size.height);
[UIView animateWithDuration:2 animations:^{
if (weakSelf != nil) {
weakSelf.loader.frame = CGRectMake(0.0f, 0.0f, weakSelf.frame.size.width, weakSelf.frame.size.height);
}
} completion:^(BOOL isFinished) {
if (weakSelf != nil && weakSelf.isAnimating) {
[weakSelf animateLoader];
}
}];
}
- (void)hideLoader
{
self.isAnimating = NO;
self.loader.alpha = 0.0f;
}
#pragma mark - Subviews #pragma mark - Subviews
- (void)configureBodyTextView - (void)configureBodyTextView
@ -842,6 +881,8 @@ NS_ASSUME_NONNULL_BEGIN
LKVoiceMessageView *voiceMessageView = [[LKVoiceMessageView alloc] initWithVoiceMessage:attachment isOutgoing:self.isOutgoing]; LKVoiceMessageView *voiceMessageView = [[LKVoiceMessageView alloc] initWithVoiceMessage:attachment isOutgoing:self.isOutgoing];
[voiceMessageView setDuration:(int)self.viewItem.audioDurationSeconds]; [voiceMessageView setDuration:(int)self.viewItem.audioDurationSeconds];
[voiceMessageView updateForProgress:self.viewItem.audioProgressSeconds / self.viewItem.audioDurationSeconds]; [voiceMessageView updateForProgress:self.viewItem.audioProgressSeconds / self.viewItem.audioDurationSeconds];
[voiceMessageView setDelegate:self];
[voiceMessageView initialize];
self.viewItem.lastAudioMessageView = voiceMessageView; self.viewItem.lastAudioMessageView = voiceMessageView;

Loading…
Cancel
Save