$xmpp $mol_view
	plugins /
		<= Theme $mol_theme_auto
	sub <= panes /
	-
	Login_pane $mol_page
		title @ \XMPP Client
		tools /
			<= Lights $mol_lights_toggle
		body /
			<= Login_form $mol_form
				form_fields /
					<= Server_field $mol_form_field
						name @ \WebSocket URL
						control <= Server_input $mol_string
							hint \wss://jabber.example.com/ws
							value? <=> server? \
					<= Jid_field $mol_form_field
						name @ \JID
						control <= Jid_input $mol_string
							hint \user@jabber.example.com
							value? <=> jid? \
					<= Pass_field $mol_form_field
						name @ \Password
						control <= Pass_input $mol_string
							type \password
							value? <=> password? \
					<= Error_field $mol_form_field
						name @ \Error
						control <= Error_view $mol_view
							sub /
								<= error_text \
				buttons /
					<= Connect_button $mol_button_major
						title <= connect_title @ \Connect
						click? <=> do_connect? null
						disabled <= connecting false
	-
	Folders_pane $mol_view
		sub /
			<= My_avatar $mol_view
				dom_name \img
				attr *
					^
					src <= my_avatar_uri \
					alt \
				event *
					^
					click? <=> do_set_avatar? null
			<= Folder_all $mol_link
				arg *
					folder null
				sub /
					<= folder_all_label @ \All
			<= Folder_chats $mol_link
				arg *
					folder \chats
				sub /
					<= folder_chats_label @ \Chats
			<= Folder_rooms $mol_link
				arg *
					folder \rooms
				sub /
					<= folder_rooms_label @ \Rooms
			<= User_folders $mol_view
				sub <= user_folder_views /
			<= New_folder_zone $mol_drop
				adopt?transfer <=> folder_adopt?transfer null
				receive?obj <=> new_folder_receive?obj null
				Sub <= New_folder_label $mol_view
					sub /
						<= new_folder_text @ \+ Drop chat
			<= Folders_spacer $mol_view
			<= Settings_button $mol_button_minor
				hint @ \Settings
				click? <=> do_open_settings? null
				sub /
					<= Settings_icon $mol_icon_cog
			<= Lights2 $mol_lights_toggle
			<= Disconnect_button $mol_button_minor
				hint <= disconnect_label @ \Disconnect
				click? <=> do_disconnect? null
				sub /
					<= Disconnect_icon $mol_icon_logout
	-
	User_folder* $mol_drop
		adopt?transfer <=> folder_adopt?transfer null
		receive?obj <=> folder_receive*?obj null
		Sub <= User_folder_link* $mol_link
			arg *
				folder <= user_folder_name* \
			sub /
				<= user_folder_label* \
	-
	Roster_pane $mol_view
		sub /
			<= Roster_header $mol_view
				sub <= roster_header_sub /
			<= Search_input $mol_string
				hint @ \Search or enter JID…
				value? <=> search_query? \
			<= Roster_list $mol_view
				sub <= roster_rows /
			<= Search_actions $mol_view
				sub <= search_actions_sub /
	-
	Search_action_chat $mol_button_minor
		title <= search_action_chat_title \
		click? <=> do_search_chat? null
	-
	Search_action_room $mol_button_minor
		title <= search_action_room_title \
		click? <=> do_search_room? null
	-
	Settings_modal $mol_view
		sub /
			<= Settings_dim $mol_view
				event *
					^
					click? <=> do_close_settings? null
			<= Settings_dialog $mol_view
				sub /
					<= Settings_header $mol_view
						sub /
							<= Settings_title $mol_view
								sub /
									<= settings_title @ \Settings
							<= Settings_close $mol_button_minor
								click? <=> do_close_settings? null
								sub /
									<= Settings_close_icon $mol_icon_close
					<= Notif_section $mol_view
						sub /
							<= Notif_section_title $mol_view
								sub /
									<= notif_section_title @ \Notifications
							<= Notif_inapp_button $mol_button_minor
								click? <=> do_set_notif_inapp? null
								attr *
									^
									xmpp_active <= notif_inapp_active false
								sub /
									<= notif_inapp_label @ \In-app toast
							<= Notif_system_button $mol_button_minor
								click? <=> do_set_notif_system? null
								attr *
									^
									xmpp_active <= notif_system_active false
								sub /
									<= notif_system_label @ \System notification
					<= Sound_section $mol_view
						sub /
							<= Sound_section_title $mol_view
								sub /
									<= sound_section_title @ \Notification sound
							<= Sound_status $mol_view
								sub /
									<= sound_status_text \
							<= Sound_pick_button $mol_button_minor
								click? <=> do_pick_sound? null
								sub /
									<= sound_pick_label @ \Choose sound file
							<= Sound_test_button $mol_button_minor
								click? <=> do_test_sound? null
								sub /
									<= sound_test_label @ \Test
							<= Sound_clear_button $mol_button_minor
								click? <=> do_clear_sound? null
								sub /
									<= sound_clear_label @ \Reset to default
					<= Theme_section $mol_view
						sub /
							<= Theme_section_title $mol_view
								sub /
									<= theme_section_title @ \Theme
							<= Theme_presets $mol_view
								sub <= theme_preset_views /
							<= Theme_custom $mol_view
								sub /
									<= Theme_color_label $mol_view
										sub /
											<= theme_color_label @ \Custom hue
									<= Theme_color_input $mol_string
										type \color
										value? <=> theme_color? \
	-
	Theme_preset* $mol_button_minor
		click? <=> do_apply_preset*? null
		attr *
			^
			xmpp_active <= theme_preset_active* false
		sub /
			<= theme_preset_label* \
	-
	Roster_static_header $mol_view
		sub /
			<= roster_static_text \
	-
	Roster_folder_header $mol_view
		sub /
			<= Roster_folder_input $mol_string
				value? <=> roster_folder_input? \
				hint @ \Folder name
			<= Roster_folder_delete $mol_button_minor
				title @ \Delete folder
				click? <=> do_delete_current_folder? null
	-
	Chat_pane $mol_view
		sub <= chat_pane_content /
	-
	Chat_placeholder $mol_view
		sub /
			<= chat_placeholder_text @ \Select a chat to start messaging
	-
	Chat_view* $mol_view
		sub /
			<= Chat_header* $mol_view
				sub /
					<= Chat_avatar* $mol_view
						dom_name \img
						attr *
							^
							src <= chat_avatar_uri* \
							alt \
					<= Chat_title* $mol_view
						sub /
							<= chat_with* \
					<= Chat_leave* $mol_button_minor
						title @ \Leave
						click? <=> do_leave_room*? null
						attr *
							^
							hidden <= chat_leave_hidden* \
			<= Messages_area* $mol_view
				sub /
					<= Messages_list* $mol_list
						rows <= message_rows* /
					<= Scroll_down_button* $mol_button_minor
						hint @ \Scroll to bottom
						click? <=> do_scroll_down*? null
						attr *
							^
							hidden <= scroll_down_hidden* \
						sub /
							<= Scroll_down_icon* $mol_icon_chevron_double_down
			<= Compose_pane* $mol_view
				sub /
					<= Compose_input* $mol_string
						dom_name \textarea
						hint @ \Type a message…
						value? <=> compose*? \
						event *
							^
							keydown? <=> compose_keydown*? null
							paste? <=> compose_paste*? null
					<= Attach_button* $mol_button_minor
						title @ \Attach
						click? <=> do_attach*? null
					<= Record_button* $mol_button_minor
						title <= record_title* @ \Record
						click? <=> do_record*? null
					<= Send_button* $mol_button_major
						title <= send_label @ \Send
						click? <=> do_send*? null
	-
	Roster_contact* $mol_view
		attr *
			^
			xmpp_pinned <= contact_pinned* false
		sub /
			<= Roster_contact_drag* $mol_drag
				transfer *
					text/plain <= roster_jid* \
				Sub <= Roster_contact_drop* $mol_drop
					adopt?transfer <=> folder_adopt?transfer null
					receive?obj <=> reorder_pin*?obj null
					Sub <= Roster_contact_link* $mol_link
						arg *
							chat <= roster_jid* \
						sub /
							<= Contact_avatar* $mol_view
								dom_name \img
								attr *
									^
									src <= contact_avatar_uri* \
									alt \
							<= Contact_label* $mol_view
								sub /
									<= contact_display* \
			<= Pin_button* $mol_button_minor
				click? <=> toggle_pin*? null
				sub /
					<= Pin_icon* $mol_icon_pin
	-
	Msg* $mol_view
		sub /
			<= Msg_avatar* $mol_view
				dom_name \img
				attr *
					^
					src <= msg_avatar_uri* \
					alt \
			<= Msg_content* $mol_view
				sub /
					<= Msg_head* $mol_view
						sub /
							<= Msg_from* $mol_view
								sub /
									<= msg_from* \
							<= Msg_time* $mol_view
								sub /
									<= msg_time* \
					<= Msg_body* $mol_view
						sub /
							<= msg_body* \
					<= Msg_media* $mol_view
						sub <= msg_media* /
					<= Msg_status* $mol_view
						sub /
							<= msg_status* \
	-
	Msg_image* $mol_view
		dom_name \img
		attr *
			^
			src <= msg_image_uri* \
	-
	Msg_audio* $mol_view
		dom_name \audio
		attr *
			^
			controls \
			src <= msg_audio_src* \
	-
	Msg_link* $mol_link
		uri <= msg_link_uri* \
		sub /
			<= msg_link_label* @ \Open file
