mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 14:20:20 +00:00
Giveaway improvements
This commit is contained in:
@@ -67,7 +67,8 @@ fragment half4 cameraBlobFragment(RasterizerData in[[stage_in]],
|
||||
|
||||
float t = AARadius / resolution.y;
|
||||
|
||||
float cAlpha = 1.0 - primaryParameters.y;
|
||||
float cAlpha = min(1.0, 1.0 - primaryParameters.y);
|
||||
float minColor = min(1.0, 1.0 + primaryParameters.y);
|
||||
float bound = primaryParameters.x + 0.05;
|
||||
if (abs(offset) > bound) {
|
||||
cAlpha = mix(0.0, 1.0, min(1.0, (abs(offset) - bound) * 2.4));
|
||||
@@ -75,5 +76,5 @@ fragment half4 cameraBlobFragment(RasterizerData in[[stage_in]],
|
||||
|
||||
float c = smoothstep(t, -t, map(uv, primaryParameters, primaryOffset, secondaryParameters, secondaryOffset));
|
||||
|
||||
return half4(c, max(cAlpha, 0.231), max(cAlpha, 0.188), c);
|
||||
return half4(min(minColor, c), min(minColor, max(cAlpha, 0.231)), min(minColor, max(cAlpha, 0.188)), c);
|
||||
}
|
||||
|
||||
@@ -36,36 +36,47 @@ private struct CameraState: Equatable {
|
||||
case holding
|
||||
case handsFree
|
||||
}
|
||||
enum FlashTint {
|
||||
case white
|
||||
case yellow
|
||||
case blue
|
||||
}
|
||||
|
||||
let mode: CameraMode
|
||||
let position: Camera.Position
|
||||
let flashMode: Camera.FlashMode
|
||||
let flashModeDidChange: Bool
|
||||
let flashTint: FlashTint
|
||||
let recording: Recording
|
||||
let duration: Double
|
||||
let isDualCameraEnabled: Bool
|
||||
|
||||
func updatedMode(_ mode: CameraMode) -> CameraState {
|
||||
return CameraState(mode: mode, position: self.position, flashMode: self.flashMode, flashModeDidChange: self.flashModeDidChange, recording: self.recording, duration: self.duration, isDualCameraEnabled: self.isDualCameraEnabled)
|
||||
return CameraState(mode: mode, position: self.position, flashMode: self.flashMode, flashModeDidChange: self.flashModeDidChange, flashTint: self.flashTint, recording: self.recording, duration: self.duration, isDualCameraEnabled: self.isDualCameraEnabled)
|
||||
}
|
||||
|
||||
func updatedPosition(_ position: Camera.Position) -> CameraState {
|
||||
return CameraState(mode: self.mode, position: position, flashMode: self.flashMode, flashModeDidChange: self.flashModeDidChange, recording: self.recording, duration: self.duration, isDualCameraEnabled: self.isDualCameraEnabled)
|
||||
return CameraState(mode: self.mode, position: position, flashMode: self.flashMode, flashModeDidChange: self.flashModeDidChange, flashTint: self.flashTint, recording: self.recording, duration: self.duration, isDualCameraEnabled: self.isDualCameraEnabled)
|
||||
}
|
||||
|
||||
func updatedFlashMode(_ flashMode: Camera.FlashMode) -> CameraState {
|
||||
return CameraState(mode: self.mode, position: self.position, flashMode: flashMode, flashModeDidChange: self.flashMode != flashMode, recording: self.recording, duration: self.duration, isDualCameraEnabled: self.isDualCameraEnabled)
|
||||
return CameraState(mode: self.mode, position: self.position, flashMode: flashMode, flashModeDidChange: self.flashMode != flashMode, flashTint: self.flashTint, recording: self.recording, duration: self.duration, isDualCameraEnabled: self.isDualCameraEnabled)
|
||||
}
|
||||
|
||||
func updatedFlashTint(_ flashTint: FlashTint) -> CameraState {
|
||||
return CameraState(mode: self.mode, position: self.position, flashMode: self.flashMode, flashModeDidChange: self.flashModeDidChange, flashTint: flashTint, recording: self.recording, duration: self.duration, isDualCameraEnabled: self.isDualCameraEnabled)
|
||||
}
|
||||
|
||||
func updatedRecording(_ recording: Recording) -> CameraState {
|
||||
return CameraState(mode: self.mode, position: self.position, flashMode: self.flashMode, flashModeDidChange: self.flashModeDidChange, recording: recording, duration: self.duration, isDualCameraEnabled: self.isDualCameraEnabled)
|
||||
return CameraState(mode: self.mode, position: self.position, flashMode: self.flashMode, flashModeDidChange: self.flashModeDidChange, flashTint: self.flashTint, recording: recording, duration: self.duration, isDualCameraEnabled: self.isDualCameraEnabled)
|
||||
}
|
||||
|
||||
func updatedDuration(_ duration: Double) -> CameraState {
|
||||
return CameraState(mode: self.mode, position: self.position, flashMode: self.flashMode, flashModeDidChange: self.flashModeDidChange, recording: self.recording, duration: duration, isDualCameraEnabled: self.isDualCameraEnabled)
|
||||
return CameraState(mode: self.mode, position: self.position, flashMode: self.flashMode, flashModeDidChange: self.flashModeDidChange, flashTint: self.flashTint, recording: self.recording, duration: duration, isDualCameraEnabled: self.isDualCameraEnabled)
|
||||
}
|
||||
|
||||
func updatedIsDualCameraEnabled(_ isDualCameraEnabled: Bool) -> CameraState {
|
||||
return CameraState(mode: self.mode, position: self.position, flashMode: self.flashMode, flashModeDidChange: self.flashModeDidChange, recording: self.recording, duration: self.duration, isDualCameraEnabled: isDualCameraEnabled)
|
||||
return CameraState(mode: self.mode, position: self.position, flashMode: self.flashMode, flashModeDidChange: self.flashModeDidChange, flashTint: self.flashTint, recording: self.recording, duration: self.duration, isDualCameraEnabled: isDualCameraEnabled)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,6 +173,7 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
enum ImageKey: Hashable {
|
||||
case cancel
|
||||
case flip
|
||||
case flashImage
|
||||
}
|
||||
private var cachedImages: [ImageKey: UIImage] = [:]
|
||||
func image(_ key: ImageKey) -> UIImage {
|
||||
@@ -171,9 +183,21 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
var image: UIImage
|
||||
switch key {
|
||||
case .cancel:
|
||||
image = UIImage(bundleImageName: "Camera/CloseIcon")!
|
||||
image = UIImage(bundleImageName: "Camera/CloseIcon")!.withRenderingMode(.alwaysTemplate)
|
||||
case .flip:
|
||||
image = UIImage(bundleImageName: "Camera/FlipIcon")!
|
||||
image = UIImage(bundleImageName: "Camera/FlipIcon")!.withRenderingMode(.alwaysTemplate)
|
||||
case .flashImage:
|
||||
image = generateImage(CGSize(width: 393.0, height: 852.0), rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: .zero, size: size))
|
||||
|
||||
var locations: [CGFloat] = [0.0, 0.2, 0.6, 1.0]
|
||||
let colors: [CGColor] = [UIColor(rgb: 0xffffff, alpha: 0.25).cgColor, UIColor(rgb: 0xffffff, alpha: 0.25).cgColor, UIColor(rgb: 0xffffff, alpha: 1.0).cgColor, UIColor(rgb: 0xffffff, alpha: 1.0).cgColor]
|
||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as CFArray, locations: &locations)!
|
||||
|
||||
let center = CGPoint(x: size.width / 2.0, y: size.height / 2.0 - 10.0)
|
||||
context.drawRadialGradient(gradient, startCenter: center, startRadius: 0.0, endCenter: center, endRadius: size.width, options: .drawsAfterEndLocation)
|
||||
})!.withRenderingMode(.alwaysTemplate)
|
||||
}
|
||||
cachedImages[key] = image
|
||||
return image
|
||||
@@ -589,7 +613,7 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
|
||||
static var body: Body {
|
||||
let placeholder = Child(PlaceholderComponent.self)
|
||||
let frontFlash = Child(Rectangle.self)
|
||||
let frontFlash = Child(Image.self)
|
||||
let cancelButton = Child(CameraButton.self)
|
||||
let captureControls = Child(CaptureControlsComponent.self)
|
||||
let zoomControl = Child(ZoomComponent.self)
|
||||
@@ -689,19 +713,29 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
// )
|
||||
}
|
||||
|
||||
if case .none = component.cameraState.recording {
|
||||
|
||||
} else if case .front = component.cameraState.position {
|
||||
var controlsTintColor: UIColor = .white
|
||||
if case .front = component.cameraState.position, case .on = component.cameraState.flashMode {
|
||||
let flashTintColor: UIColor
|
||||
switch component.cameraState.flashTint {
|
||||
case .white:
|
||||
flashTintColor = .white
|
||||
case .yellow:
|
||||
flashTintColor = UIColor(rgb: 0xffed8c)
|
||||
case .blue:
|
||||
flashTintColor = UIColor(rgb: 0x8cdfff)
|
||||
}
|
||||
let frontFlash = frontFlash.update(
|
||||
component: Rectangle(color: UIColor(white: 1.0, alpha: 0.6)),
|
||||
availableSize: CGSize(width: availableSize.width, height: previewHeight),
|
||||
component: Image(image: state.image(.flashImage), tintColor: flashTintColor),
|
||||
availableSize: availableSize,
|
||||
transition: .easeInOut(duration: 0.2)
|
||||
)
|
||||
context.add(frontFlash
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: environment.safeInsets.top + previewHeight / 2.0))
|
||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: context.availableSize.height / 2.0))
|
||||
.appear(.default(alpha: true))
|
||||
.disappear(.default(alpha: true))
|
||||
)
|
||||
|
||||
controlsTintColor = .black
|
||||
}
|
||||
|
||||
let shutterState: ShutterButtonState
|
||||
@@ -737,6 +771,7 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
isTablet: isTablet,
|
||||
hasAppeared: component.hasAppeared && hasAllRequiredAccess,
|
||||
hasAccess: hasAllRequiredAccess,
|
||||
tintColor: controlsTintColor,
|
||||
shutterState: shutterState,
|
||||
lastGalleryAsset: state.lastGalleryAsset,
|
||||
tag: captureControlsTag,
|
||||
@@ -823,6 +858,7 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
component: AnyComponent(
|
||||
Image(
|
||||
image: state.image(.cancel),
|
||||
tintColor: controlsTintColor,
|
||||
size: CGSize(width: 40.0, height: 40.0)
|
||||
)
|
||||
)
|
||||
@@ -867,7 +903,7 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
range: nil,
|
||||
waitForCompletion: false
|
||||
),
|
||||
colors: [:],
|
||||
colors: ["__allcolors__": controlsTintColor],
|
||||
size: CGSize(width: 40.0, height: 40.0)
|
||||
)
|
||||
)
|
||||
@@ -878,7 +914,7 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
component: AnyComponent(
|
||||
BundleIconComponent(
|
||||
name: "Camera/FlashOffIcon",
|
||||
tintColor: nil
|
||||
tintColor: controlsTintColor
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -909,7 +945,10 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
content: AnyComponentWithIdentity(
|
||||
id: "dual",
|
||||
component: AnyComponent(
|
||||
DualIconComponent(isSelected: component.cameraState.isDualCameraEnabled)
|
||||
DualIconComponent(
|
||||
isSelected: component.cameraState.isDualCameraEnabled,
|
||||
tintColor: controlsTintColor
|
||||
)
|
||||
)
|
||||
),
|
||||
action: { [weak state] in
|
||||
@@ -938,7 +977,8 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
component: AnyComponent(
|
||||
FlipButtonContentComponent(
|
||||
action: animateFlipAction,
|
||||
maskFrame: .zero
|
||||
maskFrame: .zero,
|
||||
tintColor: controlsTintColor
|
||||
)
|
||||
)
|
||||
),
|
||||
@@ -971,7 +1011,7 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
let durationString = String(format: "%02d:%02d", (duration / 60) % 60, duration % 60)
|
||||
let timeLabel = timeLabel.update(
|
||||
component: MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: durationString, font: Font.with(size: 21.0, design: .camera), textColor: .white)),
|
||||
text: .plain(NSAttributedString(string: durationString, font: Font.with(size: 21.0, design: .camera), textColor: controlsTintColor)),
|
||||
horizontalAlignment: .center,
|
||||
textShadowColor: UIColor(rgb: 0x000000, alpha: 0.2)
|
||||
),
|
||||
@@ -1021,7 +1061,10 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
}
|
||||
if let hintText {
|
||||
let hintLabel = hintLabel.update(
|
||||
component: HintLabelComponent(text: hintText),
|
||||
component: HintLabelComponent(
|
||||
text: hintText,
|
||||
tintColor: controlsTintColor
|
||||
),
|
||||
availableSize: availableSize,
|
||||
transition: .immediate
|
||||
)
|
||||
@@ -1045,6 +1088,7 @@ private final class CameraScreenComponent: CombinedComponent {
|
||||
component: ModeComponent(
|
||||
isTablet: isTablet,
|
||||
strings: environment.strings,
|
||||
tintColor: controlsTintColor,
|
||||
availableModes: [.photo, .video],
|
||||
currentMode: component.cameraState.mode,
|
||||
updatedMode: { [weak state] mode in
|
||||
@@ -1358,6 +1402,7 @@ public class CameraScreen: ViewController {
|
||||
position: cameraFrontPosition ? .front : .back,
|
||||
flashMode: .off,
|
||||
flashModeDidChange: false,
|
||||
flashTint: .white,
|
||||
recording: .none,
|
||||
duration: 0.0,
|
||||
isDualCameraEnabled: isDualCameraEnabled
|
||||
@@ -2820,17 +2865,23 @@ private final class DualIconComponent: Component {
|
||||
typealias EnvironmentType = Empty
|
||||
|
||||
let isSelected: Bool
|
||||
let tintColor: UIColor
|
||||
|
||||
init(
|
||||
isSelected: Bool
|
||||
isSelected: Bool,
|
||||
tintColor: UIColor
|
||||
) {
|
||||
self.isSelected = isSelected
|
||||
self.tintColor = tintColor
|
||||
}
|
||||
|
||||
static func ==(lhs: DualIconComponent, rhs: DualIconComponent) -> Bool {
|
||||
if lhs.isSelected != rhs.isSelected {
|
||||
return false
|
||||
}
|
||||
if lhs.tintColor != rhs.tintColor {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -2849,7 +2900,7 @@ private final class DualIconComponent: Component {
|
||||
if let image = UIImage(bundleImageName: "Camera/DualIcon"), let cgImage = image.cgImage {
|
||||
context.draw(cgImage, in: CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - image.size.width) / 2.0), y: floorToScreenPixels((size.height - image.size.height) / 2.0) - 1.0), size: image.size))
|
||||
}
|
||||
})
|
||||
})?.withRenderingMode(.alwaysTemplate)
|
||||
|
||||
let selectedImage = generateImage(CGSize(width: 36.0, height: 36.0), rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: .zero, size: size))
|
||||
@@ -2861,7 +2912,7 @@ private final class DualIconComponent: Component {
|
||||
context.clip(to: CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - image.size.width) / 2.0), y: floorToScreenPixels((size.height - image.size.height) / 2.0) - 1.0), size: image.size), mask: cgImage)
|
||||
context.fill(CGRect(origin: .zero, size: size))
|
||||
}
|
||||
})
|
||||
})?.withRenderingMode(.alwaysTemplate)
|
||||
|
||||
self.iconView.image = image
|
||||
self.iconView.highlightedImage = selectedImage
|
||||
@@ -2886,6 +2937,8 @@ private final class DualIconComponent: Component {
|
||||
self.iconView.frame = CGRect(origin: .zero, size: size)
|
||||
self.iconView.isHighlighted = component.isSelected
|
||||
|
||||
self.iconView.tintColor = component.tintColor
|
||||
|
||||
return size
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ private extension SimpleShapeLayer {
|
||||
private final class ShutterButtonContentComponent: Component {
|
||||
let isTablet: Bool
|
||||
let hasAppeared: Bool
|
||||
let tintColor: UIColor
|
||||
let shutterState: ShutterButtonState
|
||||
let blobState: ShutterBlobView.BlobState
|
||||
let highlightedAction: ActionSlot<Bool>
|
||||
@@ -40,6 +41,7 @@ private final class ShutterButtonContentComponent: Component {
|
||||
init(
|
||||
isTablet: Bool,
|
||||
hasAppeared: Bool,
|
||||
tintColor: UIColor,
|
||||
shutterState: ShutterButtonState,
|
||||
blobState: ShutterBlobView.BlobState,
|
||||
highlightedAction: ActionSlot<Bool>,
|
||||
@@ -48,6 +50,7 @@ private final class ShutterButtonContentComponent: Component {
|
||||
) {
|
||||
self.isTablet = isTablet
|
||||
self.hasAppeared = hasAppeared
|
||||
self.tintColor = tintColor
|
||||
self.shutterState = shutterState
|
||||
self.blobState = blobState
|
||||
self.highlightedAction = highlightedAction
|
||||
@@ -62,6 +65,9 @@ private final class ShutterButtonContentComponent: Component {
|
||||
if lhs.hasAppeared != rhs.hasAppeared {
|
||||
return false
|
||||
}
|
||||
if lhs.tintColor != rhs.tintColor {
|
||||
return false
|
||||
}
|
||||
if lhs.shutterState != rhs.shutterState {
|
||||
return false
|
||||
}
|
||||
@@ -156,7 +162,7 @@ private final class ShutterButtonContentComponent: Component {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let innerColor: UIColor
|
||||
let innerSize: CGSize
|
||||
let ringSize: CGSize
|
||||
@@ -164,7 +170,7 @@ private final class ShutterButtonContentComponent: Component {
|
||||
var recordingProgress: Float?
|
||||
switch component.shutterState {
|
||||
case .generic, .disabled:
|
||||
innerColor = .white
|
||||
innerColor = component.tintColor
|
||||
innerSize = CGSize(width: 60.0, height: 60.0)
|
||||
ringSize = CGSize(width: 68.0, height: 68.0)
|
||||
case .video:
|
||||
@@ -188,7 +194,7 @@ private final class ShutterButtonContentComponent: Component {
|
||||
}
|
||||
|
||||
self.ringLayer.fillColor = UIColor.clear.cgColor
|
||||
self.ringLayer.strokeColor = UIColor.white.cgColor
|
||||
self.ringLayer.strokeColor = component.tintColor.cgColor
|
||||
self.ringLayer.lineWidth = ringWidth
|
||||
let ringPath = CGPath(
|
||||
ellipseIn: CGRect(
|
||||
@@ -204,7 +210,7 @@ private final class ShutterButtonContentComponent: Component {
|
||||
self.ringLayer.position = CGPoint(x: maximumShutterSize.width / 2.0, y: maximumShutterSize.height / 2.0)
|
||||
|
||||
if let blobView = self.blobView {
|
||||
blobView.updateState(component.blobState, transition: transition)
|
||||
blobView.updateState(component.blobState, tintColor: innerColor, transition: transition)
|
||||
if component.isTablet {
|
||||
blobView.bounds = CGRect(origin: .zero, size: CGSize(width: maximumShutterSize.width, height: 440.0))
|
||||
} else {
|
||||
@@ -247,14 +253,16 @@ private final class ShutterButtonContentComponent: Component {
|
||||
final class FlipButtonContentComponent: Component {
|
||||
private let action: ActionSlot<Void>
|
||||
private let maskFrame: CGRect
|
||||
private let tintColor: UIColor
|
||||
|
||||
init(action: ActionSlot<Void>, maskFrame: CGRect) {
|
||||
init(action: ActionSlot<Void>, maskFrame: CGRect, tintColor: UIColor) {
|
||||
self.action = action
|
||||
self.maskFrame = maskFrame
|
||||
self.tintColor = tintColor
|
||||
}
|
||||
|
||||
static func ==(lhs: FlipButtonContentComponent, rhs: FlipButtonContentComponent) -> Bool {
|
||||
return lhs.maskFrame == rhs.maskFrame
|
||||
return lhs.maskFrame == rhs.maskFrame && lhs.tintColor == rhs.tintColor
|
||||
}
|
||||
|
||||
final class View: UIView {
|
||||
@@ -280,7 +288,7 @@ final class FlipButtonContentComponent: Component {
|
||||
self.maskLayer.masksToBounds = true
|
||||
self.maskLayer.cornerRadius = 16.0
|
||||
|
||||
self.icon.contents = UIImage(bundleImageName: "Camera/FlipIcon")?.cgImage
|
||||
self.icon.contents = UIImage(bundleImageName: "Camera/FlipIcon")?.withRenderingMode(.alwaysTemplate).cgImage
|
||||
self.darkIcon.contents = UIImage(bundleImageName: "Camera/FlipIcon")?.cgImage
|
||||
self.darkIcon.layerTintColor = UIColor.black.cgColor
|
||||
}
|
||||
@@ -326,6 +334,8 @@ final class FlipButtonContentComponent: Component {
|
||||
|
||||
let size = CGSize(width: 48.0, height: 48.0)
|
||||
|
||||
self.icon.layerTintColor = component.tintColor.cgColor
|
||||
|
||||
self.icon.position = CGPoint(x: size.width / 2.0, y: size.height / 2.0)
|
||||
self.icon.bounds = CGRect(origin: .zero, size: size)
|
||||
|
||||
@@ -350,13 +360,15 @@ final class FlipButtonContentComponent: Component {
|
||||
|
||||
final class LockContentComponent: Component {
|
||||
private let maskFrame: CGRect
|
||||
private let tintColor: UIColor
|
||||
|
||||
init(maskFrame: CGRect) {
|
||||
init(maskFrame: CGRect, tintColor: UIColor) {
|
||||
self.maskFrame = maskFrame
|
||||
self.tintColor = tintColor
|
||||
}
|
||||
|
||||
static func ==(lhs: LockContentComponent, rhs: LockContentComponent) -> Bool {
|
||||
return lhs.maskFrame == rhs.maskFrame
|
||||
return lhs.maskFrame == rhs.maskFrame && lhs.tintColor == rhs.tintColor
|
||||
}
|
||||
|
||||
final class View: UIView {
|
||||
@@ -383,7 +395,7 @@ final class LockContentComponent: Component {
|
||||
self.maskLayer.masksToBounds = true
|
||||
self.maskLayer.cornerRadius = 24.0
|
||||
|
||||
self.icon.contents = UIImage(bundleImageName: "Camera/LockIcon")?.cgImage
|
||||
self.icon.contents = UIImage(bundleImageName: "Camera/LockIcon")?.withRenderingMode(.alwaysTemplate).cgImage
|
||||
self.darkIcon.contents = UIImage(bundleImageName: "Camera/LockedIcon")?.cgImage
|
||||
self.darkIcon.layerTintColor = UIColor.black.cgColor
|
||||
}
|
||||
@@ -397,6 +409,8 @@ final class LockContentComponent: Component {
|
||||
|
||||
let size = CGSize(width: 30.0, height: 30.0)
|
||||
|
||||
self.icon.layerTintColor = component.tintColor.cgColor
|
||||
|
||||
self.icon.position = CGPoint(x: size.width / 2.0, y: size.height / 2.0)
|
||||
self.icon.bounds = CGRect(origin: .zero, size: size)
|
||||
|
||||
@@ -447,6 +461,7 @@ final class CaptureControlsComponent: Component {
|
||||
let isTablet: Bool
|
||||
let hasAppeared: Bool
|
||||
let hasAccess: Bool
|
||||
let tintColor: UIColor
|
||||
let shutterState: ShutterButtonState
|
||||
let lastGalleryAsset: PHAsset?
|
||||
let tag: AnyObject?
|
||||
@@ -465,6 +480,7 @@ final class CaptureControlsComponent: Component {
|
||||
isTablet: Bool,
|
||||
hasAppeared: Bool,
|
||||
hasAccess: Bool,
|
||||
tintColor: UIColor,
|
||||
shutterState: ShutterButtonState,
|
||||
lastGalleryAsset: PHAsset?,
|
||||
tag: AnyObject?,
|
||||
@@ -482,6 +498,7 @@ final class CaptureControlsComponent: Component {
|
||||
self.isTablet = isTablet
|
||||
self.hasAppeared = hasAppeared
|
||||
self.hasAccess = hasAccess
|
||||
self.tintColor = tintColor
|
||||
self.shutterState = shutterState
|
||||
self.lastGalleryAsset = lastGalleryAsset
|
||||
self.tag = tag
|
||||
@@ -507,6 +524,9 @@ final class CaptureControlsComponent: Component {
|
||||
if lhs.hasAccess != rhs.hasAccess {
|
||||
return false
|
||||
}
|
||||
if lhs.tintColor != rhs.tintColor {
|
||||
return false
|
||||
}
|
||||
if lhs.shutterState != rhs.shutterState {
|
||||
return false
|
||||
}
|
||||
@@ -578,8 +598,7 @@ final class CaptureControlsComponent: Component {
|
||||
|
||||
private let shutterHightlightedAction = ActionSlot<Bool>()
|
||||
|
||||
private let lockImage = UIImage(bundleImageName: "Camera/LockIcon")
|
||||
private let zoomImage = UIImage(bundleImageName: "Camera/ZoomIcon")
|
||||
private let zoomImage = UIImage(bundleImageName: "Camera/ZoomIcon")?.withRenderingMode(.alwaysTemplate)
|
||||
|
||||
private var didFlip = false
|
||||
|
||||
@@ -946,8 +965,10 @@ final class CaptureControlsComponent: Component {
|
||||
transition.setBounds(view: galleryButtonView, bounds: CGRect(origin: .zero, size: galleryButtonFrame.size))
|
||||
transition.setPosition(view: galleryButtonView, position: galleryButtonFrame.center)
|
||||
|
||||
let normalAlpha = component.tintColor.rgb == 0xffffff ? 1.0 : 0.6
|
||||
|
||||
transition.setScale(view: galleryButtonView, scale: isRecording || isTransitioning ? 0.1 : 1.0)
|
||||
transition.setAlpha(view: galleryButtonView, alpha: isRecording || isTransitioning ? 0.0 : 1.0)
|
||||
transition.setAlpha(view: galleryButtonView, alpha: isRecording || isTransitioning ? 0.0 : normalAlpha)
|
||||
}
|
||||
|
||||
if !component.isTablet && component.hasAccess {
|
||||
@@ -963,7 +984,8 @@ final class CaptureControlsComponent: Component {
|
||||
component: AnyComponent(
|
||||
FlipButtonContentComponent(
|
||||
action: component.flipAnimationAction,
|
||||
maskFrame: flipButtonMaskFrame
|
||||
maskFrame: flipButtonMaskFrame,
|
||||
tintColor: component.tintColor
|
||||
)
|
||||
)
|
||||
),
|
||||
@@ -1011,6 +1033,7 @@ final class CaptureControlsComponent: Component {
|
||||
ShutterButtonContentComponent(
|
||||
isTablet: component.isTablet,
|
||||
hasAppeared: component.hasAppeared,
|
||||
tintColor: component.tintColor,
|
||||
shutterState: component.shutterState,
|
||||
blobState: blobState,
|
||||
highlightedAction: self.shutterHightlightedAction,
|
||||
@@ -1072,6 +1095,7 @@ final class CaptureControlsComponent: Component {
|
||||
component: AnyComponent(
|
||||
Image(
|
||||
image: self.zoomImage,
|
||||
tintColor: component.tintColor,
|
||||
size: hintIconSize
|
||||
)
|
||||
),
|
||||
@@ -1117,7 +1141,8 @@ final class CaptureControlsComponent: Component {
|
||||
id: "lock",
|
||||
component: AnyComponent(
|
||||
LockContentComponent(
|
||||
maskFrame: lockMaskFrame
|
||||
maskFrame: lockMaskFrame,
|
||||
tintColor: component.tintColor
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
@@ -21,6 +21,7 @@ private let buttonSize = CGSize(width: 55.0, height: 44.0)
|
||||
final class ModeComponent: Component {
|
||||
let isTablet: Bool
|
||||
let strings: PresentationStrings
|
||||
let tintColor: UIColor
|
||||
let availableModes: [CameraMode]
|
||||
let currentMode: CameraMode
|
||||
let updatedMode: (CameraMode) -> Void
|
||||
@@ -29,6 +30,7 @@ final class ModeComponent: Component {
|
||||
init(
|
||||
isTablet: Bool,
|
||||
strings: PresentationStrings,
|
||||
tintColor: UIColor,
|
||||
availableModes: [CameraMode],
|
||||
currentMode: CameraMode,
|
||||
updatedMode: @escaping (CameraMode) -> Void,
|
||||
@@ -36,6 +38,7 @@ final class ModeComponent: Component {
|
||||
) {
|
||||
self.isTablet = isTablet
|
||||
self.strings = strings
|
||||
self.tintColor = tintColor
|
||||
self.availableModes = availableModes
|
||||
self.currentMode = currentMode
|
||||
self.updatedMode = updatedMode
|
||||
@@ -49,6 +52,9 @@ final class ModeComponent: Component {
|
||||
if lhs.strings !== rhs.strings {
|
||||
return false
|
||||
}
|
||||
if lhs.tintColor != rhs.tintColor {
|
||||
return false
|
||||
}
|
||||
if lhs.availableModes != rhs.availableModes {
|
||||
return false
|
||||
}
|
||||
@@ -82,8 +88,17 @@ final class ModeComponent: Component {
|
||||
self.pressed()
|
||||
}
|
||||
|
||||
func update(value: String, selected: Bool) {
|
||||
self.setAttributedTitle(NSAttributedString(string: value.uppercased(), font: Font.with(size: 14.0, design: .camera, weight: .semibold), textColor: selected ? UIColor(rgb: 0xf8d74a) : .white, paragraphAlignment: .center), for: .normal)
|
||||
func update(value: String, selected: Bool, tintColor: UIColor) {
|
||||
let accentColor: UIColor
|
||||
let normalColor: UIColor
|
||||
if tintColor.rgb == 0xffffff {
|
||||
accentColor = UIColor(rgb: 0xf8d74a)
|
||||
normalColor = .white
|
||||
} else {
|
||||
accentColor = tintColor
|
||||
normalColor = tintColor.withAlphaComponent(0.5)
|
||||
}
|
||||
self.setAttributedTitle(NSAttributedString(string: value.uppercased(), font: Font.with(size: 14.0, design: .camera, weight: .semibold), textColor: selected ? accentColor : normalColor, paragraphAlignment: .center), for: .normal)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +167,7 @@ final class ModeComponent: Component {
|
||||
updatedMode(mode)
|
||||
}
|
||||
|
||||
itemView.update(value: mode.title(strings: component.strings), selected: mode == component.currentMode)
|
||||
itemView.update(value: mode.title(strings: component.strings), selected: mode == component.currentMode, tintColor: component.tintColor)
|
||||
itemView.bounds = CGRect(origin: .zero, size: itemFrame.size)
|
||||
|
||||
if isTablet {
|
||||
@@ -199,17 +214,23 @@ final class ModeComponent: Component {
|
||||
|
||||
final class HintLabelComponent: Component {
|
||||
let text: String
|
||||
let tintColor: UIColor
|
||||
|
||||
init(
|
||||
text: String
|
||||
text: String,
|
||||
tintColor: UIColor
|
||||
) {
|
||||
self.text = text
|
||||
self.tintColor = tintColor
|
||||
}
|
||||
|
||||
static func ==(lhs: HintLabelComponent, rhs: HintLabelComponent) -> Bool {
|
||||
if lhs.text != rhs.text {
|
||||
return false
|
||||
}
|
||||
if lhs.tintColor != rhs.tintColor {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -247,7 +268,7 @@ final class HintLabelComponent: Component {
|
||||
transition: .immediate,
|
||||
component: AnyComponent(
|
||||
MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: component.text.uppercased(), font: Font.with(size: 14.0, design: .camera, weight: .semibold), textColor: .white)),
|
||||
text: .plain(NSAttributedString(string: component.text.uppercased(), font: Font.with(size: 14.0, design: .camera, weight: .semibold), textColor: component.tintColor)),
|
||||
horizontalAlignment: .center
|
||||
)
|
||||
),
|
||||
|
||||
@@ -64,7 +64,6 @@ private final class AnimatableProperty<T: Interpolatable> {
|
||||
}
|
||||
|
||||
func tick(timestamp: Double) -> Bool {
|
||||
|
||||
guard let animation = self.animation, case let .curve(duration, curve) = animation.animation else {
|
||||
return false
|
||||
}
|
||||
@@ -163,10 +162,14 @@ final class ShutterBlobView: UIView {
|
||||
}
|
||||
}
|
||||
|
||||
var primaryRedness: CGFloat {
|
||||
func primaryRedness(tintColor: UIColor) -> CGFloat {
|
||||
switch self {
|
||||
case .generic:
|
||||
return 0.0
|
||||
if tintColor.rgb == 0x000000 {
|
||||
return -1.0
|
||||
} else {
|
||||
return 0.0
|
||||
}
|
||||
default:
|
||||
return 1.0
|
||||
}
|
||||
@@ -290,14 +293,14 @@ final class ShutterBlobView: UIView {
|
||||
self.displayLink?.invalidate()
|
||||
}
|
||||
|
||||
func updateState(_ state: BlobState, transition: Transition = .immediate) {
|
||||
func updateState(_ state: BlobState, tintColor: UIColor, transition: Transition = .immediate) {
|
||||
guard self.state != state else {
|
||||
return
|
||||
}
|
||||
self.state = state
|
||||
|
||||
|
||||
self.primarySize.update(value: state.primarySize, transition: transition)
|
||||
self.primaryRedness.update(value: state.primaryRedness, transition: transition)
|
||||
self.primaryRedness.update(value: state.primaryRedness(tintColor: tintColor), transition: transition)
|
||||
self.primaryCornerRadius.update(value: state.primaryCornerRadius, transition: transition)
|
||||
self.secondarySize.update(value: state.secondarySize, transition: transition)
|
||||
self.secondaryRedness.update(value: state.secondaryRedness, transition: transition)
|
||||
@@ -453,7 +456,6 @@ final class ShutterBlobView: UIView {
|
||||
renderEncoder.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: 6, instanceCount: 1)
|
||||
renderEncoder.endEncoding()
|
||||
|
||||
|
||||
var storedDrawable: MetalImageLayer.Drawable? = drawable
|
||||
commandBuffer.addCompletedHandler { _ in
|
||||
DispatchQueue.main.async {
|
||||
|
||||
Reference in New Issue
Block a user