Merge branch 'mkirk/media-gallery-call-banner'

pull/1/head
Michael Kirk 7 years ago
commit 2a7ee15ead

@ -2051,12 +2051,12 @@ typedef enum : NSUInteger {
} }
TSMessage *mediaMessage = (TSMessage *)viewItem.interaction; TSMessage *mediaMessage = (TSMessage *)viewItem.interaction;
MediaGalleryViewController *vc = [[MediaGalleryViewController alloc] MediaGallery *mediaGallery =
initWithThread:self.thread [[MediaGallery alloc] initWithThread:self.thread
uiDatabaseConnection:self.uiDatabaseConnection uiDatabaseConnection:self.uiDatabaseConnection
options:MediaGalleryOptionSliderEnabled | MediaGalleryOptionShowAllMediaButton]; options:MediaGalleryOptionSliderEnabled | MediaGalleryOptionShowAllMediaButton];
[vc presentDetailViewFromViewController:self mediaMessage:mediaMessage replacingView:imageView]; [mediaGallery presentDetailViewFromViewController:self mediaMessage:mediaMessage replacingView:imageView];
} }
- (void)didTapVideoViewItem:(id<ConversationViewItem>)viewItem - (void)didTapVideoViewItem:(id<ConversationViewItem>)viewItem
@ -2080,12 +2080,12 @@ typedef enum : NSUInteger {
} }
TSMessage *mediaMessage = (TSMessage *)viewItem.interaction; TSMessage *mediaMessage = (TSMessage *)viewItem.interaction;
MediaGalleryViewController *vc = [[MediaGalleryViewController alloc] MediaGallery *mediaGallery =
initWithThread:self.thread [[MediaGallery alloc] initWithThread:self.thread
uiDatabaseConnection:self.uiDatabaseConnection uiDatabaseConnection:self.uiDatabaseConnection
options:MediaGalleryOptionSliderEnabled | MediaGalleryOptionShowAllMediaButton]; options:MediaGalleryOptionSliderEnabled | MediaGalleryOptionShowAllMediaButton];
[vc presentDetailViewFromViewController:self mediaMessage:mediaMessage replacingView:imageView]; [mediaGallery presentDetailViewFromViewController:self mediaMessage:mediaMessage replacingView:imageView];
} }
- (void)didTapAudioViewItem:(id<ConversationViewItem>)viewItem attachmentStream:(TSAttachmentStream *)attachmentStream - (void)didTapAudioViewItem:(id<ConversationViewItem>)viewItem attachmentStream:(TSAttachmentStream *)attachmentStream

@ -168,42 +168,7 @@ protocol MediaGalleryDataSourceDelegate: class {
func mediaGalleryDataSource(_ mediaGalleryDataSource: MediaGalleryDataSource, deletedSections: IndexSet, deletedItems: [IndexPath]) func mediaGalleryDataSource(_ mediaGalleryDataSource: MediaGalleryDataSource, deletedSections: IndexSet, deletedItems: [IndexPath])
} }
class MediaGalleryViewController: OWSNavigationController, MediaGalleryDataSource, MediaTileViewControllerDelegate { class MediaGalleryNavigationController: OWSNavigationController {
private var pageViewController: MediaPageViewController?
private let uiDatabaseConnection: YapDatabaseConnection
private let editingDatabaseConnection: YapDatabaseConnection
private let mediaGalleryFinder: OWSMediaGalleryFinder
private var initialDetailItem: MediaGalleryItem?
private let thread: TSThread
private let options: MediaGalleryOption
// we start with a small range size for quick loading.
private let fetchRangeSize: UInt = 10
deinit {
Logger.debug("deinit")
}
@objc
init(thread: TSThread, uiDatabaseConnection: YapDatabaseConnection, options: MediaGalleryOption = []) {
self.thread = thread
assert(uiDatabaseConnection.isInLongLivedReadTransaction())
self.uiDatabaseConnection = uiDatabaseConnection
self.editingDatabaseConnection = OWSPrimaryStorage.shared().newDatabaseConnection()
self.options = options
self.mediaGalleryFinder = OWSMediaGalleryFinder(thread: thread)
super.init(nibName: nil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
notImplemented()
}
// MARK: View LifeCycle // MARK: View LifeCycle
@ -213,6 +178,9 @@ class MediaGalleryViewController: OWSNavigationController, MediaGalleryDataSourc
UIViewController.attemptRotationToDeviceOrientation() UIViewController.attemptRotationToDeviceOrientation()
} }
var presentationView: UIImageView!
var retainUntilDismissed: MediaGallery?
// HACK: Though we don't have an input accessory view, the VC we are presented above (ConversationVC) does. // HACK: Though we don't have an input accessory view, the VC we are presented above (ConversationVC) does.
// If the app is backgrounded and then foregrounded, when OWSWindowManager calls mainWindow.makeKeyAndVisible // If the app is backgrounded and then foregrounded, when OWSWindowManager calls mainWindow.makeKeyAndVisible
// the ConversationVC's inputAccessoryView will appear *above* us unless we'd previously become first responder. // the ConversationVC's inputAccessoryView will appear *above* us unless we'd previously become first responder.
@ -254,6 +222,52 @@ class MediaGalleryViewController: OWSNavigationController, MediaGalleryDataSourc
presentationView.contentMode = .scaleAspectFit presentationView.contentMode = .scaleAspectFit
} }
// MARK: Orientation
public override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .allButUpsideDown
}
}
@objc
class MediaGallery: NSObject, MediaGalleryDataSource, MediaTileViewControllerDelegate {
@objc
weak public var navigationController: MediaGalleryNavigationController!
private var pageViewController: MediaPageViewController?
private let uiDatabaseConnection: YapDatabaseConnection
private let editingDatabaseConnection: YapDatabaseConnection
private let mediaGalleryFinder: OWSMediaGalleryFinder
private var initialDetailItem: MediaGalleryItem?
private let thread: TSThread
private let options: MediaGalleryOption
// we start with a small range size for quick loading.
private let fetchRangeSize: UInt = 10
deinit {
Logger.debug("")
}
@objc
init(thread: TSThread, uiDatabaseConnection: YapDatabaseConnection, options: MediaGalleryOption = []) {
self.thread = thread
assert(uiDatabaseConnection.isInLongLivedReadTransaction())
self.uiDatabaseConnection = uiDatabaseConnection
self.editingDatabaseConnection = OWSPrimaryStorage.shared().newDatabaseConnection()
self.options = options
self.mediaGalleryFinder = OWSMediaGalleryFinder(thread: thread)
let navController = MediaGalleryNavigationController()
self.navigationController = navController
super.init()
navController.retainUntilDismissed = self
}
// MARK: Present/Dismiss // MARK: Present/Dismiss
private var currentItem: MediaGalleryItem { private var currentItem: MediaGalleryItem {
@ -261,7 +275,6 @@ class MediaGalleryViewController: OWSNavigationController, MediaGalleryDataSourc
} }
private var replacingView: UIView? private var replacingView: UIView?
private var presentationView: UIImageView!
private var presentationViewConstraints: [NSLayoutConstraint] = [] private var presentationViewConstraints: [NSLayoutConstraint] = []
// TODO rename to replacingOriginRect // TODO rename to replacingOriginRect
@ -292,7 +305,7 @@ class MediaGalleryViewController: OWSNavigationController, MediaGalleryDataSourc
self.addDataSourceDelegate(pageViewController) self.addDataSourceDelegate(pageViewController)
self.pageViewController = pageViewController self.pageViewController = pageViewController
self.setViewControllers([pageViewController], animated: false) navigationController.setViewControllers([pageViewController], animated: false)
self.replacingView = replacingView self.replacingView = replacingView
@ -300,13 +313,13 @@ class MediaGalleryViewController: OWSNavigationController, MediaGalleryDataSourc
self.originRect = convertedRect self.originRect = convertedRect
// loadView hasn't necessarily been called yet. // loadView hasn't necessarily been called yet.
self.loadViewIfNeeded() navigationController.loadViewIfNeeded()
self.presentationView.image = initialDetailItem.attachmentStream.thumbnailImageLarge(success: { [weak self] (image) in navigationController.presentationView.image = initialDetailItem.attachmentStream.thumbnailImageLarge(success: { [weak self] (image) in
guard let strongSelf = self else { guard let strongSelf = self else {
return return
} }
strongSelf.presentationView.image = image strongSelf.navigationController.presentationView.image = image
}, failure: { }, failure: {
Logger.warn("Could not load presentation image.") Logger.warn("Could not load presentation image.")
}) })
@ -314,8 +327,8 @@ class MediaGalleryViewController: OWSNavigationController, MediaGalleryDataSourc
self.applyInitialMediaViewConstraints() self.applyInitialMediaViewConstraints()
// Restore presentationView.alpha in case a previous dismiss left us in a bad state. // Restore presentationView.alpha in case a previous dismiss left us in a bad state.
self.setNavigationBarHidden(false, animated: false) navigationController.setNavigationBarHidden(false, animated: false)
self.presentationView.alpha = 1 navigationController.presentationView.alpha = 1
// We want to animate the tapped media from it's position in the previous VC // We want to animate the tapped media from it's position in the previous VC
// to it's resting place in the center of this view controller. // to it's resting place in the center of this view controller.
@ -328,7 +341,7 @@ class MediaGalleryViewController: OWSNavigationController, MediaGalleryDataSourc
// 2. For Video views, the AVPlayerLayer content does not scale with the presentation animation. So you instead get a full scale // 2. For Video views, the AVPlayerLayer content does not scale with the presentation animation. So you instead get a full scale
// video, wherein only the cropping is animated. // video, wherein only the cropping is animated.
// Using a simple image view allows us to address both these problems relatively easily. // Using a simple image view allows us to address both these problems relatively easily.
self.view.alpha = 0.0 navigationController.view.alpha = 0.0
guard let detailView = pageViewController.view else { guard let detailView = pageViewController.view else {
owsFailDebug("detailView was unexpectedly nil") owsFailDebug("detailView was unexpectedly nil")
@ -337,23 +350,23 @@ class MediaGalleryViewController: OWSNavigationController, MediaGalleryDataSourc
// At this point our media view should be overlayed perfectly // At this point our media view should be overlayed perfectly
// by our presentationView. Swapping them out should be imperceptible. // by our presentationView. Swapping them out should be imperceptible.
self.presentationView.isHidden = false navigationController.presentationView.isHidden = false
// We don't hide the pageViewController entirely - e.g. we want the toolbars to fade in. // We don't hide the pageViewController entirely - e.g. we want the toolbars to fade in.
pageViewController.currentViewController.view.isHidden = true pageViewController.currentViewController.view.isHidden = true
detailView.backgroundColor = .clear detailView.backgroundColor = .clear
self.view.backgroundColor = .clear navigationController.view.backgroundColor = .clear
self.presentationView.layer.cornerRadius = kOWSMessageCellCornerRadius_Small navigationController.presentationView.layer.cornerRadius = kOWSMessageCellCornerRadius_Small
fromViewController.present(self, animated: false) { fromViewController.present(navigationController, animated: false) {
// 1. Fade in the entire view. // 1. Fade in the entire view.
UIView.animate(withDuration: 0.1) { UIView.animate(withDuration: 0.1) {
self.replacingView?.alpha = 0.0 self.replacingView?.alpha = 0.0
self.view.alpha = 1.0 self.navigationController.view.alpha = 1.0
} }
self.presentationView.superview?.layoutIfNeeded() self.navigationController.presentationView.superview?.layoutIfNeeded()
self.applyFinalMediaViewConstraints() self.applyFinalMediaViewConstraints()
// 2. Animate imageView from it's initial position, which should match where it was // 2. Animate imageView from it's initial position, which should match where it was
@ -364,20 +377,20 @@ class MediaGalleryViewController: OWSNavigationController, MediaGalleryDataSourc
options: .curveEaseOut, options: .curveEaseOut,
animations: { animations: {
self.presentationView.layer.cornerRadius = 0 self.navigationController.presentationView.layer.cornerRadius = 0
self.presentationView.superview?.layoutIfNeeded() self.navigationController.presentationView.superview?.layoutIfNeeded()
// fade out content behind the pageViewController // fade out content behind the pageViewController
// and behind the presentation view // and behind the presentation view
self.view.backgroundColor = Theme.backgroundColor self.navigationController.view.backgroundColor = Theme.backgroundColor
}, },
completion: { (_: Bool) in completion: { (_: Bool) in
// At this point our presentation view should be overlayed perfectly // At this point our presentation view should be overlayed perfectly
// with our media view. Swapping them out should be imperceptible. // with our media view. Swapping them out should be imperceptible.
pageViewController.currentViewController.view.isHidden = false pageViewController.currentViewController.view.isHidden = false
self.presentationView.isHidden = true self.navigationController.presentationView.isHidden = true
self.view.isUserInteractionEnabled = true self.navigationController.view.isUserInteractionEnabled = true
pageViewController.wasPresented() pageViewController.wasPresented()
@ -388,7 +401,7 @@ class MediaGalleryViewController: OWSNavigationController, MediaGalleryDataSourc
// //
// We don't need to do this when pushing VCs onto the SignalsNavigationController - only when // We don't need to do this when pushing VCs onto the SignalsNavigationController - only when
// presenting directly from ConversationVC. // presenting directly from ConversationVC.
_ = self.becomeFirstResponder() _ = self.navigationController.becomeFirstResponder()
}) })
} }
} }
@ -424,7 +437,7 @@ class MediaGalleryViewController: OWSNavigationController, MediaGalleryDataSourc
} else { } else {
// If from conversation view // If from conversation view
mediaTileViewController.focusedItem = focusedItem mediaTileViewController.focusedItem = focusedItem
self.pushViewController(mediaTileViewController, animated: true) navigationController.pushViewController(mediaTileViewController, animated: true)
} }
} }
@ -457,7 +470,7 @@ class MediaGalleryViewController: OWSNavigationController, MediaGalleryDataSourc
guard let pageViewController = self.pageViewController else { guard let pageViewController = self.pageViewController else {
owsFailDebug("pageViewController was unexpectedly nil") owsFailDebug("pageViewController was unexpectedly nil")
self.dismiss(animated: true) self.navigationController.dismiss(animated: true)
return return
} }
@ -466,32 +479,32 @@ class MediaGalleryViewController: OWSNavigationController, MediaGalleryDataSourc
pageViewController.willBePresentedAgain() pageViewController.willBePresentedAgain()
// TODO fancy zoom animation // TODO fancy zoom animation
self.popViewController(animated: true) self.navigationController.popViewController(animated: true)
} }
} }
public func dismissMediaDetailViewController(_ mediaPageViewController: MediaPageViewController, animated isAnimated: Bool, completion: (() -> Void)?) { public func dismissMediaDetailViewController(_ mediaPageViewController: MediaPageViewController, animated isAnimated: Bool, completion: (() -> Void)?) {
self.view.isUserInteractionEnabled = false navigationController.view.isUserInteractionEnabled = false
UIApplication.shared.isStatusBarHidden = false UIApplication.shared.isStatusBarHidden = false
guard let detailView = mediaPageViewController.view else { guard let detailView = mediaPageViewController.view else {
owsFailDebug("detailView was unexpectedly nil") owsFailDebug("detailView was unexpectedly nil")
self.presentingViewController?.dismiss(animated: false, completion: completion) self.navigationController.presentingViewController?.dismiss(animated: false, completion: completion)
return return
} }
mediaPageViewController.currentViewController.view.isHidden = true mediaPageViewController.currentViewController.view.isHidden = true
self.presentationView.isHidden = false navigationController.presentationView.isHidden = false
// Move the presentationView back to it's initial position, i.e. where // Move the presentationView back to it's initial position, i.e. where
// it sits on the screen in the conversation view. // it sits on the screen in the conversation view.
let changedItems = currentItem != self.initialDetailItem let changedItems = currentItem != self.initialDetailItem
if changedItems { if changedItems {
self.presentationView.image = currentItem.attachmentStream.thumbnailImageLarge(success: { [weak self] (image) in navigationController.presentationView.image = currentItem.attachmentStream.thumbnailImageLarge(success: { [weak self] (image) in
guard let strongSelf = self else { guard let strongSelf = self else {
return return
} }
strongSelf.presentationView.image = image strongSelf.navigationController.presentationView.image = image
}, failure: { }, failure: {
Logger.warn("Could not load presentation image.") Logger.warn("Could not load presentation image.")
}) })
@ -506,14 +519,14 @@ class MediaGalleryViewController: OWSNavigationController, MediaGalleryDataSourc
options: .curveEaseOut, options: .curveEaseOut,
animations: { animations: {
// Move back over it's original location // Move back over it's original location
self.presentationView.superview?.layoutIfNeeded() self.navigationController.presentationView.superview?.layoutIfNeeded()
detailView.alpha = 0 detailView.alpha = 0
if changedItems { if changedItems {
self.presentationView.alpha = 0 self.navigationController.presentationView.alpha = 0
} else { } else {
self.presentationView.layer.cornerRadius = kOWSMessageCellCornerRadius_Small self.navigationController.presentationView.layer.cornerRadius = kOWSMessageCellCornerRadius_Small
} }
}, },
completion: { (_: Bool) in completion: { (_: Bool) in
@ -530,24 +543,24 @@ class MediaGalleryViewController: OWSNavigationController, MediaGalleryDataSourc
animations: { animations: {
guard let replacingView = self.replacingView else { guard let replacingView = self.replacingView else {
owsFailDebug("replacingView was unexpectedly nil") owsFailDebug("replacingView was unexpectedly nil")
self.presentingViewController?.dismiss(animated: false, completion: completion) self.navigationController.presentingViewController?.dismiss(animated: false, completion: completion)
return return
} }
// fade out content and toolbars // fade out content and toolbars
self.view.alpha = 0.0 self.navigationController.view.alpha = 0.0
replacingView.alpha = 1.0 replacingView.alpha = 1.0
}, },
completion: { (_: Bool) in completion: { (_: Bool) in
self.presentingViewController?.dismiss(animated: false, completion: completion) self.navigationController.presentingViewController?.dismiss(animated: false, completion: completion)
}) })
} else { } else {
guard let replacingView = self.replacingView else { guard let replacingView = self.replacingView else {
owsFailDebug("replacingView was unexpectedly nil") owsFailDebug("replacingView was unexpectedly nil")
self.presentingViewController?.dismiss(animated: false, completion: completion) navigationController.presentingViewController?.dismiss(animated: false, completion: completion)
return return
} }
replacingView.alpha = 1.0 replacingView.alpha = 1.0
self.presentingViewController?.dismiss(animated: false, completion: completion) navigationController.presentingViewController?.dismiss(animated: false, completion: completion)
} }
} }
@ -562,17 +575,17 @@ class MediaGalleryViewController: OWSNavigationController, MediaGalleryDataSourc
return return
} }
guard let presentationSuperview = self.presentationView.superview else { guard let presentationSuperview = navigationController.presentationView.superview else {
owsFailDebug("presentationView.superview was unexpectedly nil") owsFailDebug("presentationView.superview was unexpectedly nil")
return return
} }
let convertedRect: CGRect = presentationSuperview.convert(originRect, from: UIApplication.shared.keyWindow) let convertedRect: CGRect = presentationSuperview.convert(originRect, from: UIApplication.shared.keyWindow)
self.presentationViewConstraints += self.presentationView.autoSetDimensions(to: convertedRect.size) self.presentationViewConstraints += navigationController.presentationView.autoSetDimensions(to: convertedRect.size)
self.presentationViewConstraints += [ self.presentationViewConstraints += [
self.presentationView.autoPinEdge(toSuperviewEdge: .top, withInset: convertedRect.origin.y), navigationController.presentationView.autoPinEdge(toSuperviewEdge: .top, withInset: convertedRect.origin.y),
self.presentationView.autoPinEdge(toSuperviewEdge: .left, withInset: convertedRect.origin.x) navigationController.presentationView.autoPinEdge(toSuperviewEdge: .left, withInset: convertedRect.origin.x)
] ]
} }
@ -583,10 +596,10 @@ class MediaGalleryViewController: OWSNavigationController, MediaGalleryDataSourc
} }
self.presentationViewConstraints = [ self.presentationViewConstraints = [
self.presentationView.autoPinEdge(toSuperviewEdge: .leading), navigationController.presentationView.autoPinEdge(toSuperviewEdge: .leading),
self.presentationView.autoPinEdge(toSuperviewEdge: .top), navigationController.presentationView.autoPinEdge(toSuperviewEdge: .top),
self.presentationView.autoPinEdge(toSuperviewEdge: .trailing), navigationController.presentationView.autoPinEdge(toSuperviewEdge: .trailing),
self.presentationView.autoPinEdge(toSuperviewEdge: .bottom) navigationController.presentationView.autoPinEdge(toSuperviewEdge: .bottom)
] ]
} }
@ -597,9 +610,9 @@ class MediaGalleryViewController: OWSNavigationController, MediaGalleryDataSourc
} }
self.presentationViewConstraints += [ self.presentationViewConstraints += [
self.presentationView.autoPinEdge(toSuperviewEdge: .leading), navigationController.presentationView.autoPinEdge(toSuperviewEdge: .leading),
self.presentationView.autoPinEdge(toSuperviewEdge: .trailing), navigationController.presentationView.autoPinEdge(toSuperviewEdge: .trailing),
self.presentationView.autoPinEdge(.top, to: .bottom, of: self.view) navigationController.presentationView.autoPinEdge(.top, to: .bottom, of: self.navigationController.view)
] ]
} }
@ -916,10 +929,4 @@ class MediaGalleryViewController: OWSNavigationController, MediaGalleryDataSourc
} }
return Int(count) - deletedMessages.count return Int(count) - deletedMessages.count
} }
// MARK: Orientation
public override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .allButUpsideDown
}
} }

@ -615,17 +615,17 @@ class MessageDetailViewController: OWSViewController, MediaGalleryDataSourceDele
// MARK: OWSMessageBubbleViewDelegate // MARK: OWSMessageBubbleViewDelegate
func didTapImageViewItem(_ viewItem: ConversationViewItem, attachmentStream: TSAttachmentStream, imageView: UIView) { func didTapImageViewItem(_ viewItem: ConversationViewItem, attachmentStream: TSAttachmentStream, imageView: UIView) {
let mediaGalleryViewController = MediaGalleryViewController(thread: self.thread, uiDatabaseConnection: self.uiDatabaseConnection) let mediaGallery = MediaGallery(thread: self.thread, uiDatabaseConnection: self.uiDatabaseConnection)
mediaGalleryViewController.addDataSourceDelegate(self) mediaGallery.addDataSourceDelegate(self)
mediaGalleryViewController.presentDetailView(fromViewController: self, mediaMessage: self.message, replacingView: imageView) mediaGallery.presentDetailView(fromViewController: self, mediaMessage: self.message, replacingView: imageView)
} }
func didTapVideoViewItem(_ viewItem: ConversationViewItem, attachmentStream: TSAttachmentStream, imageView: UIView) { func didTapVideoViewItem(_ viewItem: ConversationViewItem, attachmentStream: TSAttachmentStream, imageView: UIView) {
let mediaGalleryViewController = MediaGalleryViewController(thread: self.thread, uiDatabaseConnection: self.uiDatabaseConnection) let mediaGallery = MediaGallery(thread: self.thread, uiDatabaseConnection: self.uiDatabaseConnection)
mediaGalleryViewController.addDataSourceDelegate(self) mediaGallery.addDataSourceDelegate(self)
mediaGalleryViewController.presentDetailView(fromViewController: self, mediaMessage: self.message, replacingView: imageView) mediaGallery.presentDetailView(fromViewController: self, mediaMessage: self.message, replacingView: imageView)
} }
func didTapContactShare(_ viewItem: ConversationViewItem) { func didTapContactShare(_ viewItem: ConversationViewItem) {

@ -54,7 +54,7 @@ const CGFloat kIconViewLength = 24;
@property (nonatomic) NSArray<NSNumber *> *disappearingMessagesDurations; @property (nonatomic) NSArray<NSNumber *> *disappearingMessagesDurations;
@property (nonatomic) OWSDisappearingMessagesConfiguration *disappearingMessagesConfiguration; @property (nonatomic) OWSDisappearingMessagesConfiguration *disappearingMessagesConfiguration;
@property (nullable, nonatomic) MediaGalleryViewController *mediaGalleryViewController; @property (nullable, nonatomic) MediaGalleryNavigationController *mediaGalleryViewController;
@property (nonatomic, readonly) TSAccountManager *accountManager; @property (nonatomic, readonly) TSAccountManager *accountManager;
@property (nonatomic, readonly) OWSContactsManager *contactsManager; @property (nonatomic, readonly) OWSContactsManager *contactsManager;
@property (nonatomic, readonly) OWSMessageSender *messageSender; @property (nonatomic, readonly) OWSMessageSender *messageSender;
@ -1273,19 +1273,18 @@ const CGFloat kIconViewLength = 24;
- (void)showMediaGallery - (void)showMediaGallery
{ {
OWSLogDebug(@"in showMediaGallery"); OWSLogDebug(@"");
MediaGalleryViewController *vc = MediaGallery *mediaGallery = [[MediaGallery alloc] initWithThread:self.thread
[[MediaGalleryViewController alloc] initWithThread:self.thread uiDatabaseConnection:self.uiDatabaseConnection
uiDatabaseConnection:self.uiDatabaseConnection options:MediaGalleryOptionSliderEnabled];
options:MediaGalleryOptionSliderEnabled];
// although we don't present the mediaGalleryViewController directly, we need to maintain a strong // although we don't present the mediaGalleryViewController directly, we need to maintain a strong
// reference to it until we're dismissed. // reference to it until we're dismissed.
self.mediaGalleryViewController = vc; self.mediaGalleryViewController = mediaGallery.navigationController;
OWSAssertDebug([self.navigationController isKindOfClass:[OWSNavigationController class]]); OWSAssertDebug([self.navigationController isKindOfClass:[OWSNavigationController class]]);
[vc pushTileViewFromNavController:(OWSNavigationController *)self.navigationController]; [mediaGallery pushTileViewFromNavController:(OWSNavigationController *)self.navigationController];
} }
#pragma mark - Notifications #pragma mark - Notifications

@ -24,28 +24,24 @@ NS_ASSUME_NONNULL_BEGIN
@implementation OWSNavigationController @implementation OWSNavigationController
- (instancetype)initWithRootViewController:(UIViewController *)rootViewController - (instancetype)init
{ {
self = [self initWithNavigationBarClass:[OWSNavigationBar class] toolbarClass:nil]; self = [super initWithNavigationBarClass:[OWSNavigationBar class] toolbarClass:nil];
if (!self) { if (!self) {
return self; return self;
} }
[self setupNavbar];
[self pushViewController:rootViewController animated:NO]; return self;
}
if (![self.navigationBar isKindOfClass:[OWSNavigationBar class]]) { - (instancetype)initWithRootViewController:(UIViewController *)rootViewController
OWSFailDebug(@"navigationBar was unexpected class: %@", self.navigationBar); {
self = [self init];
if (!self) {
return self; return self;
} }
[self pushViewController:rootViewController animated:NO];
OWSNavigationBar *navbar = (OWSNavigationBar *)self.navigationBar;
navbar.navBarLayoutDelegate = self;
[self updateLayoutForNavbar:navbar];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(themeDidChange:)
name:ThemeDidChangeNotification
object:nil];
return self; return self;
} }
@ -55,6 +51,8 @@ NS_ASSUME_NONNULL_BEGIN
[[NSNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] removeObserver:self];
} }
#pragma mark -
- (void)themeDidChange:(NSNotification *)notification - (void)themeDidChange:(NSNotification *)notification
{ {
OWSAssertIsOnMainThread(); OWSAssertIsOnMainThread();
@ -73,6 +71,22 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - UINavigationBarDelegate #pragma mark - UINavigationBarDelegate
- (void)setupNavbar
{
if (![self.navigationBar isKindOfClass:[OWSNavigationBar class]]) {
OWSFailDebug(@"navigationBar was unexpected class: %@", self.navigationBar);
return;
}
OWSNavigationBar *navbar = (OWSNavigationBar *)self.navigationBar;
navbar.navBarLayoutDelegate = self;
[self updateLayoutForNavbar:navbar];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(themeDidChange:)
name:ThemeDidChangeNotification
object:nil];
}
// All OWSNavigationController serve as the UINavigationBarDelegate for their navbar. // All OWSNavigationController serve as the UINavigationBarDelegate for their navbar.
// We override shouldPopItem: in order to cancel some back button presses - for example, // We override shouldPopItem: in order to cancel some back button presses - for example,
// if a view has unsaved changes. // if a view has unsaved changes.

Loading…
Cancel
Save