Rework cvc wallpaper blur again.

This commit is contained in:
Matthew Chen 2021-04-28 10:51:51 -03:00
parent a61098bcda
commit 92c841caa9
19 changed files with 419 additions and 442 deletions

View File

@ -84,6 +84,7 @@
341D392925472F3B00996E7B /* CVViewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341D392825472F3B00996E7B /* CVViewState.swift */; };
341F2C0F1F2B8AE700D07D6B /* DebugUIMisc.m in Sources */ = {isa = PBXBuildFile; fileRef = 341F2C0E1F2B8AE700D07D6B /* DebugUIMisc.m */; };
3420CF6D26327B1A00E7DCB0 /* CVBackgroundContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3420CF6C26327B1A00E7DCB0 /* CVBackgroundContainer.swift */; };
3420CF6F2638A01A00E7DCB0 /* CVWallpaperBlurView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3420CF6E2638A01A00E7DCB0 /* CVWallpaperBlurView.swift */; };
3421981C21061D2E00C57195 /* ByteParserTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3421981B21061D2E00C57195 /* ByteParserTest.swift */; };
34235F3824213550008C74CB /* ConversationSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34235F3724213550008C74CB /* ConversationSettingsViewController.swift */; };
3425A5992631DC05006D5863 /* LinkPreviewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3425A5982631DC05006D5863 /* LinkPreviewState.swift */; };
@ -1096,6 +1097,7 @@
341F2C0D1F2B8AE700D07D6B /* DebugUIMisc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUIMisc.h; sourceTree = "<group>"; };
341F2C0E1F2B8AE700D07D6B /* DebugUIMisc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIMisc.m; sourceTree = "<group>"; };
3420CF6C26327B1A00E7DCB0 /* CVBackgroundContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CVBackgroundContainer.swift; sourceTree = "<group>"; };
3420CF6E2638A01A00E7DCB0 /* CVWallpaperBlurView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CVWallpaperBlurView.swift; sourceTree = "<group>"; };
3421981B21061D2E00C57195 /* ByteParserTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ByteParserTest.swift; sourceTree = "<group>"; };
34235F3724213550008C74CB /* ConversationSettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationSettingsViewController.swift; sourceTree = "<group>"; };
3425A5982631DC05006D5863 /* LinkPreviewState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LinkPreviewState.swift; sourceTree = "<group>"; };
@ -2694,6 +2696,7 @@
347C381C252CE69400F3D941 /* CVStackView.swift */,
3470C8812559B23F00F5847C /* CVUpdate.swift */,
345772B5257E4E01001D7D44 /* CVViewStateSnapshot.swift */,
3420CF6E2638A01A00E7DCB0 /* CVWallpaperBlurView.swift */,
);
path = CV;
sourceTree = "<group>";
@ -5287,6 +5290,7 @@
34330AA31E79686200DF2FB9 /* OWSProgressView.m in Sources */,
886BB3D325BA0CA400079781 /* SetWallpaperViewController.swift in Sources */,
887CD47D2473051D00FDD265 /* DeviceTransferService+Manifest.swift in Sources */,
3420CF6F2638A01A00E7DCB0 /* CVWallpaperBlurView.swift in Sources */,
88D23D2623CEC0C700B0E74B /* CallUIAdapter.swift in Sources */,
34FB6A5325D2D10400E599B1 /* PaymentsViewUtils.swift in Sources */,
E44AD4E624E98F440035D7B8 /* PhotoCaptureDismiss.swift in Sources */,

View File

@ -174,24 +174,6 @@ public class CVCell: UICollectionViewCell, CVItemCell, CVRootComponentHost {
renderItem: renderItem,
messageSwipeActionState: messageSwipeActionState)
}
public func willSnapshotForMessageActions() {
guard let rootComponent = rootComponent,
let componentView = componentView else {
owsFailDebug("Missing component.")
return
}
rootComponent.willSnapshotForMessageActions(componentView: componentView)
}
public func didSnapshotForMessageActions() {
guard let rootComponent = rootComponent,
let componentView = componentView else {
owsFailDebug("Missing component.")
return
}
rootComponent.didSnapshotForMessageActions(componentView: componentView)
}
}
// MARK: -
@ -401,12 +383,12 @@ public extension CVRootComponentHost {
componentView: componentView)
}
func buildWallpaperMask(_ wallpaperMaskBuilder: WallpaperMaskBuilder) {
func updateWallpaperBlur(delegate: CVWallpaperBlurDelegate) {
guard let rootComponent = rootComponent,
let componentView = componentView else {
owsFailDebug("Missing component.")
return
}
rootComponent.buildWallpaperMask(wallpaperMaskBuilder, componentView: componentView)
rootComponent.updateWallpaperBlur(delegate: delegate, componentView: componentView)
}
}

View File

@ -55,9 +55,6 @@ public protocol CVComponent: class {
func cellDidBecomeVisible(componentView: CVComponentView,
renderItem: CVRenderItem,
messageSwipeActionState: CVMessageSwipeActionState)
func buildWallpaperMask(_ wallpaperMaskBuilder: WallpaperMaskBuilder,
componentView: CVComponentView)
}
// MARK: -
@ -77,9 +74,8 @@ public protocol CVRootComponent: CVComponent {
var isDedicatedCell: Bool { get }
func willSnapshotForMessageActions(componentView: CVComponentView)
func didSnapshotForMessageActions(componentView: CVComponentView)
func updateWallpaperBlur(delegate: CVWallpaperBlurDelegate,
componentView: CVComponentView)
}
// MARK: -
@ -161,14 +157,6 @@ public class CVComponentBase: NSObject {
itemModel.itemViewState.isShowingSelectionUI
}
public func willSnapshotForMessageActions(componentView: CVComponentView) {
// Do nothing.
}
public func didSnapshotForMessageActions(componentView: CVComponentView) {
// Do nothing.
}
// MARK: - Root Components
public static func configureCellRootComponent(rootComponent: CVRootComponent,
@ -194,8 +182,8 @@ public class CVComponentBase: NSObject {
// MARK: -
public func buildWallpaperMask(_ wallpaperMaskBuilder: WallpaperMaskBuilder,
componentView: CVComponentView) {
public func updateWallpaperBlur(delegate: CVWallpaperBlurDelegate,
componentView: CVComponentView) {
// Do nothing.
}
}

View File

@ -41,15 +41,16 @@ public class CVComponentDateHeader: CVComponentBase, CVRootComponent {
CVComponentViewDateHeader()
}
public override func buildWallpaperMask(_ wallpaperMaskBuilder: WallpaperMaskBuilder,
componentView: CVComponentView) {
super.buildWallpaperMask(wallpaperMaskBuilder, componentView: componentView)
public override func updateWallpaperBlur(delegate: CVWallpaperBlurDelegate,
componentView: CVComponentView) {
super.updateWallpaperBlur(delegate: delegate,
componentView: componentView)
guard let componentView = componentView as? CVComponentViewDateHeader else {
owsFailDebug("Unexpected componentView.")
return
}
wallpaperMaskBuilder.append(blurView: componentView.blurView)
componentView.wallpaperBlurView?.configure(delegate: delegate)
}
public func configureForRendering(componentView: CVComponentView,
@ -87,17 +88,20 @@ public class CVComponentDateHeader: CVComponentBase, CVRootComponent {
innerStack.reset()
outerStack.reset()
titleLabel.removeFromSuperview()
componentView.blurView?.removeFromSuperview()
componentView.blurView = nil
componentView.wallpaperBlurView?.removeFromSuperview()
componentView.wallpaperBlurView = nil
if hasWallpaper {
let wallpaperBlurView = CVWallpaperBlurView()
wallpaperBlurView.layer.cornerRadius = 8
innerStack.addSubviewToFillSuperviewEdges(wallpaperBlurView)
componentView.wallpaperBlurView = wallpaperBlurView
}
innerStack.configure(config: innerStackConfig,
cellMeasurement: cellMeasurement,
measurementKey: Self.measurementKey_innerStack,
subviews: [ titleLabel ])
if hasWallpaper {
innerStack.layer.cornerRadius = 8
componentView.blurView = innerStack
}
outerStack.configure(config: outerStackConfig,
cellMeasurement: cellMeasurement,
@ -176,7 +180,7 @@ public class CVComponentDateHeader: CVComponentBase, CVRootComponent {
fileprivate let innerStack = ManualStackView(name: "dateHeader.innerStackView")
fileprivate let titleLabel = CVLabel()
fileprivate var blurView: UIView?
fileprivate var wallpaperBlurView: CVWallpaperBlurView?
fileprivate var hasWallpaper = false
fileprivate var isDarkThemeEnabled = false
@ -203,8 +207,8 @@ public class CVComponentDateHeader: CVComponentBase, CVRootComponent {
titleLabel.removeFromSuperview()
blurView?.removeFromSuperview()
blurView = nil
wallpaperBlurView?.removeFromSuperview()
wallpaperBlurView = nil
hasWallpaper = false
isDarkThemeEnabled = false

View File

@ -37,22 +37,6 @@ public class CVComponentSystemMessage: CVComponentBase, CVRootComponent {
componentView: componentView)
}
public override func willSnapshotForMessageActions(componentView: CVComponentView) {
guard let componentView = componentView as? CVComponentViewSystemMessage else {
owsFailDebug("Unexpected componentView.")
return
}
componentView.blurView?.backgroundColor = bubbleBackgroundColor
}
public override func didSnapshotForMessageActions(componentView: CVComponentView) {
guard let componentView = componentView as? CVComponentViewSystemMessage else {
owsFailDebug("Unexpected componentView.")
return
}
componentView.blurView?.backgroundColor = .clear
}
private var bubbleBackgroundColor: UIColor {
Theme.backgroundColor
}
@ -83,15 +67,16 @@ public class CVComponentSystemMessage: CVComponentBase, CVRootComponent {
layoutMargins: .zero)
}
public override func buildWallpaperMask(_ wallpaperMaskBuilder: WallpaperMaskBuilder,
componentView: CVComponentView) {
super.buildWallpaperMask(wallpaperMaskBuilder, componentView: componentView)
public override func updateWallpaperBlur(delegate: CVWallpaperBlurDelegate,
componentView: CVComponentView) {
super.updateWallpaperBlur(delegate: delegate,
componentView: componentView)
guard let componentView = componentView as? CVComponentViewSystemMessage else {
owsFailDebug("Unexpected componentView.")
return
}
wallpaperMaskBuilder.append(blurView: componentView.blurView)
componentView.wallpaperBlurView?.configure(delegate: delegate)
}
public func buildComponentView(componentDelegate: CVComponentDelegate) -> CVComponentView {
@ -212,8 +197,8 @@ public class CVComponentSystemMessage: CVComponentBase, CVRootComponent {
measurementKey: Self.measurementKey_outerHStack,
subviews: outerHStackViews)
componentView.blurView?.removeFromSuperview()
componentView.blurView = nil
componentView.wallpaperBlurView?.removeFromSuperview()
componentView.wallpaperBlurView = nil
componentView.backgroundView?.removeFromSuperview()
componentView.backgroundView = nil
@ -221,16 +206,15 @@ public class CVComponentSystemMessage: CVComponentBase, CVRootComponent {
let bubbleView: UIView
if hasWallpaper {
// This view doesn't need to render to render blur,
// but it does need to render for the message actions snapshot.
let blurView = UIView.container()
componentView.blurView = blurView
bubbleView = blurView
let wallpaperBlurView = CVWallpaperBlurView()
wallpaperBlurView.layer.cornerRadius = 8
componentView.wallpaperBlurView = wallpaperBlurView
bubbleView = wallpaperBlurView
} else {
let backgroundView = UIView()
backgroundView.backgroundColor = Theme.backgroundColor
componentView.backgroundView = backgroundView
bubbleView = backgroundView
backgroundView.backgroundColor = Theme.backgroundColor
}
if isFirstInCluster && isLastInCluster {
@ -416,7 +400,7 @@ public class CVComponentSystemMessage: CVComponentBase, CVRootComponent {
fileprivate let titleLabel = CVLabel()
fileprivate let selectionView = MessageSelectionView()
fileprivate var blurView: UIView?
fileprivate var wallpaperBlurView: CVWallpaperBlurView?
fileprivate var backgroundView: UIView?
fileprivate var button: OWSButton?
@ -453,8 +437,8 @@ public class CVComponentSystemMessage: CVComponentBase, CVRootComponent {
innerVStack.reset()
outerVStack.reset()
blurView?.removeFromSuperview()
blurView = nil
wallpaperBlurView?.removeFromSuperview()
wallpaperBlurView = nil
backgroundView?.removeFromSuperview()
backgroundView = nil

View File

@ -44,15 +44,16 @@ public class CVComponentThreadDetails: CVComponentBase, CVRootComponent {
CVComponentViewThreadDetails()
}
public override func buildWallpaperMask(_ wallpaperMaskBuilder: WallpaperMaskBuilder,
componentView: CVComponentView) {
super.buildWallpaperMask(wallpaperMaskBuilder, componentView: componentView)
public override func updateWallpaperBlur(delegate: CVWallpaperBlurDelegate,
componentView: CVComponentView) {
super.updateWallpaperBlur(delegate: delegate,
componentView: componentView)
guard let componentView = componentView as? CVComponentViewThreadDetails else {
owsFailDebug("Unexpected componentView.")
return
}
wallpaperMaskBuilder.append(blurView: componentView.blurView)
componentView.wallpaperBlurView?.configure(delegate: delegate)
}
public func configureForRendering(componentView componentViewParam: CVComponentView,
@ -117,8 +118,10 @@ public class CVComponentThreadDetails: CVComponentBase, CVRootComponent {
innerViews.append(UIView.spacer(withHeight: 1))
if conversationStyle.hasWallpaper {
innerStackView.layer.cornerRadius = 12
componentView.blurView = innerStackView
let wallpaperBlurView = CVWallpaperBlurView()
wallpaperBlurView.layer.cornerRadius = 12
innerStackView.addSubviewToFillSuperviewEdges(wallpaperBlurView)
componentView.wallpaperBlurView = wallpaperBlurView
}
let titleLabel = componentView.titleLabel
@ -514,7 +517,7 @@ public class CVComponentThreadDetails: CVComponentBase, CVRootComponent {
fileprivate let outerStackView = ManualStackView(name: "Thread details outer")
fileprivate let innerStackView = ManualStackView(name: "Thread details inner")
fileprivate var blurView: UIView?
fileprivate var wallpaperBlurView: CVWallpaperBlurView?
public var isDedicatedCellView = false
@ -536,8 +539,8 @@ public class CVComponentThreadDetails: CVComponentBase, CVRootComponent {
mutualGroupsLabel.text = nil
avatarView = nil
blurView?.removeFromSuperview()
blurView = nil
wallpaperBlurView?.removeFromSuperview()
wallpaperBlurView = nil
}
}
}

View File

@ -34,15 +34,16 @@ public class CVComponentUnreadIndicator: CVComponentBase, CVRootComponent {
CVComponentViewUnreadIndicator()
}
public override func buildWallpaperMask(_ wallpaperMaskBuilder: WallpaperMaskBuilder,
componentView: CVComponentView) {
super.buildWallpaperMask(wallpaperMaskBuilder, componentView: componentView)
public override func updateWallpaperBlur(delegate: CVWallpaperBlurDelegate,
componentView: CVComponentView) {
super.updateWallpaperBlur(delegate: delegate,
componentView: componentView)
guard let componentView = componentView as? CVComponentViewUnreadIndicator else {
owsFailDebug("Unexpected componentView.")
return
}
wallpaperMaskBuilder.append(blurView: componentView.blurView)
componentView.wallpaperBlurView?.configure(delegate: delegate)
}
public func configureForRendering(componentView: CVComponentView,
@ -79,8 +80,8 @@ public class CVComponentUnreadIndicator: CVComponentBase, CVRootComponent {
} else {
outerStack.reset()
titleLabel.removeFromSuperview()
componentView.blurView?.removeFromSuperview()
componentView.blurView = nil
componentView.wallpaperBlurView?.removeFromSuperview()
componentView.wallpaperBlurView = nil
innerStack.reset()
innerStack.configure(config: innerStackConfig,
@ -91,9 +92,10 @@ public class CVComponentUnreadIndicator: CVComponentBase, CVRootComponent {
if hasWallpaper {
strokeView.backgroundColor = .ows_blackAlpha80
let blurView = innerStack
blurView.layer.cornerRadius = 8
componentView.blurView = blurView
let wallpaperBlurView = CVWallpaperBlurView()
wallpaperBlurView.layer.cornerRadius = 8
innerStack.addSubviewToFillSuperviewEdges(wallpaperBlurView)
componentView.wallpaperBlurView = wallpaperBlurView
} else {
strokeView.backgroundColor = .ows_gray45
}
@ -175,7 +177,7 @@ public class CVComponentUnreadIndicator: CVComponentBase, CVRootComponent {
fileprivate let titleLabel = CVLabel()
fileprivate var blurView: UIView?
fileprivate var wallpaperBlurView: CVWallpaperBlurView?
fileprivate var hasWallpaper = false
fileprivate var isDarkThemeEnabled = false
@ -201,8 +203,8 @@ public class CVComponentUnreadIndicator: CVComponentBase, CVRootComponent {
outerStack.reset()
innerStack.reset()
blurView?.removeFromSuperview()
blurView = nil
wallpaperBlurView?.removeFromSuperview()
wallpaperBlurView = nil
hasWallpaper = false
isDarkThemeEnabled = false

View File

@ -0,0 +1,153 @@
//
// Copyright (c) 2021 Open Whisper Systems. All rights reserved.
//
import Foundation
public protocol CVWallpaperBlurDelegate: class {
var wallpaperBlurState: WallpaperBlurState? { get }
var isAnimating: Bool { get }
}
// MARK: -
@objc
public class CVWallpaperBlurView: ManualLayoutView {
private weak var delegate: CVWallpaperBlurDelegate?
private let imageView = CVImageView()
// private let imageLayer = CALayer()
private let maskLayer = CAShapeLayer()
private var state: WallpaperBlurState?
required init() {
super.init(name: "CVWallpaperBlurView")
self.clipsToBounds = true
imageView.contentMode = .scaleAspectFill
imageView.layer.mask = maskLayer
imageView.layer.masksToBounds = true
addSubview(imageView)
// addSubview(imageView) { view in
// guard let view = view as? CVWallpaperBlurView else {
// owsFailDebug("Invalid view.")
// return
// }
// view.imageView.frame = view.imageViewFrame
// }
// self.layer.addSublayer(imageLayer)
// self.layer.masksToBounds = true
// imageLayer.contentsGravity = .resizeAspectFill
// imageLayer.mask = maskLayer
// self.layer.mask = maskLayer
addLayoutBlock { [weak self] _ in
self?.applyLayout()
}
addRedBorder()
// addLayoutBlock { view in
// guard let view = view as? CVWallpaperBlurView else {
// owsFailDebug("Invalid view.")
// return
// }
// view.imageLayer.frame = view.imageViewFrame
// }
}
private func applyLayout() {
imageView.frame = imageViewFrame
// imageLayer.frame = imageViewFrame
maskLayer.frame = imageView.bounds
let maskPath = UIBezierPath(roundedRect: maskFrame, cornerRadius: layer.cornerRadius)
maskLayer.path = maskPath.cgPath
}
@available(swift, obsoleted: 1.0)
required init(name: String) {
owsFail("Do not use this initializer.")
}
public func configure(delegate: CVWallpaperBlurDelegate) {
// TODO: Observe provider changes.
self.delegate = delegate
configure()
}
private func configure() {
guard let delegate = delegate else {
owsFailDebug("Missing delegate.")
resetContent()
return
}
guard let state = delegate.wallpaperBlurState else {
resetContent()
return
}
guard state.id != self.state?.id else {
ensurePositioning()
return
}
self.state = state
imageView.image = state.image
// imageLayer.contents = state.image.cgImage
ensurePositioning()
}
private var imageViewFrame: CGRect = .zero
private var maskFrame: CGRect = .zero
private func ensurePositioning() {
// guard let delegate = delegate else {
// owsFailDebug("Missing delegate.")
// resetContent()
// return
// }
guard let state = self.state else {
resetContent()
return
}
// guard let image = imageView.image else {
// owsFailDebug("Missing image.")
// resetContent()
// return
// }
let referenceView = state.referenceView
self.imageViewFrame = self.convert(referenceView.bounds, from: referenceView)
self.maskFrame = referenceView.convert(self.bounds, from: self)
// let widthFactor = referenceView.bounds.width / image.size.width
// let heightFactor = referenceView.bounds.height / image.size.height
// let scalingFactor = max(widthFactor, heightFactor)
// let contentsScale = 1 / scalingFactor
// Logger.verbose("---- scalingFactor: \(scalingFactor), contentsScale: \(layer.contentsScale), UIScreen.main.scale: \(UIScreen.main.scale)")
//// self.layer.contentsScale
// // https://developer.apple.com/documentation/quartzcore/calayer/1410746-contentsscale
// // By using contentsScale to scale the blurred background image, we not only
// // (increase) the scale so that it is rendered at the correct size, we also
// // reduce the size of the bitmap used to present the layer content, which
// // helps perf.
// self.layer.contentsScale = contentsScale
// let referencePoint = self.convert(referenceView.bounds.center, from: referenceView)
// Logger.verbose("---- contentsCenter: \(layer.contentsCenter), position: \(layer.position), anchorPoint: \(layer.anchorPoint), referencePoint: \(referencePoint)")
Logger.verbose("---- imageViewFrame: \(imageViewFrame)")
Logger.verbose("---- maskFrame: \(maskFrame)")
// self.layer.contentsCenter = CGRect(origin: .zero, size: <#T##CGSize#>) referencePoint
// imageView.frame = imageViewFrame
applyLayout()
}
private func resetContent() {
imageView.image = nil
// imageLayer.contents = nil
imageViewFrame = .zero
maskFrame = .zero
delegate = nil
}
}

View File

@ -8,6 +8,7 @@ import Foundation
public protocol CVBackgroundContainerDelegate: class {
func updateSelectionHighlight()
func updateScrollingContent()
func updateCellWallpaperBlur()
}
// MARK: -
@ -19,7 +20,6 @@ public class CVBackgroundContainer: ManualLayoutViewWithLayer {
case wallpaperContent = 0
case wallpaperDimming = 1
case selectionHighlight = 2
case wallpaperBlur = 3
}
fileprivate var wallpaperView: WallpaperView?
@ -55,7 +55,6 @@ public class CVBackgroundContainer: ManualLayoutViewWithLayer {
}
public func set(wallpaperView: WallpaperView?) {
self.wallpaperView?.blurView?.removeFromSuperview()
self.wallpaperView?.contentView?.removeFromSuperview()
self.wallpaperView?.dimmingView?.removeFromSuperview()
self.wallpaperView = wallpaperView
@ -71,10 +70,6 @@ public class CVBackgroundContainer: ManualLayoutViewWithLayer {
addSubview(dimmingView)
dimmingView.layer.zPosition = ZPositioning.wallpaperDimming.rawValue
}
if let blurView = wallpaperView.blurView {
addSubview(blurView)
blurView.layer.zPosition = ZPositioning.wallpaperBlur.rawValue
}
setNeedsLayout()
} else {
@ -87,17 +82,13 @@ public class CVBackgroundContainer: ManualLayoutViewWithLayer {
super.layoutSubviews()
let shouldUpdateWallpaperBlur = wallpaperView?.blurView?.frame != bounds
let shouldUpdateSelectionHighlight = selectionHighlightView.frame != bounds
wallpaperView?.blurView?.frame = bounds
wallpaperView?.contentView?.frame = bounds
wallpaperView?.dimmingView?.frame = bounds
selectionHighlightView.frame = bounds
if shouldUpdateWallpaperBlur {
wallpaperView?.updateBlurContentAndMask()
}
delegate?.updateCellWallpaperBlur()
if shouldUpdateSelectionHighlight {
delegate?.updateSelectionHighlight()
}
@ -108,12 +99,11 @@ public class CVBackgroundContainer: ManualLayoutViewWithLayer {
fileprivate extension CVBackgroundContainer {
func updateWallpaperBlurMask() {
AssertIsOnMainThread()
let isAnimating = shouldHaveUpdateScrollingContentTimer.get() > 0
wallpaperView?.updateBlurMask(isAnimating: isAnimating)
}
// func updateWallpaperBlur(_ delegate: CVWallpaperBlurDelegate) {
// AssertIsOnMainThread()
//
// updateCellWallpaperBlur()
// }
func updateScrollingContentForAnimation(duration: TimeInterval) {
AssertIsOnMainThread()
@ -121,7 +111,7 @@ fileprivate extension CVBackgroundContainer {
// To ensure a "smooth landing" of these animations, we need to continue
// to update the mask for a short period after the animations lands.
let duration = duration * 2
startUpdateScrollingContentTimer()
DispatchQueue.main.asyncAfter(deadline: .now() + duration) { [weak self] in
self?.stopUpdateScrollingContentTimer()
@ -164,37 +154,60 @@ fileprivate extension CVBackgroundContainer {
// MARK: -
extension CVBackgroundContainer: CVWallpaperBlurDelegate {
public var wallpaperBlurState: WallpaperBlurState? {
wallpaperView?.blurProvider?.getState()
}
public var isAnimating: Bool {
shouldHaveUpdateScrollingContentTimer.get() > 0
}
}
// MARK: -
extension ConversationViewController: CVBackgroundContainerDelegate {
var selectionHighlightView: SelectionHighlightView {
viewState.backgroundContainer.selectionHighlightView
backgroundContainer.selectionHighlightView
}
@objc
public func updateScrollingContent() {
AssertIsOnMainThread()
viewState.backgroundContainer.updateWallpaperBlurMask()
updateCellWallpaperBlur()
updateSelectionHighlight()
}
public func updateCellWallpaperBlur() {
let provider = backgroundContainer.wallpaperView?.blurProvider
for cell in collectionView.visibleCells {
guard let cell = cell as? CVCell else {
owsFailDebug("Invalid cell.")
continue
}
cell.updateWallpaperBlur(delegate: backgroundContainer)
}
}
@objc
public func updateScrollingContentForAnimation(duration: TimeInterval) {
AssertIsOnMainThread()
viewState.backgroundContainer.updateScrollingContentForAnimation(duration: duration)
backgroundContainer.updateScrollingContentForAnimation(duration: duration)
}
@objc
public func startUpdateScrollingContentTimer() {
AssertIsOnMainThread()
viewState.backgroundContainer.startUpdateScrollingContentTimer()
backgroundContainer.startUpdateScrollingContentTimer()
}
@objc
public func stopUpdateScrollingContentTimer() {
AssertIsOnMainThread()
viewState.backgroundContainer.stopUpdateScrollingContentTimer()
backgroundContainer.stopUpdateScrollingContentTimer()
}
}

View File

@ -273,6 +273,9 @@ public extension ConversationViewController {
get { viewState.messageActionsOriginalFocusY }
set { viewState.messageActionsOriginalFocusY = newValue }
}
var backgroundContainer: CVBackgroundContainer {
get { viewState.backgroundContainer }
}
// MARK: -

View File

@ -33,30 +33,12 @@ extension ConversationViewController {
AssertIsOnMainThread()
guard let wallpaperView = databaseStorage.read(block: { transaction in
Wallpaper.view(for: self.thread,
maskDataSource: self,
transaction: transaction)
Wallpaper.view(for: self.thread, transaction: transaction)
}) else {
viewState.backgroundContainer.set(wallpaperView: nil)
backgroundContainer.set(wallpaperView: nil)
return
}
viewState.backgroundContainer.set(wallpaperView: wallpaperView)
backgroundContainer.set(wallpaperView: wallpaperView)
}
}
// MARK: -
extension ConversationViewController: WallpaperMaskDataSource {
public func buildWallpaperMask(_ wallpaperMaskBuilder: WallpaperMaskBuilder) {
for cell in collectionView.visibleCells {
guard let cell = cell as? CVCell else {
owsFailDebug("Invalid cell.")
continue
}
cell.buildWallpaperMask(wallpaperMaskBuilder)
}
}
public var isWallpaperPreview: Bool { false }
}

View File

@ -478,7 +478,7 @@ typedef enum : NSUInteger {
// The view controller will only automatically adjust content insets for a
// scrollView at index 0, so we need the collection view to remain subview index 0.
// But the background views should appear visually behind the collection view.
CVBackgroundContainer *backgroundContainer = self.viewState.backgroundContainer;
CVBackgroundContainer *backgroundContainer = self.backgroundContainer;
backgroundContainer.delegate = self;
[self.view addSubview:backgroundContainer];
[backgroundContainer autoPinEdgesToSuperviewEdges];

View File

@ -126,14 +126,6 @@ public class MessageActionsViewController: UIViewController {
snapshotFocusedView?.removeFromSuperview()
snapshotFocusedView = nil
if let cell = focusedView as? CVCell {
cell.willSnapshotForMessageActions()
}
defer {
if let cell = focusedView as? CVCell {
cell.didSnapshotForMessageActions()
}
}
guard let snapshotView = focusedView.snapshotView(afterScreenUpdates: true) else {
return owsFailDebug("snapshotView was unexpectedly nil")
}

View File

@ -147,7 +147,6 @@ class PreviewWallpaperViewController: UIViewController {
case .photo(let selectedPhoto):
owsAssertDebug(self.standalonePage == nil)
let standalonePage = WallpaperPage(wallpaper: .photo,
maskDataSource: mockConversationView,
thread: thread,
photo: selectedPhoto)
self.standalonePage = standalonePage
@ -165,7 +164,6 @@ class PreviewWallpaperViewController: UIViewController {
}
currentPage = WallpaperPage(wallpaper: selectedWallpaper,
maskDataSource: mockConversationView,
thread: thread)
blurButton.isHidden = true
}
@ -218,14 +216,12 @@ extension PreviewWallpaperViewController: UIPageViewControllerDataSource, UIPage
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
guard let currentPage = currentPage, currentPage.wallpaper != .photo else { return nil }
return WallpaperPage(wallpaper: wallpaper(before: currentPage.wallpaper),
maskDataSource: mockConversationView,
thread: thread)
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
guard let currentPage = currentPage, currentPage.wallpaper != .photo else { return nil }
return WallpaperPage(wallpaper: wallpaper(after: currentPage.wallpaper),
maskDataSource: mockConversationView,
thread: thread)
}
@ -290,14 +286,10 @@ private class WallpaperPage: UIViewController {
let photo: UIImage?
var shouldBlur = false { didSet { updatePhoto() } }
private weak var maskDataSource: WallpaperMaskDataSource?
init(wallpaper: Wallpaper,
maskDataSource: WallpaperMaskDataSource,
thread: TSThread?,
photo: UIImage? = nil) {
self.wallpaper = wallpaper
self.maskDataSource = maskDataSource
self.thread = thread
self.photo = photo
@ -315,36 +307,27 @@ private class WallpaperPage: UIViewController {
var wallpaperViewHeightAndWidthPriorityConstraints = [NSLayoutConstraint]()
var wallpaperView: WallpaperView?
var wallpaperContentPreviewView: UIView?
var wallpaperBlurPreviewView: UIView?
var wallpaperPreviewView: UIView?
override func loadView() {
let rootView = ManualLayoutViewWithLayer(name: "rootView")
rootView.shouldDeactivateConstraints = false
rootView.translatesAutoresizingMaskIntoConstraints = true
rootView.backgroundColor = Theme.darkThemeBackgroundColor
rootView.addLayoutBlock { [weak self] _ in
guard let self = self else { return }
self.wallpaperView?.updateBlurContentAndMask()
}
view = rootView
let shouldDim = databaseStorage.read { transaction in
Wallpaper.shouldDim(thread: thread, transaction: transaction)
}
guard let wallpaperView = Wallpaper.view(for: wallpaper,
maskDataSource: maskDataSource,
photo: photo,
shouldDim: shouldDim) else {
return owsFailDebug("Failed to create photo wallpaper view")
}
self.wallpaperView = wallpaperView
let wallpaperContentPreviewView = wallpaperView.asPreviewView(mode: .contentAndDimming)
self.wallpaperContentPreviewView = wallpaperContentPreviewView
let wallpaperBlurPreviewView = wallpaperView.asPreviewView(mode: .blur)
self.wallpaperBlurPreviewView = wallpaperBlurPreviewView
let wallpaperPreviewView = wallpaperView.asPreviewView()
self.wallpaperPreviewView = wallpaperPreviewView
// If this is a photo, embed it in a scrollView for pinch & zoom
if case .photo = wallpaper, let photo = photo {
@ -355,17 +338,17 @@ private class WallpaperPage: UIViewController {
scrollView.delegate = self
view.addSubview(scrollView)
scrollView.autoPinEdgesToSuperviewEdges()
scrollView.addSubview(wallpaperContentPreviewView)
scrollView.addSubview(wallpaperPreviewView)
wallpaperContentPreviewView.autoPinEdgesToSuperviewEdges()
wallpaperPreviewView.autoPinEdgesToSuperviewEdges()
wallpaperViewWidthPriorityConstraints = [
wallpaperContentPreviewView.autoMatch(
wallpaperPreviewView.autoMatch(
.width,
to: .width,
of: scrollView
),
wallpaperContentPreviewView.autoMatch(
wallpaperPreviewView.autoMatch(
.height,
to: .width,
of: scrollView,
@ -375,12 +358,12 @@ private class WallpaperPage: UIViewController {
wallpaperViewWidthPriorityConstraints.forEach { $0.isActive = false }
wallpaperViewHeightPriorityConstraints = [
wallpaperContentPreviewView.autoMatch(
wallpaperPreviewView.autoMatch(
.height,
to: .height,
of: scrollView
),
wallpaperContentPreviewView.autoMatch(
wallpaperPreviewView.autoMatch(
.width,
to: .height,
of: scrollView,
@ -390,12 +373,12 @@ private class WallpaperPage: UIViewController {
wallpaperViewHeightPriorityConstraints.forEach { $0.isActive = false }
wallpaperViewHeightAndWidthPriorityConstraints = [
wallpaperContentPreviewView.autoMatch(
wallpaperPreviewView.autoMatch(
.height,
to: .height,
of: scrollView
),
wallpaperContentPreviewView.autoMatch(
wallpaperPreviewView.autoMatch(
.width,
to: .width,
of: scrollView
@ -405,24 +388,9 @@ private class WallpaperPage: UIViewController {
updateWallpaperConstraints(reference: view.bounds.size)
} else {
view.addSubview(wallpaperContentPreviewView)
wallpaperContentPreviewView.autoPinEdgesToSuperviewEdges()
view.addSubview(wallpaperPreviewView)
wallpaperPreviewView.autoPinEdgesToSuperviewEdges()
}
view.addSubview(wallpaperBlurPreviewView)
wallpaperBlurPreviewView.autoPinEdgesToSuperviewEdges()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.wallpaperView?.updateBlurContentAndMask()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.wallpaperView?.updateBlurContentAndMask()
}
private func updatePhoto() {
@ -491,7 +459,7 @@ private class WallpaperPage: UIViewController {
extension WallpaperPage: UIScrollViewDelegate {
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return wallpaperContentPreviewView
return wallpaperPreviewView
}
}

View File

@ -242,8 +242,7 @@ class WallpaperCell: UICollectionViewCell {
Wallpaper.shouldDim(thread: thread, transaction: transaction)
}
wallpaperView = Wallpaper.view(for: wallpaper,
maskDataSource: nil,
shouldDim: shouldDim)?.asPreviewView(mode: .all)
shouldDim: shouldDim)?.asPreviewView()
guard let wallpaperView = wallpaperView else {
return owsFailDebug("Missing wallpaper view")

View File

@ -202,12 +202,10 @@ class MiniPreviewView: UIView {
backgroundColor = Theme.isDarkThemeEnabled ? .ows_gray65 : .ows_gray05
let stackViewContainer: UIView
if let wallpaperView = databaseStorage.read(
block: { Wallpaper.view(for: thread,
maskDataSource: nil,
transaction: $0) }
) {
stackViewContainer = wallpaperView.asPreviewView(mode: .all)
if let wallpaperView = (databaseStorage.read { transaction in
Wallpaper.view(for: thread, transaction: transaction)
}) {
stackViewContainer = wallpaperView.asPreviewView()
} else {
stackViewContainer = UIView()
stackViewContainer.backgroundColor = Theme.backgroundColor

View File

@ -197,15 +197,15 @@ class MockConversationView: UIView {
// MARK: -
extension MockConversationView: WallpaperMaskDataSource {
func buildWallpaperMask(_ wallpaperMaskBuilder: WallpaperMaskBuilder) {
outgoingMessageView.buildWallpaperMask(wallpaperMaskBuilder)
incomingMessageView.buildWallpaperMask(wallpaperMaskBuilder)
dateHeaderView.buildWallpaperMask(wallpaperMaskBuilder)
}
var isWallpaperPreview: Bool { true }
}
// extension MockConversationView: WallpaperMaskDataSource {
// func updateWallpaperBlur(_ delegate: CVWallpaperBlurDelegate) {
// outgoingMessageView.buildWallpaperMask(delegate)
// incomingMessageView.buildWallpaperMask(delegate)
// dateHeaderView.buildWallpaperMask(delegate)
// }
//
// var isWallpaperPreview: Bool { true }
// }
// MARK: - Mock Classes

View File

@ -142,7 +142,6 @@ public enum Wallpaper: String, CaseIterable {
}
public static func view(for thread: TSThread? = nil,
maskDataSource: WallpaperMaskDataSource?,
transaction: SDSAnyReadTransaction) -> WallpaperView? {
AssertIsOnMainThread()
@ -176,7 +175,6 @@ public enum Wallpaper: String, CaseIterable {
dimInDarkMode(for: thread, transaction: transaction))
guard let view = view(for: wallpaper,
maskDataSource: maskDataSource,
photo: photo,
shouldDim: shouldDim) else {
return nil
@ -192,7 +190,6 @@ public enum Wallpaper: String, CaseIterable {
}
public static func view(for wallpaper: Wallpaper,
maskDataSource: WallpaperMaskDataSource?,
photo: UIImage? = nil,
shouldDim: Bool) -> WallpaperView? {
AssertIsOnMainThread()
@ -215,9 +212,7 @@ public enum Wallpaper: String, CaseIterable {
}() else {
return nil
}
return WallpaperView(mode: mode,
maskDataSource: maskDataSource,
shouldDim: shouldDim)
return WallpaperView(mode: mode, shouldDim: shouldDim)
}
}
@ -356,49 +351,6 @@ fileprivate extension Wallpaper {
// MARK: -
public struct WallpaperMaskBuilder {
fileprivate let maskPath = UIBezierPath()
public let referenceView: UIView
fileprivate let isAnimating: Bool
public func append(blurPath: UIBezierPath) {
maskPath.append(blurPath)
}
public func append(blurView: UIView?) {
guard let blurView = blurView else {
Logger.warn("Missing blurView.")
return
}
let blurFrame: CGRect
if isAnimating,
let srcLayer = blurView.layer.presentation(),
let dstLayer = referenceView.layer.presentation() {
blurFrame = dstLayer.convert(srcLayer.bounds, from: srcLayer)
} else {
blurFrame = referenceView.convert(blurView.bounds, from: blurView)
}
let blurPath: UIBezierPath = {
return UIBezierPath(roundedRect: blurFrame,
byRoundingCorners: blurView.layer.maskedCorners.asUIRectCorner,
cornerRadii: .square(blurView.layer.cornerRadius))
}()
append(blurPath: blurPath)
}
}
// MARK: -
public protocol WallpaperMaskDataSource: class {
func buildWallpaperMask(_ wallpaperMaskBuilder: WallpaperMaskBuilder)
var isWallpaperPreview: Bool { get }
}
// MARK: -
public class WallpaperView {
fileprivate enum Mode {
case solidColor(solidColor: UIColor)
@ -406,22 +358,18 @@ public class WallpaperView {
case image(image: UIImage)
}
private var _blurView: BlurView?
public var blurView: UIView? { _blurView }
public private(set) var contentView: UIView?
public private(set) var dimmingView: UIView?
public private(set) var blurProvider: WallpaperBlurProvider?
private let mode: Mode
fileprivate init(mode: Mode,
maskDataSource: WallpaperMaskDataSource?,
shouldDim: Bool) {
fileprivate init(mode: Mode, shouldDim: Bool) {
self.mode = mode
configure(maskDataSource: maskDataSource, shouldDim: shouldDim)
configure(shouldDim: shouldDim)
}
@available(swift, obsoleted: 1.0)
@ -429,213 +377,167 @@ public class WallpaperView {
owsFail("Do not use this initializer.")
}
public enum PreviewMode {
case all
case blur
case contentAndDimming
fileprivate var showContentAndDimming: Bool {
switch self {
case .all, .contentAndDimming:
return true
case .blur:
return false
}
}
fileprivate var showBlur: Bool {
switch self {
case .all, .contentAndDimming:
return false
case .blur:
return true
}
}
}
public func asPreviewView(mode: PreviewMode) -> UIView {
public func asPreviewView() -> UIView {
let previewView = UIView.container()
if mode.showContentAndDimming,
let contentView = self.contentView {
if let contentView = self.contentView {
previewView.addSubview(contentView)
contentView.autoPinEdgesToSuperviewEdges()
}
if mode.showContentAndDimming,
let dimmingView = self.dimmingView {
if let dimmingView = self.dimmingView {
previewView.addSubview(dimmingView)
dimmingView.autoPinEdgesToSuperviewEdges()
}
if mode.showBlur,
let blurView = self.blurView {
previewView.addSubview(blurView)
blurView.autoPinEdgesToSuperviewEdges()
}
return previewView
}
private func configure(maskDataSource: WallpaperMaskDataSource?,
shouldDim: Bool) {
private func configure(shouldDim: Bool) {
func addDimmingViewIfNecessary() {
if shouldDim {
let dimmingView = UIView()
dimmingView.backgroundColor = .ows_blackAlpha20
self.dimmingView = dimmingView
}
}
let contentView: UIView = {
switch mode {
case .solidColor(let solidColor):
let isWallpaperPreview = maskDataSource?.isWallpaperPreview ?? false
if isWallpaperPreview {
let contentView = OWSLayerView(frame: .zero) { [weak self] _ in
self?.updateBlurContentAndMask()
}
contentView.backgroundColor = solidColor
return contentView
} else {
let contentView = UIView()
contentView.backgroundColor = solidColor
return contentView
}
// Bake the dimming into the color.
let color = (shouldDim
? solidColor.blended(with: .ows_black, alpha: 0.2)
: solidColor)
let contentView = UIView()
contentView.backgroundColor = color
return contentView
case .gradientView(let gradientView):
addDimmingViewIfNecessary()
return gradientView
case .image(let image):
let imageView = UIImageView(image: image)
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
// TODO: Bake dimming into the image.
addDimmingViewIfNecessary()
return imageView
}
}()
self.contentView = contentView
addBlurView(contentView: contentView, maskDataSource: maskDataSource)
if shouldDim {
let dimmingView = UIView()
dimmingView.backgroundColor = .ows_blackAlpha20
self.dimmingView = dimmingView
}
addBlurProvider(contentView: contentView)
}
private func addBlurView(contentView: UIView,
maskDataSource: WallpaperMaskDataSource?) {
guard let maskDataSource = maskDataSource else {
return
}
let blurView = BlurView(contentView: contentView, maskDataSource: maskDataSource)
_blurView = blurView
private func addBlurProvider(contentView: UIView) {
self.blurProvider = WallpaperBlurProvider(contentView: contentView)
}
public func updateBlurContentAndMask(isAnimating: Bool = false) {
_blurView?.updateContentAndMask(isAnimating: isAnimating)
// public func updateBlurContentAndMask(isAnimating: Bool = false) {
// _blurView?.updateContentAndMask(isAnimating: isAnimating)
// }
//
// public func updateBlurMask(isAnimating: Bool = false) {
// _blurView?.updateMask(isAnimating: isAnimating)
// }
}
// MARK: -
private struct WallpaperBlurToken: Equatable {
let contentSize: CGSize
let isDarkThemeEnabled: Bool
}
// MARK: -
public class WallpaperBlurState {
public let image: UIImage
public let referenceView: UIView
fileprivate let token: WallpaperBlurToken
private static let idCounter = AtomicUInt(0)
public let id: UInt = WallpaperBlurState.idCounter.increment()
fileprivate init(image: UIImage,
referenceView: UIView,
token: WallpaperBlurToken) {
self.image = image
self.referenceView = referenceView
self.token = token
}
}
// MARK: -
public class WallpaperBlurProvider {
private let contentView: UIView
private var state: WallpaperBlurState?
init(contentView: UIView) {
self.contentView = contentView
}
public func updateBlurMask(isAnimating: Bool = false) {
_blurView?.updateMask(isAnimating: isAnimating)
@available(swift, obsoleted: 1.0)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: -
public func reset() {
self.state = nil
}
private class BlurView: UIImageView {
private let contentView: UIView
private let maskLayer = CAShapeLayer()
private weak var maskDataSource: WallpaperMaskDataSource?
public func getState() -> WallpaperBlurState? {
AssertIsOnMainThread()
init(contentView: UIView, maskDataSource: WallpaperMaskDataSource) {
self.contentView = contentView
self.maskDataSource = maskDataSource
super.init(frame: .zero)
self.contentMode = .scaleAspectFill
self.clipsToBounds = true
self.layer.mask = maskLayer
NotificationCenter.default.addObserver(self,
selector: #selector(themeDidChange),
name: .ThemeDidChange,
object: nil)
// De-bounce.
let bounds = contentView.bounds
let isDarkThemeEnabled = Theme.isDarkThemeEnabled
let newToken = WallpaperBlurToken(contentSize: bounds.size,
isDarkThemeEnabled: isDarkThemeEnabled)
if let state = self.state,
state.token == newToken {
return state
}
@available(swift, obsoleted: 1.0)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
reset()
@objc
private func themeDidChange() {
updateContent()
}
func updateContentAndMask(isAnimating: Bool) {
updateContent()
updateMask(isAnimating: isAnimating)
}
func updateMask(isAnimating: Bool) {
guard let maskDataSource = self.maskDataSource else {
owsFailDebug("Missing maskDataSource.")
resetMask()
return
do {
guard bounds.width > 0, bounds.height > 0 else {
return nil
}
let builder = WallpaperMaskBuilder(referenceView: self, isAnimating: isAnimating)
maskDataSource.buildWallpaperMask(builder)
maskLayer.path = builder.maskPath.cgPath
}
private struct ContentToken: Equatable {
let contentSize: CGSize
let isDarkThemeEnabled: Bool
}
private var contentToken: ContentToken?
func updateContent() {
// De-bounce.
let isDarkThemeEnabled = Theme.isDarkThemeEnabled
let newContentToken = ContentToken(contentSize: bounds.size,
isDarkThemeEnabled: isDarkThemeEnabled)
guard contentToken != newContentToken else {
return
guard let contentImage = contentView.renderAsImage() else {
owsFailDebug("Could not render contentView.")
return nil
}
do {
guard bounds.width > 0, bounds.height > 0 else {
resetContent()
return
}
guard let contentImage = contentView.renderAsImage() else {
owsFailDebug("Could not render contentView.")
resetContent()
return
}
// We approximate the behavior of UIVisualEffectView(effect: UIBlurEffect(style: .regular)).
let tintColor: UIColor = (isDarkThemeEnabled
? UIColor.ows_black.withAlphaComponent(0.9)
: .ows_whiteAlpha60)
let resizeFactor: CGFloat = 8
let resizeDimension = contentImage.size.largerAxis / resizeFactor
guard let scaledImage = contentImage.resized(withMaxDimensionPoints: resizeDimension) else {
owsFailDebug("Could not resize contentImage.")
resetContent()
return
}
let blurRadius: CGFloat = 32 / resizeFactor
let blurredImage = try scaledImage.withGausianBlur(radius: blurRadius,
tintColor: tintColor)
self.image = blurredImage
self.contentToken = newContentToken
} catch {
owsFailDebug("Error: \(error).")
resetContent()
// We approximate the behavior of UIVisualEffectView(effect: UIBlurEffect(style: .regular)).
// let tintColor: UIColor = (isDarkThemeEnabled
// ? UIColor.ows_black.withAlphaComponent(0.9)
// : UIColor.white.withAlphaComponent(0.6)
let tintColor: UIColor = (isDarkThemeEnabled
? UIColor.ows_black.withAlphaComponent(0.3)
: UIColor.white.withAlphaComponent(0.3))
let resizeFactor: CGFloat = 8
let resizeDimension = contentImage.size.largerAxis / resizeFactor
guard let scaledImage = contentImage.resized(withMaxDimensionPoints: resizeDimension) else {
owsFailDebug("Could not resize contentImage.")
return nil
}
}
private func reset() {
resetContent()
resetMask()
}
private func resetMask() {
maskLayer.path = nil
}
private func resetContent() {
image = nil
contentToken = nil
let blurRadius: CGFloat = 1 / resizeFactor
// let blurRadius: CGFloat = 32 / resizeFactor
let blurredImage = try scaledImage.withGausianBlur(radius: blurRadius,
tintColor: tintColor)
let state = WallpaperBlurState(image: blurredImage,
referenceView: contentView,
token: newToken)
self.state = state
return state
} catch {
owsFailDebug("Error: \(error).")
return nil
}
}
}

View File

@ -231,7 +231,7 @@ public class DebugFlags: BaseFlags {
public static let suppressBackgroundActivity = false
@objc
public static let reduceLogChatter = false && build.includes(.dev)
public static let reduceLogChatter = true && build.includes(.dev)
@objc
public static let logSQLQueries = build.includes(.dev) && !reduceLogChatter