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

Release/2.6.2 [main] #915

Merged
merged 6 commits into from
Dec 12, 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 android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ android {
applicationId "lab.childmindinstitute.data"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1601
versionName "2.6.1"
versionCode 1604
versionName "2.6.2"
resValue "string", "app_name", "Mindlogger"
resValue "string", "build_config_package", "lab.childmindinstitute.data"
manifestPlaceholders = [
Expand Down
2 changes: 1 addition & 1 deletion assets/translations/el.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@
"common_refresh_error": "Η λίστα βοηθητικών εφαρμογών δεν ανανεώθηκε. Προσπαθήστε ξανά."
},
"activity_list_component": {
"no_activities_yet": "Δεν έχουν καθοριστεί ακόμη δραστηριότητες",
"no_activities": "Δεν υπάρχουν διαθέσιμες δραστηριότητες για να ολοκληρώσετε αυτήν τη στιγμή",
"insufficient_data_error": "Αυτή η βοηθητική εφαρμογή δεν ανανεώθηκε. Προσπαθήστε να ανανεώσετε ξανά.",
"other_error": "Προέκυψε απροσδιόριστο σφάλμα"
},
Expand Down
2 changes: 1 addition & 1 deletion assets/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@
"common_refresh_error": "The applets list was not refreshed. Please try again."
},
"activity_list_component": {
"no_activities_yet": "No activities specified yet",
"no_activities": "No activities are available for you to complete right now",
"insufficient_data_error": "This applet was not refreshed. Please try to refresh again.",
"other_error": "Undefined error occurred"
},
Expand Down
2 changes: 1 addition & 1 deletion assets/translations/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@
"common_refresh_error": "La liste des applets n'a pas été actualisée. Veuillez réessayer."
},
"activity_list_component": {
"no_activities_yet": "Aucune activité spécifiée pour le moment",
"no_activities": "Aucune activité n'est disponible pour le moment",
"insufficient_data_error": "Cette applet n'a pas été actualisée. Veuillez réessayer d'actualiser.",
"other_error": "Une erreur non définie s'est produite"
},
Expand Down
137 changes: 85 additions & 52 deletions ios/FlankerNativeComponents/GameManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,16 @@ enum TypeTimeStamps {
}

protocol GameManagerProtocol: AnyObject {
func updateText(text: String, color: UIColor, font: UIFont, isStart: Bool, typeTime: TypeTimeStamps)
func updateText(
text: String, color: UIColor, font: UIFont, isStart: Bool, typeTime: TypeTimeStamps)
func updateFixations(image: URL?, isStart: Bool, typeTime: TypeTimeStamps)
func updateTime(time: String)
func setEnableButton(isEnable: Bool)
func updateTitleButton(left: String?, right: String?, leftImage: URL?, rightImage: URL?, countButton: Int)
func resultTest(avrgTime: Int?, procentCorrect: Int?, data: FlankerModel?, dataArray: [FlankerModel]?, isShowResults: Bool, minAccuracy: Int)
func updateTitleButton(
left: String?, right: String?, leftImage: URL?, rightImage: URL?, countButton: Int)
func resultTest(
avrgTime: Int?, procentCorrect: Int?, data: FlankerModel?, dataArray: [FlankerModel]?,
isShowResults: Bool, minAccuracy: Int)
}

class GameManager {
Expand Down Expand Up @@ -78,11 +82,11 @@ class GameManager {
weak var delegate: GameManagerProtocol?

private let bootTime: Double = {
let uptime = CACurrentMediaTime()
let nowTime = Date().timeIntervalSince1970
return nowTime - uptime
}()
let uptime = CACurrentMediaTime()
let nowTime = Date().timeIntervalSince1970
return nowTime - uptime
}()

func startGame(timeSpeed: Float, isShowAnswers: Bool, countGame: Int) {
countAllGame = countGame
timeSpeedGame = TimeInterval(timeSpeed)
Expand Down Expand Up @@ -115,7 +119,7 @@ class GameManager {
case .fixations:
startFixationsTimestamp = time
case .trial:
break
break
case .feedback:
startFeedbackTimestamp = time
case .response:
Expand All @@ -137,14 +141,15 @@ class GameManager {

func checkedAnswer(button: SelectedButton) {
guard !hasRespondedInCurrentTrial else { return }
guard let startTrialTimestamp = startTrialTimestamp else { return }
hasRespondedInCurrentTrial = true
respondTouchButton = bootTime + CACurrentMediaTime()
invalidateTimers()

delegate?.setEnableButton(isEnable: false)

guard let gameParameters = gameParameters else { return }
guard let startTrialTimestamp = startTrialTimestamp else { return }
guard countTest >= 0 && countTest < gameParameters.trials.count else { return }
var resultTime = (respondTouchButton! - startTrialTimestamp) * 1000

arrayTimes.append(Int(resultTime))
Expand All @@ -155,31 +160,39 @@ class GameManager {
startFeedbackTimestamp = bootTime + CACurrentMediaTime()

let correctChoice = gameParameters.trials[countTest].correctChoice
let isCorrect = (button == .left && correctChoice == 0) || (button == .right && correctChoice == 1)
let isCorrect =
(button == .left && correctChoice == 0) || (button == .right && correctChoice == 1)
if isCorrect {
correctAnswers += 1
}

let buttonPressed = (button == .left) ? "0" : "1"
let model = FlankerModel(rt: resultTime,
stimulus: text,
button_pressed: buttonPressed,
image_time: endTrialTimestamp! * 1000,
correct: isCorrect,
start_timestamp: 0,
tag: Constants.tag,
trial_index: countTest + 1,
start_time: startTrialTimestamp * 1000,
response_touch_timestamp: respondTouchButton! * 1000)
let model = FlankerModel(
rt: resultTime,
stimulus: text,
button_pressed: buttonPressed,
image_time: endTrialTimestamp! * 1000,
correct: isCorrect,
start_timestamp: 0,
tag: Constants.tag,
trial_index: countTest + 1,
start_time: startTrialTimestamp * 1000,
response_touch_timestamp: respondTouchButton! * 1000)

resultManager.addStepData(data: model)
delegate?.resultTest(avrgTime: nil, procentCorrect: nil, data: model, dataArray: nil, isShowResults: false, minAccuracy: gameParameters.minimumAccuracy)
delegate?.resultTest(
avrgTime: nil, procentCorrect: nil, data: model, dataArray: nil, isShowResults: false,
minAccuracy: gameParameters.minimumAccuracy)

if gameParameters.showFeedback {
let feedbackText = isCorrect ? Constants.correctText : Constants.inCorrectText
let feedbackColor = isCorrect ? Constants.greenColor : Constants.redColor
delegate?.updateText(text: feedbackText, color: feedbackColor, font: Constants.smallFont, isStart: false, typeTime: .feedback)
let timer = Timer(timeInterval: Constants.lowTimeInterval, target: self, selector: #selector(setDefaultText), userInfo: nil, repeats: false)
delegate?.updateText(
text: feedbackText, color: feedbackColor, font: Constants.smallFont, isStart: false,
typeTime: .feedback)
let timer = Timer(
timeInterval: Constants.lowTimeInterval, target: self, selector: #selector(setDefaultText),
userInfo: nil, repeats: false)
RunLoop.main.add(timer, forMode: .common)
} else {
setDefaultText(isFirst: false)
Expand All @@ -189,9 +202,10 @@ class GameManager {
@objc func setDefaultText(isFirst: Bool) {
guard let gameParameters = gameParameters else { return }

hasRespondedInCurrentTrial = false
delegate?.setEnableButton(isEnable: false)

hasRespondedInCurrentTrial = false

if !isFirst {
endFeedbackTimestamp = bootTime + CACurrentMediaTime()
countTest += 1
Expand All @@ -208,12 +222,17 @@ class GameManager {

if gameParameters.showFixation {
startFixationsTimestamp = bootTime + CACurrentMediaTime()
if let image = URL(string: gameParameters.fixation), gameParameters.fixation.contains("https") {
if let image = URL(string: gameParameters.fixation), gameParameters.fixation.contains("https")
{
delegate?.updateFixations(image: image, isStart: true, typeTime: .fixations)
} else {
delegate?.updateText(text: gameParameters.fixation, color: .black, font: Constants.bigFont, isStart: true, typeTime: .fixations)
delegate?.updateText(
text: gameParameters.fixation, color: .black, font: Constants.bigFont, isStart: true,
typeTime: .fixations)
}
timerSetText = Timer(timeInterval: gameParameters.fixationDuration / 1000, target: self, selector: #selector(setText), userInfo: nil, repeats: false)
timerSetText = Timer(
timeInterval: gameParameters.fixationDuration / 1000, target: self,
selector: #selector(setText), userInfo: nil, repeats: false)
RunLoop.main.add(timerSetText!, forMode: .common)
} else {
setText()
Expand All @@ -223,27 +242,33 @@ class GameManager {
@objc func setText() {
guard let gameParameters = gameParameters else { return }
guard countTest < gameParameters.trials.count else {
handleEndOfGame()
return
handleEndOfGame()
return
}

endFixationsTimestamp = bootTime + CACurrentMediaTime()

startTrialTimestamp = bootTime + CACurrentMediaTime()

hasRespondedInCurrentTrial = false

text = gameParameters.trials[countTest].stimulus.en

if let image = URL(string: text), text.contains("https") {
delegate?.updateFixations(image: image, isStart: true, typeTime: .trial)
} else {
delegate?.updateText(text: text, color: .black, font: Constants.bigFont, isStart: true, typeTime: .trial)
delegate?.updateText(
text: text, color: .black, font: Constants.bigFont, isStart: true, typeTime: .trial)
}

DispatchQueue.main.asyncAfter(deadline: .now()) {
self.delegate?.setEnableButton(isEnable: true)
self.timeResponse = Timer(timeInterval: gameParameters.trialDuration / 1000, target: self, selector: #selector(self.timeResponseFailed), userInfo: nil, repeats: false)
RunLoop.main.add(self.timeResponse!, forMode: .common)
}
delegate?.setEnableButton(isEnable: true)

timeResponse = Timer(
timeInterval: gameParameters.trialDuration / 1000,
target: self,
selector: #selector(timeResponseFailed),
userInfo: nil,
repeats: false)
RunLoop.main.add(timeResponse!, forMode: .common)
}

@objc func timeResponseFailed() {
Expand All @@ -256,27 +281,34 @@ class GameManager {
startFeedbackTimestamp = bootTime + CACurrentMediaTime()

if gameParameters.showFeedback {
delegate?.updateText(text: Constants.timeRespondText, color: .black, font: Constants.smallFont, isStart: false, typeTime: .feedback)
delegate?.updateText(
text: Constants.timeRespondText, color: .black, font: Constants.smallFont, isStart: false,
typeTime: .feedback)
}

guard let startTrialTimestamp = startTrialTimestamp else { return }

let model = FlankerModel(rt: 0.0,
stimulus: text,
button_pressed: nil,
image_time: endTrialTimestamp! * 1000, // має намалювати
correct: false,
start_timestamp: 0, // вже намальовано
tag: Constants.tag,
trial_index: countTest + 1,
start_time: startTrialTimestamp * 1000,
response_touch_timestamp: 0)
let model = FlankerModel(
rt: 0.0,
stimulus: text,
button_pressed: nil,
image_time: endTrialTimestamp! * 1000, // має намалювати
correct: false,
start_timestamp: 0, // вже намальовано
tag: Constants.tag,
trial_index: countTest + 1,
start_time: startTrialTimestamp * 1000,
response_touch_timestamp: 0)

resultManager.addStepData(data: model)
delegate?.resultTest(avrgTime: nil, procentCorrect: nil, data: model, dataArray: nil,isShowResults: gameParameters.showResults, minAccuracy: gameParameters.minimumAccuracy)
delegate?.resultTest(
avrgTime: nil, procentCorrect: nil, data: model, dataArray: nil,
isShowResults: gameParameters.showResults, minAccuracy: gameParameters.minimumAccuracy)

if gameParameters.showFeedback {
let timer = Timer(timeInterval: Constants.lowTimeInterval, target: self, selector: #selector(setDefaultText), userInfo: nil, repeats: false)
let timer = Timer(
timeInterval: Constants.lowTimeInterval, target: self, selector: #selector(setDefaultText),
userInfo: nil, repeats: false)
RunLoop.main.add(timer, forMode: .common)
} else {
setDefaultText(isFirst: false)
Expand Down Expand Up @@ -314,6 +346,7 @@ class GameManager {
countTest = -1
correctAnswers = 0
arrayTimes = []
hasRespondedInCurrentTrial = false
invalidateTimers()
}

Expand All @@ -323,8 +356,8 @@ class GameManager {
}
}

private extension GameManager {
func updateButtonTitle() {
extension GameManager {
fileprivate func updateButtonTitle() {
guard let gameParameters = gameParameters else { return }
guard countTest < gameParameters.trials.count else { return }

Expand Down
Loading
Loading