room_view.gd 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. extends PanelContainer
  2. var preload_message = preload("res://message.tscn")
  3. var scroll_to_bottom = true
  4. var scrolled_to_bottom = true
  5. var scrolled_to_top = false
  6. var backfill_thread
  7. var room: MatrixRoom setget set_room
  8. onready var room_name_label: Label = find_node("ROOM_NAME")
  9. onready var room_topic_label: Label = find_node("ROOM_TOPIC")
  10. onready var typing_indicator: Label = find_node("TYPING_INDICATOR")
  11. onready var message_box: LineEdit = find_node("MESSAGE_INPUT")
  12. onready var message_list: VBoxContainer = find_node("MESSAGE_LIST")
  13. onready var messages_scroller_box: ScrollContainer = find_node("MESSAGES")
  14. func set_room(r, c=true):
  15. if (c):
  16. clear()
  17. room = r
  18. #backfill_thread = Thread.new()
  19. #backfill_thread.start(self, "fetch_backfill")
  20. room.connect("ephemeral_event", self, "ephemeral_event")
  21. room.connect("timeline_event", self, "timeline_event")
  22. room.connect("old_timeline_event", self, "old_timeline_event")
  23. room.connect("state_event", self, "state_event")
  24. room.state_sync().wait_to_finish()
  25. for event in room.get_events():
  26. process_timeline_event(event)
  27. find_node("room_meta_line").visible = true
  28. find_node("message_input_container").visible = true
  29. func clear():
  30. for thing_to_clear in [room_name_label, room_topic_label, typing_indicator, message_box]:
  31. thing_to_clear.text = ""
  32. for c in message_list.get_children():
  33. message_list.remove_child(c)
  34. find_node("room_meta_line").visible = false
  35. find_node("message_input_container").visible = false
  36. if room:
  37. room.disconnect("ephemeral_event", self, "ephemeral_event")
  38. room.disconnect("timeline_event", self, "timeline_event")
  39. room.disconnect("old_timeline_event", self, "old_timeline_event")
  40. room.disconnect("state_event", self, "state_event")
  41. func _ready():
  42. messages_scroller_box.get_v_scrollbar().connect("changed", self, "scrollbar_changed")
  43. messages_scroller_box.get_v_scrollbar().connect("value_changed", self, "scrollbar_value_changed")
  44. find_node("leave_button").connect("button_up", self, "leave_room")
  45. clear()
  46. func leave_room():
  47. room.leave_room()
  48. func scrollbar_changed():
  49. var scrollbar = messages_scroller_box.get_v_scrollbar()
  50. if scrollbar.page >= message_list.get_minimum_size().y:
  51. scrolled_to_bottom = true
  52. if scroll_to_bottom:
  53. scrollbar.set_value(scrollbar.max_value-scrollbar.page)
  54. scroll_to_bottom = false
  55. if scrolled_to_bottom:
  56. scrollbar.set_value(scrollbar.max_value-scrollbar.page)
  57. func scrollbar_value_changed(v):
  58. var scrollbar = messages_scroller_box.get_v_scrollbar()
  59. scrolled_to_bottom = (scrollbar.max_value == 0 or scrollbar.value == scrollbar.max_value-scrollbar.page)
  60. scrolled_to_top = scrollbar.value == 0
  61. func fetch_backfill(args=null):
  62. while true:
  63. var scrollbar = messages_scroller_box.get_v_scrollbar()
  64. if room:
  65. var dist_from_bottom = scrollbar.max_value-scrollbar.page-scrollbar.value
  66. while scrollbar.page >= message_list.get_minimum_size().y:
  67. room.get_old_events(1)
  68. yield(scrollbar, "changed")
  69. scrollbar.set_value(scrollbar.max_value-scrollbar.page)
  70. if scrollbar.value == 0:
  71. room.get_old_events(5)
  72. yield(scrollbar, "changed")
  73. scrollbar.set_value(dist_from_bottom)
  74. yield(scrollbar, "value_changed")
  75. func has_room():
  76. if (room):
  77. return true
  78. return false
  79. func process_timeline_event(e, old=false):
  80. if (e['type'] == "m.room.message" and e.has('content') and e['content'].has('body')):
  81. var message = preload_message.instance(true)
  82. add_event(message, old)
  83. message.set_sender_name(self.__get_name(e['sender']))
  84. print(e['content']['body'].length())
  85. message.set_message_text(e['content']['body'])
  86. elif (e['type'] == "m.room.name"):
  87. var message = preload_message.instance(true)
  88. add_event(message, old)
  89. message.set_sender_name(self.__get_name(e['sender']))
  90. message.set_message_text("changed the room name to "+e['content']['name'])
  91. elif (e['type'] == "m.room.topic"):
  92. var message = preload_message.instance(true)
  93. add_event(message, old)
  94. message.set_sender_name(self.__get_name(e['sender']))
  95. message.set_message_text("changed the room topic to "+e['content']['topic'])
  96. else:
  97. pass
  98. func add_event(event, old):
  99. if not old:
  100. message_list.add_child(event)
  101. if (scrolled_to_bottom):
  102. scroll_to_bottom = true
  103. else:
  104. message_list.add_child(event)
  105. message_list.move_child(event, 0)
  106. yield(messages_scroller_box.get_v_scrollbar(), "changed")
  107. func __get_name(user_id):
  108. return room.get_member_display_name(user_id, true)
  109. func timeline_event(event):
  110. process_timeline_event(event, false)
  111. func old_timeline_event(event):
  112. process_timeline_event(event, true)
  113. func send_message(text=""):
  114. if (message_box.text != ""):
  115. room.send_text_message(message_box.text)
  116. message_box.clear()
  117. func ephemeral_event(event):
  118. if (event['type'] == "m.typing"):
  119. if (event['content']['user_ids'].size() == 0):
  120. typing_indicator.text = ""
  121. elif (event['content']['user_ids'].size() == 1):
  122. typing_indicator.text = event['content']['user_ids'][0] + " is typing"
  123. else:
  124. var typing_text = String(event['content']['user_ids'])
  125. typing_text = typing_text.substr(1, typing_text.length()-2)
  126. typing_indicator.text = typing_text + " are typing"
  127. func state_event(event):
  128. room_name_label.text = room.get_name(false)
  129. room_topic_label.text = room.get_topic(false)