forked from shadowfacts/Tusker
parent
82ad3b9fc4
commit
1c9b1b9ac3
|
@ -134,6 +134,8 @@
|
||||||
D64D0AB12128D9AE005A6F37 /* OnboardingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64D0AB02128D9AE005A6F37 /* OnboardingViewController.swift */; };
|
D64D0AB12128D9AE005A6F37 /* OnboardingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64D0AB02128D9AE005A6F37 /* OnboardingViewController.swift */; };
|
||||||
D64D8CA92463B494006B0BAA /* CachedDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64D8CA82463B494006B0BAA /* CachedDictionary.swift */; };
|
D64D8CA92463B494006B0BAA /* CachedDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64D8CA82463B494006B0BAA /* CachedDictionary.swift */; };
|
||||||
D64F80E2215875CC00BEF393 /* XCBActionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64F80E1215875CC00BEF393 /* XCBActionType.swift */; };
|
D64F80E2215875CC00BEF393 /* XCBActionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64F80E1215875CC00BEF393 /* XCBActionType.swift */; };
|
||||||
|
D6531DEE246B81C9000F9538 /* GifvAttachmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6531DED246B81C9000F9538 /* GifvAttachmentView.swift */; };
|
||||||
|
D6531DF0246B867E000F9538 /* GifvAttachmentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6531DEF246B867E000F9538 /* GifvAttachmentViewController.swift */; };
|
||||||
D6538945214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6538944214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift */; };
|
D6538945214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6538944214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift */; };
|
||||||
D65A37F321472F300087646E /* SwiftSoup.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D6BED16E212663DA00F02DA0 /* SwiftSoup.framework */; };
|
D65A37F321472F300087646E /* SwiftSoup.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D6BED16E212663DA00F02DA0 /* SwiftSoup.framework */; };
|
||||||
D65F613423AEAB6600F3CFD3 /* OnboardingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D65F613323AEAB6600F3CFD3 /* OnboardingTests.swift */; };
|
D65F613423AEAB6600F3CFD3 /* OnboardingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D65F613323AEAB6600F3CFD3 /* OnboardingTests.swift */; };
|
||||||
|
@ -428,6 +430,8 @@
|
||||||
D64D0AB02128D9AE005A6F37 /* OnboardingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingViewController.swift; sourceTree = "<group>"; };
|
D64D0AB02128D9AE005A6F37 /* OnboardingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingViewController.swift; sourceTree = "<group>"; };
|
||||||
D64D8CA82463B494006B0BAA /* CachedDictionary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CachedDictionary.swift; sourceTree = "<group>"; };
|
D64D8CA82463B494006B0BAA /* CachedDictionary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CachedDictionary.swift; sourceTree = "<group>"; };
|
||||||
D64F80E1215875CC00BEF393 /* XCBActionType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCBActionType.swift; sourceTree = "<group>"; };
|
D64F80E1215875CC00BEF393 /* XCBActionType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCBActionType.swift; sourceTree = "<group>"; };
|
||||||
|
D6531DED246B81C9000F9538 /* GifvAttachmentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GifvAttachmentView.swift; sourceTree = "<group>"; };
|
||||||
|
D6531DEF246B867E000F9538 /* GifvAttachmentViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GifvAttachmentViewController.swift; sourceTree = "<group>"; };
|
||||||
D6538944214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewSwipeActionProvider.swift; sourceTree = "<group>"; };
|
D6538944214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewSwipeActionProvider.swift; sourceTree = "<group>"; };
|
||||||
D65F612D23AE990C00F3CFD3 /* Embassy.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Embassy.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
D65F612D23AE990C00F3CFD3 /* Embassy.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Embassy.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
D65F613023AE99E000F3CFD3 /* Ambassador.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Ambassador.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
D65F613023AE99E000F3CFD3 /* Ambassador.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Ambassador.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
@ -597,6 +601,7 @@
|
||||||
children = (
|
children = (
|
||||||
04D14BAE22B34A2800642648 /* GalleryViewController.swift */,
|
04D14BAE22B34A2800642648 /* GalleryViewController.swift */,
|
||||||
D647D92724257BEB0005044F /* AttachmentPreviewViewController.swift */,
|
D647D92724257BEB0005044F /* AttachmentPreviewViewController.swift */,
|
||||||
|
D6531DEF246B867E000F9538 /* GifvAttachmentViewController.swift */,
|
||||||
);
|
);
|
||||||
path = "Attachment Gallery";
|
path = "Attachment Gallery";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -1216,6 +1221,7 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
D6C94D882139E6EC00CB5196 /* AttachmentView.swift */,
|
D6C94D882139E6EC00CB5196 /* AttachmentView.swift */,
|
||||||
|
D6531DED246B81C9000F9538 /* GifvAttachmentView.swift */,
|
||||||
D6C7D27C22B6EBF800071952 /* AttachmentsContainerView.swift */,
|
D6C7D27C22B6EBF800071952 /* AttachmentsContainerView.swift */,
|
||||||
);
|
);
|
||||||
path = Attachments;
|
path = Attachments;
|
||||||
|
@ -1650,6 +1656,7 @@
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
D626493523BD94CE00612E6E /* CompositionAttachmentData.swift in Sources */,
|
D626493523BD94CE00612E6E /* CompositionAttachmentData.swift in Sources */,
|
||||||
|
D6531DF0246B867E000F9538 /* GifvAttachmentViewController.swift in Sources */,
|
||||||
D6285B5321EA708700FE4B39 /* StatusFormat.swift in Sources */,
|
D6285B5321EA708700FE4B39 /* StatusFormat.swift in Sources */,
|
||||||
D6DD353D22F28CD000A9563A /* ContentWarningCopyMode.swift in Sources */,
|
D6DD353D22F28CD000A9563A /* ContentWarningCopyMode.swift in Sources */,
|
||||||
0427033A22B31269000D31B6 /* AdvancedPrefsView.swift in Sources */,
|
0427033A22B31269000D31B6 /* AdvancedPrefsView.swift in Sources */,
|
||||||
|
@ -1702,6 +1709,7 @@
|
||||||
D6B053A623BD2D0C00A066FA /* AssetCollectionViewController.swift in Sources */,
|
D6B053A623BD2D0C00A066FA /* AssetCollectionViewController.swift in Sources */,
|
||||||
04DACE8E212CC7CC009840C4 /* ImageCache.swift in Sources */,
|
04DACE8E212CC7CC009840C4 /* ImageCache.swift in Sources */,
|
||||||
D627FF7B217E951500CC0648 /* DraftsTableViewController.swift in Sources */,
|
D627FF7B217E951500CC0648 /* DraftsTableViewController.swift in Sources */,
|
||||||
|
D6531DEE246B81C9000F9538 /* GifvAttachmentView.swift in Sources */,
|
||||||
D6370B9C24421FF30092A7FF /* Tusker.xcdatamodeld in Sources */,
|
D6370B9C24421FF30092A7FF /* Tusker.xcdatamodeld in Sources */,
|
||||||
D6A3BC8F2321FFB900FD64D5 /* StatusActionAccountListTableViewController.swift in Sources */,
|
D6A3BC8F2321FFB900FD64D5 /* StatusActionAccountListTableViewController.swift in Sources */,
|
||||||
D6AEBB4823216B1D00E5038B /* AccountActivity.swift in Sources */,
|
D6AEBB4823216B1D00E5038B /* AccountActivity.swift in Sources */,
|
||||||
|
|
|
@ -75,6 +75,8 @@ class GalleryViewController: UIPageViewController, UIPageViewControllerDataSourc
|
||||||
let vc = AVPlayerViewController()
|
let vc = AVPlayerViewController()
|
||||||
vc.player = AVPlayer(url: $0.url)
|
vc.player = AVPlayer(url: $0.url)
|
||||||
return vc
|
return vc
|
||||||
|
case .gifv:
|
||||||
|
return GifvAttachmentViewController(attachment: $0)
|
||||||
default:
|
default:
|
||||||
fatalError()
|
fatalError()
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
//
|
||||||
|
// GifvAttachmentViewController.swift
|
||||||
|
// Tusker
|
||||||
|
//
|
||||||
|
// Created by Shadowfacts on 5/12/20.
|
||||||
|
// Copyright © 2020 Shadowfacts. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import Pachyderm
|
||||||
|
import AVFoundation
|
||||||
|
|
||||||
|
class GifvAttachmentViewController: UIViewController {
|
||||||
|
|
||||||
|
private let attachment: Attachment
|
||||||
|
|
||||||
|
init(attachment: Attachment) {
|
||||||
|
precondition(attachment.kind == .gifv)
|
||||||
|
self.attachment = attachment
|
||||||
|
|
||||||
|
super.init(nibName: nil, bundle: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override func loadView() {
|
||||||
|
let asset = AVURLAsset(url: attachment.url)
|
||||||
|
self.view = GifvAttachmentView(asset: asset, gravity: .resizeAspect)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -81,6 +81,8 @@ class AttachmentView: UIImageView, GIFAnimatable {
|
||||||
loadVideo()
|
loadVideo()
|
||||||
case .audio:
|
case .audio:
|
||||||
loadAudio()
|
loadAudio()
|
||||||
|
case .gifv:
|
||||||
|
loadGifv()
|
||||||
default:
|
default:
|
||||||
preconditionFailure("invalid attachment type")
|
preconditionFailure("invalid attachment type")
|
||||||
}
|
}
|
||||||
|
@ -111,9 +113,9 @@ class AttachmentView: UIImageView, GIFAnimatable {
|
||||||
let asset = AVURLAsset(url: attachmentURL)
|
let asset = AVURLAsset(url: attachmentURL)
|
||||||
let generator = AVAssetImageGenerator(asset: asset)
|
let generator = AVAssetImageGenerator(asset: asset)
|
||||||
generator.appliesPreferredTrackTransform = true
|
generator.appliesPreferredTrackTransform = true
|
||||||
guard let image = try? generator.copyCGImage(at: CMTime(seconds: 0, preferredTimescale: 1), actualTime: nil) else { return }
|
guard let image = try? generator.copyCGImage(at: .zero, actualTime: nil) else { return }
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async { [weak self] in
|
||||||
guard self.attachment.url == attachmentURL else { return }
|
guard let self = self, self.attachment.url == attachmentURL else { return }
|
||||||
self.image = UIImage(cgImage: image)
|
self.image = UIImage(cgImage: image)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,6 +152,30 @@ class AttachmentView: UIImageView, GIFAnimatable {
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loadGifv() {
|
||||||
|
let attachmentURL = self.attachment.url
|
||||||
|
let asset = AVURLAsset(url: attachmentURL)
|
||||||
|
DispatchQueue.global(qos: .userInitiated).async {
|
||||||
|
let generator = AVAssetImageGenerator(asset: asset)
|
||||||
|
generator.appliesPreferredTrackTransform = true
|
||||||
|
guard let image = try? generator.copyCGImage(at: .zero, actualTime: nil) else { return }
|
||||||
|
DispatchQueue.main.async { [weak self] in
|
||||||
|
guard let self = self, self.attachment.url == attachmentURL else { return }
|
||||||
|
self.image = UIImage(cgImage: image)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let gifvView = GifvAttachmentView(asset: asset, gravity: .resizeAspectFill)
|
||||||
|
gifvView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
addSubview(gifvView)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
gifvView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||||
|
gifvView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||||
|
gifvView.topAnchor.constraint(equalTo: topAnchor),
|
||||||
|
gifvView.bottomAnchor.constraint(equalTo: bottomAnchor),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
override func display(_ layer: CALayer) {
|
override func display(_ layer: CALayer) {
|
||||||
updateImageIfNeeded()
|
updateImageIfNeeded()
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ import Pachyderm
|
||||||
|
|
||||||
class AttachmentsContainerView: UIView {
|
class AttachmentsContainerView: UIView {
|
||||||
|
|
||||||
static let supportedAttachmentTypes = [Attachment.Kind.image, .video, .audio]
|
static let supportedAttachmentTypes = [Attachment.Kind.image, .video, .audio, .gifv]
|
||||||
|
|
||||||
weak var delegate: AttachmentViewDelegate?
|
weak var delegate: AttachmentViewDelegate?
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
//
|
||||||
|
// GifvAttachmentView.swift
|
||||||
|
// Tusker
|
||||||
|
//
|
||||||
|
// Created by Shadowfacts on 5/12/20.
|
||||||
|
// Copyright © 2020 Shadowfacts. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import AVFoundation
|
||||||
|
|
||||||
|
class GifvAttachmentView: UIView {
|
||||||
|
|
||||||
|
override class var layerClass: AnyClass {
|
||||||
|
return AVPlayerLayer.self
|
||||||
|
}
|
||||||
|
|
||||||
|
private var playerLayer: AVPlayerLayer {
|
||||||
|
layer as! AVPlayerLayer
|
||||||
|
}
|
||||||
|
|
||||||
|
private let item: AVPlayerItem
|
||||||
|
private let player: AVPlayer
|
||||||
|
|
||||||
|
init(asset: AVAsset, gravity: AVLayerVideoGravity) {
|
||||||
|
item = AVPlayerItem(asset: asset)
|
||||||
|
player = AVPlayer(playerItem: item)
|
||||||
|
|
||||||
|
super.init(frame: .zero)
|
||||||
|
|
||||||
|
playerLayer.player = player
|
||||||
|
playerLayer.videoGravity = gravity
|
||||||
|
player.play()
|
||||||
|
|
||||||
|
NotificationCenter.default.addObserver(self, selector: #selector(restartItem), name: .AVPlayerItemDidPlayToEndTime, object: item)
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func restartItem() {
|
||||||
|
item.seek(to: .zero) { (success) in
|
||||||
|
guard success else { return }
|
||||||
|
self.player.play()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue