Add wifi sharing as a card, new settings for lan url, root and ssh

This commit is contained in:
Ana Custura 2026-02-19 16:42:57 +00:00
parent 947b4ac59a
commit ed1b03a609
52 changed files with 9067 additions and 94 deletions

View file

@ -1,9 +0,0 @@
{% extends "base.html" %}
{% block content %}
<h1 class="title is-large butter-title">About this {{get_setting('butterbox_name')}}.</h1>
<div class="block" style="align-content: center; text-align: center;">
<p> Some info here about butter and how to create your own.</p>
</div>
{% endblock %}

View file

@ -1,33 +1,47 @@
{% extends "base.html" %}
{% block navbar_logout %}
<div class="navbar-item"><button class="button is-warning"><a class="navbar-item" href="{{ url_for('logout') }}">Logout</a></button></div>
{% endblock %}
{% block content %}
<h1 class="title is-large butter-title">{{ _('Application Settings') }}</h1>
{% import "bulma_wtf.html" as wtf %}
<form action="" method="post" enctype="multipart/form-data" novalidate >
{{ form.hidden_tag() }}
<p> {{ form.submit( class="button is-link") }}
<div class="control block">
{{ form.submit( class="button is-link") }}
{% if config['SETTINGS_CHANGED'] %}
{{ form.apply_changes(class="button is-warning") }}
{% endif %}
</p>
</div>
<div class="field">
{{ wtf.form_input_field(form.ssid) }}
{{ wtf.form_input_field(form.ssid, form.ssid.errors) }}
<p class="help"> This is the name of the advertised Wi-Fi network. Current SSID: {{ get_setting('ssid') }}</p>
</div>
<div class="password">
{{ wtf.form_input_field(form.wifi_password) }}
{{ wtf.form_input_field(form.wifi_password, form.wifi_password.errors) }}
<p class="help"> This is the secret key needed to connect to the Wi-Fi network. By default, this is not set and everyone can join.
Current password: {{ get_setting('wifi_password') or 'Not set' }}</p>
</div>
<div class="field">
{{ wtf.form_input_field(form.butterbox_name) }}
<p class="help">This is the name shown in the UI, and used to access the box locally by adding .local or .lan in your browser.
Current name: {{ get_setting('butterbox_name') }}, accessed at {{ get_setting('butterbox_name') }}.local.</p>
{{ wtf.form_input_field(form.butterbox_name, form.butterbox_name.errors) }}
<p class="help">This is the name shown in the UI.
Current name: {{ get_setting('butterbox_name') }}, accessed at {{ get_setting('butterbox_name') }}.local.</p>
</div>
<div class="field">
{{ wtf.form_input_field(form.butterbox_hostname, form.butterbox_hostname.errors) }}
<p class="help">This is used to access the box locally by adding .local or .lan in your browser.
Current hostname: {{ get_setting('butterbox_hostname') }}.local.</p>
<div class="checkbox">
{{ wtf.form_bool_field(form.enable_access_point) }}
<p class="help">Whether this box will advertise a WiFi network.</p>
<p class="help">Whether this box will advertise a Wi-Fi network.</p>
</div>
<div class="checkbox">
{{ wtf.form_bool_field(form.enable_wifi_sharing) }}
<p class="help">Whether a share button for the Wi-Fi network is available.</p>
</div>
<div class="checkbox">
{{ wtf.form_bool_field(form.enable_map_viewer) }}
@ -50,22 +64,46 @@
<p class="help">Whether app store services are enabled.</p>
</div>
<div class="field">
{{ wtf.form_input_field(form.admin_password) }}
<p class="help">Password for accessing this interface.</p>
{{ wtf.form_password_field(form.admin_password, form.admin_password.errors) }}
<p class="help">Password for accessing this browser interface.</p>
</div>
<div class="field block">
<label class="label">{{ form.root_account_settings.label }} </label>
{% for subfield in form.root_account_settings %}
<label class="radio">
{% if get_setting('root_account_settings') == subfield._value() %}
<input id='{{subfield.id}}' type='radio' name='{{subfield.name}}' value='{{subfield._value()}}' checked/>
{% else %}
<input id='{{subfield.id}}' type='radio' name='{{subfield.name}}' value='{{subfield._value()}}'/>
{% endif %}
{{ subfield.label }}
</label>
{% endfor %}
{{ wtf.field_errors(form.root_account_settings.errors)}}
</div>
<div class="control block">
<label class="label">{{ form.ssh_access_settings.label }} </label>
{% for subfield in form.ssh_access_settings %}
<label class="radio">
{% if get_setting('ssh_access_settings') == subfield._value() %}
<input id='{{subfield.id}}' type='radio' name='{{subfield.name}}' value='{{subfield._value()}}' checked/>
{% else %}
<input id='{{subfield.id}}' type='radio' name='{{subfield.name}}' value='{{subfield._value()}}'/>
{% endif %}
{{ subfield.label }}
</label>
{% endfor %}
{{ wtf.field_errors(form.ssh_access_settings.errors) }}
</div>
<div class="field">
<label class="label">{{ form.butterbox_logo.label }} </label>
<div class="control">{{ form.butterbox_logo(class='label', style="width: 280px") }}</div>
{% for error in form.butterbox_logo.errors %}
<p class="help is-danger">{{ error }}</p>
{% endfor %}
<p class="help">This is the logo shown in the UI. Current logo: <br>
<img src="{{ get_setting('butterbox_logo') }}" style="height: 50px"> </p>
<div class="control block">{{ form.butterbox_logo(class='label', style="width: 280px") }}</div>
{{ wtf.field_errors(form.butterbox_logo.errors) }}
<div class="block"><p class="help">This is the logo shown in the UI. Current logo:</p></div>
<img src="{{ get_setting('butterbox_logo') }}" style="height: 50px">
</div>
</form>
<a href="{{ url_for('logout') }}">Logout</a>
{% endblock %}

View file

@ -6,20 +6,22 @@
{% if title %}
<title>{{ title }}</title>
{% else %}
<title>"{{ get_setting('butterbox_name') }}"</title>
<title>{{ get_setting('butterbox_name') }}</title>
{% endif %}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@1.0.4/css/bulma.min.css">
<link rel="stylesheet" href="{{ url_for('static', filename='butter_styles.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/bulma.min.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/butter_styles.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='font-awesome-4.7.0/css/font-awesome.min.css') }}">
<script src="{{ url_for('static', filename='navbar.js') }}"></script>
</head>
<body>
<div class="container">
<nav class="navbar" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
<a href="/"><img class="image is-32x32" src="{{ get_setting('butterbox_logo') }}"></a>
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false">
<a class="navbar-item" href="/"><img class="image" src="{{ get_setting('butterbox_logo') }}"></a>
<a role="button" class="navbar-burger" is-active="true" aria-label="menu" aria-expanded="false" data-target="navbarBasic">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
@ -27,19 +29,15 @@
</a>
</div>
<div id="navbarBasicExample" class="navbar-menu">
<div id="navbarBasic" class="navbar-menu">
<div class="navbar-start">
<a href="{{ url_for('share') }}" class="navbar-item">
Share
<a href="{{ url_for('admin') }}" class="navbar-item">Admin
</a>
<a href="{{ url_for('about') }}" class="navbar-item">
About
</a>
<a href="{{ url_for('admin') }}" class="navbar-item">
Admin
</a>
</div>
</div>
</div>
<div class="navbar-end">
{% block navbar_logout %}{% endblock %}
</div>
</div>
</nav>
<div class="content"> </div>

View file

@ -1,8 +1,8 @@
{% macro form_input_field(field) %}
<div class="control">
{% macro form_input_field(field, errors=[]) %}
<div class="control block">
{{ field.label(class='label')}}
{{ field(class='input' + (' is-danger' if field.errors else ' is_success'), type="text") }}
{% for error in field.errors %}
{{ field(class='input' + (' is-danger' if errors else ' is_success'), type="text") }}
{% for error in errors %}
<p class="help is-danger">{{ error }}</p>
{% endfor %}
</div>
@ -10,11 +10,46 @@
{% macro form_bool_field(field) %}
<div class="control">
<div class="control block">
{{ field.label(class='label')}}
{{ field(class='checkbox', type="checkbox") }}
{% for error in field.errors %}
{% for error in errors %}
<p class="help is-danger">{{ error }}</p>
{% endfor %}
</div>
{% endmacro %}
{% endmacro %}
{% macro form_password_field(field, errors=[]) %}
<div class="control block">
{{ field.label(class='label')}}
{{ field(class='input', type="password") }}
{% for error in errors %}
<p class="help is-danger">{{ error }}</p>
{% endfor %}
</div>
{% endmacro %}
{% macro field_errors(errors) %}
{% for error in errors %}
<p class="help is-danger">{{ error }}</p>
{% endfor %}
{% endmacro %}
{% macro form_radio_field(field, setting, errors=[]) %}
<div class="control block">
<label class="label">{{ field.label }} {{setting}}</label>
{% for subfield in field %}
<label class="radio">
{% if setting == subfield._value() %}
<input id='{{ subfield.id }}' type="radio" name='{{ subfield.name }}' value='{{ subfield._value() }}'/> # to debug. checked here is not rendered as a word, but rendered as 'checked="", so we can't use the macro yet'
{% else %}
<input id='{{ subfield.id }}' type='radio' name='{{ subfield.name }}' value='{{ subfield._value() }}'/>
{% endif %}
{{ subfield.label }}
</label>
{% endfor %}
{% for error in errors %}
<p class="help is-danger">{{ error }}</p>
{% endfor %}
</div>{% endmacro %}

View file

@ -7,7 +7,7 @@
<form action="" method="post" novalidate>
{{ form.hidden_tag() }}
<div class="field">{{ wtf.form_input_field(form.username) }}</div>
<div class="field">{{ wtf.form_input_field(form.password) }}</div>
<div class="field">{{ wtf.form_password_field(form.password) }}</div>
<div>{{ form.submit(class="button is-link") }}</div>
</form>

View file

@ -3,16 +3,17 @@
{% block content %}
<h1 class="title is-large butter-title">Share access to {{get_setting('butterbox_name')}}.</h1>
<div class="block butter-centered">
{% if display_wifi_password %}
<div class="block" style="align-content: center; text-align: center;">
<p>Connect to WiFi name: "{{ get_setting('ssid') }}" with password: "{{ get_setting('wifi_password') }}". You can also use the following QR code to join:</p>
<img class="image is-256x256" style="margin: 0 auto" src="{{ url_for('static', filename='images/wifi_qr_code.png') }}">
</div>
<p>Connect to WiFi name: "{{ get_setting('ssid') }}" with password: "{{ get_setting('wifi_password') }}".</p>
{% else %}
<div class="block" style="align-content: center; text-align: center;">
<p>Your WiFi name is "{{ get_setting('ssid') }}". You will be able to join without a password.</p>
</div>
<p>Your WiFi name is "{{ get_setting('ssid') }}". You will be able to join without a password.</p>
{% endif %}
<p>You can also use the following QR code to join:</p>
</div>
<div class="block butter-centered">
<img class="image is-256x256" style="margin: 0 auto" src="{{ url_for('static', filename='images/wifi_qr_code.png') }}">
</div>
{% endblock %}

View file

@ -34,6 +34,11 @@
{% endif %}
</tr>
{% endfor %}
{% if not render_files %}
<tr>
<td colspan="4"> <p class="butter-centered has-text-grey">Directory is empty</p></td>
</tr>
{% endif %}
</tbody>
</table>
{% endblock %}