Wallpaper fixes

This commit is contained in:
Ilya Laktyushin 2019-01-28 23:03:05 +03:00
parent da044344ab
commit 4e46f2f90e
14 changed files with 1370 additions and 1324 deletions

View File

@ -134,7 +134,7 @@ class AutodownloadSizeLimitItemNode: ListViewItemNode {
value = CGFloat(index)
sliderView.value = value
sliderView.backgroundColor = item.theme.list.itemBlocksBackgroundColor
sliderView.backColor = item.theme.list.itemSecondaryTextColor
sliderView.backColor = item.theme.list.disclosureArrowColor
sliderView.trackColor = item.theme.list.itemAccentColor
sliderView.knobImage = generateKnobImage()
@ -211,7 +211,7 @@ class AutodownloadSizeLimitItemNode: ListViewItemNode {
if let sliderView = strongSelf.sliderView {
if themeUpdated {
sliderView.backgroundColor = item.theme.list.itemBlocksBackgroundColor
sliderView.backColor = item.theme.list.itemSecondaryTextColor
sliderView.backColor = item.theme.list.disclosureArrowColor
sliderView.trackColor = item.theme.list.itemAccentColor
sliderView.knobImage = generateKnobImage()
}

View File

@ -51,11 +51,13 @@ func imageHasTransparency(_ cgImage: CGImage) -> Bool {
return false
}
if let (histogramBins, alphaBinIndex) = generateHistogram(cgImage: cgImage) {
let opaqueCount: vImagePixelCount = histogramBins[alphaBinIndex][255]
var transparentCount: vImagePixelCount = 0
for i in 0 ..< 255 {
if histogramBins[alphaBinIndex][i] > 0 {
return true
}
transparentCount += histogramBins[alphaBinIndex][i]
}
let totalCount = opaqueCount + transparentCount
return Double(transparentCount) / Double(totalCount) > 0.02
}
return false
}

File diff suppressed because it is too large Load Diff

View File

@ -369,7 +369,7 @@ final class ThemeGridControllerNode: ASDisplayNode {
}
for wallpaper in sortedWallpapers {
if case let .file(file) = wallpaper, deletedWallpaperSlugs.contains(file.slug) {
if case let .file(file) = wallpaper, deletedWallpaperSlugs.contains(file.slug) || file.isPattern {
continue
}
let selected = areWallpapersEqual(presentationData.chatWallpaper, wallpaper)

View File

@ -80,7 +80,7 @@ final class ThemeGridSearchItemNode: GridItemNode {
if let largestRepresentation = largestImageRepresentation(image.representations) {
imageDimensions = largestRepresentation.dimensions
}
imageResource = imageRepresentationLargerThan(image.representations, size: CGSize(width: 200.0, height: 100.0))?.resource
imageResource = imageRepresentationLargerThan(image.representations, size: CGSize(width: 600.0, height: 600.0))?.resource
if let file = file {
if let thumbnailRepresentation = smallestImageRepresentation(file.previewRepresentations) {
thumbnailDimensions = thumbnailRepresentation.dimensions

View File

@ -112,7 +112,7 @@ class ThemeSettingsBrightnessItemNode: ListViewItemNode {
if let item = self.item, let params = self.layoutParams {
sliderView.value = CGFloat(item.value)
sliderView.backgroundColor = item.theme.list.itemBlocksBackgroundColor
sliderView.backColor = item.theme.list.itemSecondaryTextColor
sliderView.backColor = item.theme.list.disclosureArrowColor
sliderView.trackColor = item.theme.list.itemAccentColor
sliderView.knobImage = generateKnobImage()

View File

@ -132,7 +132,7 @@ class ThemeSettingsFontSizeItemNode: ListViewItemNode {
}
sliderView.value = value
sliderView.backgroundColor = item.theme.list.itemBlocksBackgroundColor
sliderView.backColor = item.theme.list.itemSecondaryTextColor
sliderView.backColor = item.theme.list.disclosureArrowColor
sliderView.trackColor = item.theme.list.itemAccentColor
sliderView.knobImage = generateKnobImage()
@ -222,7 +222,7 @@ class ThemeSettingsFontSizeItemNode: ListViewItemNode {
if let sliderView = strongSelf.sliderView {
if themeUpdated {
sliderView.backgroundColor = item.theme.list.itemBlocksBackgroundColor
sliderView.backColor = item.theme.list.itemSecondaryTextColor
sliderView.backColor = item.theme.list.disclosureArrowColor
sliderView.trackColor = item.theme.list.itemAccentColor
sliderView.knobImage = generateKnobImage()
}

View File

@ -382,7 +382,6 @@ final class WallpaperColorPickerNode: ASDisplayNode {
private let brightnessNode: WallpaperColorBrightnessNode
private let brightnessKnobNode: ASImageNode
private let backgroundNode: WallpaperIntensityPickerNode
private let intensityNode: WallpaperIntensityPickerNode
private let colorNode: WallpaperColorHueSaturationNode
@ -409,7 +408,6 @@ final class WallpaperColorPickerNode: ASDisplayNode {
if newHSV != self.colorHSV {
self.colorHSV = newHSV
self.backgroundNode.value = 1.0 - self.colorHSV.2
self.update()
}
}
@ -433,7 +431,6 @@ final class WallpaperColorPickerNode: ASDisplayNode {
let value = self.adjustingPattern
self.brightnessNode.isHidden = value
self.brightnessKnobNode.isHidden = value
self.backgroundNode.isHidden = !value
self.intensityNode.isHidden = !value
self.setNeedsLayout()
}
@ -448,8 +445,6 @@ final class WallpaperColorPickerNode: ASDisplayNode {
self.colorNode.hitTestSlop = UIEdgeInsetsMake(-16.0, -16.0, -16.0, -16.0)
self.colorKnobNode = WallpaperColorKnobNode()
self.backgroundNode = WallpaperIntensityPickerNode(theme: nil, title: strings.WallpaperPreview_PatternColor, bordered: true)
self.backgroundNode.isHidden = true
self.intensityNode = WallpaperIntensityPickerNode(theme: nil, title: strings.WallpaperPreview_PatternIntensity, bordered: true)
self.intensityNode.isHidden = true
@ -462,7 +457,6 @@ final class WallpaperColorPickerNode: ASDisplayNode {
self.addSubnode(self.brightnessKnobNode)
self.addSubnode(self.colorNode)
self.addSubnode(self.colorKnobNode)
self.addSubnode(self.backgroundNode)
self.addSubnode(self.intensityNode)
let valueChanged: (CGFloat, Bool) -> Void = { [weak self] value, ended in
@ -481,14 +475,6 @@ final class WallpaperColorPickerNode: ASDisplayNode {
}
}
self.backgroundNode.valueChanged = { value in
valueChanged(value, false)
}
self.backgroundNode.valueChangeEnded = { value in
valueChanged(value, true)
}
self.intensityNode.valueChanged = { [weak self] value in
if let strongSelf = self {
strongSelf.intensityChanged?(Int32(value * 100.0))
@ -530,7 +516,6 @@ final class WallpaperColorPickerNode: ASDisplayNode {
let min = self.colorHSV
let max = patternColor(for: self.color, intensity: 1.0).hsv
self.intensityNode.updateExtrema(min: min, max: max)
self.backgroundNode.updateExtrema(min: self.colorHSV, max: (self.colorHSV.0, self.colorHSV.1, 0.0))
}
func updateKnobLayout(size: CGSize, panningColor: Bool, transition: ContainedViewLayoutTransition) {
@ -563,10 +548,9 @@ final class WallpaperColorPickerNode: ASDisplayNode {
transition.updateFrame(node: self.brightnessNode, frame: CGRect(x: inset, y: size.height - 55.0, width: size.width - inset * 2.0, height: 29.0))
let slidersInset: CGFloat = 24.0
transition.updateFrame(node: self.backgroundNode, frame: CGRect(x: slidersInset, y: size.height - 103.0, width: size.width - slidersInset * 2.0, height: 50.0))
transition.updateFrame(node: self.intensityNode, frame: CGRect(x: slidersInset, y: size.height - 54.0, width: size.width - slidersInset * 2.0, height: 50.0))
self.updateKnobLayout(size: size, panningColor: false, transition: transition)
self.updateKnobLayout(size: size, panningColor: false, transition: .immediate)
}
@objc private func colorTap(_ recognizer: UITapGestureRecognizer) {

View File

@ -94,6 +94,12 @@ private func updatedFileWallpaper(id: Int64? = nil, accessHash: Int64? = nil, sl
return .file(id: id ?? 0, accessHash: accessHash ?? 0, isCreator: false, isDefault: false, isPattern: isPattern, slug: slug, file: file, settings: WallpaperSettings(blur: false, motion: false, color: colorValue, intensity: intensityValue))
}
private struct WallpaperPatternTransition: Equatable {
let pattern: TelegramWallpaper
let intensity: Int32?
let preview: Bool
}
class WallpaperGalleryController: ViewController {
private var galleryNode: GalleryControllerNode {
return self.displayNode as! GalleryControllerNode
@ -118,6 +124,8 @@ class WallpaperGalleryController: ViewController {
private var entries: [WallpaperGalleryEntry] = []
private var centralEntryIndex: Int?
private let patternTransition = Promise<WallpaperPatternTransition?>()
private let centralItemSubtitle = Promise<String?>()
private let centralItemStatus = Promise<MediaResourceStatus>()
private let centralItemAction = Promise<UIBarButtonItem?>()
@ -223,6 +231,12 @@ class WallpaperGalleryController: ViewController {
strongSelf.navigationItem.rightBarButtonItem = barButton
}
}))
self.centralItemAttributesDisposable.add(self.patternTransition.get().start(next: { [weak self] transition in
if let strongSelf = self, let transition = transition {
strongSelf.updateEntries(pattern: transition.pattern, intensity: transition.intensity, preview: transition.preview)
}
}))
}
required init(coder aDecoder: NSCoder) {
@ -437,21 +451,6 @@ class WallpaperGalleryController: ViewController {
}
}
if let entry = node.entry, case let .wallpaper(wallpaper) = entry {
var entryColor: UIColor = .white
switch wallpaper {
case let .color(color):
entryColor = UIColor(rgb: UInt32(bitPattern: color))
case let .file(file):
if let color = file.settings.color {
entryColor = UIColor(rgb: UInt32(bitPattern: color))
}
default:
break
}
self.patternPanelNode?.color = entryColor
}
if let (layout, bottomInset) = self.validLayout {
self.updateMessagesLayout(layout: layout, bottomInset: bottomInset, transition: .immediate)
}
@ -643,10 +642,13 @@ class WallpaperGalleryController: ViewController {
if let patternPanelNode = self.patternPanelNode {
currentPatternPanelNode = patternPanelNode
} else {
let intensityValue = ThrottledValue<WallpaperPatternTransition?>(value: nil, interval: 0.01)
self.patternTransition.set(intensityValue.get())
let patternPanelNode = WallpaperPatternPanelNode(account: self.account, theme: presentationData.theme, strings: presentationData.strings)
patternPanelNode.patternChanged = { [weak self] pattern, intensity, preview in
if let strongSelf = self, strongSelf.validLayout != nil {
strongSelf.updateEntries(pattern: pattern, intensity: intensity, preview: preview)
intensityValue.set(value: WallpaperPatternTransition(pattern: pattern, intensity: intensity, preview: preview))
}
}
self.patternPanelNode = patternPanelNode

View File

@ -15,6 +15,8 @@ final class WallpaperOptionButtonNode: HighlightTrackingButtonNode {
private let colorNode: ASImageNode
private let textNode: ASTextNode
private var textSize: CGSize?
private var _value: WallpaperOptionButtonValue
override var isSelected: Bool {
get {
@ -140,21 +142,32 @@ final class WallpaperOptionButtonNode: HighlightTrackingButtonNode {
self.isUserInteractionEnabled = enabled
}
// override func measure(_ constrainedSize: CGSize) -> CGSize {
// let size = self.textNode.measure(constrainedSize)
// return CGSize(width: size.width + 56.0, height: 30.0)
// }
override func measure(_ constrainedSize: CGSize) -> CGSize {
let size = self.textNode.measure(constrainedSize)
self.textSize = size
return CGSize(width: ceil(size.width) + 52.0, height: 30.0)
}
override func layout() {
super.layout()
self.backgroundNode.frame = self.bounds
let checkSize = CGSize(width: 18.0, height: 18.0)
self.checkNode.frame = CGRect(origin: CGPoint(x: 12.0, y: 6.0), size: checkSize)
self.colorNode.frame = CGRect(origin: CGPoint(x: 12.0, y: 6.0), size: checkSize)
guard let textSize = self.textSize else {
return
}
self.textNode.frame = CGRect(x: 39.0, y: 6.0 + UIScreenPixel, width: 100.0, height: 20.0)
let checkSize = CGSize(width: 18.0, height: 18.0)
let spacing: CGFloat = 9.0
let totalWidth = checkSize.width + spacing + textSize.width
let origin = floor((self.bounds.width - totalWidth) / 2.0)
self.checkNode.frame = CGRect(origin: CGPoint(x: origin, y: 6.0), size: checkSize)
self.colorNode.frame = CGRect(origin: CGPoint(x: origin, y: 6.0), size: checkSize)
if let textSize = self.textSize {
self.textNode.frame = CGRect(x: origin + checkSize.width + spacing, y: 6.0 + UIScreenPixel, width: textSize.width, height: textSize.height)
}
}
}

View File

@ -639,7 +639,13 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
}
func updateButtonsLayout(layout: ContainerViewLayout, offset: CGPoint, transition: ContainedViewLayoutTransition) {
let buttonSize = CGSize(width: 100.0, height: 30.0)
let patternButtonSize = self.patternButtonNode.measure(layout.size)
let colorButtonSize = self.colorButtonNode.measure(layout.size)
let blurButtonSize = self.blurButtonNode.measure(layout.size)
let motionButtonSize = self.motionButtonNode.measure(layout.size)
let maxButtonWidth = max(patternButtonSize.width, max(colorButtonSize.width, max(blurButtonSize.width, motionButtonSize.width)))
let buttonSize = CGSize(width: maxButtonWidth, height: 30.0)
let alpha = 1.0 - min(1.0, max(0.0, abs(offset.y) / 50.0))
var additionalYOffset: CGFloat = 0.0
@ -695,19 +701,18 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
motionFrame = rightButtonFrame
case let .file(file):
if file.isPattern {
motionAlpha = 1.0
if self.arguments.isColorsList {
patternAlpha = 1.0
if self.patternButtonNode.isSelected {
patternFrame = leftButtonFrame
}
} else {
colorAlpha = 1.0
colorFrame = leftButtonFrame
}
if !self.arguments.isColorsList || self.patternButtonNode.isSelected {
motionAlpha = 1.0
motionFrame = rightButtonFrame
}
// if !self.arguments.isColorsList || self.patternButtonNode.isSelected {
// motionAlpha = 1.0
// motionFrame = rightButtonFrame
// }
} else {
blurAlpha = 1.0
blurFrame = leftButtonFrame

View File

@ -4,6 +4,8 @@ import SwiftSignalKit
import Display
import TelegramCore
import LegacyComponents
private let itemSize = CGSize(width: 88.0, height: 88.0)
private let inset: CGFloat = 12.0
@ -14,20 +16,14 @@ final class WallpaperPatternPanelNode: ASDisplayNode {
private let topSeparatorNode: ASDisplayNode
private let scrollNode: ASScrollNode
private let intensityNode: WallpaperIntensityPickerNode
private let labelNode: ASTextNode
private var sliderView: TGPhotoEditorSliderView?
private var disposable: Disposable?
private var wallpapers: [TelegramWallpaper] = []
private var currentWallpaper: TelegramWallpaper?
var color: UIColor = .white {
didSet {
let min = self.color.hsv
let max = patternColor(for: self.color, intensity: 1.0).hsv
self.intensityNode.updateExtrema(min: min, max: max)
}
}
var patternChanged: ((TelegramWallpaper, Int32?, Bool) -> Void)?
init(account: Account, theme: PresentationTheme, strings: PresentationStrings) {
@ -41,15 +37,16 @@ final class WallpaperPatternPanelNode: ASDisplayNode {
self.scrollNode = ASScrollNode()
self.intensityNode = WallpaperIntensityPickerNode(theme: theme, title: strings.WallpaperPreview_PatternIntensity, bordered: false)
self.intensityNode.value = 0.4
self.labelNode = ASTextNode()
self.labelNode.attributedText = NSAttributedString(string: strings.WallpaperPreview_PatternIntensity, font: Font.regular(14.0), textColor: theme.rootController.navigationBar.primaryTextColor)
super.init()
self.addSubnode(self.backgroundNode)
self.addSubnode(self.topSeparatorNode)
self.addSubnode(self.scrollNode)
self.addSubnode(self.intensityNode)
self.addSubnode(self.labelNode)
self.disposable = ((telegramWallpapers(postbox: account.postbox, network: account.network)
|> map { wallpapers in
@ -85,7 +82,9 @@ final class WallpaperPatternPanelNode: ASDisplayNode {
node.pressed = { [weak self, weak node] in
if let strongSelf = self {
strongSelf.currentWallpaper = updatedWallpaper
strongSelf.patternChanged?(updatedWallpaper, Int32(strongSelf.intensityNode.value * 100), false)
if let sliderView = strongSelf.sliderView {
strongSelf.patternChanged?(updatedWallpaper, Int32(sliderView.value), false)
}
if let subnodes = strongSelf.scrollNode.subnodes {
for case let subnode as SettingsThemeWallpaperNode in subnodes {
subnode.setSelected(node === subnode, animated: true)
@ -103,18 +102,6 @@ final class WallpaperPatternPanelNode: ASDisplayNode {
strongSelf.wallpapers = wallpapers
}
}))
self.intensityNode.valueChanged = { [weak self] value in
if let strongSelf = self, let wallpaper = strongSelf.currentWallpaper {
strongSelf.patternChanged?(wallpaper, strongSelf.intensityNode.intensity, true)
}
}
self.intensityNode.valueChangeEnded = { [weak self] value in
if let strongSelf = self, let wallpaper = strongSelf.currentWallpaper {
strongSelf.patternChanged?(wallpaper, strongSelf.intensityNode.intensity, false)
}
}
}
deinit {
@ -127,12 +114,39 @@ final class WallpaperPatternPanelNode: ASDisplayNode {
self.scrollNode.view.showsHorizontalScrollIndicator = false
self.scrollNode.view.showsVerticalScrollIndicator = false
self.scrollNode.view.alwaysBounceHorizontal = true
let sliderView = TGPhotoEditorSliderView()
//sliderView.enablePanHandling = true
sliderView.trackCornerRadius = 1.0
sliderView.lineSize = 2.0
sliderView.minimumValue = 0.0
sliderView.startValue = 0.0
sliderView.maximumValue = 100.0
sliderView.value = 40.0
sliderView.disablesInteractiveTransitionGestureRecognizer = true
sliderView.backgroundColor = .clear
sliderView.backColor = self.theme.list.disclosureArrowColor
sliderView.trackColor = self.theme.list.itemAccentColor
self.view.addSubview(sliderView)
sliderView.addTarget(self, action: #selector(self.sliderValueChanged), for: .valueChanged)
self.sliderView = sliderView
}
@objc func sliderValueChanged() {
guard let sliderView = self.sliderView else {
return
}
if let wallpaper = self.currentWallpaper {
self.patternChanged?(wallpaper, Int32(sliderView.value), sliderView.isTracking)
}
}
func didAppear() {
if let wallpaper = self.wallpapers.first {
self.currentWallpaper = wallpaper
self.intensityNode.value = 0.4
self.sliderView?.value = 40.0
self.scrollNode.view.contentOffset = CGPoint()
@ -144,7 +158,9 @@ final class WallpaperPatternPanelNode: ASDisplayNode {
}
}
self.patternChanged?(wallpaper, self.intensityNode.intensity, false)
if let wallpaper = self.currentWallpaper, let sliderView = self.sliderView {
self.patternChanged?(wallpaper, Int32(sliderView.value), false)
}
}
}
@ -153,7 +169,11 @@ final class WallpaperPatternPanelNode: ASDisplayNode {
transition.updateFrame(node: self.backgroundNode, frame: CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height))
transition.updateFrame(node: self.topSeparatorNode, frame: CGRect(x: 0.0, y: 0.0, width: size.width, height: separatorHeight))
transition.updateFrame(node: self.scrollNode, frame: CGRect(x: 0.0, y: 0.0, width: size.width, height: 114.0))
transition.updateFrame(node: self.intensityNode, frame: CGRect(x: 16.0, y: 114.0 + 13.0, width: size.width - 16.0 * 2.0, height: 50.0))
let labelSize = self.labelNode.measure(self.bounds.size)
transition.updateFrame(node: labelNode, frame: CGRect(origin: CGPoint(x: 14.0, y: 128.0), size: labelSize))
self.sliderView?.frame = CGRect(origin: CGPoint(x: 15.0, y: 136.0), size: CGSize(width: size.width - 15.0 * 2.0, height: 44.0))
self.layoutItemNodes(transition: transition)
}

View File

@ -9,8 +9,8 @@ private func wallpaperDatas(account: Account, fileReference: FileMediaReference?
if let smallestRepresentation = smallestImageRepresentation(representations.map({ $0.representation })), let largestRepresentation = largestImageRepresentation(representations.map({ $0.representation })), let smallestIndex = representations.index(where: { $0.representation == smallestRepresentation }), let largestIndex = representations.index(where: { $0.representation == largestRepresentation }) {
let maybeFullSize: Signal<MediaResourceData, NoError>
if thumbnail {
maybeFullSize = account.postbox.mediaBox.cachedResourceRepresentation(largestRepresentation.resource, representation: CachedScaledImageRepresentation(size: CGSize(width: 320.0, height: 320.0), mode: .aspectFit), complete: false, fetch: false)
if thumbnail, let file = fileReference?.media {
maybeFullSize = account.postbox.mediaBox.cachedResourceRepresentation(file.resource, representation: CachedScaledImageRepresentation(size: CGSize(width: 720.0, height: 720.0), mode: .aspectFit), complete: false, fetch: false)
} else {
maybeFullSize = account.postbox.mediaBox.resourceData(largestRepresentation.resource)
}
@ -38,11 +38,11 @@ private func wallpaperDatas(account: Account, fileReference: FileMediaReference?
let fetchedFullSize = fetchedMediaResource(postbox: account.postbox, reference: representations[largestIndex].reference)
let thumbnail: Signal<Data?, NoError>
let thumbnailData: Signal<Data?, NoError>
if let decodedThumbnailData = decodedThumbnailData {
thumbnail = .single(decodedThumbnailData)
thumbnailData = .single(decodedThumbnailData)
} else {
thumbnail = Signal<Data?, NoError> { subscriber in
thumbnailData = Signal<Data?, NoError> { subscriber in
let fetchedDisposable = fetchedThumbnail.start()
let thumbnailDisposable = account.postbox.mediaBox.resourceData(smallestRepresentation.resource).start(next: { next in
subscriber.putNext(next.size == 0 ? nil : try? Data(contentsOf: URL(fileURLWithPath: next.path), options: []))
@ -55,11 +55,11 @@ private func wallpaperDatas(account: Account, fileReference: FileMediaReference?
}
}
let fullSizeData: Signal<(Data?, Bool), NoError>
var fullSizeData: Signal<(Data?, Bool), NoError>
if autoFetchFullSize {
fullSizeData = Signal<(Data?, Bool), NoError> { subscriber in
let fetchedFullSizeDisposable = fetchedFullSize.start()
let fullSizeDisposable = account.postbox.mediaBox.resourceData(largestRepresentation.resource).start(next: { next in
subscriber.putNext((next.size == 0 ? nil : try? Data(contentsOf: URL(fileURLWithPath: next.path), options: []), next.complete))
}, error: subscriber.putError, completed: subscriber.putCompletion)
@ -76,14 +76,35 @@ private func wallpaperDatas(account: Account, fileReference: FileMediaReference?
}
}
return thumbnail |> mapToSignal { thumbnailData in
if thumbnail, let file = fileReference?.media {
let betterThumbnailData = account.postbox.mediaBox.cachedResourceRepresentation(file.resource, representation: CachedScaledImageRepresentation(size: CGSize(width: 720.0, height: 720.0), mode: .aspectFit), complete: false, fetch: true)
|> map { next -> (Data?, Bool) in
return (next.size == 0 ? nil : try? Data(contentsOf: URL(fileURLWithPath: next.path), options: []), next.complete)
}
return thumbnailData |> mapToSignal { thumbnailData in
return fullSizeData |> mapToSignal { (fullSizeData, complete) in
if complete {
return .single((thumbnailData, fullSizeData, complete))
|> then(
betterThumbnailData |> map { (betterFullSizeData, complete) in
return (thumbnailData, betterFullSizeData ?? fullSizeData, complete)
})
} else {
return .single((thumbnailData, fullSizeData, complete))
}
}
}
} else {
return thumbnailData |> mapToSignal { thumbnailData in
return fullSizeData |> map { (fullSizeData, complete) in
return (thumbnailData, fullSizeData, complete)
}
}
}
}
} |> filter({ $0.0 != nil || $0.1 != nil })
return signal
} else {
return .never()