个人中心开发完成
@ -226,7 +226,7 @@
|
|||||||
INFOPLIST_KEY_UIMainStoryboardFile = "";
|
INFOPLIST_KEY_UIMainStoryboardFile = "";
|
||||||
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
|
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
|
||||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
@ -263,7 +263,7 @@
|
|||||||
INFOPLIST_KEY_UIMainStoryboardFile = "";
|
INFOPLIST_KEY_UIMainStoryboardFile = "";
|
||||||
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
|
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
|
||||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
@ -14,9 +14,11 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||||||
|
|
||||||
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
|
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
|
||||||
guard let windowScene = (scene as? UIWindowScene) else { return }
|
guard let windowScene = (scene as? UIWindowScene) else { return }
|
||||||
|
let tabBarController = SPTabBarController()
|
||||||
|
SPAPPTool.mainTabBarController = tabBarController
|
||||||
|
|
||||||
window = UIWindow(windowScene: windowScene)
|
window = UIWindow(windowScene: windowScene)
|
||||||
window?.rootViewController = SPTabBarController()
|
window?.rootViewController = tabBarController
|
||||||
window?.makeKeyAndVisible()
|
window?.makeKeyAndVisible()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,8 @@ class SPNavigationController: UINavigationController {
|
|||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
self.jx_transitionAwake()
|
self.jx_transitionAwake()
|
||||||
|
|
||||||
|
self.view.backgroundColor = .backgroundColor()
|
||||||
// Do any additional setup after loading the view.
|
// Do any additional setup after loading the view.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ class SPTabBarController: UITabBarController {
|
|||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
self.view.backgroundColor = .backgroundColor()
|
||||||
|
|
||||||
let nav1 = createNavigationController(viewController: SPHomeViewController(), title: "Home".localized, image: UIImage(named: "tabbar_icon_01"), selectedImage: UIImage(named: "tabbar_icon_01_selected"))
|
let nav1 = createNavigationController(viewController: SPHomeViewController(), title: "Home".localized, image: UIImage(named: "tabbar_icon_01"), selectedImage: UIImage(named: "tabbar_icon_01_selected"))
|
||||||
|
|
||||||
@ -36,6 +37,28 @@ class SPTabBarController: UITabBarController {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension SPTabBarController {
|
||||||
|
func onPlayHistory() {
|
||||||
|
// self.selectedIndex = 1
|
||||||
|
var index: Int?
|
||||||
|
var viewController: SPMyListViewController?
|
||||||
|
self.viewControllers?.enumerated().forEach({
|
||||||
|
guard let nav = $1 as? UINavigationController else { return }
|
||||||
|
if let vc = nav.viewControllers.first as? SPMyListViewController {
|
||||||
|
index = $0
|
||||||
|
viewController = vc
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
if let index = index {
|
||||||
|
self.selectedIndex = index
|
||||||
|
viewController?.pageView.selectedIndex = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
extension SPTabBarController {
|
extension SPTabBarController {
|
||||||
|
|
||||||
func createNavigationController(viewController: UIViewController, title: String?, image: UIImage?, selectedImage: UIImage?) -> UINavigationController {
|
func createNavigationController(viewController: UIViewController, title: String?, image: UIImage?, selectedImage: UIImage?) -> UINavigationController {
|
||||||
|
@ -57,7 +57,7 @@ class SPViewController: UIViewController, JYPageChildContollerProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setBgImageView() {
|
func setBgImageView() {
|
||||||
self.view.backgroundColor = .color121317()
|
self.view.backgroundColor = .backgroundColor()
|
||||||
|
|
||||||
self.view.addSubview(toGradientView)
|
self.view.addSubview(toGradientView)
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ class SPViewController: UIViewController, JYPageChildContollerProtocol {
|
|||||||
|
|
||||||
extension UIViewController {
|
extension UIViewController {
|
||||||
|
|
||||||
func configNavigationBack(_ imageName: String = "left_arrow_icon_01") {
|
func configNavigationBack(_ imageName: String = "arrow_left_icon_01") {
|
||||||
let image = UIImage(named: imageName)
|
let image = UIImage(named: imageName)
|
||||||
|
|
||||||
let leftBarButtonItem = UIBarButtonItem(image: image, style: .plain ,target: self,action: #selector(handleBack))
|
let leftBarButtonItem = UIBarButtonItem(image: image, style: .plain ,target: self,action: #selector(handleBack))
|
||||||
|
@ -49,6 +49,7 @@ public let kSPAPPVersion: String = (Bundle.main.infoDictionary!["CFBundleShortVe
|
|||||||
public let kSPAPPBundleVersion: String = (Bundle.main.infoDictionary!["CFBundleVersion"] as? String) ?? "0"
|
public let kSPAPPBundleVersion: String = (Bundle.main.infoDictionary!["CFBundleVersion"] as? String) ?? "0"
|
||||||
|
|
||||||
public let kSPAPPBundleName: String = (Bundle.main.infoDictionary!["CFBundleName"] as? String) ?? ""
|
public let kSPAPPBundleName: String = (Bundle.main.infoDictionary!["CFBundleName"] as? String) ?? ""
|
||||||
|
public let kSPAPPName: String = (Bundle.main.infoDictionary!["CFBundleDisplayName"] as? String) ?? ""
|
||||||
|
|
||||||
//MARK: ------- 打印信息 ----------
|
//MARK: ------- 打印信息 ----------
|
||||||
public func spLog(message:Any? , file: String = #file, function: String = #function, line: Int = #line) {
|
public func spLog(message:Any? , file: String = #file, function: String = #function, line: Int = #line) {
|
||||||
|
@ -13,13 +13,13 @@ extension UIColor {
|
|||||||
return UIColor(rgb: hex, alpha: alpha)
|
return UIColor(rgb: hex, alpha: alpha)
|
||||||
}
|
}
|
||||||
|
|
||||||
// static func backgroundColor() -> UIColor {
|
static func backgroundColor() -> UIColor {
|
||||||
// return colorF3F5F7()
|
return color121317()
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
//
|
|
||||||
static func themeColor() -> UIColor {
|
static func themeColor() -> UIColor {
|
||||||
return color000000()
|
return .color121317()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -180,5 +180,17 @@ extension UIColor {
|
|||||||
static func color6D7A8F(alpha: CGFloat = 1) -> UIColor {
|
static func color6D7A8F(alpha: CGFloat = 1) -> UIColor {
|
||||||
return color(hex: 0x6D7A8F, alpha: alpha)
|
return color(hex: 0x6D7A8F, alpha: alpha)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static func color8B6C6C(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0x8B6C6C, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func color58484B(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0x58484B, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func colorE6334B(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0xE6334B, alpha: alpha)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,12 +91,12 @@ class SPVideoAPI: NSObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
///历史记录列表
|
///历史记录列表
|
||||||
static func requestPlayHistoryList(page: Int, completer: ((_ listModel: SPListModel<SPShortModel>?) -> Void)?) {
|
static func requestPlayHistoryList(page: Int, pageSize: Int = 20, completer: ((_ listModel: SPListModel<SPShortModel>?) -> Void)?) {
|
||||||
var param = SPNetworkParameters(path: "/myHistorys")
|
var param = SPNetworkParameters(path: "/myHistorys")
|
||||||
param.method = .get
|
param.method = .get
|
||||||
param.parameters = [
|
param.parameters = [
|
||||||
"current_page" : page,
|
"current_page" : page,
|
||||||
"page_size" : 20
|
"page_size" : pageSize
|
||||||
]
|
]
|
||||||
|
|
||||||
SPNetwork.request(parameters: param) { (response: SPNetworkResponse<SPListModel<SPShortModel>>) in
|
SPNetwork.request(parameters: param) { (response: SPNetworkResponse<SPListModel<SPShortModel>>) in
|
||||||
|
@ -19,10 +19,10 @@ import UIKit
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
let SPBaseURL = "https://test1-api.guyantv.com"
|
//let SPBaseURL = "https://test1-api.guyantv.com"
|
||||||
let SPURLPathPrefix = ""
|
//let SPURLPathPrefix = ""
|
||||||
//let SPBaseURL = "https://api-thimratv.thimratv.com"
|
let SPBaseURL = "https://api-thimratv.thimratv.com"
|
||||||
//let SPURLPathPrefix = "/0a2c5b02"
|
let SPURLPathPrefix = "/0a2c5b02"
|
||||||
|
|
||||||
let SPWebBaseURL = "https://www.thimratv.com"
|
let SPWebBaseURL = "https://www.thimratv.com"
|
||||||
#else
|
#else
|
||||||
@ -33,18 +33,17 @@ let SPWebBaseURL = "https://www.thimratv.com"
|
|||||||
|
|
||||||
|
|
||||||
///用户协议
|
///用户协议
|
||||||
let SPUserAgreementWebUrl = SPWebBaseURL + "/user_policy.htm"
|
let SPUserAgreementWebUrl = SPWebBaseURL + "/user_policy"
|
||||||
///隐私协议
|
///隐私协议
|
||||||
let SPPrivacyPolicyWebUrl = SPWebBaseURL + "/private.htm"
|
let SPPrivacyPolicyWebUrl = SPWebBaseURL + "/private"
|
||||||
///儿童个人信息保护规则
|
///儿童个人信息保护规则
|
||||||
let SPInformationProtectionWebUrl = SPWebBaseURL + "/information_protection.html"
|
let SPInformationProtectionWebUrl = SPWebBaseURL + "/information_protection"
|
||||||
///第三方共享清单
|
///第三方共享清单
|
||||||
let SPInformationSharingWebUrl = SPWebBaseURL + "/information_sharing.html"
|
let SPInformationSharingWebUrl = SPWebBaseURL + "/information_sharing"
|
||||||
///收集个人信息明示清单
|
///收集个人信息明示清单
|
||||||
let SPPersoInforDisclosureWebUrl = SPWebBaseURL + "/persoInfor_disclosure.html"
|
let SPPersoInforDisclosureWebUrl = SPWebBaseURL + "/persoInfor_disclosure"
|
||||||
///全国青少年互联网文明公约
|
///全国青少年互联网文明公约
|
||||||
let SPCivizatioConventionWebUrl = SPWebBaseURL + "/civizatio_convention.html"
|
let SPCivizatioConventionWebUrl = SPWebBaseURL + "/civizatio_convention"
|
||||||
///全国青少年互联网文明公约
|
|
||||||
let SPMemberShipAgreementWebUrl = SPWebBaseURL + "/member_ship_agreement.html"
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import UIKit
|
|||||||
|
|
||||||
class SPTableViewCell: UITableViewCell {
|
class SPTableViewCell: UITableViewCell {
|
||||||
|
|
||||||
var indicatorMargin: CGFloat = 7.5 {
|
var indicatorMargin: CGFloat = 15 {
|
||||||
didSet {
|
didSet {
|
||||||
indicatorImageView.snp.updateConstraints { make in
|
indicatorImageView.snp.updateConstraints { make in
|
||||||
make.right.equalToSuperview().offset(-indicatorMargin)
|
make.right.equalToSuperview().offset(-indicatorMargin)
|
||||||
@ -24,7 +24,7 @@ class SPTableViewCell: UITableViewCell {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private(set) lazy var indicatorImageView: UIImageView = {
|
private(set) lazy var indicatorImageView: UIImageView = {
|
||||||
let imageView = UIImageView(image: UIImage(named: "right_arrow_icon_01"))
|
let imageView = UIImageView(image: UIImage(named: "arrow_right_icon_02"))
|
||||||
imageView.isHidden = !showIndicator
|
imageView.isHidden = !showIndicator
|
||||||
return imageView
|
return imageView
|
||||||
}()
|
}()
|
||||||
|
@ -12,6 +12,11 @@ class SPWebView: WKWebView {
|
|||||||
|
|
||||||
weak var delegate: SPWebViewDelegate?
|
weak var delegate: SPWebViewDelegate?
|
||||||
|
|
||||||
|
private(set) var scriptMessageHandlerArray: [SPWebViewMessageName] = [
|
||||||
|
WebMessageGetUserInfo,
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
|
|
||||||
self.removeObserver(self, forKeyPath: "estimatedProgress")
|
self.removeObserver(self, forKeyPath: "estimatedProgress")
|
||||||
@ -21,7 +26,7 @@ class SPWebView: WKWebView {
|
|||||||
|
|
||||||
override init(frame: CGRect, configuration: WKWebViewConfiguration) {
|
override init(frame: CGRect, configuration: WKWebViewConfiguration) {
|
||||||
super.init(frame: frame, configuration: configuration)
|
super.init(frame: frame, configuration: configuration)
|
||||||
// addScriptMessageHandler()
|
addScriptMessageHandler()
|
||||||
_setupInit()
|
_setupInit()
|
||||||
}
|
}
|
||||||
required init?(coder: NSCoder) {
|
required init?(coder: NSCoder) {
|
||||||
@ -58,6 +63,17 @@ class SPWebView: WKWebView {
|
|||||||
self.load(request)
|
self.load(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func removeScriptMessageHandler() {
|
||||||
|
self.scriptMessageHandlerArray.forEach{
|
||||||
|
configuration.userContentController.removeScriptMessageHandler(forName: $0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func addScriptMessageHandler() {
|
||||||
|
self.scriptMessageHandlerArray.forEach{
|
||||||
|
configuration.userContentController.add(YYWeakProxy(target: self) as! WKScriptMessageHandler, name: $0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//MARK:-------------- WKUIDelegate --------------
|
//MARK:-------------- WKUIDelegate --------------
|
||||||
|
28
Thimra/Base/WebView/SPWebViewController+ScriptMessage.swift
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// SPWebViewController+ScriptMessage.swift
|
||||||
|
// Thimra
|
||||||
|
//
|
||||||
|
// Created by Overseas on 2025/4/24.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import WebKit
|
||||||
|
|
||||||
|
typealias SPWebViewMessageName = String
|
||||||
|
|
||||||
|
///获取用户信息
|
||||||
|
let WebMessageGetUserInfo: SPWebViewMessageName = "getUserInfo"
|
||||||
|
|
||||||
|
|
||||||
|
extension SPWebViewController {
|
||||||
|
|
||||||
|
func _webViewUserContentController(didReceive message: WKScriptMessage) {
|
||||||
|
let name = message.name
|
||||||
|
let body = message.body
|
||||||
|
|
||||||
|
|
||||||
|
// let js = "window.returnGPSposition('{\"longitude\":\(placemark.longitude ?? 0),\"latitude\":\(placemark.latitude ?? 0)}')"
|
||||||
|
// self.webView.evaluateJavaScript(js, completionHandler: nil)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -27,6 +27,7 @@ class SPWebViewController: SPViewController {
|
|||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
// self.edgesForExtendedLayout = .top
|
||||||
configNavigationBack()
|
configNavigationBack()
|
||||||
|
|
||||||
_setupUI()
|
_setupUI()
|
||||||
@ -36,6 +37,9 @@ class SPWebViewController: SPViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func setBgImageView() {
|
||||||
|
self.view.backgroundColor = .backgroundColor()
|
||||||
|
}
|
||||||
|
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
super.viewWillAppear(animated)
|
super.viewWillAppear(animated)
|
||||||
@ -86,4 +90,8 @@ extension SPWebViewController: SPWebViewDelegate {
|
|||||||
func webView(_ webView: SPWebView, didFailLoadWithError error: any Error) {
|
func webView(_ webView: SPWebView, didFailLoadWithError error: any Error) {
|
||||||
spLog(message: error)
|
spLog(message: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
|
||||||
|
_webViewUserContentController(didReceive: message)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,16 @@ class SPAllShortViewController: SPViewController {
|
|||||||
private lazy var dataArr: [SPShortModel] = []
|
private lazy var dataArr: [SPShortModel] = []
|
||||||
private lazy var page = 1
|
private lazy var page = 1
|
||||||
|
|
||||||
|
private lazy var isOpen = false
|
||||||
|
private var tagMaxHeight: CGFloat {
|
||||||
|
var height = CGFloat(MAXFLOAT)
|
||||||
|
if !isOpen {
|
||||||
|
height = tagView.tagHeight * 2 + tagView.tagVerticalGap
|
||||||
|
}
|
||||||
|
return height
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//MARK: UI属性
|
//MARK: UI属性
|
||||||
private lazy var tagView: JXTagView = {
|
private lazy var tagView: JXTagView = {
|
||||||
let tagView = JXTagView()
|
let tagView = JXTagView()
|
||||||
@ -44,6 +54,34 @@ class SPAllShortViewController: SPViewController {
|
|||||||
return tagView
|
return tagView
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
///展开按钮边上的渐变
|
||||||
|
private lazy var openGradientLayer: CAGradientLayer = {
|
||||||
|
let layer = CAGradientLayer()
|
||||||
|
layer.colors = [UIColor.clear.withAlphaComponent(1).cgColor, UIColor.clear.withAlphaComponent(0).cgColor]
|
||||||
|
layer.locations = [0, 1]
|
||||||
|
layer.rasterizationScale = UIScreen.main.scale
|
||||||
|
layer.startPoint = CGPoint(x: 0.7, y: 0.5)
|
||||||
|
layer.endPoint = CGPoint(x: 1, y: 1)
|
||||||
|
// layer.frame = CGRect(x: 0, y: 0, width: 100, height: tagView.height)
|
||||||
|
|
||||||
|
return layer
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var openButton: UIButton = {
|
||||||
|
let button = UIButton(type: .custom)
|
||||||
|
button.setImage(UIImage(named: "arrow_bown_icon_01"), for: .normal)
|
||||||
|
button.setImage(UIImage(named: "arrow_up_icon_01"), for: .selected)
|
||||||
|
button.setImage(UIImage(named: "arrow_up_icon_01"), for: [.selected, .highlighted])
|
||||||
|
button.addTarget(self, action: #selector(handleOpenButton), for: .touchUpInside)
|
||||||
|
return button
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var bgView: UIView = {
|
||||||
|
let view = UIView()
|
||||||
|
view.addEffectView(style: .dark)
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
private lazy var collectionViewLayout: UICollectionViewFlowLayout = {
|
private lazy var collectionViewLayout: UICollectionViewFlowLayout = {
|
||||||
let width = floor((kSPScreenWidth - 32 - 14 * 2) / 3)
|
let width = floor((kSPScreenWidth - 32 - 14 * 2) / 3)
|
||||||
let height = 145 / 105 * width + 36
|
let height = 145 / 105 * width + 36
|
||||||
@ -56,12 +94,6 @@ class SPAllShortViewController: SPViewController {
|
|||||||
return layout
|
return layout
|
||||||
}()
|
}()
|
||||||
|
|
||||||
private lazy var bgView: UIView = {
|
|
||||||
let view = UIView()
|
|
||||||
view.addEffectView(style: .dark)
|
|
||||||
return view
|
|
||||||
}()
|
|
||||||
|
|
||||||
private lazy var collectionView: SPCollectionView = {
|
private lazy var collectionView: SPCollectionView = {
|
||||||
let collectionView = SPCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
|
let collectionView = SPCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
|
||||||
collectionView.delegate = self
|
collectionView.delegate = self
|
||||||
@ -87,6 +119,18 @@ class SPAllShortViewController: SPViewController {
|
|||||||
_setupUI()
|
_setupUI()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func viewDidLayoutSubviews() {
|
||||||
|
super.viewDidLayoutSubviews()
|
||||||
|
|
||||||
|
let widht: CGFloat = 100
|
||||||
|
let height = self.tagView.tagHeight
|
||||||
|
let x = self.tagView.width - widht
|
||||||
|
let y = self.tagView.height - height
|
||||||
|
|
||||||
|
// openGradientLayer.frame = CGRect(x: x, y: y, width: widht, height: height)
|
||||||
|
openGradientLayer.frame = self.tagView.bounds
|
||||||
|
}
|
||||||
|
|
||||||
override func setBgImageView() {
|
override func setBgImageView() {
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -102,17 +146,39 @@ class SPAllShortViewController: SPViewController {
|
|||||||
self?.collectionView.sp_endFooterRefreshing()
|
self?.collectionView.sp_endFooterRefreshing()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc private func handleOpenButton() {
|
||||||
|
self.isOpen = !self.isOpen
|
||||||
|
|
||||||
|
self.openButton.isSelected = self.isOpen
|
||||||
|
|
||||||
|
tagView.snp.updateConstraints { make in
|
||||||
|
make.height.lessThanOrEqualTo(tagMaxHeight)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SPAllShortViewController {
|
extension SPAllShortViewController {
|
||||||
private func _setupUI() {
|
private func _setupUI() {
|
||||||
|
tagView.layer.mask = self.openGradientLayer
|
||||||
|
|
||||||
view.addSubview(tagView)
|
view.addSubview(tagView)
|
||||||
view.addSubview(bgView)
|
view.addSubview(bgView)
|
||||||
|
view.addSubview(openButton)
|
||||||
bgView.addSubview(collectionView)
|
bgView.addSubview(collectionView)
|
||||||
|
|
||||||
tagView.snp.makeConstraints { make in
|
tagView.snp.makeConstraints { make in
|
||||||
make.left.right.equalToSuperview()
|
make.left.right.equalToSuperview()
|
||||||
make.top.equalToSuperview().offset(kSPStatusbarHeight + 40 + 12)
|
make.top.equalToSuperview().offset(kSPStatusbarHeight + 40 + 12)
|
||||||
|
make.height.lessThanOrEqualTo(tagMaxHeight)
|
||||||
|
}
|
||||||
|
|
||||||
|
openButton.snp.makeConstraints { make in
|
||||||
|
make.right.equalToSuperview().offset(-16)
|
||||||
|
make.bottom.equalTo(tagView)
|
||||||
|
make.height.equalTo(tagView.tagHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
bgView.snp.makeConstraints { make in
|
bgView.snp.makeConstraints { make in
|
||||||
|
@ -8,11 +8,106 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
class SPAboutUsViewController: SPViewController {
|
class SPAboutUsViewController: SPViewController {
|
||||||
|
|
||||||
|
private lazy var dataArr: [SPMineItem] = {
|
||||||
|
let arr = [
|
||||||
|
SPMineItem(type: .userAgreement, title: "User Agreement".localized),
|
||||||
|
SPMineItem(type: .privacyPolicy, title: "Privacy Policy".localized),
|
||||||
|
SPMineItem(type: .informationProtection, title: "Child Personal Information Protection Rules".localized),
|
||||||
|
SPMineItem(type: .civizatioConvention, title: "Youth Civilization Convention".localized),
|
||||||
|
SPMineItem(type: .informationSharing, title: "List of Third-Party Sharing of Personal Information".localized),
|
||||||
|
SPMineItem(type: .persoInforDisclosure, title: "Explicit List of Personal Information Collection".localized),
|
||||||
|
]
|
||||||
|
return arr
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var tableView: SPTableView = {
|
||||||
|
let tableView = SPTableView(frame: .zero, style: .plain)
|
||||||
|
tableView.delegate = self
|
||||||
|
tableView.dataSource = self
|
||||||
|
tableView.rowHeight = 50
|
||||||
|
SPAboutUsCell.registerCell(tableView: tableView)
|
||||||
|
return tableView
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var headerView: SPAboutUsHeaderView = {
|
||||||
|
let view = SPAboutUsHeaderView(frame: .init(x: 0, y: 0, width: kSPScreenWidth, height: 200))
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
self.title = "About Us".localized
|
||||||
|
|
||||||
|
_setupUI()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
|
super.viewWillAppear(animated)
|
||||||
|
self.navigationController?.setNavigationBarHidden(false, animated: true)
|
||||||
|
setNavigationNormalStyle()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func setBgImageView() {
|
||||||
|
self.view.backgroundColor = .backgroundColor()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension SPAboutUsViewController {
|
||||||
|
private func _setupUI() {
|
||||||
|
self.tableView.tableHeaderView = self.headerView
|
||||||
|
view.addSubview(tableView)
|
||||||
|
|
||||||
|
tableView.snp.makeConstraints { make in
|
||||||
|
make.edges.equalToSuperview()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//MARK: -------------- UITableViewDelegate & UITableViewDataSource --------------
|
||||||
|
extension SPAboutUsViewController: UITableViewDelegate, UITableViewDataSource {
|
||||||
|
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||||
|
let cell = SPAboutUsCell.dequeueReusableCell(tableView: tableView, indexPath: indexPath)
|
||||||
|
cell.item = dataArr[indexPath.row]
|
||||||
|
return cell
|
||||||
|
}
|
||||||
|
|
||||||
|
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||||
|
return dataArr.count
|
||||||
|
}
|
||||||
|
|
||||||
|
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||||
|
let item = dataArr[indexPath.row]
|
||||||
|
var urlStr: String?
|
||||||
|
|
||||||
|
switch item.type {
|
||||||
|
case .userAgreement:
|
||||||
|
urlStr = SPUserAgreementWebUrl
|
||||||
|
|
||||||
|
case.privacyPolicy:
|
||||||
|
urlStr = SPPrivacyPolicyWebUrl
|
||||||
|
|
||||||
|
case.informationProtection:
|
||||||
|
urlStr = SPInformationProtectionWebUrl
|
||||||
|
|
||||||
|
case.civizatioConvention:
|
||||||
|
urlStr = SPCivizatioConventionWebUrl
|
||||||
|
|
||||||
|
case.informationSharing:
|
||||||
|
urlStr = SPInformationSharingWebUrl
|
||||||
|
|
||||||
|
case.persoInforDisclosure:
|
||||||
|
urlStr = SPPersoInforDisclosureWebUrl
|
||||||
|
|
||||||
|
default: break
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
let vc = SPWebViewController()
|
||||||
|
vc.urlStr = urlStr
|
||||||
|
self.navigationController?.pushViewController(vc, animated: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -11,23 +11,26 @@ class SPMineViewController: SPViewController {
|
|||||||
|
|
||||||
private lazy var dataArr: [SPMineItem] = {
|
private lazy var dataArr: [SPMineItem] = {
|
||||||
let arr = [
|
let arr = [
|
||||||
SPMineItem(type: .orderRecord, iconImage: UIImage(named: "order_record_icon_01"), title: "Order Record".localized),
|
// SPMineItem(type: .language, iconImage: UIImage(named: "language_icon_01"), title: "Language".localized),
|
||||||
SPMineItem(type: .language, iconImage: UIImage(named: "language_icon_01"), title: "Language".localized),
|
|
||||||
SPMineItem(type: .privacyPolicy, iconImage: UIImage(named: "privacy_policy_icon_01"), title: "Privacy Policy".localized),
|
SPMineItem(type: .privacyPolicy, iconImage: UIImage(named: "privacy_policy_icon_01"), title: "Privacy Policy".localized),
|
||||||
SPMineItem(type: .userAgreement, iconImage: UIImage(named: "user_agreement_icon_01"), title: "User Agreement".localized),
|
SPMineItem(type: .userAgreement, iconImage: UIImage(named: "user_agreement_icon_01"), title: "User Agreement".localized),
|
||||||
SPMineItem(type: .helpCenter, iconImage: UIImage(named: "help_center_icon_01"), title: "Help Center".localized),
|
|
||||||
SPMineItem(type: .aboutUs, iconImage: UIImage(named: "about_us_icon_01"), title: "About Us".localized),
|
SPMineItem(type: .aboutUs, iconImage: UIImage(named: "about_us_icon_01"), title: "About Us".localized),
|
||||||
]
|
]
|
||||||
return arr
|
return arr
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
///是否进入过
|
||||||
|
private var isHaveEntered = false
|
||||||
|
|
||||||
|
//MARK: UI 属性
|
||||||
private lazy var headerView: SPMineHeaderView = {
|
private lazy var headerView: SPMineHeaderView = {
|
||||||
let view = SPMineHeaderView(frame: CGRect(x: 0, y: 0, width: kSPScreenWidth, height: 200))
|
let view = SPMineHeaderView()
|
||||||
|
view.frame = CGRect(x: 0, y: 0, width: kSPScreenWidth, height: view.contentHeight)
|
||||||
return view
|
return view
|
||||||
}()
|
}()
|
||||||
|
|
||||||
private lazy var tableView: SPTableView = {
|
private lazy var tableView: SPTableView = {
|
||||||
let tableView = SPTableView(frame: .zero, style: .insetGrouped)
|
let tableView = SPTableView(frame: .zero, style: .plain)
|
||||||
tableView.delegate = self
|
tableView.delegate = self
|
||||||
tableView.dataSource = self
|
tableView.dataSource = self
|
||||||
tableView.rowHeight = 50
|
tableView.rowHeight = 50
|
||||||
@ -38,17 +41,35 @@ class SPMineViewController: SPViewController {
|
|||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
|
||||||
requestUserInfo()
|
requestData()
|
||||||
|
|
||||||
_setupUI()
|
_setupUI()
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
super.viewWillAppear(animated)
|
super.viewWillAppear(animated)
|
||||||
self.setNavigationNormalStyle()
|
self.navigationController?.setNavigationBarHidden(true, animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func viewDidAppear(_ animated: Bool) {
|
||||||
|
super.viewDidAppear(animated)
|
||||||
|
if isHaveEntered {
|
||||||
|
requestData()
|
||||||
|
}
|
||||||
|
|
||||||
|
isHaveEntered = true
|
||||||
|
}
|
||||||
|
|
||||||
|
private func updateHeaderView() {
|
||||||
|
tableView.tableHeaderView = nil
|
||||||
|
self.headerView.height = self.headerView.contentHeight
|
||||||
|
|
||||||
|
tableView.tableHeaderView = headerView
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SPMineViewController {
|
extension SPMineViewController {
|
||||||
@ -103,11 +124,29 @@ extension SPMineViewController: UITableViewDelegate, UITableViewDataSource {
|
|||||||
|
|
||||||
extension SPMineViewController {
|
extension SPMineViewController {
|
||||||
|
|
||||||
|
private func requestData() {
|
||||||
|
requestUserInfo()
|
||||||
|
requestPlayHistoryList()
|
||||||
|
}
|
||||||
|
|
||||||
|
///获取用户信息
|
||||||
private func requestUserInfo() {
|
private func requestUserInfo() {
|
||||||
|
SPUserAPI.requestUserInfo { [weak self] userInfo in
|
||||||
SPUserAPI.requestUserInfo { userInfo in
|
guard let self = self else { return }
|
||||||
|
if let userInfo = userInfo {
|
||||||
|
self.headerView.userInfo = userInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
///获取播放记录
|
||||||
|
private func requestPlayHistoryList() {
|
||||||
|
SPVideoAPI.requestPlayHistoryList(page: 1, pageSize: 3) { [weak self] listModel in
|
||||||
|
guard let self = self else { return }
|
||||||
|
if let list = listModel?.list {
|
||||||
|
self.headerView.playHistoryArr = list
|
||||||
|
|
||||||
|
self.updateHeaderView()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,14 @@ struct SPMineItem {
|
|||||||
case helpCenter
|
case helpCenter
|
||||||
///关于我们
|
///关于我们
|
||||||
case aboutUs
|
case aboutUs
|
||||||
|
///儿童个人信息保护规则
|
||||||
|
case informationProtection
|
||||||
|
///全国青少年互联网文明公约
|
||||||
|
case civizatioConvention
|
||||||
|
///第三方共享清单
|
||||||
|
case informationSharing
|
||||||
|
///收集个人信息明示清单
|
||||||
|
case persoInforDisclosure
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
50
Thimra/Class/Mine/View/SPAboutUsCell.swift
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
//
|
||||||
|
// SPAboutUsCell.swift
|
||||||
|
// Thimra
|
||||||
|
//
|
||||||
|
// Created by Overseas on 2025/4/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class SPAboutUsCell: SPTableViewCell {
|
||||||
|
|
||||||
|
var item: SPMineItem? {
|
||||||
|
didSet {
|
||||||
|
titleLabel.text = item?.title
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private lazy var titleLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = .fontMedium(ofSize: 14)
|
||||||
|
label.textColor = .colorFFFFFF()
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||||
|
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||||
|
showIndicator = true
|
||||||
|
|
||||||
|
_setupUI()
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SPAboutUsCell {
|
||||||
|
|
||||||
|
private func _setupUI() {
|
||||||
|
contentView.addSubview(titleLabel)
|
||||||
|
|
||||||
|
titleLabel.snp.makeConstraints { make in
|
||||||
|
make.centerY.equalToSuperview()
|
||||||
|
make.left.equalToSuperview().offset(16)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
74
Thimra/Class/Mine/View/SPAboutUsHeaderView.swift
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
//
|
||||||
|
// SPAboutUsHeaderView.swift
|
||||||
|
// Thimra
|
||||||
|
//
|
||||||
|
// Created by Overseas on 2025/4/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class SPAboutUsHeaderView: UIView {
|
||||||
|
|
||||||
|
|
||||||
|
private lazy var logoImageView: UIImageView = {
|
||||||
|
let imageView = UIImageView(image: UIImage(named: "about_us_logo_icon"))
|
||||||
|
imageView.layer.cornerRadius = 8
|
||||||
|
imageView.layer.masksToBounds = true
|
||||||
|
imageView.backgroundColor = .red
|
||||||
|
return imageView
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var nameLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = .fontBold(ofSize: 18)
|
||||||
|
label.textColor = .colorFFFFFF()
|
||||||
|
label.text = kSPAPPName
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var versionLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = .fontRegular(ofSize: 12)
|
||||||
|
label.textColor = .colorFFFFFF(alpha: 0.8)
|
||||||
|
label.text = "version:\(kSPAPPVersion)"
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
|
||||||
|
_setupUI()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SPAboutUsHeaderView {
|
||||||
|
|
||||||
|
private func _setupUI() {
|
||||||
|
addSubview(logoImageView)
|
||||||
|
addSubview(nameLabel)
|
||||||
|
addSubview(versionLabel)
|
||||||
|
|
||||||
|
logoImageView.snp.makeConstraints { make in
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
make.top.equalToSuperview().offset(40)
|
||||||
|
make.width.height.equalTo(100)
|
||||||
|
}
|
||||||
|
|
||||||
|
nameLabel.snp.makeConstraints { make in
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
make.top.equalTo(logoImageView.snp.bottom).offset(10)
|
||||||
|
}
|
||||||
|
|
||||||
|
versionLabel.snp.makeConstraints { make in
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
make.top.equalTo(nameLabel.snp.bottom).offset(5)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -23,15 +23,15 @@ class SPMineCell: SPTableViewCell {
|
|||||||
|
|
||||||
private lazy var titleLabel: UILabel = {
|
private lazy var titleLabel: UILabel = {
|
||||||
let label = UILabel()
|
let label = UILabel()
|
||||||
label.font = .fontRegular(ofSize: 14)
|
label.font = .fontMedium(ofSize: 16)
|
||||||
label.textColor = .colorFFFFFF(alpha: 0.9)
|
label.textColor = .colorFFFFFF()
|
||||||
return label
|
return label
|
||||||
}()
|
}()
|
||||||
|
|
||||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||||
|
showIndicator = true
|
||||||
self.contentView.backgroundColor = .colorFFFFFF(alpha: 0.04)
|
// self.contentView.backgroundColor = .colorFFFFFF(alpha: 0.04)
|
||||||
|
|
||||||
_setupUI()
|
_setupUI()
|
||||||
|
|
||||||
@ -51,12 +51,12 @@ extension SPMineCell {
|
|||||||
|
|
||||||
iconImageView.snp.makeConstraints { make in
|
iconImageView.snp.makeConstraints { make in
|
||||||
make.centerY.equalToSuperview()
|
make.centerY.equalToSuperview()
|
||||||
make.left.equalToSuperview().offset(10)
|
make.left.equalToSuperview().offset(16)
|
||||||
}
|
}
|
||||||
|
|
||||||
titleLabel.snp.makeConstraints { make in
|
titleLabel.snp.makeConstraints { make in
|
||||||
make.centerY.equalToSuperview()
|
make.centerY.equalToSuperview()
|
||||||
make.left.equalToSuperview().offset(40)
|
make.left.equalToSuperview().offset(46)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,145 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
class SPMineHeaderView: UIView {
|
class SPMineHeaderView: UIView {
|
||||||
|
|
||||||
|
var contentHeight: CGFloat {
|
||||||
|
var height: CGFloat = kSPStatusbarHeight + 108
|
||||||
|
|
||||||
|
if playHistoryArr?.count ?? 0 > 0 {
|
||||||
|
height += playHistoryView.contentHeight
|
||||||
|
height += 10
|
||||||
|
}
|
||||||
|
|
||||||
|
return height
|
||||||
|
}
|
||||||
|
|
||||||
|
var userInfo: SPUserInfo? {
|
||||||
|
didSet {
|
||||||
|
avatarImageView.sp_setImage(url: userInfo?.avator, placeholder: UIImage(named: "avatar_image_01"))
|
||||||
|
|
||||||
|
if let name = userInfo?.family_name, name.count > 0 {
|
||||||
|
nicknameLabel.text = name
|
||||||
|
} else {
|
||||||
|
nicknameLabel.text = "Vistor"
|
||||||
|
}
|
||||||
|
idLabel.text = "ID \(userInfo?.customer_id ?? "")"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var playHistoryArr: [SPShortModel]? {
|
||||||
|
didSet {
|
||||||
|
stackView.removeAllArrangedSubview()
|
||||||
|
|
||||||
|
if let arr = playHistoryArr, arr.count > 0 {
|
||||||
|
stackView.addArrangedSubview(playHistoryView)
|
||||||
|
}
|
||||||
|
|
||||||
|
playHistoryView.dataArr = playHistoryArr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//MARK: UI属性
|
||||||
|
private lazy var avatarImageView: SPImageView = {
|
||||||
|
let imageView = SPImageView(image: UIImage(named: "avatar_image_01"))
|
||||||
|
imageView.layer.cornerRadius = 31
|
||||||
|
imageView.layer.masksToBounds = true
|
||||||
|
imageView.layer.borderColor = UIColor.colorFFFFFF(alpha: 0.3).cgColor
|
||||||
|
imageView.layer.borderWidth = 2
|
||||||
|
return imageView
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var nicknameLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = .fontMedium(ofSize: 16)
|
||||||
|
label.textColor = .colorFFFFFF()
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var idLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = .fontRegular(ofSize: 14)
|
||||||
|
label.textColor = .color8B6C6C()
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var copyButton: UIButton = {
|
||||||
|
let button = UIButton(type: .custom)
|
||||||
|
button.setTitle("Copy".localized, for: .normal)
|
||||||
|
button.setTitleColor(.colorFFFFFF(), for: .normal)
|
||||||
|
button.titleLabel?.font = .fontRegular(ofSize: 12)
|
||||||
|
button.setBackgroundImage(UIImage(color: .color58484B(alpha: 0.56)), for: .normal)
|
||||||
|
button.layer.cornerRadius = 2
|
||||||
|
button.layer.masksToBounds = true
|
||||||
|
button.addTarget(self, action: #selector(handleCopyButton), for: .touchUpInside)
|
||||||
|
return button
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var stackView: UIStackView = {
|
||||||
|
let view = UIStackView()
|
||||||
|
view.axis = .vertical
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var playHistoryView: SPMinePlayHistoryView = {
|
||||||
|
let view = SPMinePlayHistoryView()
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
_setupUI()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc private func handleCopyButton() {
|
||||||
|
SPAPPTool.copy(text: userInfo?.customer_id)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SPMineHeaderView {
|
||||||
|
|
||||||
|
private func _setupUI() {
|
||||||
|
addSubview(avatarImageView)
|
||||||
|
addSubview(nicknameLabel)
|
||||||
|
addSubview(idLabel)
|
||||||
|
addSubview(copyButton)
|
||||||
|
addSubview(stackView)
|
||||||
|
|
||||||
|
avatarImageView.snp.makeConstraints { make in
|
||||||
|
make.left.equalToSuperview().offset(16)
|
||||||
|
make.top.equalToSuperview().offset(kSPStatusbarHeight + 22)
|
||||||
|
make.width.height.equalTo(62)
|
||||||
|
}
|
||||||
|
|
||||||
|
nicknameLabel.snp.makeConstraints { make in
|
||||||
|
make.left.equalTo(avatarImageView.snp.right).offset(15)
|
||||||
|
make.top.equalTo(avatarImageView).offset(9)
|
||||||
|
}
|
||||||
|
|
||||||
|
idLabel.snp.makeConstraints { make in
|
||||||
|
make.left.equalTo(nicknameLabel)
|
||||||
|
make.top.equalTo(nicknameLabel.snp.bottom).offset(6)
|
||||||
|
}
|
||||||
|
|
||||||
|
let copyWidth = (copyButton.currentTitle?.size(font: copyButton.titleLabel?.font ?? .fontRegular(ofSize: 12)).width ?? 0) + 8
|
||||||
|
|
||||||
|
copyButton.snp.makeConstraints { make in
|
||||||
|
make.centerY.equalTo(idLabel)
|
||||||
|
make.left.equalTo(idLabel.snp.right).offset(6)
|
||||||
|
make.height.equalTo(18)
|
||||||
|
make.width.equalTo(copyWidth)
|
||||||
|
}
|
||||||
|
|
||||||
|
stackView.snp.makeConstraints { make in
|
||||||
|
make.left.right.equalToSuperview()
|
||||||
|
make.top.equalToSuperview().offset(kSPStatusbarHeight + 108)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
86
Thimra/Class/Mine/View/SPMinePlayHistoryCell.swift
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
//
|
||||||
|
// SPMinePlayHistoryCell.swift
|
||||||
|
// Thimra
|
||||||
|
//
|
||||||
|
// Created by Overseas on 2025/4/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class SPMinePlayHistoryCell: SPCollectionViewCell {
|
||||||
|
|
||||||
|
var model: SPShortModel? {
|
||||||
|
didSet {
|
||||||
|
coverImageView.sp_setImage(url: model?.image_url)
|
||||||
|
titleLabel.text = model?.name
|
||||||
|
|
||||||
|
let episode_total = "\(model?.episode_total ?? 0)"
|
||||||
|
let episode = String(format: "EP.%@/%@", "\(model?.current_episode ?? "0")", episode_total)
|
||||||
|
|
||||||
|
let episodeString = NSMutableAttributedString(string: episode)
|
||||||
|
episodeString.color = .colorE6334B()
|
||||||
|
|
||||||
|
let range = NSRange(location: episode.length() - episode_total.length(), length: episode_total.length())
|
||||||
|
episodeString.setColor(.colorAFAFAF(), range: range)
|
||||||
|
episodeLabel.attributedText = episodeString
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//MARK: UI属性
|
||||||
|
private lazy var coverImageView: SPImageView = {
|
||||||
|
let imageView = SPImageView()
|
||||||
|
imageView.layer.cornerRadius = 4
|
||||||
|
imageView.layer.masksToBounds = true
|
||||||
|
return imageView
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var titleLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = .fontMedium(ofSize: 12)
|
||||||
|
label.textColor = .colorAFAFAF()
|
||||||
|
label.numberOfLines = 2
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var episodeLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = .fontMedium(ofSize: 12)
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
|
||||||
|
_setupUI()
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SPMinePlayHistoryCell {
|
||||||
|
|
||||||
|
private func _setupUI() {
|
||||||
|
contentView.addSubview(coverImageView)
|
||||||
|
contentView.addSubview(titleLabel)
|
||||||
|
contentView.addSubview(episodeLabel)
|
||||||
|
|
||||||
|
coverImageView.snp.makeConstraints { make in
|
||||||
|
make.left.right.top.equalToSuperview()
|
||||||
|
make.bottom.equalToSuperview().offset(-58)
|
||||||
|
}
|
||||||
|
|
||||||
|
titleLabel.snp.makeConstraints { make in
|
||||||
|
make.left.equalToSuperview()
|
||||||
|
make.right.lessThanOrEqualToSuperview()
|
||||||
|
make.top.equalTo(coverImageView.snp.bottom).offset(12)
|
||||||
|
}
|
||||||
|
|
||||||
|
episodeLabel.snp.makeConstraints { make in
|
||||||
|
make.left.equalToSuperview()
|
||||||
|
make.top.equalTo(titleLabel.snp.bottom).offset(4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
139
Thimra/Class/Mine/View/SPMinePlayHistoryView.swift
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
//
|
||||||
|
// SPMinePlayHistoryView.swift
|
||||||
|
// Thimra
|
||||||
|
//
|
||||||
|
// Created by Overseas on 2025/4/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class SPMinePlayHistoryView: UIView {
|
||||||
|
|
||||||
|
var contentHeight: CGFloat {
|
||||||
|
return collectionViewLayout.itemSize.height + 20 + 12
|
||||||
|
}
|
||||||
|
|
||||||
|
override var intrinsicContentSize: CGSize {
|
||||||
|
return CGSize(width: kSPScreenWidth, height: contentHeight)
|
||||||
|
}
|
||||||
|
|
||||||
|
var dataArr: [SPShortModel]? {
|
||||||
|
didSet {
|
||||||
|
self.collectionView.reloadData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//MARK: UI属性
|
||||||
|
private lazy var titleIconImageView: UIImageView = {
|
||||||
|
let imageView = UIImageView(image: UIImage(named: "history_icon_01"))
|
||||||
|
return imageView
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var titleLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = .fontMedium(ofSize: 16)
|
||||||
|
label.textColor = .colorFFFFFF()
|
||||||
|
label.text = "Watch History".localized
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var moreButton: UIButton = {
|
||||||
|
let button = UIButton(type: .custom)
|
||||||
|
button.setImage(UIImage(named: "arrow_right_icon_02"), for: .normal)
|
||||||
|
button.addTarget(self, action: #selector(handleMoreButton), for: .touchUpInside)
|
||||||
|
return button
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var collectionViewLayout: UICollectionViewFlowLayout = {
|
||||||
|
let width = floor((kSPScreenWidth - 32 - 16) / 3)
|
||||||
|
let height = 145 / 109 * width + 58
|
||||||
|
|
||||||
|
let layout = UICollectionViewFlowLayout()
|
||||||
|
layout.itemSize = CGSize(width: width, height: height)
|
||||||
|
layout.minimumLineSpacing = 8
|
||||||
|
layout.minimumInteritemSpacing = 8
|
||||||
|
layout.sectionInset = .init(top: 0, left: 16, bottom: 0, right: 16)
|
||||||
|
return layout
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var collectionView: SPCollectionView = {
|
||||||
|
let collectionView = SPCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
|
||||||
|
collectionView.delegate = self
|
||||||
|
collectionView.dataSource = self
|
||||||
|
collectionView.isScrollEnabled = false
|
||||||
|
SPMinePlayHistoryCell.registerCell(collectionView: collectionView)
|
||||||
|
return collectionView
|
||||||
|
}()
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
|
||||||
|
_setupUI()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc private func handleMoreButton() {
|
||||||
|
SPAPPTool.mainTabBarController?.onPlayHistory()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SPMinePlayHistoryView {
|
||||||
|
|
||||||
|
private func _setupUI() {
|
||||||
|
addSubview(titleIconImageView)
|
||||||
|
addSubview(titleLabel)
|
||||||
|
addSubview(moreButton)
|
||||||
|
addSubview(collectionView)
|
||||||
|
|
||||||
|
titleIconImageView.snp.makeConstraints { make in
|
||||||
|
make.left.equalToSuperview().offset(16)
|
||||||
|
make.top.equalToSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
titleLabel.snp.makeConstraints { make in
|
||||||
|
make.centerY.equalTo(titleIconImageView)
|
||||||
|
make.left.equalTo(titleIconImageView.snp.right).offset(12)
|
||||||
|
}
|
||||||
|
|
||||||
|
moreButton.snp.makeConstraints { make in
|
||||||
|
make.centerY.equalTo(titleIconImageView)
|
||||||
|
make.right.equalToSuperview().offset(-3)
|
||||||
|
make.width.equalTo(40)
|
||||||
|
make.height.equalTo(40)
|
||||||
|
}
|
||||||
|
|
||||||
|
collectionView.snp.makeConstraints { make in
|
||||||
|
make.left.right.bottom.equalToSuperview()
|
||||||
|
make.height.equalTo(self.collectionViewLayout.itemSize.height)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//MARK: -------------- UICollectionViewDelegate & UICollectionViewDataSource --------------
|
||||||
|
extension SPMinePlayHistoryView: UICollectionViewDelegate, UICollectionViewDataSource {
|
||||||
|
|
||||||
|
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||||
|
let cell = SPMinePlayHistoryCell.dequeueReusableCell(collectionView: collectionView, indexPath: indexPath)
|
||||||
|
cell.model = self.dataArr?[indexPath.row]
|
||||||
|
return cell
|
||||||
|
}
|
||||||
|
|
||||||
|
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||||
|
return dataArr?.count ?? 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||||
|
let model = self.dataArr?[indexPath.row]
|
||||||
|
|
||||||
|
let vc = SPPlayerDetailViewController()
|
||||||
|
vc.shortPlayId = model?.short_play_id
|
||||||
|
vc.playHistoryModel = model
|
||||||
|
self.viewController?.navigationController?.pushViewController(vc, animated: true)
|
||||||
|
}
|
||||||
|
}
|
@ -46,7 +46,7 @@ class SPMyListViewController: SPViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//MARK: UI属性
|
//MARK: UI属性
|
||||||
private lazy var pageView: JYPageController = {
|
private(set) lazy var pageView: JYPageController = {
|
||||||
let pageView = JYPageController()
|
let pageView = JYPageController()
|
||||||
pageView.delegate = self
|
pageView.delegate = self
|
||||||
pageView.dataSource = self
|
pageView.dataSource = self
|
||||||
|
@ -210,7 +210,9 @@ extension SPPlayerListViewController {
|
|||||||
|
|
||||||
collectionView.snp.makeConstraints { make in
|
collectionView.snp.makeConstraints { make in
|
||||||
// make.edges.equalToSuperview()
|
// make.edges.equalToSuperview()
|
||||||
make.center.equalToSuperview()
|
// make.center.equalToSuperview()
|
||||||
|
make.top.equalToSuperview()
|
||||||
|
make.left.equalToSuperview()
|
||||||
make.width.equalTo(self.contentSize.width)
|
make.width.equalTo(self.contentSize.width)
|
||||||
make.height.equalTo(self.contentSize.height)
|
make.height.equalTo(self.contentSize.height)
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@ import UIKit
|
|||||||
|
|
||||||
class SPAPPTool: NSObject {
|
class SPAPPTool: NSObject {
|
||||||
|
|
||||||
|
static var mainTabBarController: SPTabBarController?
|
||||||
|
|
||||||
static func getAppDelegate() -> AppDelegate? {
|
static func getAppDelegate() -> AppDelegate? {
|
||||||
return UIApplication.shared.delegate as? AppDelegate
|
return UIApplication.shared.delegate as? AppDelegate
|
||||||
}
|
}
|
||||||
@ -76,6 +78,7 @@ extension SPAPPTool {
|
|||||||
if let text = text {
|
if let text = text {
|
||||||
let copy = UIPasteboard.general
|
let copy = UIPasteboard.general
|
||||||
copy.string = text
|
copy.string = text
|
||||||
|
SPToast.show(text: "Succeed".localized)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,18 +228,18 @@ extension SPPlayer {
|
|||||||
} else if loadState == .playable, isPlaying, self.player.playState != .playStatePlaying {
|
} else if loadState == .playable, isPlaying, self.player.playState != .playStatePlaying {
|
||||||
self.start()
|
self.start()
|
||||||
}
|
}
|
||||||
switch loadState {
|
// switch loadState {
|
||||||
case .prepare:
|
// case .prepare:
|
||||||
spLog(message: "加载状态====准备完成")
|
// spLog(message: "加载状态====准备完成")
|
||||||
case .playable:
|
// case .playable:
|
||||||
spLog(message: "加载状态====可播放")
|
// spLog(message: "加载状态====可播放")
|
||||||
case .playthroughOK:
|
// case .playthroughOK:
|
||||||
spLog(message: "加载状态====将自动播放")
|
// spLog(message: "加载状态====将自动播放")
|
||||||
case .stalled:
|
// case .stalled:
|
||||||
spLog(message: "加载状态====如果已启动,将自动暂停")
|
// spLog(message: "加载状态====如果已启动,将自动暂停")
|
||||||
default:
|
// default:
|
||||||
break
|
// break
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
//错误信息
|
//错误信息
|
||||||
|
BIN
Thimra/Source/Assets.xcassets/AppIcon.appiconset/APP图标 (1).jpg
Normal file
After Width: | Height: | Size: 270 KiB |
@ -1,28 +1,7 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"filename" : "APP图标 (1).jpg",
|
||||||
"platform" : "ios",
|
|
||||||
"size" : "1024x1024"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"appearances" : [
|
|
||||||
{
|
|
||||||
"appearance" : "luminosity",
|
|
||||||
"value" : "dark"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"idiom" : "universal",
|
|
||||||
"platform" : "ios",
|
|
||||||
"size" : "1024x1024"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"appearances" : [
|
|
||||||
{
|
|
||||||
"appearance" : "luminosity",
|
|
||||||
"value" : "tinted"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"platform" : "ios",
|
"platform" : "ios",
|
||||||
"size" : "1024x1024"
|
"size" : "1024x1024"
|
||||||
|
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 3.1 KiB |
@ -5,12 +5,12 @@
|
|||||||
"scale" : "1x"
|
"scale" : "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "About Us@2x.png",
|
"filename" : "Frame@2x.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "2x"
|
"scale" : "2x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "About Us@3x.png",
|
"filename" : "Frame@3x.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "3x"
|
"scale" : "3x"
|
||||||
}
|
}
|
||||||
|
BIN
Thimra/Source/Assets.xcassets/icon/about_us_icon_01.imageset/Frame@2x.png
vendored
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Thimra/Source/Assets.xcassets/icon/about_us_icon_01.imageset/Frame@3x.png
vendored
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
Thimra/Source/Assets.xcassets/icon/about_us_logo_icon.imageset/APP图标 (1).jpg
vendored
Normal file
After Width: | Height: | Size: 9.3 KiB |
@ -5,12 +5,11 @@
|
|||||||
"scale" : "1x"
|
"scale" : "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Help Center@2x.png",
|
"filename" : "APP图标 (1).jpg",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "2x"
|
"scale" : "2x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Help Center@3x.png",
|
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "3x"
|
"scale" : "3x"
|
||||||
}
|
}
|
@ -5,12 +5,12 @@
|
|||||||
"scale" : "1x"
|
"scale" : "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Order Record@2x.png",
|
"filename" : "Frame@2x.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "2x"
|
"scale" : "2x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Order Record@3x.png",
|
"filename" : "Frame@3x.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "3x"
|
"scale" : "3x"
|
||||||
}
|
}
|
BIN
Thimra/Source/Assets.xcassets/icon/arrow_bown_icon_01.imageset/Frame@2x.png
vendored
Normal file
After Width: | Height: | Size: 243 B |
BIN
Thimra/Source/Assets.xcassets/icon/arrow_bown_icon_01.imageset/Frame@3x.png
vendored
Normal file
After Width: | Height: | Size: 318 B |
@ -18,5 +18,8 @@
|
|||||||
"info" : {
|
"info" : {
|
||||||
"author" : "xcode",
|
"author" : "xcode",
|
||||||
"version" : 1
|
"version" : 1
|
||||||
|
},
|
||||||
|
"properties" : {
|
||||||
|
"template-rendering-intent" : "original"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
22
Thimra/Source/Assets.xcassets/icon/arrow_right_icon_02.imageset/Contents.json
vendored
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
BIN
Thimra/Source/Assets.xcassets/icon/arrow_right_icon_02.imageset/Frame@2x.png
vendored
Normal file
After Width: | Height: | Size: 279 B |
BIN
Thimra/Source/Assets.xcassets/icon/arrow_right_icon_02.imageset/Frame@3x.png
vendored
Normal file
After Width: | Height: | Size: 495 B |
22
Thimra/Source/Assets.xcassets/icon/arrow_up_icon_01.imageset/Contents.json
vendored
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
BIN
Thimra/Source/Assets.xcassets/icon/arrow_up_icon_01.imageset/Frame@2x.png
vendored
Normal file
After Width: | Height: | Size: 245 B |
BIN
Thimra/Source/Assets.xcassets/icon/arrow_up_icon_01.imageset/Frame@3x.png
vendored
Normal file
After Width: | Height: | Size: 317 B |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 3.0 KiB |
22
Thimra/Source/Assets.xcassets/icon/history_icon_01.imageset/Contents.json
vendored
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
BIN
Thimra/Source/Assets.xcassets/icon/history_icon_01.imageset/Frame@2x.png
vendored
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Thimra/Source/Assets.xcassets/icon/history_icon_01.imageset/Frame@3x.png
vendored
Normal file
After Width: | Height: | Size: 2.1 KiB |
@ -5,12 +5,12 @@
|
|||||||
"scale" : "1x"
|
"scale" : "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Language@2x.png",
|
"filename" : "Vector@2x.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "2x"
|
"scale" : "2x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Language@3x.png",
|
"filename" : "Vector@3x.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "3x"
|
"scale" : "3x"
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 5.3 KiB |
BIN
Thimra/Source/Assets.xcassets/icon/language_icon_01.imageset/Vector@2x.png
vendored
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
Thimra/Source/Assets.xcassets/icon/language_icon_01.imageset/Vector@3x.png
vendored
Normal file
After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 3.3 KiB |
@ -5,12 +5,12 @@
|
|||||||
"scale" : "1x"
|
"scale" : "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Privacy Policy@2x.png",
|
"filename" : "Frame@2x.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "2x"
|
"scale" : "2x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Privacy Policy@3x.png",
|
"filename" : "Frame@3x.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "3x"
|
"scale" : "3x"
|
||||||
}
|
}
|
||||||
|
BIN
Thimra/Source/Assets.xcassets/icon/privacy_policy_icon_01.imageset/Frame@2x.png
vendored
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Thimra/Source/Assets.xcassets/icon/privacy_policy_icon_01.imageset/Frame@3x.png
vendored
Normal file
After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 3.8 KiB |
@ -5,12 +5,12 @@
|
|||||||
"scale" : "1x"
|
"scale" : "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "User Agreement@2x.png",
|
"filename" : "Frame@2x.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "2x"
|
"scale" : "2x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "User Agreement@3x.png",
|
"filename" : "Frame@3x.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "3x"
|
"scale" : "3x"
|
||||||
}
|
}
|
||||||
|
BIN
Thimra/Source/Assets.xcassets/icon/user_agreement_icon_01.imageset/Frame@2x.png
vendored
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Thimra/Source/Assets.xcassets/icon/user_agreement_icon_01.imageset/Frame@3x.png
vendored
Normal file
After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 2.3 KiB |
22
Thimra/Source/Assets.xcassets/image/avatar_image_01.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Frame 1912056660@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Frame 1912056660@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
Thimra/Source/Assets.xcassets/image/avatar_image_01.imageset/Frame 1912056660@2x.png
vendored
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
Thimra/Source/Assets.xcassets/image/avatar_image_01.imageset/Frame 1912056660@3x.png
vendored
Normal file
After Width: | Height: | Size: 4.5 KiB |
@ -20,11 +20,9 @@
|
|||||||
"Episodes" = "Episodes";
|
"Episodes" = "Episodes";
|
||||||
"Save" = "Save";
|
"Save" = "Save";
|
||||||
"Added" = "Added";
|
"Added" = "Added";
|
||||||
"Order Record" = "Order Record";
|
|
||||||
"Language" = "Language";
|
"Language" = "Language";
|
||||||
"Privacy Policy" = "Privacy Policy";
|
"Privacy Policy" = "Privacy Policy";
|
||||||
"User Agreement" = "User Agreement";
|
"User Agreement" = "User Agreement";
|
||||||
"Help Center" = "Help Center";
|
|
||||||
"About Us" = "About Us";
|
"About Us" = "About Us";
|
||||||
"My list" = "My list";
|
"My list" = "My list";
|
||||||
"Watch list" = "Watch list";
|
"Watch list" = "Watch list";
|
||||||
@ -44,5 +42,12 @@
|
|||||||
"All" = "All";
|
"All" = "All";
|
||||||
"Shorts" = "Shorts";
|
"Shorts" = "Shorts";
|
||||||
"EP.%@" = "EP.%@";
|
"EP.%@" = "EP.%@";
|
||||||
|
"Copy" = "Copy";
|
||||||
|
"Succeed" = "Succeed";
|
||||||
|
"Watch History" = "Watch History";
|
||||||
|
"Child Personal Information Protection Rules" = "Child Personal Information Protection Rules";
|
||||||
|
"Youth Civilization Convention" = "Youth Civilization Convention";
|
||||||
|
"List of Third-Party Sharing of Personal Information" = "List of Third-Party Sharing of Personal Information";
|
||||||
|
"Explicit List of Personal Information Collection" = "Explicit List of Personal Information Collection";
|
||||||
|
|
||||||
|
|
||||||
|