chore: add mosaicView
This commit is contained in:
parent
6c0a767435
commit
6b9ae8d05d
@ -60,6 +60,7 @@
|
|||||||
2D61335E25C1894B00CAE157 /* APIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D61335D25C1894B00CAE157 /* APIService.swift */; };
|
2D61335E25C1894B00CAE157 /* APIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D61335D25C1894B00CAE157 /* APIService.swift */; };
|
||||||
2D61336925C18A4F00CAE157 /* AlamofireNetworkActivityIndicator in Frameworks */ = {isa = PBXBuildFile; productRef = 2D61336825C18A4F00CAE157 /* AlamofireNetworkActivityIndicator */; };
|
2D61336925C18A4F00CAE157 /* AlamofireNetworkActivityIndicator in Frameworks */ = {isa = PBXBuildFile; productRef = 2D61336825C18A4F00CAE157 /* AlamofireNetworkActivityIndicator */; };
|
||||||
2D650FAB25ECDC9300851B58 /* Mastodon+Entity+Error+Detail.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D650FAA25ECDC9300851B58 /* Mastodon+Entity+Error+Detail.swift */; };
|
2D650FAB25ECDC9300851B58 /* Mastodon+Entity+Error+Detail.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D650FAA25ECDC9300851B58 /* Mastodon+Entity+Error+Detail.swift */; };
|
||||||
|
2D694A7425F9EB4E0038ADDC /* MosaicView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D694A7325F9EB4E0038ADDC /* MosaicView.swift */; };
|
||||||
2D69CFF425CA9E2200C3A1B2 /* LoadMoreConfigurableTableViewContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D69CFF325CA9E2200C3A1B2 /* LoadMoreConfigurableTableViewContainer.swift */; };
|
2D69CFF425CA9E2200C3A1B2 /* LoadMoreConfigurableTableViewContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D69CFF325CA9E2200C3A1B2 /* LoadMoreConfigurableTableViewContainer.swift */; };
|
||||||
2D69D00A25CAA00300C3A1B2 /* APIService+CoreData+Toot.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D69D00925CAA00300C3A1B2 /* APIService+CoreData+Toot.swift */; };
|
2D69D00A25CAA00300C3A1B2 /* APIService+CoreData+Toot.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D69D00925CAA00300C3A1B2 /* APIService+CoreData+Toot.swift */; };
|
||||||
2D76316525C14BD100929FB9 /* PublicTimelineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D76316425C14BD100929FB9 /* PublicTimelineViewController.swift */; };
|
2D76316525C14BD100929FB9 /* PublicTimelineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D76316425C14BD100929FB9 /* PublicTimelineViewController.swift */; };
|
||||||
@ -301,6 +302,7 @@
|
|||||||
2D61335725C188A000CAE157 /* APIService+Persist+Timeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Persist+Timeline.swift"; sourceTree = "<group>"; };
|
2D61335725C188A000CAE157 /* APIService+Persist+Timeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Persist+Timeline.swift"; sourceTree = "<group>"; };
|
||||||
2D61335D25C1894B00CAE157 /* APIService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIService.swift; sourceTree = "<group>"; };
|
2D61335D25C1894B00CAE157 /* APIService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIService.swift; sourceTree = "<group>"; };
|
||||||
2D650FAA25ECDC9300851B58 /* Mastodon+Entity+Error+Detail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Mastodon+Entity+Error+Detail.swift"; sourceTree = "<group>"; };
|
2D650FAA25ECDC9300851B58 /* Mastodon+Entity+Error+Detail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Mastodon+Entity+Error+Detail.swift"; sourceTree = "<group>"; };
|
||||||
|
2D694A7325F9EB4E0038ADDC /* MosaicView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MosaicView.swift; sourceTree = "<group>"; };
|
||||||
2D69CFF325CA9E2200C3A1B2 /* LoadMoreConfigurableTableViewContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoadMoreConfigurableTableViewContainer.swift; sourceTree = "<group>"; };
|
2D69CFF325CA9E2200C3A1B2 /* LoadMoreConfigurableTableViewContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoadMoreConfigurableTableViewContainer.swift; sourceTree = "<group>"; };
|
||||||
2D69D00925CAA00300C3A1B2 /* APIService+CoreData+Toot.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "APIService+CoreData+Toot.swift"; sourceTree = "<group>"; };
|
2D69D00925CAA00300C3A1B2 /* APIService+CoreData+Toot.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "APIService+CoreData+Toot.swift"; sourceTree = "<group>"; };
|
||||||
2D76316425C14BD100929FB9 /* PublicTimelineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublicTimelineViewController.swift; sourceTree = "<group>"; };
|
2D76316425C14BD100929FB9 /* PublicTimelineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublicTimelineViewController.swift; sourceTree = "<group>"; };
|
||||||
@ -1177,6 +1179,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
DB9D6C0D25E4F9780051B173 /* MosaicImageViewContainer.swift */,
|
DB9D6C0D25E4F9780051B173 /* MosaicImageViewContainer.swift */,
|
||||||
|
2D694A7325F9EB4E0038ADDC /* MosaicView.swift */,
|
||||||
2D206B7125F5D27F00143C56 /* AudioContainerView.swift */,
|
2D206B7125F5D27F00143C56 /* AudioContainerView.swift */,
|
||||||
5DF1057825F88A1D00D6C0D4 /* MosaicPlayerView.swift */,
|
5DF1057825F88A1D00D6C0D4 /* MosaicPlayerView.swift */,
|
||||||
5DF1057E25F88A4100D6C0D4 /* TouchBlockingView.swift */,
|
5DF1057E25F88A4100D6C0D4 /* TouchBlockingView.swift */,
|
||||||
@ -1632,6 +1635,7 @@
|
|||||||
2D45E5BF25C9549700A6D639 /* PublicTimelineViewModel+State.swift in Sources */,
|
2D45E5BF25C9549700A6D639 /* PublicTimelineViewModel+State.swift in Sources */,
|
||||||
DB8AF55D25C138B7002E6C99 /* UIViewController.swift in Sources */,
|
DB8AF55D25C138B7002E6C99 /* UIViewController.swift in Sources */,
|
||||||
2D3F9E0425DFA133004262D9 /* UITapGestureRecognizer.swift in Sources */,
|
2D3F9E0425DFA133004262D9 /* UITapGestureRecognizer.swift in Sources */,
|
||||||
|
2D694A7425F9EB4E0038ADDC /* MosaicView.swift in Sources */,
|
||||||
DB4481CC25EE2AFE00BEFB67 /* PollItem.swift in Sources */,
|
DB4481CC25EE2AFE00BEFB67 /* PollItem.swift in Sources */,
|
||||||
DB4563BD25E11A24004DA0B9 /* KeyboardResponderService.swift in Sources */,
|
DB4563BD25E11A24004DA0B9 /* KeyboardResponderService.swift in Sources */,
|
||||||
DB5086BE25CC0D9900C2C187 /* SplashPreference.swift in Sources */,
|
DB5086BE25CC0D9900C2C187 /* SplashPreference.swift in Sources */,
|
||||||
|
@ -192,6 +192,14 @@ extension StatusSection {
|
|||||||
let scale: CGFloat = 1.3
|
let scale: CGFloat = 1.3
|
||||||
return CGSize(width: maxWidth, height: maxWidth * scale)
|
return CGSize(width: maxWidth, height: maxWidth * scale)
|
||||||
}()
|
}()
|
||||||
|
cell.statusView.mosaicPlayerView.mosaicView.blurVisualEffectView.effect = isStatusSensitive ? MosaicImageViewContainer.blurVisualEffect : nil
|
||||||
|
cell.statusView.mosaicPlayerView.mosaicView.vibrancyVisualEffectView.alpha = isStatusSensitive ? 1.0 : 0.0
|
||||||
|
cell.statusView.mosaicPlayerView.mosaicView.mosaicButton.publisher(for: .touchUpInside)
|
||||||
|
.sink { [weak cell] _ in
|
||||||
|
guard let cell = cell else { return }
|
||||||
|
cell.delegate?.statusTableViewCell(cell, mosaicView: cell.statusView.mosaicPlayerView.mosaicView, didTapContentWarningVisualEffectView: cell.statusView.mosaicPlayerView.mosaicView.blurVisualEffectView)
|
||||||
|
}
|
||||||
|
.store(in: &cell.disposeBag)
|
||||||
|
|
||||||
if let videoAttachment = mediaAttachments.filter({ $0.type == .gifv || $0.type == .video }).first,
|
if let videoAttachment = mediaAttachments.filter({ $0.type == .gifv || $0.type == .video }).first,
|
||||||
let videoPlayerViewModel = dependency.context.videoPlaybackService.dequeueVideoPlayerViewModel(for: videoAttachment)
|
let videoPlayerViewModel = dependency.context.videoPlaybackService.dequeueVideoPlayerViewModel(for: videoAttachment)
|
||||||
|
@ -45,7 +45,28 @@ extension StatusTableViewCellDelegate where Self: StatusProvider {
|
|||||||
func statusTableViewCell(_ cell: StatusTableViewCell, mosaicImageViewContainer: MosaicImageViewContainer, didTapImageView imageView: UIImageView, atIndex index: Int) {
|
func statusTableViewCell(_ cell: StatusTableViewCell, mosaicImageViewContainer: MosaicImageViewContainer, didTapImageView imageView: UIImageView, atIndex index: Int) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
func statusTableViewCell(_ cell: StatusTableViewCell, mosaicView: MosaicView, didTapContentWarningVisualEffectView visualEffectView: UIVisualEffectView) {
|
||||||
|
guard let diffableDataSource = self.tableViewDiffableDataSource else { return }
|
||||||
|
guard let item = item(for: cell, indexPath: nil) else { return }
|
||||||
|
|
||||||
|
switch item {
|
||||||
|
case .homeTimelineIndex(_, let attribute):
|
||||||
|
attribute.isStatusSensitive = false
|
||||||
|
case .toot(_, let attribute):
|
||||||
|
attribute.isStatusSensitive = false
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var snapshot = diffableDataSource.snapshot()
|
||||||
|
snapshot.reloadItems([item])
|
||||||
|
UIView.animate(withDuration: 0.33) {
|
||||||
|
mosaicView.blurVisualEffectView.effect = nil
|
||||||
|
mosaicView.vibrancyVisualEffectView.alpha = 0.0
|
||||||
|
} completion: { _ in
|
||||||
|
diffableDataSource.apply(snapshot, animatingDifferences: false, completion: nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
func statusTableViewCell(_ cell: StatusTableViewCell, mosaicImageViewContainer: MosaicImageViewContainer, didTapContentWarningVisualEffectView visualEffectView: UIVisualEffectView) {
|
func statusTableViewCell(_ cell: StatusTableViewCell, mosaicImageViewContainer: MosaicImageViewContainer, didTapContentWarningVisualEffectView visualEffectView: UIVisualEffectView) {
|
||||||
guard let diffableDataSource = self.tableViewDiffableDataSource else { return }
|
guard let diffableDataSource = self.tableViewDiffableDataSource else { return }
|
||||||
guard let item = item(for: cell, indexPath: nil) else { return }
|
guard let item = item(for: cell, indexPath: nil) else { return }
|
||||||
|
@ -15,6 +15,11 @@ final class MosaicPlayerView: UIView {
|
|||||||
private let touchBlockingView = TouchBlockingView()
|
private let touchBlockingView = TouchBlockingView()
|
||||||
private var containerHeightLayoutConstraint: NSLayoutConstraint!
|
private var containerHeightLayoutConstraint: NSLayoutConstraint!
|
||||||
|
|
||||||
|
let mosaicView: MosaicView = {
|
||||||
|
let mosaicView = MosaicView()
|
||||||
|
return mosaicView
|
||||||
|
}()
|
||||||
|
|
||||||
let playerViewController = AVPlayerViewController()
|
let playerViewController = AVPlayerViewController()
|
||||||
|
|
||||||
let gifIndicatorLabel: UILabel = {
|
let gifIndicatorLabel: UILabel = {
|
||||||
@ -38,6 +43,14 @@ final class MosaicPlayerView: UIView {
|
|||||||
|
|
||||||
extension MosaicPlayerView {
|
extension MosaicPlayerView {
|
||||||
private func _init() {
|
private func _init() {
|
||||||
|
addSubview(mosaicView)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
mosaicView.topAnchor.constraint(equalTo: topAnchor),
|
||||||
|
mosaicView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||||
|
mosaicView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||||
|
mosaicView.bottomAnchor.constraint(equalTo: bottomAnchor)
|
||||||
|
])
|
||||||
|
|
||||||
container.translatesAutoresizingMaskIntoConstraints = false
|
container.translatesAutoresizingMaskIntoConstraints = false
|
||||||
addSubview(container)
|
addSubview(container)
|
||||||
containerHeightLayoutConstraint = container.heightAnchor.constraint(equalToConstant: 162).priority(.required - 1)
|
containerHeightLayoutConstraint = container.heightAnchor.constraint(equalToConstant: 162).priority(.required - 1)
|
||||||
|
74
Mastodon/Scene/Share/View/Container/MosaicView.swift
Normal file
74
Mastodon/Scene/Share/View/Container/MosaicView.swift
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
//
|
||||||
|
// MosaicView.swift
|
||||||
|
// Mastodon
|
||||||
|
//
|
||||||
|
// Created by sxiaojian on 2021/3/11.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class MosaicView: UIView {
|
||||||
|
static let cornerRadius: CGFloat = 4
|
||||||
|
static let blurVisualEffect = UIBlurEffect(style: .systemUltraThinMaterial)
|
||||||
|
let blurVisualEffectView = UIVisualEffectView(effect: MosaicView.blurVisualEffect)
|
||||||
|
let vibrancyVisualEffectView = UIVisualEffectView(effect: UIVibrancyEffect(blurEffect: MosaicView.blurVisualEffect))
|
||||||
|
|
||||||
|
let mosaicButton: UIButton = {
|
||||||
|
let button = UIButton(type: .custom)
|
||||||
|
button.backgroundColor = .clear
|
||||||
|
return button
|
||||||
|
}()
|
||||||
|
|
||||||
|
let contentWarningLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15))
|
||||||
|
label.text = L10n.Common.Controls.Status.mediaContentWarning
|
||||||
|
label.textAlignment = .center
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
_init()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
super.init(coder: coder)
|
||||||
|
_init()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension MosaicView {
|
||||||
|
private func _init() {
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
addSubview(mosaicButton)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
mosaicButton.topAnchor.constraint(equalTo: topAnchor),
|
||||||
|
mosaicButton.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||||
|
mosaicButton.bottomAnchor.constraint(equalTo: bottomAnchor),
|
||||||
|
mosaicButton.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||||
|
])
|
||||||
|
// add blur visual effect view in the setup method
|
||||||
|
blurVisualEffectView.layer.masksToBounds = true
|
||||||
|
blurVisualEffectView.layer.cornerRadius = MosaicView.cornerRadius
|
||||||
|
blurVisualEffectView.layer.cornerCurve = .continuous
|
||||||
|
|
||||||
|
vibrancyVisualEffectView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
blurVisualEffectView.contentView.addSubview(vibrancyVisualEffectView)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
vibrancyVisualEffectView.topAnchor.constraint(equalTo: blurVisualEffectView.topAnchor),
|
||||||
|
vibrancyVisualEffectView.leadingAnchor.constraint(equalTo: blurVisualEffectView.leadingAnchor),
|
||||||
|
vibrancyVisualEffectView.trailingAnchor.constraint(equalTo: blurVisualEffectView.trailingAnchor),
|
||||||
|
vibrancyVisualEffectView.bottomAnchor.constraint(equalTo: blurVisualEffectView.bottomAnchor),
|
||||||
|
])
|
||||||
|
|
||||||
|
contentWarningLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
vibrancyVisualEffectView.contentView.addSubview(contentWarningLabel)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
contentWarningLabel.leadingAnchor.constraint(equalTo: vibrancyVisualEffectView.contentView.layoutMarginsGuide.leadingAnchor),
|
||||||
|
contentWarningLabel.trailingAnchor.constraint(equalTo: vibrancyVisualEffectView.contentView.layoutMarginsGuide.trailingAnchor),
|
||||||
|
contentWarningLabel.centerYAnchor.constraint(equalTo: vibrancyVisualEffectView.contentView.centerYAnchor),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
@ -23,6 +23,7 @@ protocol StatusTableViewCellDelegate: class {
|
|||||||
|
|
||||||
func statusTableViewCell(_ cell: StatusTableViewCell, statusView: StatusView, contentWarningActionButtonPressed button: UIButton)
|
func statusTableViewCell(_ cell: StatusTableViewCell, statusView: StatusView, contentWarningActionButtonPressed button: UIButton)
|
||||||
func statusTableViewCell(_ cell: StatusTableViewCell, mosaicImageViewContainer: MosaicImageViewContainer, didTapContentWarningVisualEffectView visualEffectView: UIVisualEffectView)
|
func statusTableViewCell(_ cell: StatusTableViewCell, mosaicImageViewContainer: MosaicImageViewContainer, didTapContentWarningVisualEffectView visualEffectView: UIVisualEffectView)
|
||||||
|
func statusTableViewCell(_ cell: StatusTableViewCell, mosaicView: MosaicView, didTapContentWarningVisualEffectView visualEffectView: UIVisualEffectView)
|
||||||
func statusTableViewCell(_ cell: StatusTableViewCell, mosaicImageViewContainer: MosaicImageViewContainer, didTapImageView imageView: UIImageView, atIndex index: Int)
|
func statusTableViewCell(_ cell: StatusTableViewCell, mosaicImageViewContainer: MosaicImageViewContainer, didTapImageView imageView: UIImageView, atIndex index: Int)
|
||||||
func statusTableViewCell(_ cell: StatusTableViewCell, actionToolbarContainer: ActionToolbarContainer, likeButtonDidPressed sender: UIButton)
|
func statusTableViewCell(_ cell: StatusTableViewCell, actionToolbarContainer: ActionToolbarContainer, likeButtonDidPressed sender: UIButton)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user