from otree.api import * doc = """ Of course oTree has a readymade chat widget described here: https://otree.readthedocs.io/en/latest/multiplayer/chat.html But you can use this if you want a chat box that is more easily customizable, or if you want programmatic access to the chat messages. This app can also help you learn about live pages in general. """ class C(BaseConstants): NAME_IN_URL = 'chat_from_scratch' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 CHAT_TEMPLATE = __name__ + '/chat.html' INSTRUCTIONS_TEMPLATE = 'chat/instructions.html' class Subsession(BaseSubsession): pass class Group(BaseGroup): whose_turn = models.StringField(initial='X') pass class Player(BasePlayer): symbol = models.StringField() pass def creating_session(subsession: Subsession): for p in subsession.get_players(): p.symbol = {1: 'X', 2: 'O'}[p.id_in_group] class Introduction(Page): form_model = 'player' class Message(ExtraModel): group = models.Link(Group) sender = models.Link(Player) text = models.StringField() turn = models.StringField() symbol = models.StringField() def to_dict(msg: Message): return dict(sender=msg.sender.id_in_group, text=msg.text, turn=msg.sender.group.whose_turn, symbol=msg.sender.symbol) # PAGES class MyPage(Page): @staticmethod def js_vars(player: Player): return dict(my_symbol=player.symbol) @staticmethod def js_vars(player: Player): return dict(my_id=player.id_in_group) @staticmethod def live_method(player: Player, data): my_id = player.id_in_group group = player.group broadcast = {} if 'text' in data: text = data['text'] if player.symbol != group.whose_turn: msg = Message.create(group=group, sender=player, text='', turn=group.whose_turn, symbol=player.symbol) return {0: [to_dict(msg)]} group.whose_turn = player.get_others_in_group()[0].symbol msg = Message.create(group=group, sender=player, text=text, turn=group.whose_turn, symbol=player.symbol) return {0: [to_dict(msg)]} players = group.get_players() broadcast['whose_turn'] = group.whose_turn broadcast['messages'] = {my_id: [to_dict(msg) for msg in Message.filter(group=group)]} return {my_id: [to_dict(msg) for msg in Message.filter(group=group)]} #return {0: broadcast} #page_sequence = [Introduction, MyPage] page_sequence = [MyPage]