137 lines
3.8 KiB
Swift
137 lines
3.8 KiB
Swift
//
|
|
// Copyright 2024 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
import SignalServiceKit
|
|
import SignalUI
|
|
|
|
class FlipCameraTooltipManager {
|
|
private let db: any DB
|
|
|
|
init(db: any DB) {
|
|
self.db = db
|
|
}
|
|
|
|
private static let keyValueStore = KeyValueStore(collection: "FlipCameraButton")
|
|
private static let tooltipWasSeenKey = "tooltipWasSeen"
|
|
|
|
private var flipCameraTooltip: FlipCameraTooltipView?
|
|
|
|
private func markTooltipAsRead() {
|
|
db.write { tx in
|
|
Self.keyValueStore.setBool(true, key: Self.tooltipWasSeenKey, transaction: tx)
|
|
}
|
|
}
|
|
|
|
private func isTooltipRead() -> Bool {
|
|
return db.read { tx in
|
|
Self.keyValueStore.getBool(Self.tooltipWasSeenKey, defaultValue: false, transaction: tx)
|
|
}
|
|
}
|
|
|
|
func presentTooltipIfNecessary(
|
|
fromView: UIView,
|
|
widthReferenceView: UIView,
|
|
tailReferenceView: UIView,
|
|
tailDirection: TooltipView.TailDirection,
|
|
isVideoMuted: Bool
|
|
) {
|
|
guard !isTooltipRead() else {
|
|
// Tooltip already seen once. Don't show again.
|
|
return
|
|
}
|
|
guard !isVideoMuted, self.flipCameraTooltip == nil else {
|
|
return
|
|
}
|
|
self.flipCameraTooltip = FlipCameraTooltipView.present(
|
|
fromView: fromView,
|
|
widthReferenceView: widthReferenceView,
|
|
tailReferenceView: tailReferenceView,
|
|
tailDirection: tailDirection
|
|
) { [weak self] in
|
|
self?.dismissTooltip()
|
|
}
|
|
self.markTooltipAsRead()
|
|
}
|
|
|
|
func dismissTooltip() {
|
|
self.flipCameraTooltip?.removeFromSuperview()
|
|
self.flipCameraTooltip = nil
|
|
}
|
|
|
|
// MARK: - DebugUI
|
|
|
|
#if USE_DEBUG_UI
|
|
func markTooltipAsUnread() {
|
|
db.write { tx in
|
|
Self.keyValueStore.setBool(false, key: Self.tooltipWasSeenKey, transaction: tx)
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
class FlipCameraTooltipView: TooltipView {
|
|
private var _tailDir: TailDirection
|
|
|
|
public class func present(
|
|
fromView: UIView,
|
|
widthReferenceView: UIView,
|
|
tailReferenceView: UIView,
|
|
tailDirection: TailDirection,
|
|
wasTappedBlock: (() -> Void)?
|
|
) -> FlipCameraTooltipView {
|
|
FlipCameraTooltipView(
|
|
fromView: fromView,
|
|
widthReferenceView: widthReferenceView,
|
|
tailReferenceView: tailReferenceView,
|
|
tailDirection: tailDirection,
|
|
wasTappedBlock: wasTappedBlock
|
|
)
|
|
}
|
|
|
|
init(
|
|
fromView: UIView,
|
|
widthReferenceView: UIView,
|
|
tailReferenceView: UIView,
|
|
tailDirection: TailDirection,
|
|
wasTappedBlock: (() -> Void)?
|
|
) {
|
|
self._tailDir = tailDirection
|
|
super.init(
|
|
fromView: fromView,
|
|
widthReferenceView: widthReferenceView,
|
|
tailReferenceView: tailReferenceView,
|
|
wasTappedBlock: wasTappedBlock
|
|
)
|
|
}
|
|
|
|
required init?(coder aDecoder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
public override func bubbleContentView() -> UIView {
|
|
let label = UILabel()
|
|
label.text = OWSLocalizedString(
|
|
"FLIP_CAMERA_BUTTON_MOVED_TO_PIP_TOOLTIP",
|
|
comment: "Tooltip notifying users that the flip camera button moved to the picture-in-picture view of themselves in a call"
|
|
)
|
|
label.font = .dynamicTypeSubheadline
|
|
label.textColor = .ows_white
|
|
label.numberOfLines = 0
|
|
label.lineBreakMode = .byWordWrapping
|
|
return horizontalStack(forSubviews: [label])
|
|
}
|
|
|
|
override var tailDirection: TooltipView.TailDirection {
|
|
self._tailDir
|
|
}
|
|
|
|
override var bubbleColor: UIColor {
|
|
.ows_accentBlue
|
|
}
|
|
|
|
override var tailReferenceViewUsesAutolayout: Bool {
|
|
false
|
|
}
|
|
}
|