mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2025-10-27 16:59:25 +00:00
Compare commits
1 Commits
f2f03b135f
...
44-contain
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
885b832661 |
@@ -1,36 +1,38 @@
|
|||||||
% rebase('webpage_base.tpl')
|
% rebase('webpage_base.tpl')
|
||||||
|
|
||||||
<div id="info-container" class="mt-4">
|
<div class="container main-container">
|
||||||
<h2 class="mt-4 mb-4">About Spothole</h2>
|
<div id="info-container" class="mt-4">
|
||||||
<p>Spothole is a utility to aggregate "spots" from amateur radio DX clusters and xOTA spotting sites, and provide an open JSON API as well as a website to browse the data.</p>
|
<h2 class="mt-4 mb-4">About Spothole</h2>
|
||||||
<p>While there are several other web-based interfaces to DX clusters, and sites that aggregate spots from various outdoor activity programmes for amateur radio, Spothole differentiates itself by supporting a large number of data sources, and by being "API first" rather than just providing a web front-end. This allows other software to be built on top of it.</p>
|
<p>Spothole is a utility to aggregate "spots" from amateur radio DX clusters and xOTA spotting sites, and provide an open JSON API as well as a website to browse the data.</p>
|
||||||
<p>The API is deliberately well-defined with an <a href="/apidocs/openapi.yml">OpenAPI specification</a> and <a href="/apidocs">API documentation</a>. The API delivers spots in a consistent format regardless of the data source, freeing developers from needing to know how each individual data source presents its data.</p>
|
<p>While there are several other web-based interfaces to DX clusters, and sites that aggregate spots from various outdoor activity programmes for amateur radio, Spothole differentiates itself by supporting a large number of data sources, and by being "API first" rather than just providing a web front-end. This allows other software to be built on top of it.</p>
|
||||||
<p>Spothole itself is also open source, Public Domain licenced code that anyone can take and modify. <a href="https://git.ianrenton.com/ian/metaspot/">The source code is here</a>. If you want to run your own copy of Spothole, or start modifying it for your own purposes, the <a href="https://git.ianrenton.com/ian/spothole/src/branch/main/README.md">README file</a> contains a description of how the software works and how it's laid out, as well as instructions for configuring systemd, nginx and anything else you might need to run your own server.</p>
|
<p>The API is deliberately well-defined with an <a href="/apidocs/openapi.yml">OpenAPI specification</a> and <a href="/apidocs">API documentation</a>. The API delivers spots in a consistent format regardless of the data source, freeing developers from needing to know how each individual data source presents its data.</p>
|
||||||
<p>Supported data sources include DX Clusters, the Reverse Beacon Network (RBN), the APRS Internet Service (APRS-IS), POTA, SOTA, WWFF, GMA, WWBOTA, HEMA, and Parks 'n' Peaks.</p>
|
<p>Spothole itself is also open source, Public Domain licenced code that anyone can take and modify. <a href="https://git.ianrenton.com/ian/metaspot/">The source code is here</a>. If you want to run your own copy of Spothole, or start modifying it for your own purposes, the <a href="https://git.ianrenton.com/ian/spothole/src/branch/main/README.md">README file</a> contains a description of how the software works and how it's laid out, as well as instructions for configuring systemd, nginx and anything else you might need to run your own server.</p>
|
||||||
<p>The software was written by <a href="https://ianrenton.com">Ian Renton, MØTRT</a> and other contributors. Full details are available in the README.</p>
|
<p>Supported data sources include DX Clusters, the Reverse Beacon Network (RBN), the APRS Internet Service (APRS-IS), POTA, SOTA, WWFF, GMA, WWBOTA, HEMA, and Parks 'n' Peaks.</p>
|
||||||
<p>This server is running Spothole version {{software_version}}.</p>
|
<p>The software was written by <a href="https://ianrenton.com">Ian Renton, MØTRT</a> and other contributors. Full details are available in the README.</p>
|
||||||
<h2 id="faq" class="mt-4">FAQ</h2>
|
<p>This server is running Spothole version {{software_version}}.</p>
|
||||||
<h4 class="mt-4">"Spots"? "DX Clusters"? What does any of this mean?</h4>
|
<h2 id="faq" class="mt-4">FAQ</h2>
|
||||||
<p>This is a tool for amateur ("ham") radio users. Many amateur radio operators like to make contacts with others who are doing something more interesting than sitting in their home "shack", such as people in rarely-seen countries, remote islands, or on mountaintops. Such operators are often "spotted", i.e. when someone speaks to them, they will put the details such as their operating frequency into an online system, to let others know where to find them. A DX Cluster is one type of those systems. Most outdoor radio awards programmes, such as "Parks on the Air" (POTA) have their own websites for posting spots.</p>
|
<h4 class="mt-4">"Spots"? "DX Clusters"? What does any of this mean?</h4>
|
||||||
<p>Spothole is an "aggregator" for those spots, so it checks lots of different services for data, and brings it all together in one place. So no matter what kinds of interesting spots you are looking for, you can find them here.</p>
|
<p>This is a tool for amateur ("ham") radio users. Many amateur radio operators like to make contacts with others who are doing something more interesting than sitting in their home "shack", such as people in rarely-seen countries, remote islands, or on mountaintops. Such operators are often "spotted", i.e. when someone speaks to them, they will put the details such as their operating frequency into an online system, to let others know where to find them. A DX Cluster is one type of those systems. Most outdoor radio awards programmes, such as "Parks on the Air" (POTA) have their own websites for posting spots.</p>
|
||||||
<p>As well as spots, it also provides a similar feed of "alerts". This is where amateur radio users who are going to interesting places soon will announce their intentions.</p>
|
<p>Spothole is an "aggregator" for those spots, so it checks lots of different services for data, and brings it all together in one place. So no matter what kinds of interesting spots you are looking for, you can find them here.</p>
|
||||||
<h4 class="mt-4">What are "DX", "DE" and modes?</h4>
|
<p>As well as spots, it also provides a similar feed of "alerts". This is where amateur radio users who are going to interesting places soon will announce their intentions.</p>
|
||||||
<p>In amateur radio terminology, the "DX" contact is the "interesting" one that is using the frequency shown. They might be on a remote island or just in a local park, but either way it's interesting enough that someone has "spotted" them. The callsign listed under "DE" is the person who spotted the "DX" operator. "Modes" are the type of communication they are using. You might see "CW" which is Morse Code, or voice "modes" like SSB or FM, or more exotic "data" modes which are used for computer-to-computer communication.</p>
|
<h4 class="mt-4">What are "DX", "DE" and modes?</h4>
|
||||||
<h4 class="mt-4">How is this better than DXheat, DXsummit, POTA's own website, etc?</h4>
|
<p>In amateur radio terminology, the "DX" contact is the "interesting" one that is using the frequency shown. They might be on a remote island or just in a local park, but either way it's interesting enough that someone has "spotted" them. The callsign listed under "DE" is the person who spotted the "DX" operator. "Modes" are the type of communication they are using. You might see "CW" which is Morse Code, or voice "modes" like SSB or FM, or more exotic "data" modes which are used for computer-to-computer communication.</p>
|
||||||
<p>It's probably not? But it's nice to have choice.</p>
|
<h4 class="mt-4">How is this better than DXheat, DXsummit, POTA's own website, etc?</h4>
|
||||||
<p>I think it's got two key advantages over those sites:</p>
|
<p>It's probably not? But it's nice to have choice.</p>
|
||||||
<ol><li>It provides a public, <a href="/apidocs">well-documented API</a> with an <a href="/apidocs/openapi.yml">OpenAPI specification</a>. Other sites don't have official APIs or don't bother documenting them publicly, because they want people to use their web page. I like Spothole's web page, but you don't have to use it—if you're a programmer, you can build your own software on Spothole's API. Spothole does the hard work of taking all the various data sources and providing a consistent, well-documented data set. You can then do the fun bit of writing your own application.</li>
|
<p>I think it's got two key advantages over those sites:</p>
|
||||||
<li>It grabs data from a lot more sources, and it's easy to add more. Since it's open source, anyone can contribute a new data source and share it with the community.</li></ol>
|
<ol><li>It provides a public, <a href="/apidocs">well-documented API</a> with an <a href="/apidocs/openapi.yml">OpenAPI specification</a>. Other sites don't have official APIs or don't bother documenting them publicly, because they want people to use their web page. I like Spothole's web page, but you don't have to use it—if you're a programmer, you can build your own software on Spothole's API. Spothole does the hard work of taking all the various data sources and providing a consistent, well-documented data set. You can then do the fun bit of writing your own application.</li>
|
||||||
<h4 class="mt-4">Why does this website ask me if I want to install it?</h4>
|
<li>It grabs data from a lot more sources, and it's easy to add more. Since it's open source, anyone can contribute a new data source and share it with the community.</li></ol>
|
||||||
<p>Spothole is a Progressive Web App, which means you can install it on an Android or iOS device by opening the site in Chrome or Safari respectively, and clicking "Install" on the pop-up panel. It'll only prompt you once, so if you dismiss the prompt and change your mind, you'll find an Install / Add to Home Screen option on your browser's menu.</p>
|
<h4 class="mt-4">Why does this website ask me if I want to install it?</h4>
|
||||||
<p>Installing Spothole on your phone is completely optional, the website works exactly the same way as the "app" does.</p>
|
<p>Spothole is a Progressive Web App, which means you can install it on an Android or iOS device by opening the site in Chrome or Safari respectively, and clicking "Install" on the pop-up panel. It'll only prompt you once, so if you dismiss the prompt and change your mind, you'll find an Install / Add to Home Screen option on your browser's menu.</p>
|
||||||
<h4 class="mt-4">What licence does Spothole use?</h4>
|
<p>Installing Spothole on your phone is completely optional, the website works exactly the same way as the "app" does.</p>
|
||||||
<p>Spothole's source code is licenced under the Public Domain. You can write a Spothole client, run your own server, modify it however you like, you can claim you wrote it and charge people £1000 for a copy, I don't really mind. (Please don't do the last one. But if you're using my code for something cool, it would be nice to hear from you!)</p>
|
<h4 class="mt-4">What licence does Spothole use?</h4>
|
||||||
<h2 id="privacy" class="mt-4">Privacy</h2>
|
<p>Spothole's source code is licenced under the Public Domain. You can write a Spothole client, run your own server, modify it however you like, you can claim you wrote it and charge people £1000 for a copy, I don't really mind. (Please don't do the last one. But if you're using my code for something cool, it would be nice to hear from you!)</p>
|
||||||
<p>Spothole collects no data about you, and there is no way to enter personally identifying information into the site apart from by spotting and alerting through Spothole or the various services it connects to. All spots and alerts are "timed out" and deleted from the system after a set interval, which by default is one hour for spots and one week for alerts.</p>
|
<h2 id="privacy" class="mt-4">Privacy</h2>
|
||||||
<p>Settings you select from Spothole's menus are sent to the server, in order to provide the data with the requested filters. They are also stored in your browser's local storage, so that your preferences are remembered between sessions.</p>
|
<p>Spothole collects no data about you, and there is no way to enter personally identifying information into the site apart from by spotting and alerting through Spothole or the various services it connects to. All spots and alerts are "timed out" and deleted from the system after a set interval, which by default is one hour for spots and one week for alerts.</p>
|
||||||
<p>There are no trackers, no ads, and no cookies.</p>
|
<p>Settings you select from Spothole's menus are sent to the server, in order to provide the data with the requested filters. They are also stored in your browser's local storage, so that your preferences are remembered between sessions.</p>
|
||||||
<p>Spothole is open source, so you can audit <a href="https://git.ianrenton.com/ian/spothole">the code</a> if you like.</p>
|
<p>There are no trackers, no ads, and no cookies.</p>
|
||||||
|
<p>Spothole is open source, so you can audit <a href="https://git.ianrenton.com/ian/spothole">the code</a> if you like.</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>$(document).ready(function() { $("#nav-link-about").addClass("active"); }); <!-- highlight active page in nav --></script>
|
<script>$(document).ready(function() { $("#nav-link-about").addClass("active"); }); <!-- highlight active page in nav --></script>
|
||||||
@@ -1,149 +1,151 @@
|
|||||||
% rebase('webpage_base.tpl')
|
% rebase('webpage_base.tpl')
|
||||||
|
|
||||||
<div class="mt-3">
|
<div class="container main-container mobile-no-gutters">
|
||||||
<div class="row">
|
<div class="mt-3">
|
||||||
<div class="col-auto me-auto pt-3">
|
<div class="row">
|
||||||
<p id="timing-container">Loading...</p>
|
<div class="col-auto me-auto pt-3">
|
||||||
</div>
|
<p id="timing-container">Loading...</p>
|
||||||
<div class="col-auto">
|
</div>
|
||||||
<p class="d-inline-flex gap-1">
|
<div class="col-auto">
|
||||||
<button id="filters-button" type="button" class="btn btn-outline-primary" data-bs-toggle="button" onclick="toggleFiltersPanel();"><i class="fa-solid fa-filter"></i> Filters</button>
|
<p class="d-inline-flex gap-1">
|
||||||
<button id="display-button" type="button" class="btn btn-outline-primary" data-bs-toggle="button" onclick="toggleDisplayPanel();"><i class="fa-solid fa-desktop"></i> Display</button>
|
<button id="filters-button" type="button" class="btn btn-outline-primary" data-bs-toggle="button" onclick="toggleFiltersPanel();"><i class="fa-solid fa-filter"></i> Filters</button>
|
||||||
</p>
|
<button id="display-button" type="button" class="btn btn-outline-primary" data-bs-toggle="button" onclick="toggleDisplayPanel();"><i class="fa-solid fa-desktop"></i> Display</button>
|
||||||
</div>
|
</p>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="filters-area" class="appearing-panel card mb-3">
|
|
||||||
<div class="card-header text-white bg-primary">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-auto me-auto">
|
|
||||||
Filters
|
|
||||||
</div>
|
|
||||||
<div class="col-auto d-inline-flex">
|
|
||||||
<button id="close-filters-button" type="button" class="btn-close btn-close-white" aria-label="Close" onclick="closeFiltersPanel();"></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
|
||||||
<div class="row row-cols-1 row-cols-md-3 g-4">
|
<div id="filters-area" class="appearing-panel card mb-3">
|
||||||
<div class="col">
|
<div class="card-header text-white bg-primary">
|
||||||
<div class="card">
|
<div class="row">
|
||||||
<div class="card-body">
|
<div class="col-auto me-auto">
|
||||||
<h5 class="card-title">DX Continent</h5>
|
Filters
|
||||||
<p id="dx-continent-options" class="card-text spothole-card-text"></p>
|
</div>
|
||||||
</div>
|
<div class="col-auto d-inline-flex">
|
||||||
|
<button id="close-filters-button" type="button" class="btn-close btn-close-white" aria-label="Close" onclick="closeFiltersPanel();"></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
|
||||||
<div class="card">
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title">Sources</h5>
|
<div class="row row-cols-1 row-cols-md-3 g-4">
|
||||||
<p id="source-options" class="card-text spothole-card-text"></p>
|
<div class="col">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title">DX Continent</h5>
|
||||||
|
<p id="dx-continent-options" class="card-text spothole-card-text"></p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="col">
|
||||||
<div class="col">
|
<div class="card">
|
||||||
<div class="card">
|
<div class="card-body">
|
||||||
<div class="card-body">
|
<h5 class="card-title">Sources</h5>
|
||||||
<h5 class="card-title">Duration Limit <i class='fa-solid fa-circle-question' title='Some users create long-duration alerts for the period they will be generally in and around xOTA references, when they are not indending to be on the air most of the time. Use this control to restrict the maximum duration of spots that the software will display, and exclude any with a long duration, to avoid these filling up the list. By default, we allow DXpeditions to be displayed even if they are longer than this limit, because on a DXpedition the operators typically ARE on the air most of the time.'></i></h5>
|
<p id="source-options" class="card-text spothole-card-text"></p>
|
||||||
<p class="card-text spothole-card-text">
|
</div>
|
||||||
Hide any alerts lasting more than:<br/>
|
</div>
|
||||||
<select id="max-duration" class="storeable-select form-select" onclick="filtersUpdated();" style="width: 8em; display: inline-block;">
|
</div>
|
||||||
<option value="10800">3 hours</option>
|
<div class="col">
|
||||||
<option value="43200">12 hours</option>
|
<div class="card">
|
||||||
<option value="86400" selected>24 hours</option>
|
<div class="card-body">
|
||||||
<option value="604800">1 week</option>
|
<h5 class="card-title">Duration Limit <i class='fa-solid fa-circle-question' title='Some users create long-duration alerts for the period they will be generally in and around xOTA references, when they are not indending to be on the air most of the time. Use this control to restrict the maximum duration of spots that the software will display, and exclude any with a long duration, to avoid these filling up the list. By default, we allow DXpeditions to be displayed even if they are longer than this limit, because on a DXpedition the operators typically ARE on the air most of the time.'></i></h5>
|
||||||
<option value="2419200">4 weeks</option>
|
<p class="card-text spothole-card-text">
|
||||||
<option value="9999999999">No limit</option>
|
Hide any alerts lasting more than:<br/>
|
||||||
</select>
|
<select id="max-duration" class="storeable-select form-select" onclick="filtersUpdated();" style="width: 8em; display: inline-block;">
|
||||||
</p>
|
<option value="10800">3 hours</option>
|
||||||
<p class='card-text spothole-card-text' style='line-height: 1.5em !important;'>
|
<option value="43200">12 hours</option>
|
||||||
<input class="form-check-input storeable-checkbox" type="checkbox" value="" onclick="filtersUpdated();" id="dxpeditions_skip_max_duration_check" checked><label class="form-check-label ms-2" for="dxpeditions_skip_max_duration_check">Allow DXpeditions that are longer</label>
|
<option value="86400" selected>24 hours</option>
|
||||||
</p>
|
<option value="604800">1 week</option>
|
||||||
|
<option value="2419200">4 weeks</option>
|
||||||
|
<option value="9999999999">No limit</option>
|
||||||
|
</select>
|
||||||
|
</p>
|
||||||
|
<p class='card-text spothole-card-text' style='line-height: 1.5em !important;'>
|
||||||
|
<input class="form-check-input storeable-checkbox" type="checkbox" value="" onclick="filtersUpdated();" id="dxpeditions_skip_max_duration_check" checked><label class="form-check-label ms-2" for="dxpeditions_skip_max_duration_check">Allow DXpeditions that are longer</label>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="display-area" class="appearing-panel card mb-3">
|
<div id="display-area" class="appearing-panel card mb-3">
|
||||||
<div class="card-header text-white bg-primary">
|
<div class="card-header text-white bg-primary">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-auto me-auto">
|
<div class="col-auto me-auto">
|
||||||
Display
|
Display
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto d-inline-flex">
|
<div class="col-auto d-inline-flex">
|
||||||
<button id="close-display-button" type="button" class="btn-close btn-close-white" aria-label="Close" onclick="closeDisplayPanel();"></button>
|
<button id="close-display-button" type="button" class="btn-close btn-close-white" aria-label="Close" onclick="closeDisplayPanel();"></button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
</div>
|
<div id="display-container" class="row row-cols-1 row-cols-md-3 g-4">
|
||||||
<div class="card-body">
|
<div class="col">
|
||||||
<div id="display-container" class="row row-cols-1 row-cols-md-3 g-4">
|
<div class="card">
|
||||||
<div class="col">
|
<div class="card-body">
|
||||||
<div class="card">
|
<h5 class="card-title">Time Zone</h5>
|
||||||
<div class="card-body">
|
<p class="card-text spothole-card-text"> Use
|
||||||
<h5 class="card-title">Time Zone</h5>
|
<select id="timeZone" class="storeable-select form-select ms-2 me-2 d-inline-block" oninput="timeZoneUpdated();" style="width: 8em; display: inline-block;">
|
||||||
<p class="card-text spothole-card-text"> Use
|
<option value="UTC" selected>UTC</option>
|
||||||
<select id="timeZone" class="storeable-select form-select ms-2 me-2 d-inline-block" oninput="timeZoneUpdated();" style="width: 8em; display: inline-block;">
|
<option value="local">Local time</option>
|
||||||
<option value="UTC" selected>UTC</option>
|
</select>
|
||||||
<option value="local">Local time</option>
|
</p>
|
||||||
</select>
|
</div>
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="col">
|
||||||
<div class="col">
|
<div class="card">
|
||||||
<div class="card">
|
<div class="card-body">
|
||||||
<div class="card-body">
|
<h5 class="card-title">Number of Alerts</h5>
|
||||||
<h5 class="card-title">Number of Alerts</h5>
|
<p class="card-text spothole-card-text">Show up to
|
||||||
<p class="card-text spothole-card-text">Show up to
|
<select id="alerts-to-fetch" class="storeable-select form-select ms-2" oninput="filtersUpdated();" style="width: 5em;display: inline-block;">
|
||||||
<select id="alerts-to-fetch" class="storeable-select form-select ms-2" oninput="filtersUpdated();" style="width: 5em;display: inline-block;">
|
<option value="25">25</option>
|
||||||
<option value="25">25</option>
|
<option value="50">50</option>
|
||||||
<option value="50">50</option>
|
<option value="100" selected>100</option>
|
||||||
<option value="100" selected>100</option>
|
<option value="200">200</option>
|
||||||
<option value="200">200</option>
|
<option value="500">500</option>
|
||||||
<option value="500">500</option>
|
</select>
|
||||||
</select>
|
alerts
|
||||||
alerts
|
</p>
|
||||||
</p>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="col">
|
||||||
<div class="col">
|
<div class="card">
|
||||||
<div class="card">
|
<div class="card-body">
|
||||||
<div class="card-body">
|
<h5 class="card-title">Table Data</h5>
|
||||||
<h5 class="card-title">Table Data</h5>
|
<div class="form-group">
|
||||||
<div class="form-group">
|
<div class="form-check form-check-inline">
|
||||||
<div class="form-check form-check-inline">
|
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowStartTime" value="tableShowStartTime" oninput="columnsUpdated();" checked>
|
||||||
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowStartTime" value="tableShowStartTime" oninput="columnsUpdated();" checked>
|
<label class="form-check-label" for="tableShowStartTime">Start Time</label>
|
||||||
<label class="form-check-label" for="tableShowStartTime">Start Time</label>
|
</div>
|
||||||
</div>
|
<div class="form-check form-check-inline">
|
||||||
<div class="form-check form-check-inline">
|
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowEndTime" value="tableShowEndTime" oninput="columnsUpdated();" checked>
|
||||||
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowEndTime" value="tableShowEndTime" oninput="columnsUpdated();" checked>
|
<label class="form-check-label" for="tableShowEndTime">End Time</label>
|
||||||
<label class="form-check-label" for="tableShowEndTime">End Time</label>
|
</div>
|
||||||
</div>
|
<div class="form-check form-check-inline">
|
||||||
<div class="form-check form-check-inline">
|
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowDX" value="tableShowDX" oninput="columnsUpdated();" checked>
|
||||||
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowDX" value="tableShowDX" oninput="columnsUpdated();" checked>
|
<label class="form-check-label" for="tableShowDX">DX</label>
|
||||||
<label class="form-check-label" for="tableShowDX">DX</label>
|
</div>
|
||||||
</div>
|
<div class="form-check form-check-inline">
|
||||||
<div class="form-check form-check-inline">
|
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowFreqsModes" value="tableShowFreqsModes" oninput="columnsUpdated();" checked>
|
||||||
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowFreqsModes" value="tableShowFreqsModes" oninput="columnsUpdated();" checked>
|
<label class="form-check-label" for="tableShowFreqsModes">Frequencies & Modes</label>
|
||||||
<label class="form-check-label" for="tableShowFreqsModes">Frequencies & Modes</label>
|
</div>
|
||||||
</div>
|
<div class="form-check form-check-inline">
|
||||||
<div class="form-check form-check-inline">
|
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowComment" value="tableShowComment" oninput="columnsUpdated();" checked>
|
||||||
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowComment" value="tableShowComment" oninput="columnsUpdated();" checked>
|
<label class="form-check-label" for="tableShowComment">Comment</label>
|
||||||
<label class="form-check-label" for="tableShowComment">Comment</label>
|
</div>
|
||||||
</div>
|
<div class="form-check form-check-inline">
|
||||||
<div class="form-check form-check-inline">
|
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowSource" value="tableShowSource" oninput="columnsUpdated();" checked>
|
||||||
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowSource" value="tableShowSource" oninput="columnsUpdated();" checked>
|
<label class="form-check-label" for="tableShowSource">Source</label>
|
||||||
<label class="form-check-label" for="tableShowSource">Source</label>
|
</div>
|
||||||
</div>
|
<div class="form-check form-check-inline">
|
||||||
<div class="form-check form-check-inline">
|
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowRef" value="tableShowRef" oninput="columnsUpdated();" checked>
|
||||||
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowRef" value="tableShowRef" oninput="columnsUpdated();" checked>
|
<label class="form-check-label" for="tableShowRef">Ref.</label>
|
||||||
<label class="form-check-label" for="tableShowRef">Ref.</label>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -151,10 +153,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="table-container"></div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="table-container"></div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="/js/common.js"></script>
|
<script src="/js/common.js"></script>
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
% rebase('webpage_base.tpl')
|
% rebase('webpage_base.tpl')
|
||||||
|
|
||||||
<redoc spec-url="/apidocs/openapi.yml"></redoc>
|
<div class="container main-container">
|
||||||
|
<redoc spec-url="/apidocs/openapi.yml"></redoc>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script src="https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js"> </script>
|
<script src="https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js"> </script>
|
||||||
<script>$(document).ready(function() { $("#nav-link-api").addClass("active"); }); <!-- highlight active page in nav --></script>
|
<script>$(document).ready(function() { $("#nav-link-api").addClass("active"); }); <!-- highlight active page in nav --></script>
|
||||||
@@ -67,6 +67,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
</div>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
|
|
||||||
@@ -74,6 +75,7 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
<div class="hideonmobile hideonmap">
|
<div class="hideonmobile hideonmap">
|
||||||
<footer class="d-flex flex-wrap justify-content-between align-items-center py-3 my-4 border-top">
|
<footer class="d-flex flex-wrap justify-content-between align-items-center py-3 my-4 border-top">
|
||||||
<p class="col-md-4 mb-0 text-body-secondary">Made with love by <a href="https://ianrenton.com" class="text-body-secondary">Ian, MØTRT</a> and other contributors.</p>
|
<p class="col-md-4 mb-0 text-body-secondary">Made with love by <a href="https://ianrenton.com" class="text-body-secondary">Ian, MØTRT</a> and other contributors.</p>
|
||||||
|
|||||||
@@ -1,115 +1,117 @@
|
|||||||
% rebase('webpage_base.tpl')
|
% rebase('webpage_base.tpl')
|
||||||
|
|
||||||
<div id="map">
|
<div class="container main-container mobile-no-gutters">
|
||||||
<div class="mt-3 px-3" style="z-index: 1002; position: relative;">
|
<div id="map">
|
||||||
<div class="row">
|
<div class="mt-3 px-3" style="z-index: 1002; position: relative;">
|
||||||
<div class="col-auto me-auto pt-3"></div>
|
<div class="row">
|
||||||
<div class="col-auto">
|
<div class="col-auto me-auto pt-3"></div>
|
||||||
<p class="d-inline-flex gap-1">
|
<div class="col-auto">
|
||||||
<button id="filters-button" type="button" class="btn btn-outline-primary" data-bs-toggle="button" onclick="toggleFiltersPanel();"><i class="fa-solid fa-filter"></i> Filters</button>
|
<p class="d-inline-flex gap-1">
|
||||||
<button id="display-button" type="button" class="btn btn-outline-primary" data-bs-toggle="button" onclick="toggleDisplayPanel();"><i class="fa-solid fa-desktop"></i> Display</button>
|
<button id="filters-button" type="button" class="btn btn-outline-primary" data-bs-toggle="button" onclick="toggleFiltersPanel();"><i class="fa-solid fa-filter"></i> Filters</button>
|
||||||
</p>
|
<button id="display-button" type="button" class="btn btn-outline-primary" data-bs-toggle="button" onclick="toggleDisplayPanel();"><i class="fa-solid fa-desktop"></i> Display</button>
|
||||||
</div>
|
</p>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="filters-area" class="appearing-panel card mb-3">
|
|
||||||
<div class="card-header text-white bg-primary">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-auto me-auto">
|
|
||||||
Filters
|
|
||||||
</div>
|
|
||||||
<div class="col-auto d-inline-flex">
|
|
||||||
<button id="close-filters-button" type="button" class="btn-close btn-close-white" aria-label="Close" onclick="closeFiltersPanel();"></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
|
||||||
<div class="row row-cols-1 g-4 mb-4">
|
<div id="filters-area" class="appearing-panel card mb-3">
|
||||||
<div class="col">
|
<div class="card-header text-white bg-primary">
|
||||||
<div class="card">
|
<div class="row">
|
||||||
<div class="card-body">
|
<div class="col-auto me-auto">
|
||||||
<h5 class="card-title">Bands</h5>
|
Filters
|
||||||
<p id="band-options" class="card-text spothole-card-text"></p>
|
</div>
|
||||||
</div>
|
<div class="col-auto d-inline-flex">
|
||||||
|
<button id="close-filters-button" type="button" class="btn-close btn-close-white" aria-label="Close" onclick="closeFiltersPanel();"></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="row row-cols-1 row-cols-md-4 g-4">
|
<div class="card-body">
|
||||||
<div class="col">
|
<div class="row row-cols-1 g-4 mb-4">
|
||||||
<div class="card">
|
<div class="col">
|
||||||
<div class="card-body">
|
<div class="card">
|
||||||
<h5 class="card-title">DX Continent</h5>
|
<div class="card-body">
|
||||||
<p id="dx-continent-options" class="card-text spothole-card-text"></p>
|
<h5 class="card-title">Bands</h5>
|
||||||
|
<p id="band-options" class="card-text spothole-card-text"></p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="row row-cols-1 row-cols-md-4 g-4">
|
||||||
<div class="card">
|
<div class="col">
|
||||||
<div class="card-body">
|
<div class="card">
|
||||||
<h5 class="card-title">DE Continent</h5>
|
<div class="card-body">
|
||||||
<p id="de-continent-options" class="card-text spothole-card-text"></p>
|
<h5 class="card-title">DX Continent</h5>
|
||||||
|
<p id="dx-continent-options" class="card-text spothole-card-text"></p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="col">
|
||||||
<div class="col">
|
<div class="card">
|
||||||
<div class="card">
|
<div class="card-body">
|
||||||
<div class="card-body">
|
<h5 class="card-title">DE Continent</h5>
|
||||||
<h5 class="card-title">Modes</h5>
|
<p id="de-continent-options" class="card-text spothole-card-text"></p>
|
||||||
<p id="mode-options" class="card-text spothole-card-text"></p>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="col">
|
||||||
<div class="col">
|
<div class="card">
|
||||||
<div class="card">
|
<div class="card-body">
|
||||||
<div class="card-body">
|
<h5 class="card-title">Modes</h5>
|
||||||
<h5 class="card-title">Sources</h5>
|
<p id="mode-options" class="card-text spothole-card-text"></p>
|
||||||
<p id="source-options" class="card-text spothole-card-text"></p>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title">Sources</h5>
|
||||||
|
<p id="source-options" class="card-text spothole-card-text"></p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="display-area" class="appearing-panel card mb-3">
|
<div id="display-area" class="appearing-panel card mb-3">
|
||||||
<div class="card-header text-white bg-primary">
|
<div class="card-header text-white bg-primary">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-auto me-auto">
|
<div class="col-auto me-auto">
|
||||||
Display
|
Display
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto d-inline-flex">
|
<div class="col-auto d-inline-flex">
|
||||||
<button id="close-display-button" type="button" class="btn-close btn-close-white" aria-label="Close" onclick="closeDisplayPanel();"></button>
|
<button id="close-display-button" type="button" class="btn-close btn-close-white" aria-label="Close" onclick="closeDisplayPanel();"></button>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div id="display-container" class="row row-cols-1 row-cols-md-4 g-4">
|
|
||||||
<div class="col">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
<h5 class="card-title">Spot Age</h5>
|
|
||||||
<p class="card-text spothole-card-text">Last
|
|
||||||
<select id="max-spot-age" class="storeable-select form-select ms-2 me-2 d-inline-block" oninput="filtersUpdated();" style="width: 5em; display: inline-block;">
|
|
||||||
<option value="300">5</option>
|
|
||||||
<option value="600">10</option>
|
|
||||||
<option value="1800" selected>30</option>
|
|
||||||
<option value="3600">60</option>
|
|
||||||
</select>
|
|
||||||
minutes
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
|
||||||
<div class="card">
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title">Map Features</h5>
|
<div id="display-container" class="row row-cols-1 row-cols-md-4 g-4">
|
||||||
<div class="form-group">
|
<div class="col">
|
||||||
<div class="form-check form-check-inline">
|
<div class="card">
|
||||||
<input class="form-check-input storeable-checkbox" type="checkbox" id="mapShowGeodesics" value="mapShowGeodesics" oninput="displayUpdated();">
|
<div class="card-body">
|
||||||
<label class="form-check-label" for="mapShowGeodesics">Geodesic Lines</label>
|
<h5 class="card-title">Spot Age</h5>
|
||||||
|
<p class="card-text spothole-card-text">Last
|
||||||
|
<select id="max-spot-age" class="storeable-select form-select ms-2 me-2 d-inline-block" oninput="filtersUpdated();" style="width: 5em; display: inline-block;">
|
||||||
|
<option value="300">5</option>
|
||||||
|
<option value="600">10</option>
|
||||||
|
<option value="1800" selected>30</option>
|
||||||
|
<option value="3600">60</option>
|
||||||
|
</select>
|
||||||
|
minutes
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title">Map Features</h5>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input class="form-check-input storeable-checkbox" type="checkbox" id="mapShowGeodesics" value="mapShowGeodesics" oninput="displayUpdated();">
|
||||||
|
<label class="form-check-label" for="mapShowGeodesics">Geodesic Lines</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,240 +1,242 @@
|
|||||||
% rebase('webpage_base.tpl')
|
% rebase('webpage_base.tpl')
|
||||||
|
|
||||||
<div id="intro-box" class="mt-3">
|
<div class="container main-container mobile-no-gutters">
|
||||||
<div class="alert alert-primary alert-dismissible fade show" role="alert">
|
<div id="intro-box" class="mt-3">
|
||||||
<i class="fa-solid fa-circle-info"></i> <strong>What is Spothole?</strong><br/>Spothole is an aggregator of amateur radio spots from DX clusters and outdoor activity programmes. It's free for anyone to use and includes an API that developers can build other applications on. For more information, check out the <a href="/about" class="alert-link">"About" page</a>. If that sounds like nonsense to you, you can visit <a href="/about#faq" class="alert-link">the FAQ section</a> to learn more.
|
<div class="alert alert-primary alert-dismissible fade show" role="alert">
|
||||||
<button type="button" id="intro-box-dismiss" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
<i class="fa-solid fa-circle-info"></i> <strong>What is Spothole?</strong><br/>Spothole is an aggregator of amateur radio spots from DX clusters and outdoor activity programmes. It's free for anyone to use and includes an API that developers can build other applications on. For more information, check out the <a href="/about" class="alert-link">"About" page</a>. If that sounds like nonsense to you, you can visit <a href="/about#faq" class="alert-link">the FAQ section</a> to learn more.
|
||||||
</div>
|
<button type="button" id="intro-box-dismiss" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-3">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-auto me-auto pt-3">
|
|
||||||
<p id="timing-container">Loading...</p>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto">
|
|
||||||
<p class="d-inline-flex gap-1">
|
|
||||||
<button id="add-spot-button" type="button" class="btn btn-outline-primary" data-bs-toggle="button" onclick="toggleAddSpotPanel();"><i class="fa-solid fa-comment"></i> Add Spot</button>
|
|
||||||
<button id="filters-button" type="button" class="btn btn-outline-primary" data-bs-toggle="button" onclick="toggleFiltersPanel();"><i class="fa-solid fa-filter"></i> Filters</button>
|
|
||||||
<button id="display-button" type="button" class="btn btn-outline-primary" data-bs-toggle="button" onclick="toggleDisplayPanel();"><i class="fa-solid fa-desktop"></i> Display</button>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="filters-area" class="appearing-panel card mb-3">
|
<div class="mt-3">
|
||||||
<div class="card-header text-white bg-primary">
|
<div class="row">
|
||||||
<div class="row">
|
<div class="col-auto me-auto pt-3">
|
||||||
<div class="col-auto me-auto">
|
<p id="timing-container">Loading...</p>
|
||||||
Filters
|
|
||||||
</div>
|
|
||||||
<div class="col-auto d-inline-flex">
|
|
||||||
<button id="close-filters-button" type="button" class="btn-close btn-close-white" aria-label="Close" onclick="closeFiltersPanel();"></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-auto">
|
||||||
</div>
|
<p class="d-inline-flex gap-1">
|
||||||
<div class="card-body">
|
<button id="add-spot-button" type="button" class="btn btn-outline-primary" data-bs-toggle="button" onclick="toggleAddSpotPanel();"><i class="fa-solid fa-comment"></i> Add Spot</button>
|
||||||
<div class="row row-cols-1 g-4 mb-4">
|
<button id="filters-button" type="button" class="btn btn-outline-primary" data-bs-toggle="button" onclick="toggleFiltersPanel();"><i class="fa-solid fa-filter"></i> Filters</button>
|
||||||
<div class="col">
|
<button id="display-button" type="button" class="btn btn-outline-primary" data-bs-toggle="button" onclick="toggleDisplayPanel();"><i class="fa-solid fa-desktop"></i> Display</button>
|
||||||
<div class="card">
|
</p>
|
||||||
<div class="card-body">
|
|
||||||
<h5 class="card-title">Bands</h5>
|
|
||||||
<p id="band-options" class="card-text spothole-card-text"></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row row-cols-1 row-cols-md-4 g-4">
|
|
||||||
<div class="col">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
<h5 class="card-title">DX Continent</h5>
|
|
||||||
<p id="dx-continent-options" class="card-text spothole-card-text"></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
<h5 class="card-title">DE Continent</h5>
|
|
||||||
<p id="de-continent-options" class="card-text spothole-card-text"></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
<h5 class="card-title">Modes</h5>
|
|
||||||
<p id="mode-options" class="card-text spothole-card-text"></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
<h5 class="card-title">Sources</h5>
|
|
||||||
<p id="source-options" class="card-text spothole-card-text"></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="display-area" class="appearing-panel card mb-3">
|
<div id="filters-area" class="appearing-panel card mb-3">
|
||||||
<div class="card-header text-white bg-primary">
|
<div class="card-header text-white bg-primary">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-auto me-auto">
|
<div class="col-auto me-auto">
|
||||||
Display
|
Filters
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto d-inline-flex">
|
<div class="col-auto d-inline-flex">
|
||||||
<button id="close-display-button" type="button" class="btn-close btn-close-white" aria-label="Close" onclick="closeDisplayPanel();"></button>
|
<button id="close-filters-button" type="button" class="btn-close btn-close-white" aria-label="Close" onclick="closeFiltersPanel();"></button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
</div>
|
<div class="row row-cols-1 g-4 mb-4">
|
||||||
<div class="card-body">
|
<div class="col">
|
||||||
<div id="display-container" class="row row-cols-1 row-cols-md-4 g-4">
|
<div class="card">
|
||||||
<div class="col">
|
<div class="card-body">
|
||||||
<div class="card">
|
<h5 class="card-title">Bands</h5>
|
||||||
<div class="card-body">
|
<p id="band-options" class="card-text spothole-card-text"></p>
|
||||||
<h5 class="card-title">Time Zone</h5>
|
|
||||||
<p class="card-text spothole-card-text"> Use
|
|
||||||
<select id="timeZone" class="storeable-select form-select ms-2 me-2 d-inline-block" oninput="timeZoneUpdated();" style="width: 8em; display: inline-block;">
|
|
||||||
<option value="UTC" selected>UTC</option>
|
|
||||||
<option value="local">Local time</option>
|
|
||||||
</select>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
<h5 class="card-title">Number of Spots</h5>
|
|
||||||
<p class="card-text spothole-card-text">Show up to
|
|
||||||
<select id="spots-to-fetch" class="storeable-select form-select ms-2 me-2 d-inline-block" oninput="filtersUpdated();" style="width: 5em; display: inline-block;">
|
|
||||||
<option value="10">10</option>
|
|
||||||
<option value="25">25</option>
|
|
||||||
<option value="50" selected>50</option>
|
|
||||||
<option value="100">100</option>
|
|
||||||
</select>
|
|
||||||
spots
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
<h5 class="card-title">Table Columns</h5>
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="form-check form-check-inline">
|
|
||||||
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowTime" value="tableShowTime" oninput="columnsUpdated();" checked>
|
|
||||||
<label class="form-check-label" for="tableShowTime">Time</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check form-check-inline">
|
|
||||||
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowDX" value="tableShowDX" oninput="columnsUpdated();" checked>
|
|
||||||
<label class="form-check-label" for="tableShowDX">DX</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check form-check-inline">
|
|
||||||
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowFreq" value="tableShowFreq" oninput="columnsUpdated();" checked>
|
|
||||||
<label class="form-check-label" for="tableShowFreq">Frequency</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check form-check-inline">
|
|
||||||
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowMode" value="tableShowMode" oninput="columnsUpdated();" checked>
|
|
||||||
<label class="form-check-label" for="tableShowMode">Mode</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check form-check-inline">
|
|
||||||
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowComment" value="tableShowComment" oninput="columnsUpdated();" checked>
|
|
||||||
<label class="form-check-label" for="tableShowComment">Comment</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check form-check-inline">
|
|
||||||
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowBearing" value="tableShowBearing" oninput="columnsUpdated();">
|
|
||||||
<label class="form-check-label" for="tableShowBearing">Bearing</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check form-check-inline">
|
|
||||||
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowSource" value="tableShowSource" oninput="columnsUpdated();" checked>
|
|
||||||
<label class="form-check-label" for="tableShowSource">Source</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check form-check-inline">
|
|
||||||
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowRef" value="tableShowRef" oninput="columnsUpdated();" checked>
|
|
||||||
<label class="form-check-label" for="tableShowRef">Ref.</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check form-check-inline">
|
|
||||||
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowDE" value="tableShowDE" oninput="columnsUpdated();" checked>
|
|
||||||
<label class="form-check-label" for="tableShowDE">DE</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="row row-cols-1 row-cols-md-4 g-4">
|
||||||
<div class="card">
|
<div class="col">
|
||||||
<div class="card-body">
|
<div class="card">
|
||||||
<h5 class="card-title">Location</h5>
|
<div class="card-body">
|
||||||
<div class="form-group spothole-card-text">
|
<h5 class="card-title">DX Continent</h5>
|
||||||
<label for="userGrid">Your grid:</label>
|
<p id="dx-continent-options" class="card-text spothole-card-text"></p>
|
||||||
<input type="text" class="storeable-text form-control" id="userGrid" placeholder="AA00aa" oninput="userGridUpdated();" style="width: 10em; display: inline-block;">
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title">DE Continent</h5>
|
||||||
|
<p id="de-continent-options" class="card-text spothole-card-text"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title">Modes</h5>
|
||||||
|
<p id="mode-options" class="card-text spothole-card-text"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title">Sources</h5>
|
||||||
|
<p id="source-options" class="card-text spothole-card-text"></p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="add-spot-area" class="appearing-panel card mb-3">
|
<div id="display-area" class="appearing-panel card mb-3">
|
||||||
<div class="card-header text-white bg-primary">
|
<div class="card-header text-white bg-primary">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-auto me-auto">
|
<div class="col-auto me-auto">
|
||||||
Add a Spot
|
Display
|
||||||
|
</div>
|
||||||
|
<div class="col-auto d-inline-flex">
|
||||||
|
<button id="close-display-button" type="button" class="btn-close btn-close-white" aria-label="Close" onclick="closeDisplayPanel();"></button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto d-inline-flex">
|
|
||||||
<button id="close-add-spot-button" type="button" class="btn-close btn-close-white" aria-label="Close" onclick="closeAddSpotPanel();"></button>
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div id="display-container" class="row row-cols-1 row-cols-md-4 g-4">
|
||||||
|
<div class="col">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title">Time Zone</h5>
|
||||||
|
<p class="card-text spothole-card-text"> Use
|
||||||
|
<select id="timeZone" class="storeable-select form-select ms-2 me-2 d-inline-block" oninput="timeZoneUpdated();" style="width: 8em; display: inline-block;">
|
||||||
|
<option value="UTC" selected>UTC</option>
|
||||||
|
<option value="local">Local time</option>
|
||||||
|
</select>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title">Number of Spots</h5>
|
||||||
|
<p class="card-text spothole-card-text">Show up to
|
||||||
|
<select id="spots-to-fetch" class="storeable-select form-select ms-2 me-2 d-inline-block" oninput="filtersUpdated();" style="width: 5em; display: inline-block;">
|
||||||
|
<option value="10">10</option>
|
||||||
|
<option value="25">25</option>
|
||||||
|
<option value="50" selected>50</option>
|
||||||
|
<option value="100">100</option>
|
||||||
|
</select>
|
||||||
|
spots
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title">Table Columns</h5>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowTime" value="tableShowTime" oninput="columnsUpdated();" checked>
|
||||||
|
<label class="form-check-label" for="tableShowTime">Time</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowDX" value="tableShowDX" oninput="columnsUpdated();" checked>
|
||||||
|
<label class="form-check-label" for="tableShowDX">DX</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowFreq" value="tableShowFreq" oninput="columnsUpdated();" checked>
|
||||||
|
<label class="form-check-label" for="tableShowFreq">Frequency</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowMode" value="tableShowMode" oninput="columnsUpdated();" checked>
|
||||||
|
<label class="form-check-label" for="tableShowMode">Mode</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowComment" value="tableShowComment" oninput="columnsUpdated();" checked>
|
||||||
|
<label class="form-check-label" for="tableShowComment">Comment</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowBearing" value="tableShowBearing" oninput="columnsUpdated();">
|
||||||
|
<label class="form-check-label" for="tableShowBearing">Bearing</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowSource" value="tableShowSource" oninput="columnsUpdated();" checked>
|
||||||
|
<label class="form-check-label" for="tableShowSource">Source</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowRef" value="tableShowRef" oninput="columnsUpdated();" checked>
|
||||||
|
<label class="form-check-label" for="tableShowRef">Ref.</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input class="form-check-input storeable-checkbox" type="checkbox" id="tableShowDE" value="tableShowDE" oninput="columnsUpdated();" checked>
|
||||||
|
<label class="form-check-label" for="tableShowDE">DE</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title">Location</h5>
|
||||||
|
<div class="form-group spothole-card-text">
|
||||||
|
<label for="userGrid">Your grid:</label>
|
||||||
|
<input type="text" class="storeable-text form-control" id="userGrid" placeholder="AA00aa" oninput="userGridUpdated();" style="width: 10em; display: inline-block;">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
|
||||||
<form class="row g-2">
|
|
||||||
<div class="col-auto">
|
|
||||||
<label for="add-spot-dx-call" class="form-label">DX Call</label>
|
|
||||||
<input type="text" class="form-control" id="add-spot-dx-call" placeholder="N0CALL" style="max-width: 8em;">
|
|
||||||
</div>
|
|
||||||
<div class="col-auto">
|
|
||||||
<label for="add-spot-freq" class="form-label">Frequency (kHz)</label>
|
|
||||||
<input type="text" class="form-control" id="add-spot-freq" placeholder="14100" style="max-width: 8em;">
|
|
||||||
</div>
|
|
||||||
<div class="col-auto">
|
|
||||||
<label for="add-spot-mode" class="form-label">Mode</label>
|
|
||||||
<input type="text" class="form-control" id="add-spot-mode" placeholder="SSB" style="max-width: 6em;">
|
|
||||||
</div>
|
|
||||||
<div class="col-auto">
|
|
||||||
<label for="add-spot-comment" class="form-label">Comment</label>
|
|
||||||
<input type="text" class="form-control" id="add-spot-comment" placeholder="59 TNX QSO 73" style="max-width: 12em;">
|
|
||||||
</div>
|
|
||||||
<div class="col-auto">
|
|
||||||
<label for="add-spot-de-call" class="form-label">Your Call</label>
|
|
||||||
<input type="text" class="form-control" id="add-spot-de-call" placeholder="N0CALL" style="max-width: 8em;">
|
|
||||||
</div>
|
|
||||||
<div class="col-auto">
|
|
||||||
<button type="button" class="btn btn-primary" style="margin-top: 2em;" onclick="addSpot();">Spot</button>
|
|
||||||
<span id="post-spot-result-good"></span>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<div id="post-spot-result-bad"></div>
|
<div id="add-spot-area" class="appearing-panel card mb-3">
|
||||||
|
<div class="card-header text-white bg-primary">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-auto me-auto">
|
||||||
|
Add a Spot
|
||||||
|
</div>
|
||||||
|
<div class="col-auto d-inline-flex">
|
||||||
|
<button id="close-add-spot-button" type="button" class="btn-close btn-close-white" aria-label="Close" onclick="closeAddSpotPanel();"></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="alert alert-warning alert-dismissible fade show mb-0 mt-4" role="alert">
|
</div>
|
||||||
Please note that spots added to Spothole are not currently sent "upstream" to DX clusters or xOTA spotting sites.
|
<div class="card-body">
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
<form class="row g-2">
|
||||||
|
<div class="col-auto">
|
||||||
|
<label for="add-spot-dx-call" class="form-label">DX Call</label>
|
||||||
|
<input type="text" class="form-control" id="add-spot-dx-call" placeholder="N0CALL" style="max-width: 8em;">
|
||||||
|
</div>
|
||||||
|
<div class="col-auto">
|
||||||
|
<label for="add-spot-freq" class="form-label">Frequency (kHz)</label>
|
||||||
|
<input type="text" class="form-control" id="add-spot-freq" placeholder="14100" style="max-width: 8em;">
|
||||||
|
</div>
|
||||||
|
<div class="col-auto">
|
||||||
|
<label for="add-spot-mode" class="form-label">Mode</label>
|
||||||
|
<input type="text" class="form-control" id="add-spot-mode" placeholder="SSB" style="max-width: 6em;">
|
||||||
|
</div>
|
||||||
|
<div class="col-auto">
|
||||||
|
<label for="add-spot-comment" class="form-label">Comment</label>
|
||||||
|
<input type="text" class="form-control" id="add-spot-comment" placeholder="59 TNX QSO 73" style="max-width: 12em;">
|
||||||
|
</div>
|
||||||
|
<div class="col-auto">
|
||||||
|
<label for="add-spot-de-call" class="form-label">Your Call</label>
|
||||||
|
<input type="text" class="form-control" id="add-spot-de-call" placeholder="N0CALL" style="max-width: 8em;">
|
||||||
|
</div>
|
||||||
|
<div class="col-auto">
|
||||||
|
<button type="button" class="btn btn-primary" style="margin-top: 2em;" onclick="addSpot();">Spot</button>
|
||||||
|
<span id="post-spot-result-good"></span>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div id="post-spot-result-bad"></div>
|
||||||
|
|
||||||
|
<div class="alert alert-warning alert-dismissible fade show mb-0 mt-4" role="alert">
|
||||||
|
Please note that spots added to Spothole are not currently sent "upstream" to DX clusters or xOTA spotting sites.
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="table-container"></div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="table-container"></div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="/js/common.js"></script>
|
<script src="/js/common.js"></script>
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
% rebase('webpage_base.tpl')
|
% rebase('webpage_base.tpl')
|
||||||
|
|
||||||
<div id="status-container" class="row row-cols-1 row-cols-md-4 g-4 mt-4"></div>
|
<div class="container main-container">
|
||||||
|
<div id="status-container" class="row row-cols-1 row-cols-md-4 g-4 mt-4"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script src="/js/common.js"></script>
|
<script src="/js/common.js"></script>
|
||||||
<script src="/js/status.js"></script>
|
<script src="/js/status.js"></script>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
/* GENERAL PAGE LAYOUT */
|
/* GENERAL PAGE LAYOUT */
|
||||||
|
|
||||||
div.container {
|
div.main-container {
|
||||||
display:grid;
|
display:grid;
|
||||||
grid-template-rows:auto 1fr auto;
|
grid-template-rows:auto 1fr auto;
|
||||||
grid-template-columns:100%;
|
grid-template-columns:100%;
|
||||||
@@ -155,6 +155,10 @@ a.leaflet-popup-callsign-link {
|
|||||||
.hideonmobile {
|
.hideonmobile {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
.mobile-no-gutters {
|
||||||
|
padding-left: 0 !important;
|
||||||
|
padding-right: 0 !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 992px) {
|
@media (min-width: 992px) {
|
||||||
|
|||||||
Reference in New Issue
Block a user