From 108bf3141b97b061e4621fc7c1fba428b1d3121a Mon Sep 17 00:00:00 2001 From: zjx Date: Wed, 16 Jul 2025 17:45:06 +0800 Subject: [PATCH] 1 --- BeeReel/Base/Extension/UIColor+BRAdd.swift | 4 + .../Controller/BRExploreViewController.swift | 70 ++++++++++++++++++ .../BRPlayerListViewController.swift | 32 ++++++++ .../Model/BRPlayerControlProtocol.swift | 2 + .../Class/Player/Model/BRPlayerProtocol.swift | 1 + .../Player/View/BRPlayerControlView.swift | 59 ++++++++++++++- .../Class/Player/View/BRPlayerListCell.swift | 8 +- .../Player/ViewModel/BRPlayerViewModel.swift | 8 ++ .../episode_icon_01.imageset/Contents.json | 22 ++++++ .../episode_icon_01.imageset/Frame@2x.png | Bin 0 -> 622 bytes .../episode_icon_01.imageset/Frame@3x.png | Bin 0 -> 870 bytes .../explore_title_icon.imageset/Contents.json | 22 ++++++ .../Discover@2x.png | Bin 0 -> 3399 bytes .../Discover@3x.png | Bin 0 -> 5427 bytes .../favorite_icon_02.imageset/Contents.json | 22 ++++++ .../favorite_icon_02.imageset/Frame@2x.png | Bin 0 -> 479 bytes .../favorite_icon_02.imageset/Frame@3x.png | Bin 0 -> 736 bytes .../icon/play_icon_05.imageset/Contents.json | 22 ++++++ .../play_icon_05.imageset/Polygon 1@2x.png | Bin 0 -> 1155 bytes .../play_icon_05.imageset/Polygon 1@3x.png | Bin 0 -> 1588 bytes .../search_icon_01.imageset/Contents.json | 22 ++++++ .../icon/search_icon_01.imageset/Frame@2x.png | Bin 0 -> 783 bytes .../icon/search_icon_01.imageset/Frame@3x.png | Bin 0 -> 1134 bytes 23 files changed, 290 insertions(+), 4 deletions(-) create mode 100644 BeeReel/Sources/Assets.xcassets/icon/episode_icon_01.imageset/Contents.json create mode 100644 BeeReel/Sources/Assets.xcassets/icon/episode_icon_01.imageset/Frame@2x.png create mode 100644 BeeReel/Sources/Assets.xcassets/icon/episode_icon_01.imageset/Frame@3x.png create mode 100644 BeeReel/Sources/Assets.xcassets/icon/explore_title_icon.imageset/Contents.json create mode 100644 BeeReel/Sources/Assets.xcassets/icon/explore_title_icon.imageset/Discover@2x.png create mode 100644 BeeReel/Sources/Assets.xcassets/icon/explore_title_icon.imageset/Discover@3x.png create mode 100644 BeeReel/Sources/Assets.xcassets/icon/favorite_icon_02.imageset/Contents.json create mode 100644 BeeReel/Sources/Assets.xcassets/icon/favorite_icon_02.imageset/Frame@2x.png create mode 100644 BeeReel/Sources/Assets.xcassets/icon/favorite_icon_02.imageset/Frame@3x.png create mode 100644 BeeReel/Sources/Assets.xcassets/icon/play_icon_05.imageset/Contents.json create mode 100644 BeeReel/Sources/Assets.xcassets/icon/play_icon_05.imageset/Polygon 1@2x.png create mode 100644 BeeReel/Sources/Assets.xcassets/icon/play_icon_05.imageset/Polygon 1@3x.png create mode 100644 BeeReel/Sources/Assets.xcassets/icon/search_icon_01.imageset/Contents.json create mode 100644 BeeReel/Sources/Assets.xcassets/icon/search_icon_01.imageset/Frame@2x.png create mode 100644 BeeReel/Sources/Assets.xcassets/icon/search_icon_01.imageset/Frame@3x.png diff --git a/BeeReel/Base/Extension/UIColor+BRAdd.swift b/BeeReel/Base/Extension/UIColor+BRAdd.swift index ffb6194..29833ca 100644 --- a/BeeReel/Base/Extension/UIColor+BRAdd.swift +++ b/BeeReel/Base/Extension/UIColor+BRAdd.swift @@ -62,4 +62,8 @@ extension UIColor { static func color5A5D45(alpha: CGFloat = 1) -> UIColor { return UIColor(rgb: 0x5A5D45, alpha: alpha) } + + static func colorFFFDF9(alpha: CGFloat = 1) -> UIColor { + return UIColor(rgb: 0xFFFDF9, alpha: alpha) + } } diff --git a/BeeReel/Class/Explore/Controller/BRExploreViewController.swift b/BeeReel/Class/Explore/Controller/BRExploreViewController.swift index 45b366c..d5f9800 100644 --- a/BeeReel/Class/Explore/Controller/BRExploreViewController.swift +++ b/BeeReel/Class/Explore/Controller/BRExploreViewController.swift @@ -24,6 +24,40 @@ class BRExploreViewController: BRPlayerListViewController { return CGSize(width: width, height: height) } + private lazy var titleImageView: UIImageView = { + let imageView = UIImageView(image: UIImage(named: "explore_title_icon")) + return imageView + }() + + private lazy var searchButton: UIButton = { + let button = UIButton(type: .custom) + button.setImage(UIImage(named: "search_icon_01"), for: .normal) + return button + }() + + private lazy var videoNameLabel: UILabel = { + let label = UILabel() + label.font = .fontMedium(ofSize: 12) + label.textColor = .colorFFFDF9() + return label + }() + + private lazy var episodeButton: UIButton = { + let button = UIButton(type: .custom) + button.setImage(UIImage(named: "episode_icon_01"), for: .normal) + button.setContentHuggingPriority(.required, for: .horizontal) + button.setContentCompressionResistancePriority(.required, for: .horizontal) + return button + }() + + private lazy var favoriteButton: UIButton = { + let button = UIButton(type: .custom) + button.setImage(UIImage(named: "favorite_icon_02"), for: .normal) + button.setContentHuggingPriority(.required, for: .horizontal) + button.setContentCompressionResistancePriority(.required, for: .horizontal) + return button + }() + override func viewDidLoad() { super.viewDidLoad() self.edgesForExtendedLayout = .all @@ -67,12 +101,44 @@ extension BRExploreViewController { self.collectionView.layer.cornerRadius = 20 self.collectionView.layer.masksToBounds = true + view.addSubview(titleImageView) + view.addSubview(searchButton) + view.addSubview(episodeButton) + view.addSubview(favoriteButton) + view.addSubview(videoNameLabel) + self.collectionView.snp.remakeConstraints { make in make.left.equalToSuperview().offset(15) make.top.equalToSuperview().offset(UIScreen.statusBarHeight + 50) make.width.equalTo(contentSize.width) make.height.equalTo(contentSize.height) } + + titleImageView.snp.makeConstraints { make in + make.left.equalToSuperview().offset(15) + make.bottom.equalTo(collectionView.snp.top).offset(-15) + } + + searchButton.snp.makeConstraints { make in + make.centerY.equalTo(titleImageView) + make.right.equalToSuperview().offset(-15) + } + + episodeButton.snp.makeConstraints { make in + make.right.equalToSuperview().offset(-15) + make.top.equalTo(collectionView.snp.bottom).offset(10) + } + + favoriteButton.snp.makeConstraints { make in + make.centerY.equalTo(episodeButton) + make.right.equalTo(episodeButton.snp.left).offset(-40) + } + + videoNameLabel.snp.makeConstraints { make in + make.centerY.equalTo(episodeButton) + make.left.equalToSuperview().offset(15) + make.right.lessThanOrEqualTo(favoriteButton.snp.left).offset(-25) + } } } @@ -94,6 +160,10 @@ extension BRExploreViewController: BRPlayerListViewControllerDelegate, BRPlayerL func br_playerListViewController(_ viewController: BRPlayerListViewController, _ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return dataArr.count } + + func br_playerListViewController(_ viewController: BRPlayerListViewController, didChangeIndexPathForVisible indexPath: IndexPath) { + videoNameLabel.text = self.viewModel.currentPlayer?.shortModel?.name + } } diff --git a/BeeReel/Class/Player/Controller/BRPlayerListViewController.swift b/BeeReel/Class/Player/Controller/BRPlayerListViewController.swift index df80a45..1fc25c9 100644 --- a/BeeReel/Class/Player/Controller/BRPlayerListViewController.swift +++ b/BeeReel/Class/Player/Controller/BRPlayerListViewController.swift @@ -88,6 +88,10 @@ class BRPlayerListViewController: BRViewController { override func viewDidLoad() { super.viewDidLoad() self.statusBarStyle = .lightContent + + NotificationCenter.default.addObserver(self, selector: #selector(didBecomeActiveNotification), name: UIApplication.didBecomeActiveNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(willResignActiveNotification), name: UIApplication.willResignActiveNotification, object: nil) + br_setupUI() } @@ -131,6 +135,11 @@ class BRPlayerListViewController: BRViewController { // } } + func pause() { + self.viewModel.currentPlayer?.pause() + self.viewModel.isPlaying = false + } + func reloadData(completion: (() -> Void)? = nil) { UIView.performWithoutAnimation { @@ -276,6 +285,13 @@ extension BRPlayerListViewController: BRPlayerViewModelDelegate { scrollToNextEpisode() } + func br_switchPlayAndPause(viewModel: BRPlayerViewModel) { + if self.viewModel.isPlaying { + self.pause() + } else { + self.play() + } + } } @@ -332,3 +348,19 @@ extension BRPlayerListViewController { return BRPlayerCache.prefetch(urlString: url) } } + +//MARK: -------------- 系统回调 -------------- +extension BRPlayerListViewController { + + @objc func didBecomeActiveNotification() { + if self.viewModel.isPlaying && isDidAppear { + self.viewModel.currentPlayer?.start() + } + } + + @objc func willResignActiveNotification() { + self.viewModel.currentPlayer?.pause() + } + + +} diff --git a/BeeReel/Class/Player/Model/BRPlayerControlProtocol.swift b/BeeReel/Class/Player/Model/BRPlayerControlProtocol.swift index 80f4bd9..9224712 100644 --- a/BeeReel/Class/Player/Model/BRPlayerControlProtocol.swift +++ b/BeeReel/Class/Player/Model/BRPlayerControlProtocol.swift @@ -10,6 +10,8 @@ import UIKit @objc protocol BRPlayerControlProtocol { + + var isCurrent: Bool { get set } ///点击事件 func singleTapEvent() diff --git a/BeeReel/Class/Player/Model/BRPlayerProtocol.swift b/BeeReel/Class/Player/Model/BRPlayerProtocol.swift index 528198d..ee22b82 100644 --- a/BeeReel/Class/Player/Model/BRPlayerProtocol.swift +++ b/BeeReel/Class/Player/Model/BRPlayerProtocol.swift @@ -11,6 +11,7 @@ import UIKit var videoInfo: BRVideoInfoModel? { get set } + var shortModel: BRShortModel? { get set } var isCurrent: Bool { get set } diff --git a/BeeReel/Class/Player/View/BRPlayerControlView.swift b/BeeReel/Class/Player/View/BRPlayerControlView.swift index 1f454e9..f3b4df7 100644 --- a/BeeReel/Class/Player/View/BRPlayerControlView.swift +++ b/BeeReel/Class/Player/View/BRPlayerControlView.swift @@ -16,7 +16,7 @@ class BRPlayerControlView: UIView, BRPlayerControlProtocol { weak var viewModel: BRPlayerViewModel? { didSet { - + self.viewModel?.addObserver(self, forKeyPath: "isPlaying", context: nil) } } @@ -32,18 +32,73 @@ class BRPlayerControlView: UIView, BRPlayerControlProtocol { } } + private lazy var playIconImageView: UIImageView = { + let imageView = UIImageView(image: UIImage(named: "play_icon_05")) + return imageView + }() + deinit { + self.viewModel?.removeObserver(self, forKeyPath: "isPlaying") + } override init(frame: CGRect) { super.init(frame: frame) + + br_setupUI() + self.updatePlayIconState() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } -//MARK: BRPlayerControlProtocol + + override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { + if keyPath == "isPlaying" { + self.updatePlayIconState() + } + } + + + + //MARK: BRPlayerControlProtocol + + var isCurrent: Bool = false { + didSet { + self.updatePlayIconState() + } + } + func singleTapEvent() { + self.viewModel?.switchPlayAndPause() + } + + + +} + + +extension BRPlayerControlView { + + private func br_setupUI() { + addSubview(self.playIconImageView) + self.playIconImageView.snp.makeConstraints { make in + make.center.equalToSuperview() + } } } + + +extension BRPlayerControlView { + + private func updatePlayIconState() { + if isCurrent == true, self.viewModel?.isPlaying != true { + self.playIconImageView.isHidden = false + } else { + self.playIconImageView.isHidden = true + } + + } + +} diff --git a/BeeReel/Class/Player/View/BRPlayerListCell.swift b/BeeReel/Class/Player/View/BRPlayerListCell.swift index 1db766a..f1e2ef4 100644 --- a/BeeReel/Class/Player/View/BRPlayerListCell.swift +++ b/BeeReel/Class/Player/View/BRPlayerListCell.swift @@ -30,7 +30,11 @@ class BRPlayerListCell: BRCollectionViewCell, BRPlayerProtocol { } } - var isCurrent: Bool = false + var isCurrent: Bool = false { + didSet { + self.controlView.isCurrent = isCurrent + } + } var duration: Int = 0 @@ -68,7 +72,7 @@ class BRPlayerListCell: BRCollectionViewCell, BRPlayerProtocol { } private lazy var player: BRPlayer = { - let player = BRPlayer(controlView: nil) + let player = BRPlayer(controlView: self.controlView) player.playerView = self.playerView player.delegate = self diff --git a/BeeReel/Class/Player/ViewModel/BRPlayerViewModel.swift b/BeeReel/Class/Player/ViewModel/BRPlayerViewModel.swift index 6b1643b..5e9562a 100644 --- a/BeeReel/Class/Player/ViewModel/BRPlayerViewModel.swift +++ b/BeeReel/Class/Player/ViewModel/BRPlayerViewModel.swift @@ -11,6 +11,8 @@ import UIKit @objc protocol BRPlayerViewModelDelegate { @objc optional func br_currentVideoPlayFinish(viewModel: BRPlayerViewModel) + + @objc optional func br_switchPlayAndPause(viewModel: BRPlayerViewModel) } @@ -42,4 +44,10 @@ extension BRPlayerViewModel { self.delegate?.br_currentVideoPlayFinish?(viewModel: self) } + ///切换播放跟暂停 + func switchPlayAndPause() { + self.delegate?.br_switchPlayAndPause?(viewModel: self) + } + + } diff --git a/BeeReel/Sources/Assets.xcassets/icon/episode_icon_01.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/episode_icon_01.imageset/Contents.json new file mode 100644 index 0000000..5c4d3b1 --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/episode_icon_01.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Frame@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Frame@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/episode_icon_01.imageset/Frame@2x.png b/BeeReel/Sources/Assets.xcassets/icon/episode_icon_01.imageset/Frame@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..2f810c2f5f2829f9cabf73c334d22b5f3ea4c162 GIT binary patch literal 622 zcmV-!0+IcRP)F+?bp|_k87o z!@c&SvC(3FSmj%+Fu~&?7_uMp*q92Z+#uNhf+o7Ga%GlULqw@3e6b`1t^C8M|P&S%0Q{(ZFQDHqo3*{d3!l$)LnH~p0Xm0!CgrTvu zB*uB6f^-P^9j|A7e%Q4pa3H#kFhPv{^^`DNtC?%PXU)KbevrjPw}I<9bv<)XHe#a8 z`T>G*SPMSw{^(%K1FZ=&5-3BR&?UuOc2A5X+ zWOhtwSoDq%CP=xnfRENrl!9-11u@lQVkh>*PB?JqD=JABVFxU@w31p?*tB!LYu6_| z_6Xx;XpO;n zA*GoML8$LE9Iq?G-6K)#)HxLpx%3f2Z_|g&YGW#b{aJVG7dF^&qAaKIA^-pY07*qo IM6N<$f(LaC_y7O^ literal 0 HcmV?d00001 diff --git a/BeeReel/Sources/Assets.xcassets/icon/episode_icon_01.imageset/Frame@3x.png b/BeeReel/Sources/Assets.xcassets/icon/episode_icon_01.imageset/Frame@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..77ea4c79ac31d60b1cd389bb5a5517374bf448bb GIT binary patch literal 870 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 literal 0 HcmV?d00001 diff --git a/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_02.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_02.imageset/Contents.json new file mode 100644 index 0000000..5c4d3b1 --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_02.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Frame@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Frame@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_02.imageset/Frame@2x.png b/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_02.imageset/Frame@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..0da7027fe8d5244969ca9a041c530aa0215c89b4 GIT binary patch literal 479 zcmV<50U-W~P)Y}y;fVhcRcZR7=UPdV|xa?IcgbH*Kw!*oenIYZ;v z`IhUHoG8~X$u~a84a2c^lxx^FUQttH{=0Cj;YQ9;aHMdflx_eVZ}cQ^pc9;EA*0xU<|!H$rvOkW(DPlUm(gt`rFx|ZA-@x6+L#L@xyPJPy-t49 zG`0u|jX+UI&vISuT4CIRO_~c6py? z1Qi%QX4%<4U}9ooV!~abCI=JIoHr}BPizTW%r@75pV)G?pKL#(D0;ySXkY8Ud zYWTY+J1A-zZ7Renvdi`ze_OJPqPn7~8?hyu3V)xe8x&m=O~pH_s9P3>zl6F)QBm9f zSMZ*?M^RCVx-3a1kEX`R5G(ohJNh9*kxSR;hb8CgOm!r@K?#|Vd5DlI}l%n%qs3eFJ@ zClP!?IQ$a9PY8!h1ZN0`Y{uOtDbgAICl{?{EgeF!-pR*h06_PcWB_0eKgm&ydgPY~ z>#2&b@Rx5QR(8xG9$%xJLq}J>ytcG-ly~rtT`5-hXZDaIeS|-KM#_CPcq8oUNt$1L?S0ACnqN-k^9q-$jVA25{X0t9mzdOKW^_RT`6gsq~{gm8Bh21 zF8!tFKobDMDD0;Lq?8kY(-aS#B+mqU{IFw;9e}vts!$X;g>(D@3?EAmU|V>AHDlv7 z5IGk@QRE|ve7h?0;tQ16V2LAk55)gMwM=pRz^5PKRwS(9VH^%!Y%Wx1r8q7c$;^>^ z;5@<@h+v@n6Z&<;(;Vht1T8ikV!m?qL7(czWGZl!3;Cx0N&0&a2t7ijj9)>BXJ`u{ zBN+XPhLEp3d5}-gCY(L1$xh0X!Lz_l5}|^%D^!!l!1?frG0?%!>xXoNiV1Xv5_?+s zny(!CLQR6=^eJPk#yp}wq4{qhUXmE_BVYR$s>$AO=j#Y;MCa>q ziut-`K@fsNST;h7U<^2zuNDi<$jjJw7h=H9Q@#uaGtAc+inY2;=)eg5Mv|}Ama*;$ z)fCIv;|wgqQK1=1EWF!vndMG~R*{skbG*z7VKiFznXitI&~M;nR^R#RmrzZ=Z9)%) zX7tl0^jK(0$8AFYg=TbA#tuiQru{bIz=USB*CzDiIn4L6VeF1M#DBC39aPzHX#YEMg2A*3B83v8Jpb9aR~`+LeeH&l;tZ4ZA_Z4 z@!_@jED60A&Yp`>NvH{wRC&_x04JfQ5K>Q6B-9)@>&J5vY7{vop(YXXiG&)3J(5tv zkWiz@Jqa}lXFC#V6t*Fu#$bDO_caMM1&1(sAnr%VC|etVgx-si8BA8$r}V04WB36Z z%}e$$*%Y58p*N#MenkM|sBG;j5_$`qZBf~hvEb@!^(3?wYzO?jV(j6v-(C_G+3~=^tc54m^%|U_uysVRxRglp1G6+S6V1Qu@ zZJ3i)3{$Ai$#cja?mNB97?@C%lM=5d#~Wygfe6jY#YxomQpf%a<$!H9os*s1q3o~F zEGL=yoUFn_p|_WdCh>>bjx z(C*r5UD2OV4x2P5z1kln6^bLJtKAkn$jK@apO5bp=ySe@(_VwhBm2kt6VfmVV3_D0>m?bd)9&*Mov~y zvJGYY(MW2tOzC(YHs?Mwbhv2ZMCkb*veP0_%g?lH!VHD^Xti``~{ii V3wTl2%ccMT002ovPDHLkV1ihW5C{MO literal 0 HcmV?d00001 diff --git a/BeeReel/Sources/Assets.xcassets/icon/play_icon_05.imageset/Polygon 1@3x.png b/BeeReel/Sources/Assets.xcassets/icon/play_icon_05.imageset/Polygon 1@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..0c53a3b1200fd30418722275fea80cbb6268d6b4 GIT binary patch literal 1588 zcmZ`(dsNbA7{=S6oDtq=O;N$k%%t3onHJ{#0tuy+XAxR1XX`>tF^1Rd;03#IS>j3w zlZz|MGPg`aEyWqs$@-b?n1z`b`>ALmrH0~u_W$1VzTf+P&-a|?JnugrcPBa4VddJD zFc{1sJ}xQ|>iJNeMSKCByU2=*P+P%>`ymSk^V+gpR?(t>0}yDHl^7cVYk1-YLKoYN z@Pu#}tdVEGaL^70vs1@Mh422=${?;ki6uFgu(D5Wij9uJ;&3>@=U{VY*6C4LL7ew@ zP|!UcXc@_=2=Av)nc1|Z6E}Y7Iv(@>#>>K4EzJQ1^USjij3Nf>IvTjZ(S7O3&&Q{; z=GBF+QH#iesYpbl=bH^aq>KUFzPcYBg~ffhEM0HK_``VB0rLIe^TZ(`q4sZvU7RYa z>`{>QlbwDv1xWa2!2Pdipc?;065cGaz220Zb9r#wG_CBXMT&OJuQ^cixcN~5Sbx*U z(AlxX!q2On*(Z3ZfP7)=JC|U^lU>G*OOfiJ-t(q~8vl_!bVps=FDK4mw{6= zDJFB0wYW)uA2pVIm*ZXUIhDXahPeTXu6OPE_BZ5Mm{9sRxtn`xs-iu`LTV^dPI2<& zGbnS}{wT%=wMaSE@iM6FehGwC=G1G}2Rj&3(CG?$q_Ih39L2%XF7dFW3JWp zRLwTVZ{+53zP@U56r^HYY1$tDHtcN_UUuRk$&&vi8wqwG3OVCLhx?tac#KAXhkAoR z1C+End2YgG8}QsiYHM%1o*oW&haS!d3PVS;c9|=LO1AX5FUmJByh<;7N`>i0^v_ zIm{2sf_$`v4?%OAbP<8pgY7^X=S;<9p#B`gi-5Rf(1f#*+-vgOLlBC=#>U*`V>YC# zDd^elLq(>i@hY+AleiMWK~|a#E=aJkW^W$5&LNJ+-SMuOQf#`r1~`%p2O9;4_!zHs zQvuc>>VNW?SEv_Zv*Y}Edz>_awr)U@Chv)gn0L9&$Jk%2UJ>wneJLMfBYao8y?QrA z0A7*qof9$aWN^~$8gFs=nZloz{j47DPiVt<{P_WG)|Qy~ajLBnVO#l`PlLknoYl8< zhZfhXB(q7O4q%EjGq<}gtx%C*agmudf>#YTKt8V55a>}M*{hkg0<|@nRPx>Wk1_s5 zOucVr)!{!1rvCcHcL*-KwWtqR|=9uG` zH8{o_lGw|F9!Qthp>!53s~4R0uDZ0AeaRX??lQOryvKc16q!=*4utftkexvIHIJWS z7UOV~B$fZ`Mo0=gSyCUj=iiXi*1ENPn?Ye{)?+*Yf%G{-TtVr3ZhwGXm6vc zZbDP1kbbbajK}eEZ+VUAmG|_8^m97^+)?qEYCGto^+dWUF5n4s)+3O2*#)h>s0-bq zW(PgADZQ#OXIMrPH+xrx(OD6AT3~=|;Zx1o7@hT6Iv>6YcMYCsao;7{CfIZBYaQ)Q zdpKsx<9Gkk+&!m{6zYW`*paz=R8_3%qmy4f!Gpa@;gym-w*IZ&J`q3Z>%@8)zPv!zL7Jh%}_@0jPK=p*~bbCeH_Fn3D fWM$@Hyag`4v*|nsXd-Z=$ z&wd7kBm@QvlxTDKfD0(6JWv@I%6f~)|At{8m7m`OxtqbJBwL}o)+3gxH1^hyD?=a&j;%NtAi{};#v3sTuvS4tsw z=D!K$w`Ui~hud%OO0+4!49}5 zDg_gR&D)oM6!0QB;I91}m>zf4IaA6;jlddH?9Id2cx<^JZ0~g{mN0aM9e(f_NA6J+8kADq5aji zKThF-=O+IF9&IgQKw-z2XkNcRLaNkBoI} z(!p#yl=Jw{KeC}+rJ(Bw-7g^D;WL3#rc*As6Yv?q_m!`LnVFduzX7*_9^=z)ju-#{ N002ovPDHLkV1htOUd#Xh literal 0 HcmV?d00001 diff --git a/BeeReel/Sources/Assets.xcassets/icon/search_icon_01.imageset/Frame@3x.png b/BeeReel/Sources/Assets.xcassets/icon/search_icon_01.imageset/Frame@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..e8fb6ae7df68e51ebe6979933b03905edc605ba4 GIT binary patch literal 1134 zcmV-!1d;oRP)UtYa_jXg*)1ZKdsQZf=fr zjYv_1v}`j z%<@DKj=z)u@K5o>hZ^|MS_K^U(<4mM9|4^Pxb|uq3h1z~X#G4@mYQW#tThB4ILl`B<;A1A}ahy&1Tm=5kRXg_YdlYy<=D}o7 zFG}kJ^J5R5{nwm0Gy>3rWSe_R1^Dn6mFU<&;^>+3HRNvuFy$Nt}}?PCFzKKp_$Vtceppj&JE=;;lWwe9L{x!5t^g_d*Q za0#>sXw22HZ~q){K1AKgTmn_r_CJ~)+zZEwB8cfh&Raaa&re&r0zOhYeo0$N`y}mI z=Bq7T0m%e13B0B&!xdtCYx^@zkBf&EE`jU>cT3ZQ6DaEL>JsSH+O9CY*%jO~Pt;Tz zmp~UkWEB86v`E&2xDyGQ7Q)(&o{Z%a$Ua&0U~ep-D~Pe9f#^mWrerXQFzcyJ2}(&% z(dm&2r>{0esWC+-`!&j;^t&1Omj-JZ0`L^r>LqIR7@(HtY_;R*LsTQ-W9?-kf)*Q9EvQJBRs{L$%6n-)WSwVc zL}-XF?5VcDj2NKYp@Xlk$2XJ%$*W@ZBT4{gg|(O8&wg#Z8m07*qoM6N<$f=*-x Ab^rhX literal 0 HcmV?d00001