Implemented auto ping functionality.

This commit is contained in:
mono 2022-06-06 17:37:28 +02:00
parent 651eba8948
commit 922e5f778d
17 changed files with 300 additions and 87 deletions

View File

@ -1,4 +1,5 @@
extends Node
# This is not for configuration data. See settings_singleton.gd.
signal loaded()
@ -26,6 +27,9 @@ func setup():
miscellaneous = MiscellaneousData.new()
yield(get_tree(), "idle_frame")
_load_data()
PingSystem.reschedule_pings()
yield(get_tree(), "idle_frame")
PingSystem.reevaluate_unreceived_pings()
func _load_data():

View File

@ -60,6 +60,8 @@ func get_last_message_of_user(user: User) -> Message:
func load_data():
var file = File.new()
if not file.file_exists("user://" + FILE_NAME):
return
file.open("user://" + FILE_NAME, File.READ)
var json_string = file.get_as_text()
if validate_json(json_string):

View File

@ -3,38 +3,33 @@ class_name MiscellaneousData
const FILE_NAME = "miscellaneous.dat"
var close_time_stamp
var dirty_flag = false
var lkp_time_stamp = 0 # last_key_press_time_stamp
func load_data():
pass
# var file = File.new()
# file.open("user://" + FILE_NAME, File.READ)
# var json_string = file.get_as_text()
# if validate_json(json_string):
# printerr("\"" + FILE_NAME + "\" was found, but is corrupted.")
# return
# var message_data_list = parse_json(json_string)
# for message_data in message_data_list:
# var user = Users.get_primary() if message_data["user"] else Users.get_helper()
var file = File.new()
if not file.file_exists("user://" + FILE_NAME):
return
file.open("user://" + FILE_NAME, File.READ)
var json_string = file.get_as_text()
if validate_json(json_string):
printerr("\"" + FILE_NAME + "\" was found, but is corrupted.")
return
var data = parse_json(json_string)
if data.has("lkpts"):
lkp_time_stamp = data["lkpts"]
func save_data():
# We do not apply a dirty flag here, because close_time_stamp needs to be
# saved anyway.
pass
# var message_data_list = []
# for message_group in loaded_message_groups:
# var user = message_group.associated_user.is_primary()
# for message in message_group.messages:
# var message_data = {
# "user" : user,
# "time_stamp" : message.time_stamp,
# "content" : message.content
# }
# message_data_list.append(message_data)
# var json_string = to_json(message_data_list)
# var file = File.new()
# file.open("user://" + FILE_NAME, File.WRITE)
# file.store_string(json_string)
# file.close()
if dirty_flag:
var data = {
"lkpts" : lkp_time_stamp
}
var json_string = to_json(data)
var file = File.new()
file.open("user://" + FILE_NAME, File.WRITE)
file.store_string(json_string)
file.close()
# dirty_flag needs to be set to false after successful save!
dirty_flag = false

View File

@ -37,6 +37,8 @@ func _compare_topic_index(a, b):
func load_data():
var file = File.new()
if not file.file_exists("user://" + FILE_NAME):
return
file.open("user://" + FILE_NAME, File.READ)
var json_string = file.get_as_text()
if validate_json(json_string):

View File

@ -1,30 +1,140 @@
extends Node
# warning-ignore:unused_signal
signal ping_handled
signal ping_handled(ping)
const AUTO_PING_ENABLED = true
const MAX_PINGS_ALLOWED = 8
onready var ping_sound = get_node("PingSound")
var unhandled_ping_count = 0
var unhandled_ping_list = []
var _unhandled_ping_count = 0
var total_ping_count = 0
var current_ping_id = 0
var scheduled_pings = []
func _ready():
if AUTO_PING_ENABLED:
var autoping_timer = Timer.new()
autoping_timer.wait_time = 1.0 # Every second.
autoping_timer.autostart = true
autoping_timer.connect("timeout", self, "reevaluate_unreceived_pings")
add_child(autoping_timer)
func _input(event):
if event is InputEventKey:
if event.scancode == KEY_P and event.control and event.alt:
if event.pressed and !event.is_echo():
send_ping()
send_ping(Time.get_current_time())
func send_ping():
if unhandled_ping_count < 15:
Data.messages.add_message("", Time.get_current_time(), Users.get_helper())
func send_ping(time_stamp: int):
if unhandled_ping_list.size() < MAX_PINGS_ALLOWED:
Data.messages.add_message("", time_stamp, Users.get_helper())
ping_sound.play()
OS.request_attention()
func _on_ping_handled():
unhandled_ping_count -= 1
func reschedule_pings():
scheduled_pings.clear()
var lmbp_time_stamp = _get_lmbp_time_stamp()
var lkp_time_stamp = Data.miscellaneous.lkp_time_stamp # last_key_press_time_stamp
var last_t_s_of_interaction = max(lmbp_time_stamp, lkp_time_stamp)
seed(last_t_s_of_interaction)
var minimum_t_s_for_next_ping
minimum_t_s_for_next_ping = max(
lmbp_time_stamp + _get_time_until_next_ping(),
lkp_time_stamp + 30
)
var previous_time_stamp = minimum_t_s_for_next_ping
for _i in range(8):
if not _is_time_stamp_during_active_phase(previous_time_stamp):
previous_time_stamp = Time.get_current_phase_skipped(
previous_time_stamp
) + _random_addition([-300, 600])
var keep_pinging = true
while keep_pinging:
scheduled_pings.append(previous_time_stamp)
keep_pinging = randi() % 100 < 30 # 30% chance.
if keep_pinging:
previous_time_stamp += randi() % 6
previous_time_stamp += _get_time_until_next_ping()
func _get_lmbp_time_stamp():
var lmbp # last_message_by_primary
lmbp = Data.messages.get_last_message_of_user(
Users.get_primary()
)
if lmbp:
return lmbp.time_stamp
else:
return Time.get_current_time() # Just act as if just sent.
func _is_time_stamp_during_active_phase(time_stamp: int) -> bool:
if Time.is_during_night_time(time_stamp):
return false
elif Time.is_during_inactive_time(time_stamp):
return Time.is_during_inactive_time(_get_lmbp_time_stamp())
elif Time.is_during_active_time(time_stamp):
return true
else:
return Time.is_during_calm_down_time(_get_lmbp_time_stamp())
func _get_time_until_next_ping() -> int:
var time_addition_for_next_ping = 30
var average_in_seconds = Settings.average_minutes_until_ping * 60
var rare_time_addition = [
int(average_in_seconds * 0.05), # Minimum.
int(average_in_seconds * 0.35) # Span.
]
var average_time_addition = [
int(average_in_seconds * 0.9), # Minimum.
int(average_in_seconds * 0.2) # Span.
]
var uncommon_time_addition = [
int(average_in_seconds * 0.4), # Minimum.
int(average_in_seconds * 1.2) # Span.
]
var random_number = randi() % 1000
if random_number < 35:
time_addition_for_next_ping += _random_addition(rare_time_addition)
elif random_number < 665:
time_addition_for_next_ping += _random_addition(average_time_addition)
else:
time_addition_for_next_ping += _random_addition(uncommon_time_addition)
return time_addition_for_next_ping
func _random_addition(span: Array) -> int:
return span[0] + int(span[1] * randf())
func reevaluate_unreceived_pings():
for scheduled_ping_t_s in scheduled_pings:
if scheduled_ping_t_s < Time.get_current_time():
if not scheduled_ping_t_s in unhandled_ping_list:
send_ping(scheduled_ping_t_s)
func _on_ping_handled(ping: Message):
unhandled_ping_list.erase(ping.time_stamp)
current_ping_id += 1

View File

@ -2,3 +2,13 @@ extends Node
# warning-ignore:unused_signal
signal settings_menu_requested
var menu_open = false
# Ping System behavior.
var inactive_time = 7
var active_time = 15
var calm_down_time = 19
var night_time = 22
var average_minutes_until_ping = 50

View File

@ -1,8 +1,92 @@
extends Node
var locational_time_offset: int = 7200
var offset: int = 0 # This is for debug purposes. (Doing sudden time jumps)
func get_current_time() -> int:
return OS.get_unix_time() + offset
return OS.get_unix_time() + locational_time_offset + offset
func get_time_string(time_stamp: int) -> String:
var datetime: Dictionary = OS.get_datetime_from_unix_time(time_stamp)
var hour = datetime["hour"]
var minute = datetime["minute"]
var am_pm
var offset_wrapped_hour = wrapi(hour - 1, 0, 24)
var processed_hour = offset_wrapped_hour
if offset_wrapped_hour >= 12:
processed_hour -= 12
if hour >= 12:
am_pm = " PM"
else:
am_pm = " AM"
processed_hour += 1
var hour_string = str(processed_hour)
var minute_string = "%02d" % minute
return hour_string + ":" + minute_string + am_pm
func get_date_string(time_stamp: int) -> String:
var datetime: Dictionary = OS.get_datetime_from_unix_time(time_stamp)
var month_string = "%02d" % datetime["month"]
var day_string = "%02d" % datetime["day"]
var year_string = str(datetime["year"])
return month_string + "/" + day_string + "/" + year_string
func is_during_night_time(time_stamp: int) -> bool:
var datetime: Dictionary = OS.get_datetime_from_unix_time(time_stamp)
var hour = datetime["hour"]
return hour >= Settings.night_time or hour < Settings.inactive_time
func is_during_inactive_time(time_stamp: int) -> bool:
var datetime: Dictionary = OS.get_datetime_from_unix_time(time_stamp)
var hour = datetime["hour"]
return hour >= Settings.inactive_time and hour < Settings.active_time
func is_during_active_time(time_stamp: int) -> bool:
var datetime: Dictionary = OS.get_datetime_from_unix_time(time_stamp)
var hour = datetime["hour"]
return hour >= Settings.active_time and hour < Settings.calm_down_time
func is_during_calm_down_time(time_stamp: int) -> bool:
var datetime: Dictionary = OS.get_datetime_from_unix_time(time_stamp)
var hour = datetime["hour"]
return hour >= Settings.calm_down_time and hour < Settings.night_time
func get_current_phase_skipped(time_stamp: int) -> int:
var DAY_IN_SECONDS = 86400
var datetime: Dictionary = OS.get_datetime_from_unix_time(time_stamp)
var hour = datetime["hour"]
if hour < Settings.inactive_time:
datetime["hour"] = Settings.inactive_time
elif hour >= Settings.inactive_time and hour < Settings.active_time:
datetime["hour"] = Settings.active_time
elif hour >= Settings.active_time and hour < Settings.calm_down_time:
datetime["hour"] = Settings.calm_down_time
elif hour >= Settings.calm_down_time and hour < Settings.night_time:
datetime["hour"] = Settings.night_time
else:
datetime = OS.get_datetime_from_unix_time(time_stamp + DAY_IN_SECONDS)
datetime["hour"] = Settings.inactive_time
datetime["minute"] = 0
datetime["second"] = 0
return OS.get_unix_time_from_datetime(datetime)

View File

@ -21,7 +21,7 @@ func _input(event):
func _on_message_box_confirmed(content):
if PingSystem.unhandled_ping_count == 0 and not content.empty():
if PingSystem.unhandled_ping_list.size() == 0 and not content.empty():
text_edit.text = ""
text_edit._on_text_changed() # To go back to minimum height.
else:

View File

@ -40,8 +40,11 @@ func _setup_insert_mode():
# warning-ignore:return_value_discarded
PingSystem.connect("ping_handled", self, "_on_ping_handled")
ping_id = PingSystem.total_ping_count
PingSystem.unhandled_ping_count += 1
PingSystem.unhandled_ping_list.append(
associated_message.get_ref().time_stamp
)
PingSystem.total_ping_count += 1
auto_focus = false
# warning-ignore:return_value_discarded
_check_if_next_ping()
@ -127,7 +130,7 @@ func _disable_insert_mode():
text_edit.min_width = 0
text_edit.min_height = 0
PingSystem.disconnect("ping_handled", self, "_on_ping_handled")
PingSystem.emit_signal("ping_handled")
PingSystem.emit_signal("ping_handled", associated_message.get_ref())
message_inserted_sound.play()
@ -155,6 +158,6 @@ func _on_text_edit_confirmed(confirmed_content): # Override
_disable_edit_mode()
func _on_ping_handled():
func _on_ping_handled(_ping):
if _check_if_next_ping():
text_edit.grab_focus()

View File

@ -23,7 +23,7 @@ func scroll_to_newest():
func _on_message_box_confirmed(content):
if PingSystem.unhandled_ping_count == 0 and not content.empty():
if PingSystem.unhandled_ping_list.size() == 0 and not content.empty():
Data.messages.add_message(
content, Time.get_current_time(), Users.get_current()
)

View File

@ -36,45 +36,18 @@ func _setup():
# Define date.
var time_stamp = associated_message_group.get_ref().time_stamp
var storaged_date = OS.get_datetime_from_unix_time(time_stamp)
var os_time = OS.get_datetime()
var os_time = OS.get_datetime_from_unix_time(Time.get_current_time())
if storaged_date.day == os_time.day:
date.text = "Today at " + _get_time_string(storaged_date)
date.text = "Today at " + Time.get_time_string(time_stamp)
elif storaged_date.day == os_time.day - 1:
date.text = "Yesterday at " + _get_time_string(storaged_date)
date.text = "Yesterday at " + Time.get_time_string(time_stamp)
else:
date.text = _get_date_string(storaged_date)
date.text = Time.get_date_string(time_stamp)
_adjust_layout_to_user()
func _get_time_string(datetime: Dictionary) -> String:
var hour = datetime.hour
var minute = datetime.minute
var am_pm
var offset_wrapped_hour = wrapi(hour - 1, 0, 24)
var processed_hour = offset_wrapped_hour
if offset_wrapped_hour >= 12:
am_pm = " PM"
processed_hour -= 12
else:
am_pm = " AM"
processed_hour += 1
var hour_string = str(processed_hour)
var minute_string = "%02d" % minute
return hour_string + ":" + minute_string + am_pm
func _get_date_string(datetime: Dictionary) -> String:
var month_string = "%02d" % datetime.month
var day_string = "%02d" % datetime.day
var year_string = str(datetime.year)
return month_string + "/" + day_string + "/" + year_string
func _adjust_layout_to_user():
if get_user().is_current():
move_child(profile_image_rect, 1)

View File

@ -10,6 +10,8 @@ func _ready():
# warning-ignore:return_value_discarded
Users.connect("switched", self, "_on_user_switched")
Users.emit_signal("switched")
print(OS.get_datetime_from_unix_time(0))
func _enter_tree():

View File

@ -20,8 +20,8 @@ tag = "Debug Settings"
[node name="TimeOffset" type="Control" parent="."]
margin_top = 19.0
margin_right = 1024.0
margin_bottom = 83.0
rect_min_size = Vector2( 0, 64 )
margin_bottom = 99.0
rect_min_size = Vector2( 0, 80 )
script = ExtResource( 2 )
[node name="LabelTimeOffset" type="Label" parent="TimeOffset"]
@ -45,8 +45,8 @@ margin_left = 86.0
margin_top = 28.0
margin_right = 160.0
margin_bottom = 52.0
min_value = -48.0
max_value = 48.0
min_value = -480.0
max_value = 480.0
__meta__ = {
"_edit_use_anchors_": false
}
@ -83,19 +83,29 @@ __meta__ = {
}
[node name="LabelTO" type="Label" parent="TimeOffset"]
margin_left = 509.0
margin_top = 32.0
margin_right = 549.0
margin_bottom = 46.0
margin_left = 68.0
margin_top = 58.0
margin_right = 108.0
margin_bottom = 72.0
text = "to:"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="LabelTimeString" type="Label" parent="TimeOffset"]
margin_left = 311.0
margin_top = 58.0
margin_right = 351.0
margin_bottom = 72.0
text = "to:"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Restart" type="Control" parent="."]
margin_top = 87.0
margin_top = 103.0
margin_right = 1024.0
margin_bottom = 151.0
margin_bottom = 167.0
rect_min_size = Vector2( 0, 64 )
script = ExtResource( 3 )

View File

@ -1,6 +1,7 @@
extends Control
onready var label_t_o = get_node("LabelTO")
onready var label_time_string = get_node("LabelTimeString")
onready var spin_box_hours = get_node("SpinBoxHours")
onready var spin_box_minutes = get_node("SpinBoxMinutes")
@ -18,6 +19,15 @@ func _ready():
_display_applied_time_offset()
func _process(_delta):
if not Settings.menu_open:
return
label_time_string.text = Time.get_time_string(
Time.get_current_time()
) + " " + Time.get_date_string(
Time.get_current_time())
func _update_unapplied_time_offset(_value):
var offset_hours = spin_box_hours.value * 3600
var offset_minutes = spin_box_minutes.value * 60

View File

@ -8,13 +8,16 @@ func _ready():
func _on_requested():
visible = true
Settings.menu_open = true
func _on_ColorRect_gui_input(event):
if event is InputEventMouseButton:
if event.button_index == BUTTON_LEFT and event.is_pressed():
visible = false
Settings.menu_open = false
func _on_CloseButton_pressed():
visible = false
Settings.menu_open = false

View File

@ -66,6 +66,9 @@ func _on_text_changed():
if expand_width:
# I honestly don't know why, but the second call helps with refreshing.
adjust_size()
Data.miscellaneous.lkp_time_stamp = Time.get_current_time()
Data.miscellaneous.dirty_flag = true
PingSystem.reschedule_pings()
func _on_resized():

View File

@ -13,6 +13,7 @@ onready var text_edit = get_node("VBoxContainer/MarginContainer/ContentFitTextEd
onready var popup_menu = get_node("PopupMenu")
var auto_focus: bool = true
var edit_mode: bool = false
@ -132,9 +133,10 @@ func _enable_edit_mode():
text_edit.adjust_size()
text_edit.grab_focus()
yield(get_tree(), "idle_frame")
text_edit.select_all()
if auto_focus:
text_edit.grab_focus()
yield(get_tree(), "idle_frame")
text_edit.select_all()
func _post_enable_edit_mode(): # Virtual.