Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"images" : [
{
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "tinted"
}
],
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
6 changes: 6 additions & 0 deletions SiriusGamesLiveActivity/Assets.xcassets/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
11 changes: 11 additions & 0 deletions SiriusGamesLiveActivity/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.widgetkit-extension</string>
</dict>
</dict>
</plist>
63 changes: 63 additions & 0 deletions SiriusGamesLiveActivity/SiriusGamesLiveActivity.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//
// SiriusGamesLiveActivity.swift
// SiriusGamesLiveActivity
//
// Created by Илья Лебедев on 04.04.2025.
//
import ActivityKit
import SwiftUI
import WidgetKit

@main
struct SportsActivityWidget: Widget {
var body: some WidgetConfiguration {
ActivityConfiguration(for: EventAttributes.self) { context in
if let eventState = EventState(rawValue: context.state.status), let nextEventSutus = EventState(rawValue: context.state.nextEventSatus) {
LockScreenActivityView(
eventName: context.state.eventName,
currentEventState: eventState,
status: context.state.status,
nextEventName: context.state.nextEventName,
nextEventStatus: nextEventSutus,
score: context.state.score
)
}
} dynamicIsland: { context in
DynamicIsland {
DynamicIslandExpandedRegion(.leading) {
if let eventState = EventState(rawValue: context.state.status) {
HStack {
Circle()
.foregroundStyle(eventState.getColor())
.frame(width: 10)
Text("\(NSLocalizedString(context.state.status, comment: "status"))")
}
}
Text("\(context.state.eventName)")
}
DynamicIslandExpandedRegion(.center) {
Text(NSLocalizedString("score", comment: "score") + ": \(context.state.score)")
.bold()
}
DynamicIslandExpandedRegion(.trailing) {
if let eventState = EventState(rawValue: context.state.nextEventSatus) {
HStack {
Circle()
.foregroundStyle(eventState.getColor())
.frame(width: 10)
Text("\(context.state.nextEventSatus)")
}
}
Text("\(context.state.nextEventName)")
}
} compactLeading: {
Text("\(context.state.eventName)")
} compactTrailing: {
Text("\(context.state.score)")
.bold()
} minimal: {
Text("")
}
}
}
}
2 changes: 1 addition & 1 deletion SiriusProject/SiriusProject/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ struct ContentView: View {
ContentView(
appViewModel: AppViewModel(
logging: printLogging,
eventsListViewModel: EventsListViewModel(networkManager: FakeNetworkManager(logging: printLogging), logging: printLogging),
eventsListViewModel: EventsListViewModel(networkManager: FakeNetworkManager(logging: printLogging), liveActivtityManager: LiveActivityManager(), logging: printLogging),
settingsViewModel: SettingsViewModel(networkManager: FakeNetworkManager(logging: printLogging), logging: printLogging),
loginViewModel: LoginViewModel(networkManager: FakeNetworkManager(logging: printLogging), logging: { _ in }),
pointsViewModel: PointsViewModel(networkManager: FakeNetworkManager(logging: printLogging)),
Expand Down
6 changes: 6 additions & 0 deletions SiriusProject/SiriusProject/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,11 @@
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSSupportsLiveActivities</key>
<true/>
<key>NSSupportsLiveActivitiesFrequentUpdates</key>
<true/>
<key>NSLiveActivityUsageDescription</key>
<string>Используется для отображения актуальной информации на экране блокировки</string>
</dict>
</plist>
43 changes: 43 additions & 0 deletions SiriusProject/SiriusProject/Managers/LiveActivityManager.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// LiveActivityManager.swift
// SiriusProject
//
// Created by Илья Лебедев on 04.04.2025.
//

import ActivityKit
import Foundation

class LiveActivityManager {
private var activity: Activity<EventAttributes>?

func startActivity(currentEvent: Event?, nextEvent: Event?, score: Int) {
let attributes = EventAttributes()
let initialState = EventAttributes.ContentState(currentEvent: currentEvent, nextEvent: nextEvent, score: score)

do {
activity = try Activity<EventAttributes>.request(
attributes: attributes,
contentState: initialState,
pushType: nil
)
print("Live Activity запущена!")
} catch {
print("Ошибка запуска Live Activity: \(error.localizedDescription)")
}
}

func updateActivity(currentEvent: Event?, nextEvent: Event?, score: Int) {
Task {
let newState = EventAttributes.ContentState(currentEvent: currentEvent, nextEvent: nextEvent, score: score)
await activity?.update(using: newState)
}
}

func endActivity() {
Task {
await activity?.end(dismissalPolicy: .immediate)
activity = nil
}
}
}
41 changes: 41 additions & 0 deletions SiriusProject/SiriusProject/Model/EventAttributes.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//
// EventAttributes.swift
// SiriusProject
//
// Created by Илья Лебедев on 04.04.2025.
//

import ActivityKit
import Foundation

struct EventAttributes: ActivityAttributes {
public typealias TimerStatus = ContentState

public struct ContentState: Codable, Hashable {
var eventName: String
var status: String
var nextEventName: String
var nextEventSatus: String
var score: Int

init(currentEvent: Event?, nextEvent: Event?, score: Int) {
if let currentEvent = currentEvent {
eventName = currentEvent.title
status = currentEvent.state.rawValue
} else {
eventName = "finish"
status = "finish"
}

if let nextEvent = nextEvent {
nextEventName = nextEvent.title
nextEventSatus = nextEvent.state.rawValue
} else {
nextEventName = "finish"
nextEventSatus = "finish"
}

self.score = score
}
}
}
7 changes: 5 additions & 2 deletions SiriusProject/SiriusProject/SiriusProjectApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import UserNotifications
struct SiriusProjectApp: App {
let networkManager: NetworkManagerProtocol
var notificationsManager: NotificationsManager
let liveAcivityManager: LiveActivityManager

var appViewModel: AppViewModel
let logging: Logging
Expand All @@ -32,13 +33,15 @@ struct SiriusProjectApp: App {

errorLogging = errorPublisherLogging(errorPublisher)

networkManager = /* FakeNetworkManager(logging: printLogging) */
networkManager =
NetworkManager(service: APIService(urlSession: URLSession.shared), logging: errorLogging)
notificationsManager = NotificationsManager()

liveAcivityManager = LiveActivityManager()

appViewModel = AppViewModel(
logging: logging,
eventsListViewModel: EventsListViewModel(networkManager: networkManager, logging: logging),
eventsListViewModel: EventsListViewModel(networkManager: networkManager, liveActivtityManager: LiveActivityManager(), logging: logging),
settingsViewModel: SettingsViewModel(networkManager: networkManager, logging: logging),
loginViewModel: LoginViewModel(networkManager: networkManager, logging: logging),
pointsViewModel: PointsViewModel(networkManager: networkManager),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ enum SportIconProvider {
case "шахматы": return "rectangle.pattern.checkered"
case "регби": return "figure.rugby"
case "скалолазание": return "figure.climbing"
case "": return "flag.pattern.checkered"
default: return "trophy.fill"
}
}
Expand Down
6 changes: 4 additions & 2 deletions SiriusProject/SiriusProject/View/EventsListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,13 @@ struct EventsListView: View {
.onAppear {
print("Try get events on appear")
viewModel.fetchEvents()
viewModel.updateLiveActivity()
}
.onChange(of: isNeedUpdate) {
print("New fetch events")
DispatchQueue.global(qos: .userInitiated).asyncAfter(deadline: .now() + 0.5) {
viewModel.fetchEvents()
viewModel.updateLiveActivity()
}
}
.overlay(alignment: .bottomTrailing) {
Expand All @@ -70,7 +72,7 @@ struct EventsListView: View {
EventsListView(
appViewModel: AppViewModel(
logging: printLogging,
eventsListViewModel: EventsListViewModel(networkManager: FakeNetworkManager(logging: printLogging), logging: printLogging),
eventsListViewModel: EventsListViewModel(networkManager: FakeNetworkManager(logging: printLogging), liveActivtityManager: LiveActivityManager(), logging: printLogging),
settingsViewModel: SettingsViewModel(networkManager: FakeNetworkManager(logging: printLogging), logging: printLogging),
loginViewModel: LoginViewModel(networkManager: FakeNetworkManager(logging: printLogging), logging: printLogging),
pointsViewModel: PointsViewModel(networkManager: FakeNetworkManager(logging: printLogging)),
Expand All @@ -79,7 +81,7 @@ struct EventsListView: View {
notificationsViewModel: NotificationsViewModel(networkManager: FakeNetworkManager(logging: printLogging), logging: printLogging), getRateReviewModel: GetRateReviewModel(networkManager: FakeNetworkManager(logging: printLogging), logging: printLogging),
createEventViewModel: CreateEventViewModel(networkManager: FakeNetworkManager(logging: printLogging), logging: printLogging), sendPushViewModel: SendPushViewModel(networkManager: FakeNetworkManager(logging: printLogging), logging: printLogging)
), eventsListViewModel: EventsListViewModel(
networkManager: FakeNetworkManager(logging: printLogging),
networkManager: FakeNetworkManager(logging: printLogging), liveActivtityManager: LiveActivityManager(),
logging: printLogging
),
isNotificationViewShowing: .constant(false)
Expand Down
66 changes: 66 additions & 0 deletions SiriusProject/SiriusProject/View/LockScreenActivityView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//
// LockScreenActivityView.swift
// SiriusProject
//
// Created by Илья Лебедев on 04.04.2025.
//

import SwiftUI

struct LockScreenActivityView: View {
@State var eventName: String = ""
@State var currentEventState: EventState = .now
@State var status: String = ""
@State var nextEventName: String = "Гольф"
@State var nextEventStatus: EventState = .next
@State var score: Int = 0
var body: some View {
VStack {
HStack {
Image(systemName: SportIconProvider.getSportIcon(for: eventName))
.font(.title)
if !eventName.isEmpty {
VStack(alignment: .leading) {
HStack {
Text(eventName)
.font(.headline)
.bold()
Circle()
.foregroundStyle(currentEventState.getColor())
.frame(width: 10)
Text("\(status)")
}

HStack {
Text(nextEventName)
.font(.footnote)
Circle()
.font(.footnote)
.foregroundStyle(nextEventStatus.getColor())
.frame(width: 7)
Text("\(nextEventStatus)")
.font(.footnote)
}
}
.padding(.horizontal)

} else {
Text("finishevents")
.font(.headline)
.padding(.horizontal)
}

Spacer()

Text("Score: \(score)")
.font(.headline)
.bold()
}
.padding(.horizontal)
}
}
}

#Preview {
LockScreenActivityView()
}
Loading
Loading