Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
RIPVessel.xcodeproj/xcshareddata/xcschemes/RIPVessel.xcscheme

RIPVessel.xcodeproj/xcuserdata/gyulakiri.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

DerivedData/
10 changes: 6 additions & 4 deletions RIPVessel.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -287,10 +287,11 @@
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = X5393PZPXX;
DEVELOPMENT_TEAM = N4FSUVZ5W3;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = RIPVessel/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = LessevPIR;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchStoryboardName = Lau;
Expand All @@ -302,7 +303,7 @@
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = hu.gyulakiri.RIPVessel;
PRODUCT_BUNDLE_IDENTIFIER = hu.gyulakiri.lessevpir;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
Expand All @@ -321,10 +322,11 @@
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = X5393PZPXX;
DEVELOPMENT_TEAM = N4FSUVZ5W3;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = RIPVessel/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = LessevPIR;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchStoryboardName = Lau;
Expand All @@ -336,7 +338,7 @@
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = hu.gyulakiri.RIPVessel;
PRODUCT_BUNDLE_IDENTIFIER = hu.gyulakiri.lessevpir;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
Expand Down
59 changes: 59 additions & 0 deletions RIPVessel/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//
// AppDelegate.swift
// RIPVessel
//
// Created by Gyula Kiri on 2024. 12. 09..
//
import Foundation
import UIKit
#if DUSZMOX
import Shake
#endif

class AppDelegate: NSObject, UIApplicationDelegate {

static var orientationLock = UIInterfaceOrientationMask.allButUpsideDown {
didSet {
print("Changed orientation lock to: \(orientationLock)")
}
}

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return AppDelegate.orientationLock
}

func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let env = ProcessInfo.processInfo.environment
loadRocketSimConnect()
#if DUSZMOX
Shake.start(apiKey: env["SHAKE_API_KEY"] ?? "")
#endif
return true
}

static func rotateScreen(to orientation: UIInterfaceOrientationMask) {
guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else { return }
windowScene.requestGeometryUpdate(.iOS(interfaceOrientations: orientation)) { error in
if let err = error as? UISceneError, err.code == .geometryRequestUnsupported {
AppDelegate.orientationLock = .allButUpsideDown
DispatchQueue.main.async {
self.rotateScreen(to: orientation)
}
}
print("Error updating geometry: \(error)")
}
}

private func loadRocketSimConnect() {
#if DEBUG
guard (Bundle(path: "/Applications/RocketSim.app/Contents/Frameworks/RocketSimConnectLinker.nocache.framework")?.load() == true) else {
print("Failed to load linker framework")
return
}
print("RocketSim Connect successfully linked")
#endif
}

}
19 changes: 18 additions & 1 deletion RIPVessel/Extensions/View+RIPVessel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by Gyula Kiri on 2024. 07. 27..
//

import SwiftUICore
import SwiftUI
import UIKit

struct DeviceRotationViewModifier: ViewModifier {
Expand Down Expand Up @@ -53,6 +53,23 @@ extension View {
.onPreferenceChange(ViewHeightKey.self, perform: onChange)
}
}
///Extension for TabView items
extension View {
@ViewBuilder
func setupTab(_ tab: Tab) -> some View {
self
.tag(tab)
.toolbar(.hidden, for: .tabBar)
}

/// SafeArea Value
var safeArea: UIEdgeInsets {
if let safeArea = (UIApplication.shared.connectedScenes.first as? UIWindowScene)?.keyWindow?.safeAreaInsets {
return safeArea
}
return .zero
}
}


#if canImport(UIKit)
Expand Down
1 change: 0 additions & 1 deletion RIPVessel/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
<string>video</string>
</array>
</dict>
</plist>
21 changes: 21 additions & 0 deletions RIPVessel/Model/PlayerConfig.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// PlayerConfig.swift
// RIPVessel
//
// Created by Gyula Kiri on 2024. 12. 09..
//
import SwiftUI

struct PlayerConfig: Equatable {
var position: CGFloat = .zero
var lastPosition: CGFloat = .zero
var progress: CGFloat = .zero
var selectedPlayerItem: Components.Schemas.BlogPostModelV3?
var showMiniPlayer: Bool = false

mutating func resetPosition() {
position = .zero
lastPosition = .zero
progress = .zero
}
}
26 changes: 26 additions & 0 deletions RIPVessel/Model/Tab.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// Tab.swift
// RIPVessel
//
// Created by Gyula Kiri on 2024. 12. 09..
//

import SwiftUI

/// Tab's
enum Tab: String, CaseIterable {
case recents = "Recents"
case creators = "Creators"
case you = "You"

var symbol: String {
switch self {
case .recents:
"house.fill"
case .creators:
"books.vertical.fill"
case .you:
"person.circle.fill"
}
}
}
82 changes: 0 additions & 82 deletions RIPVessel/RIPVesselApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,96 +6,14 @@
//

import SwiftUI
import Shake

class AppDelegate: NSObject, UIApplicationDelegate {

static var orientationLock = UIInterfaceOrientationMask.portrait

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return AppDelegate.orientationLock
}

func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let env = ProcessInfo.processInfo.environment
#if DUSZMOX
Shake.start(apiKey: env["SHAKE_API_KEY"] ?? "")
#endif
return true
}

static func rotateScreen(to orientation: UIInterfaceOrientationMask) {
guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else { return }
windowScene.requestGeometryUpdate(.iOS(interfaceOrientations: orientation)) { error in
if let err = error as? UISceneError, err.code == .geometryRequestUnsupported {
AppDelegate.orientationLock = .allButUpsideDown
DispatchQueue.main.async {
self.rotateScreen(to: orientation)
}
}
print("Error updating geometry: \(error)")
}
}
}

@main
struct RIPVesselApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
init() {
loadRocketSimConnect()
}
var body: some Scene {
WindowGroup {
MainView().environmentObject(AuthService.shared)

}
}
}

struct MainView: View {
@EnvironmentObject var auth: AuthService
@StateObject private var router = Router.shared

var body: some View {
if auth.loggedIn {
TabView {
NavigationStack {
RecentsPageView()
}.tabItem {
Label("Recents", systemImage: "play.house.fill")
}
NavigationStack {
CreatorsView()
}.tabItem {
Label("Creators", systemImage: "books.vertical.fill")
}
NavigationStack {
AccountView()
}.tabItem {
Label("Account", systemImage: "person.crop.circle.fill")
}
}
} else {
LoginView()
}
}
}

struct LoadingView: View {
var body: some View {
Text("Loading...")
.padding()
}
}

private func loadRocketSimConnect() {
#if DEBUG
guard (Bundle(path: "/Applications/RocketSim.app/Contents/Frameworks/RocketSimConnectLinker.nocache.framework")?.load() == true) else {
print("Failed to load linker framework")
return
}
print("RocketSim Connect successfully linked")
#endif
}
5 changes: 4 additions & 1 deletion RIPVessel/ViewModels/ChannelViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@
//

import Foundation
import SwiftUI

extension ChannelView {
class ViewModel: ObservableObject {
@Published var creator: Components.Schemas.CreatorModelV3?
@Published var channelId: String
@Binding var playerConfig: PlayerConfig

init(creatorId: String, channelId: String) {
init(creatorId: String, channelId: String, playerConfig: Binding<PlayerConfig>) {
_playerConfig = playerConfig
self.channelId = channelId
Task { [weak self] in
guard let self = self else { return }
Expand Down
26 changes: 21 additions & 5 deletions RIPVessel/ViewModels/VideoViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,25 @@ extension VideoView {
@Published var currentQuality: Components.Schemas.CdnDeliveryV3Variant?
@Published var video: Components.Schemas.ContentVideoV3Response?
@Published var description: String
@Published var isHidden: Bool = false

init(post: Components.Schemas.BlogPostModelV3) {
description = post.text
Task {
await initialize(post: post)
init(post: Components.Schemas.BlogPostModelV3?) {
description = post?.text ?? ""
if let post {
Task {
await initialize(post: post)
}
}
}

func updatePost(_ post: Components.Schemas.BlogPostModelV3?) {
description = post?.text ?? ""
self.post?.title = post?.title ?? ""
isHidden = true
if let post {
Task {
await initialize(post: post)
}
}
}

Expand All @@ -30,6 +44,9 @@ extension VideoView {
self.post = fetchedPost
await fetchVideoContent()
await fetchDeliveryInfo()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
self.isHidden = false
}
} catch {
print("Error initializing ViewModel: \(error)")
}
Expand Down Expand Up @@ -106,7 +123,6 @@ extension VideoView {
}

func uploadProgress(_ progress: Double) {
print(progress)
guard let video else {return}
Task {
try await ApiService.shared.client.updateProgress(body: Operations.updateProgress.Input.Body.json(Components.Schemas.UpdateProgressRequest(id: video.id, contentType: .video, progress: Int(progress))))
Expand Down
6 changes: 3 additions & 3 deletions RIPVessel/Views/Channel/ChannelView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ struct ChannelView: View {
let id: String
@StateObject var vm: ViewModel

init(id: String, creatorId: String) {
init(id: String, creatorId: String, playerConfig: Binding<PlayerConfig>) {
self.id = id
_vm = .init(wrappedValue: ViewModel(creatorId: creatorId, channelId: id))
_vm = .init(wrappedValue: ViewModel(creatorId: creatorId, channelId: id, playerConfig: playerConfig))

}

Expand All @@ -37,7 +37,7 @@ struct ChannelView: View {
.foregroundColor(.white)
}.frame(alignment: .leading)
}
RecentsView(creatorId: self.vm.creator!.id, channelId: id, scrollEnabled: .constant(false))
RecentsView(creatorId: self.vm.creator!.id, channelId: id, scrollEnabled: .constant(false), playerConfig: $vm.playerConfig)
}
}.frame(maxHeight: .infinity)
}
Expand Down
14 changes: 14 additions & 0 deletions RIPVessel/Views/Components/LoadingView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// LoadingView.swift
// RIPVessel
//
// Created by Gyula Kiri on 2024. 12. 09..
//
import SwiftUI

struct LoadingView: View {
var body: some View {
Text("Loading...")
.padding()
}
}
Loading