Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

114 remove is active #115

Merged
merged 3 commits into from
Nov 1, 2024
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
4 changes: 2 additions & 2 deletions mobile/mobile.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.4;
MARKETING_VERSION = 1.5;
PRODUCT_BUNDLE_IDENTIFIER = voynow.mobile;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
Expand Down Expand Up @@ -313,7 +313,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.4;
MARKETING_VERSION = 1.5;
PRODUCT_BUNDLE_IDENTIFIER = voynow.mobile;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
Expand Down
6 changes: 0 additions & 6 deletions mobile/mobile/APIManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@ class APIManager {
private let baseURL = "https://lwg77yq7dd.execute-api.us-east-1.amazonaws.com/prod/signup"

func fetchProfileData(token: String, completion: @escaping (Result<ProfileData, Error>) -> Void) {
let startTime = Date()
let body: [String: Any] = ["jwt_token": token, "method": "get_profile"]
performRequest(body: body, responseType: ProfileResponse.self) { result in
let totalTime = Date().timeIntervalSince(startTime)
switch result {
case .success(let response):
if response.success, let profile = response.profile {
Expand All @@ -40,11 +38,9 @@ class APIManager {
func fetchTrainingWeekData(
token: String, completion: @escaping (Result<TrainingWeekData, Error>) -> Void
) {
let startTime = Date()
let body: [String: Any] = ["jwt_token": token, "method": "get_training_week"]

performRequest(body: body, responseType: TrainingWeekResponse.self) { result in
let totalTime = Date().timeIntervalSince(startTime)
switch result {
case .success(let response):
if response.success, let trainingWeekString = response.trainingWeek,
Expand Down Expand Up @@ -132,11 +128,9 @@ class APIManager {
func fetchWeeklySummaries(
token: String, completion: @escaping (Result<[WeekSummary], Error>) -> Void
) {
let startTime = Date()
let body: [String: Any] = ["jwt_token": token, "method": "get_weekly_summaries"]

performRequest(body: body, responseType: WeeklySummariesResponse.self) { result in
let totalTime = Date().timeIntervalSince(startTime)
switch result {
case .success(let response):
if response.success, let summariesStrings = response.weekly_summaries {
Expand Down
2 changes: 0 additions & 2 deletions mobile/mobile/Models.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@ struct ProfileData: Codable {
var lastname: String
var email: String?
var profile: String
var isActive: Bool
var preferences: String?

enum CodingKeys: String, CodingKey {
case firstname, lastname, email, profile, preferences
case isActive = "is_active"
}
}

Expand Down
118 changes: 52 additions & 66 deletions mobile/mobile/ProfileView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ struct ProfileView: View {

private func shouldRefetchData() -> Bool {
guard let lastFetch = lastFetchTime else {
return true
return true
}
let timeSinceLastFetch = Date().timeIntervalSince(lastFetch)
let shouldRefetch = timeSinceLastFetch > cacheTimeout
Expand All @@ -87,24 +87,24 @@ struct ProfileView: View {

private func fetchProfileData() {
guard let token = appState.jwtToken else {
isLoading = false
return
isLoading = false
return
}

if !ProfileCache.shouldRefetch() && ProfileCache.data != nil {
self.profileData = ProfileCache.data
isLoading = false
return
self.profileData = ProfileCache.data
isLoading = false
return
}

APIManager.shared.fetchProfileData(token: token) { result in
DispatchQueue.main.async {
self.isLoading = false
if case .success(let profile) = result {
ProfileCache.update(profile)
self.profileData = profile
}
DispatchQueue.main.async {
self.isLoading = false
if case .success(let profile) = result {
ProfileCache.update(profile)
self.profileData = profile
}
}
}
}
}
Expand Down Expand Up @@ -134,7 +134,6 @@ struct ProfileInfoCard: View {
.frame(width: 80, height: 80)
.clipShape(Circle())
.overlay(Circle().stroke(ColorTheme.primary, lineWidth: 2))
StatusIndicator(isActive: profileData.isActive)
}
Spacer()
VStack(alignment: .leading, spacing: 4) {
Expand Down Expand Up @@ -164,40 +163,25 @@ struct ProfileInfoCard: View {
}
}

struct StatusIndicator: View {
let isActive: Bool
struct SignOutButton: View {
let action: () -> Void

var body: some View {
HStack(spacing: 8) {
Circle()
.fill(isActive ? ColorTheme.green : ColorTheme.darkGrey)
.frame(width: 10, height: 10)
Text(isActive ? "Active" : "Inactive")
.font(.system(size: 14, weight: .medium))
.foregroundColor(isActive ? ColorTheme.green : ColorTheme.darkGrey)
Button(action: action) {
Text("Sign Out")
.font(.system(size: 18, weight: .semibold))
.foregroundColor(ColorTheme.primaryDark)
.frame(maxWidth: .infinity)
.padding()
.background(ColorTheme.darkDarkGrey)
.overlay(
RoundedRectangle(cornerRadius: 12)
.stroke(ColorTheme.primaryDark, lineWidth: 2)
)
}
}
}

struct SignOutButton: View {
let action: () -> Void

var body: some View {
Button(action: action) {
Text("Sign Out")
.font(.system(size: 18, weight: .semibold))
.foregroundColor(ColorTheme.primaryDark)
.frame(maxWidth: .infinity)
.padding()
.background(ColorTheme.darkDarkGrey)
.overlay(
RoundedRectangle(cornerRadius: 12)
.stroke(ColorTheme.primaryDark, lineWidth: 2)
)
}
}
}

struct LoadingIcon: View {
@State private var isRotating = false

Expand All @@ -207,34 +191,36 @@ struct LoadingIcon: View {
.stroke(ColorTheme.primaryDark, lineWidth: 2)
.frame(width: 50, height: 50)
.rotationEffect(Angle(degrees: isRotating ? 360 : 0))
.animation(Animation.linear(duration: 1).repeatForever(autoreverses: false), value: isRotating)
.onAppear() {
.animation(
Animation.linear(duration: 1).repeatForever(autoreverses: false), value: isRotating
)
.onAppear {
isRotating = true
}
}
}

private enum ProfileCache {
static var lastFetchTime: Date?
static var data: ProfileData?
static let timeout: TimeInterval = 300
static func shouldRefetch() -> Bool {
guard let lastFetch = lastFetchTime else { return true }
return Date().timeIntervalSince(lastFetch) > timeout
}
static func update(_ profile: ProfileData) {
data = profile
lastFetchTime = Date()
}
static func updatePreferences(_ preferences: String) {
data?.preferences = preferences
}
static func clear() {
data = nil
lastFetchTime = nil
}
static var lastFetchTime: Date?
static var data: ProfileData?
static let timeout: TimeInterval = 300

static func shouldRefetch() -> Bool {
guard let lastFetch = lastFetchTime else { return true }
return Date().timeIntervalSince(lastFetch) > timeout
}

static func update(_ profile: ProfileData) {
data = profile
lastFetchTime = Date()
}

static func updatePreferences(_ preferences: String) {
data?.preferences = preferences
}

static func clear() {
data = nil
lastFetchTime = nil
}
}
3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ arrow==1.3.0 ; python_version >= "3.10" and python_version < "4.0"
async-timeout==4.0.3 ; python_version >= "3.10" and python_version < "3.11"
attrs==24.2.0 ; python_version >= "3.10" and python_version < "4.0"
certifi==2024.8.30 ; python_version >= "3.10" and python_version < "4.0"
cffi==1.17.1 ; python_version >= "3.10" and python_version < "4.0" and platform_python_implementation != "PyPy"
charset-normalizer==3.3.2 ; python_version >= "3.10" and python_version < "4.0"
colorama==0.4.6 ; python_version >= "3.10" and python_version < "4.0" and platform_system == "Windows"
cryptography==43.0.3 ; python_version >= "3.10" and python_version < "4.0"
deprecation==2.1.0 ; python_version >= "3.10" and python_version < "4.0"
distro==1.9.0 ; python_version >= "3.10" and python_version < "4.0"
exceptiongroup==1.2.2 ; python_version >= "3.10" and python_version < "3.11"
Expand All @@ -32,6 +34,7 @@ packaging==24.1 ; python_version >= "3.10" and python_version < "4.0"
pint==0.24.3 ; python_version >= "3.10" and python_version < "4.0"
polars==0.20.31 ; python_version >= "3.10" and python_version < "4.0"
postgrest==0.16.11 ; python_version >= "3.10" and python_version < "4.0"
pycparser==2.22 ; python_version >= "3.10" and python_version < "4.0" and platform_python_implementation != "PyPy"
pydantic==1.10.16 ; python_version >= "3.10" and python_version < "4.0"
pyjwt==2.9.0 ; python_version >= "3.10" and python_version < "4.0"
pyperclip==1.9.0 ; python_version >= "3.10" and python_version < "4.0"
Expand Down
7 changes: 3 additions & 4 deletions src/frontend_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
update_user_device_token,
)
from src.types.update_pipeline import ExeType
from src.update_pipeline import training_week_update_executor
from src.update_pipeline import update_training_week


def get_training_week_handler(athlete_id: str, payload: dict) -> dict:
Expand All @@ -37,7 +37,6 @@ def get_profile_handler(athlete_id: str, payload: dict) -> dict:
"profile": athlete.profile,
"email": user.email,
"preferences": user.preferences_json.json(),
"is_active": user.is_active,
},
}

Expand Down Expand Up @@ -71,8 +70,8 @@ def get_weekly_summaries_handler(athlete_id: str, payload: dict) -> dict:
def start_onboarding(athlete_id: str, payload: dict) -> dict:
"""Handle start_onboarding request."""
user = get_user(athlete_id)
training_week_update_executor(user, ExeType.NEW_WEEK, "onboarding-trigger")
training_week_update_executor(user, ExeType.MID_WEEK, "onboarding-trigger")
update_training_week(user, ExeType.NEW_WEEK)
update_training_week(user, ExeType.MID_WEEK)
return {"success": True}


Expand Down
13 changes: 5 additions & 8 deletions src/lambda_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
logger.setLevel(logging.INFO)


def strategy_router(event: dict, invocation_id: str) -> dict:
def strategy_router(event: dict) -> dict:
"""
Route the event to the appropriate handler based on the event type

Expand All @@ -40,16 +40,13 @@ def strategy_router(event: dict, invocation_id: str) -> dict:
)

elif webhook_router.is_strava_webhook_event(event):
return webhook_router.handle_request(event, invocation_id)
return webhook_router.handle_request(event)

elif (
event.get("resources")
and event.get("resources")[0] == os.environ["NIGHTLY_EMAIL_TRIGGER_ARN"]
):
return update_pipeline.nightly_trigger_orchestrator(invocation_id)

elif event.get("trigger_test_key") == os.environ["TRIGGER_TEST_KEY"]:
return update_pipeline.integration_test_executor(invocation_id)
return update_pipeline.nightly_trigger_orchestrator()
else:
return {"success": False, "error": f"Could not route event: {event}"}

Expand All @@ -64,10 +61,10 @@ def lambda_handler(event, context):
:return: dict with {"success": bool}
"""
invocation_id = str(uuid.uuid4())
logger.info(f"{invocation_id=} | {event=} | {context=}")
logger.info(f"{invocation_id=} | {event=}")

try:
response = strategy_router(event, invocation_id)
response = strategy_router(event)
except Exception as e:
response = {
"success": False,
Expand Down
40 changes: 0 additions & 40 deletions src/supabase_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,32 +141,6 @@ def get_training_week(athlete_id: int) -> TrainingWeek:
return TrainingWeek(**json.loads(response_data["training_week"]))


def get_training_week_test(athlete_id: int) -> TrainingWeek:
"""
Get the most recent training_week_test row by athlete_id

:param athlete_id: The ID of the athlete
:return: An instance of TrainingWeek
"""
table = client.table("training_week_test")
response = (
table.select("training_week")
.eq("athlete_id", athlete_id)
.order("created_at", desc=True)
.limit(1)
.execute()
)

try:
response_data = response.data[0]
except Exception as e:
raise ValueError(
f"Could not find training_week_test row with {athlete_id=}"
) from e

return TrainingWeek(**json.loads(response_data["training_week"]))


def upsert_training_week(
athlete_id: int,
training_week: TrainingWeek,
Expand All @@ -184,20 +158,6 @@ def upsert_training_week(
return response


def upsert_training_week_test(
athlete_id: int,
training_week: TrainingWeek,
) -> APIResponse:
"""Upsert a row into the training_week_test table"""
row_data = {
"athlete_id": athlete_id,
"training_week": training_week.json(),
}
table = client.table("training_week_test")
response = table.upsert(row_data).execute()
return response


def update_preferences(athlete_id: int, preferences_json: dict) -> APIResponse:
"""
Update user's preferences
Expand Down
1 change: 0 additions & 1 deletion src/types/user_row.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,4 @@ class UserRow(BaseModel):
preferences: str
email: Optional[str] = None
preferences_json: Optional[Preferences] = {}
is_active: bool = True
created_at: datetime = datetime.now()
Loading
Loading