Skip to content

Instantly share code, notes, and snippets.

@mgp
Created November 3, 2015 18:44
Show Gist options
  • Save mgp/9af5efb6399472e32c89 to your computer and use it in GitHub Desktop.
Save mgp/9af5efb6399472e32c89 to your computer and use it in GitHub Desktop.
visible thumbnail tracker
//
// Blehhhh.swift
// Khan Academy
//
// Created by Mike Parker on 11/2/15.
// Copyright © 2015 Khan Academy. All rights reserved.
//
import UIKit
import KHACore
public class Blehhhh: NSObject {
/// Emits thumbnails as they become available for content item identifiers which have been designated as visible with setVisibleContentItems(:). Always emits an initial value, but values may trail behind the cells that are currently visible (as thumbnails are fetched and rendered).
public var thumbnailMappingSignal: RACSignal/*<Box<[ContentItemIdentifier: UIImage]>>*/ { return visibleContentItemIdentifierToThumbnailsSubject }
private let thumbnailStore: ThumbnailStore
private let preferredThumbnailSize: CGSize
private var visibleContentItems: Set<ContentItem> = []
private let visibleContentItemIdentifierToThumbnailsSubject = RACReplaySubject/*<Box<[ContentItemIdentifier: UIImage]>>*/(capacity: 1)
private var visibleContentItemIdentifierToThumbnails = [ContentItemIdentifier: UIImage]()
private var contentItemIdentifierToThumbnailSubscriptions = [ContentItemIdentifier: RACDisposable]()
init(thumbnailStore: ThumbnailStore, preferredThumbnailSize: CGSize) {
self.thumbnailStore = thumbnailStore
self.preferredThumbnailSize = preferredThumbnailSize
}
deinit {
visibleContentItemIdentifierToThumbnailsSubject.sendCompleted()
}
public func setVisibleContentItems(visibleContentItems: Set<ContentItem>, contentItemsAndTopicTreePaths: [(ContentItem, TopicTreePath)]) {
// TODO(andy): I'd like to use aggregateWithStart, but RAC chokes because Box isn't an NSObject?! Revisit with RAC 3.
let previousVisibleContentItems = self.visibleContentItems
let addedContentItems = visibleContentItems.subtract(previousVisibleContentItems)
let removedContentItems = previousVisibleContentItems.subtract(visibleContentItems)
self.visibleContentItems = visibleContentItems
let contentItemsToTopicTreePaths = Dictionary(elements: contentItemsAndTopicTreePaths)
for addedContentItem in addedContentItems {
let addedContentItemID = addedContentItem.contentItemID
let subscription = self.thumbnailStore.thumbnailSignalForContentItem(addedContentItem, topicTreePath: contentItemsToTopicTreePaths[addedContentItem].flatMap { $0 }, size: preferredThumbnailSize)
.deliverOn(RACScheduler.mainThreadScheduler())
.takeUntil(rac_willDeallocSignal())
.subscribeNext { [unowned self] in
let image = $0 as! UIImage
self.visibleContentItemIdentifierToThumbnails[addedContentItemID] = image
self.visibleContentItemIdentifierToThumbnailsSubject.sendNext(Box(self.visibleContentItemIdentifierToThumbnails))
}
contentItemIdentifierToThumbnailSubscriptions[addedContentItemID] = subscription
}
for removedContentItem in removedContentItems {
let removedContentItemID = removedContentItem.contentItemID
visibleContentItemIdentifierToThumbnails[removedContentItemID] = nil
contentItemIdentifierToThumbnailSubscriptions[removedContentItemID]?.dispose()
contentItemIdentifierToThumbnailSubscriptions[removedContentItemID] = nil
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment