Compare commits
7 Commits
711f1dc845
...
85a104caa5
Author | SHA1 | Date | |
---|---|---|---|
85a104caa5 | |||
24b4f7db9f | |||
6c20bd7535 | |||
f56f401cc4 | |||
6d887f7743 | |||
46e7092cb7 | |||
8bdca176f0 |
1
Build.PL
1
Build.PL
@ -32,6 +32,7 @@ my $build = Module::Build->new(
|
||||
'UUID::URandom' => 0,
|
||||
'Crypt::Bcrypt' => 0,
|
||||
'DBIx::Class::TimeStamp' => 0,
|
||||
'DateTime::Format::HTTP' => 0,
|
||||
},
|
||||
);
|
||||
$build->create_build_script;
|
||||
|
@ -9,6 +9,7 @@
|
||||
<attributes>
|
||||
<attribute>hamburguesas</attribute>
|
||||
<attribute>pizzerias</attribute>
|
||||
<attribute>reparto-a-domicilio-comida</attribute>
|
||||
</attributes>
|
||||
<slug>hamburgueseria-la-ermita</slug>
|
||||
<content>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<post>
|
||||
<author>Burguillos.info</author>
|
||||
<date>2023-09-21T05:00+00:00</date>
|
||||
<date>2023-09-21T09:11+00:00</date>
|
||||
<title>Carta y menú de Bar el Polígono.</title>
|
||||
<ogdesc>Carta y menú de Bar el Polígono.</ogdesc>
|
||||
<img src="/img/bar-poligono.webp" bottom-preview="600"/>
|
||||
@ -11,6 +11,7 @@
|
||||
</attributes>
|
||||
<slug>bar-poligono</slug>
|
||||
<content>
|
||||
<h2 style="background: black; color: red;">Cerrado permanentemente.</h2>
|
||||
<img witdh="50%" alt="Puerta de la Bar el Poligono" style="border: solid 1px black" src="/img/bar-poligono.webp"/>
|
||||
|
||||
<p>El bar el polígono es un negocio de nueva apertura localizado en Calle Tomás Alba Edison número 8 donde antes se encontraba el Bar el Chori II.</p>
|
||||
|
11
generate_proto.sh
Normal file
11
generate_proto.sh
Normal file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
rm -rf ./js-src/generated/
|
||||
mkdir ./js-src/generated/
|
||||
protoc --plugin="protoc-gen-ts=./node_modules/.bin/protoc-gen-ts" \
|
||||
--plugin="protoc-gen-js=./node_modules/.bin/protoc-gen-js" \
|
||||
--ts_opt=esModuleInterop=true \
|
||||
--js_out="import_style=commonjs,binary:./js-src/generated" \
|
||||
--ts_out="./js-src/generated" \
|
||||
--proto_path="proto" \
|
||||
$(find proto/ -name '*.proto')
|
@ -20,6 +20,7 @@ import SelfPlayerUI from '@burguillosinfo/conquer/interface/self-player'
|
||||
import CreateNode from '@burguillosinfo/conquer/create-node'
|
||||
import MapState from '@burguillosinfo/conquer/map-state'
|
||||
import MapNode from '@burguillosinfo/conquer/map-node'
|
||||
import NewNodeUI from '@burguillosinfo/conquer/interface/new-node'
|
||||
|
||||
type StylesInterface = Record<string, Style>
|
||||
|
||||
|
29
js-src/conquer/interface/abstract-top-bar-interface.ts
Normal file
29
js-src/conquer/interface/abstract-top-bar-interface.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import Conquer from '@burguillosinfo/conquer'
|
||||
import ConquerInterface from '@burguillosinfo/conquer/interface'
|
||||
|
||||
export default abstract class AbstractTopBarInterface extends ConquerInterface {
|
||||
constructor() {
|
||||
super()
|
||||
const exitButton = this.getExitButton()
|
||||
exitButton.addEventListener('click', () => {
|
||||
this.runCallbacks('close')
|
||||
})
|
||||
}
|
||||
protected generateNodes(): HTMLElement[] {
|
||||
const newNode = this.getNodeFromTemplateId('conquer-interface-with-top-bar-template')
|
||||
return [newNode]
|
||||
}
|
||||
protected getMainNode(): HTMLElement {
|
||||
return this.getNodes()[0]
|
||||
}
|
||||
protected getExitButton(): HTMLElement {
|
||||
const maybeExitButton = this.getMainNode().querySelector('.conquer-exit-button')
|
||||
if (maybeExitButton === null || !(maybeExitButton instanceof HTMLElement)) {
|
||||
Conquer.fail('No exit button.')
|
||||
}
|
||||
return maybeExitButton
|
||||
}
|
||||
public generateInterfaceElementCentered(): HTMLElement {
|
||||
return this.getNodeFromTemplateId('conquer-interface-element-padded-template')
|
||||
}
|
||||
}
|
10
js-src/conquer/interface/new-node.ts
Normal file
10
js-src/conquer/interface/new-node.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import AbstractTopBarInterface from '@burguillosinfo/conquer/interface/abstract-top-bar-interface'
|
||||
import Conquer from '@burguillosinfo/conquer'
|
||||
|
||||
export default class NewNodeUI extends AbstractTopBarInterface {
|
||||
private coordinates: number[];
|
||||
constructor(coordinates: number[]) {
|
||||
super()
|
||||
this.coordinates = coordinates
|
||||
}
|
||||
}
|
@ -1,35 +1,23 @@
|
||||
import ConquerInterface from '@burguillosinfo/conquer/interface'
|
||||
import Conquer from '@burguillosinfo/conquer'
|
||||
import ConquerUser from '@burguillosinfo/conquer/user'
|
||||
import AbstractTopBarInterface from '@burguillosinfo/conquer/interface/abstract-top-bar-interface'
|
||||
|
||||
export default class SelfPlayerUI extends ConquerInterface {
|
||||
export default class SelfPlayerUI extends AbstractTopBarInterface {
|
||||
private selfPlayer: ConquerUser | null = null
|
||||
private userWelcome: HTMLElement | null = null
|
||||
|
||||
protected generateNodes(): HTMLElement[] {
|
||||
const player = this.getNodeFromTemplateId('conquer-self-player-template')
|
||||
const player = this.getNodeFromTemplateId('conquer-interface-with-top-bar-template')
|
||||
return [player]
|
||||
}
|
||||
public getSelfPlayerNode(): HTMLElement {
|
||||
return this.getNodes()[0]
|
||||
}
|
||||
public getExitButton(): HTMLElement {
|
||||
const maybeExitButton = this.getSelfPlayerNode().querySelector('.conquer-exit-button')
|
||||
if (maybeExitButton === null || !(maybeExitButton instanceof HTMLElement)) {
|
||||
Conquer.fail('No exit button.')
|
||||
}
|
||||
return maybeExitButton
|
||||
}
|
||||
|
||||
public generateInterfaceElementCentered(): HTMLElement {
|
||||
return this.getNodeFromTemplateId('conquer-interface-element-padded-template')
|
||||
}
|
||||
|
||||
public async run(): Promise<void> {
|
||||
const selfPlayerNode = this.getSelfPlayerNode()
|
||||
const selfPlayerNode = this.getMainNode()
|
||||
selfPlayerNode.classList.remove('conquer-display-none')
|
||||
const exitButton = this.getExitButton()
|
||||
exitButton.addEventListener('click', () => {
|
||||
this.runCallbacks('close')
|
||||
})
|
||||
const user = await ConquerUser.getSelfUser()
|
||||
if (user === null) {
|
||||
this.runCallbacks('close')
|
||||
@ -53,14 +41,14 @@ export default class SelfPlayerUI extends ConquerInterface {
|
||||
})
|
||||
const createNodeButtonInterface = this.generateInterfaceElementCentered()
|
||||
createNodeButtonInterface.appendChild(createNodeButton)
|
||||
this.getSelfPlayerNode().appendChild(createNodeButtonInterface)
|
||||
this.getMainNode().appendChild(createNodeButtonInterface)
|
||||
}
|
||||
|
||||
private populateWelcome(): void {
|
||||
const userWelcome = this.getUserWelcome()
|
||||
const userWelcomeInterface = this.generateInterfaceElementCentered();
|
||||
userWelcomeInterface.appendChild(userWelcome)
|
||||
this.getSelfPlayerNode().appendChild(userWelcomeInterface)
|
||||
this.getMainNode().appendChild(userWelcomeInterface)
|
||||
}
|
||||
|
||||
private getUserWelcome(): HTMLElement {
|
||||
|
30
js-src/conquer/websocket.ts
Normal file
30
js-src/conquer/websocket.ts
Normal file
@ -0,0 +1,30 @@
|
||||
export default class ConquerWebSocket {
|
||||
private webSocket: WebSocket | null = null
|
||||
private socketReady = false
|
||||
|
||||
private getWebSocket(): WebSocket {
|
||||
if (this.webSocket !== null) {
|
||||
return this.webSocket
|
||||
}
|
||||
this.webSocket = new WebSocket(`wss://${window.location.hostname}:${window.location.port}/conquer/websocket`)
|
||||
this.webSocket.addEventListener('close', (event) => {
|
||||
this.onSocketClose(event)
|
||||
})
|
||||
this.webSocket.addEventListener('error', (event) => {
|
||||
this.onSocketClose(event)
|
||||
})
|
||||
this.webSocket.addEventListener('open', (event) => {
|
||||
this.onSocketOpen(event)
|
||||
})
|
||||
return this.webSocket
|
||||
}
|
||||
|
||||
private onSocketOpen(event: Event) {
|
||||
this.socketReady = true
|
||||
}
|
||||
|
||||
private onSocketClose(event: Event) {
|
||||
this.socketReady = false
|
||||
console.error(event)
|
||||
}
|
||||
}
|
29
js-src/generated/v1/packet/open-new-node_pb.d.ts
vendored
Normal file
29
js-src/generated/v1/packet/open-new-node_pb.d.ts
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
// package: proto.v1.packet
|
||||
// file: v1/packet/open-new-node.proto
|
||||
|
||||
import * as jspb from "google-protobuf";
|
||||
|
||||
export class OpenNewNode extends jspb.Message {
|
||||
getLatitude(): number;
|
||||
setLatitude(value: number): void;
|
||||
|
||||
getLongitude(): number;
|
||||
setLongitude(value: number): void;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): OpenNewNode.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: OpenNewNode): OpenNewNode.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: OpenNewNode, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): OpenNewNode;
|
||||
static deserializeBinaryFromReader(message: OpenNewNode, reader: jspb.BinaryReader): OpenNewNode;
|
||||
}
|
||||
|
||||
export namespace OpenNewNode {
|
||||
export type AsObject = {
|
||||
latitude: number,
|
||||
longitude: number,
|
||||
}
|
||||
}
|
||||
|
206
js-src/generated/v1/packet/open-new-node_pb.js
Normal file
206
js-src/generated/v1/packet/open-new-node_pb.js
Normal file
@ -0,0 +1,206 @@
|
||||
// source: v1/packet/open-new-node.proto
|
||||
/**
|
||||
* @fileoverview
|
||||
* @enhanceable
|
||||
* @suppress {missingRequire} reports error on implicit type usages.
|
||||
* @suppress {messageConventions} JS Compiler reports an error if a variable or
|
||||
* field starts with 'MSG_' and isn't a translatable message.
|
||||
* @public
|
||||
*/
|
||||
// GENERATED CODE -- DO NOT EDIT!
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
var jspb = require('google-protobuf');
|
||||
var goog = jspb;
|
||||
var global =
|
||||
(typeof globalThis !== 'undefined' && globalThis) ||
|
||||
(typeof window !== 'undefined' && window) ||
|
||||
(typeof global !== 'undefined' && global) ||
|
||||
(typeof self !== 'undefined' && self) ||
|
||||
(function () { return this; }).call(null) ||
|
||||
Function('return this')();
|
||||
|
||||
goog.exportSymbol('proto.proto.v1.packet.OpenNewNode', null, global);
|
||||
/**
|
||||
* Generated by JsPbCodeGenerator.
|
||||
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||
* server response, or constructed directly in Javascript. The array is used
|
||||
* in place and becomes part of the constructed object. It is not cloned.
|
||||
* If no data is provided, the constructed object will be empty, but still
|
||||
* valid.
|
||||
* @extends {jspb.Message}
|
||||
* @constructor
|
||||
*/
|
||||
proto.proto.v1.packet.OpenNewNode = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
};
|
||||
goog.inherits(proto.proto.v1.packet.OpenNewNode, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
/**
|
||||
* @public
|
||||
* @override
|
||||
*/
|
||||
proto.proto.v1.packet.OpenNewNode.displayName = 'proto.proto.v1.packet.OpenNewNode';
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||
/**
|
||||
* Creates an object representation of this proto.
|
||||
* Field names that are reserved in JavaScript and will be renamed to pb_name.
|
||||
* Optional fields that are not set will be set to undefined.
|
||||
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
|
||||
* For the list of reserved names please see:
|
||||
* net/proto2/compiler/js/internal/generator.cc#kKeyword.
|
||||
* @param {boolean=} opt_includeInstance Deprecated. whether to include the
|
||||
* JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @return {!Object}
|
||||
*/
|
||||
proto.proto.v1.packet.OpenNewNode.prototype.toObject = function(opt_includeInstance) {
|
||||
return proto.proto.v1.packet.OpenNewNode.toObject(opt_includeInstance, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Static version of the {@see toObject} method.
|
||||
* @param {boolean|undefined} includeInstance Deprecated. Whether to include
|
||||
* the JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @param {!proto.proto.v1.packet.OpenNewNode} msg The msg instance to transform.
|
||||
* @return {!Object}
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.proto.v1.packet.OpenNewNode.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
latitude: jspb.Message.getFloatingPointFieldWithDefault(msg, 1, 0.0),
|
||||
longitude: jspb.Message.getFloatingPointFieldWithDefault(msg, 2, 0.0)
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
obj.$jspbMessageInstance = msg;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format).
|
||||
* @param {jspb.ByteSource} bytes The bytes to deserialize.
|
||||
* @return {!proto.proto.v1.packet.OpenNewNode}
|
||||
*/
|
||||
proto.proto.v1.packet.OpenNewNode.deserializeBinary = function(bytes) {
|
||||
var reader = new jspb.BinaryReader(bytes);
|
||||
var msg = new proto.proto.v1.packet.OpenNewNode;
|
||||
return proto.proto.v1.packet.OpenNewNode.deserializeBinaryFromReader(msg, reader);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format) from the
|
||||
* given reader into the given message object.
|
||||
* @param {!proto.proto.v1.packet.OpenNewNode} msg The message object to deserialize into.
|
||||
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||
* @return {!proto.proto.v1.packet.OpenNewNode}
|
||||
*/
|
||||
proto.proto.v1.packet.OpenNewNode.deserializeBinaryFromReader = function(msg, reader) {
|
||||
while (reader.nextField()) {
|
||||
if (reader.isEndGroup()) {
|
||||
break;
|
||||
}
|
||||
var field = reader.getFieldNumber();
|
||||
switch (field) {
|
||||
case 1:
|
||||
var value = /** @type {number} */ (reader.readDouble());
|
||||
msg.setLatitude(value);
|
||||
break;
|
||||
case 2:
|
||||
var value = /** @type {number} */ (reader.readDouble());
|
||||
msg.setLongitude(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the message to binary data (in protobuf wire format).
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
proto.proto.v1.packet.OpenNewNode.prototype.serializeBinary = function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
proto.proto.v1.packet.OpenNewNode.serializeBinaryToWriter(this, writer);
|
||||
return writer.getResultBuffer();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the given message to binary data (in protobuf wire
|
||||
* format), writing to the given BinaryWriter.
|
||||
* @param {!proto.proto.v1.packet.OpenNewNode} message
|
||||
* @param {!jspb.BinaryWriter} writer
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.proto.v1.packet.OpenNewNode.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
f = message.getLatitude();
|
||||
if (f !== 0.0) {
|
||||
writer.writeDouble(
|
||||
1,
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getLongitude();
|
||||
if (f !== 0.0) {
|
||||
writer.writeDouble(
|
||||
2,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional double latitude = 1;
|
||||
* @return {number}
|
||||
*/
|
||||
proto.proto.v1.packet.OpenNewNode.prototype.getLatitude = function() {
|
||||
return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 1, 0.0));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} value
|
||||
* @return {!proto.proto.v1.packet.OpenNewNode} returns this
|
||||
*/
|
||||
proto.proto.v1.packet.OpenNewNode.prototype.setLatitude = function(value) {
|
||||
return jspb.Message.setProto3FloatField(this, 1, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional double longitude = 2;
|
||||
* @return {number}
|
||||
*/
|
||||
proto.proto.v1.packet.OpenNewNode.prototype.getLongitude = function() {
|
||||
return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 2, 0.0));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} value
|
||||
* @return {!proto.proto.v1.packet.OpenNewNode} returns this
|
||||
*/
|
||||
proto.proto.v1.packet.OpenNewNode.prototype.setLongitude = function(value) {
|
||||
return jspb.Message.setProto3FloatField(this, 2, value);
|
||||
};
|
||||
|
||||
|
||||
goog.object.extend(exports, proto.proto.v1.packet);
|
@ -10,43 +10,61 @@ use utf8;
|
||||
use Mojo::Base 'Mojolicious::Controller', '-signatures';
|
||||
use Path::Tiny;
|
||||
use Mojo::UserAgent;
|
||||
use DateTime::Format::HTTP;
|
||||
use DateTime;
|
||||
|
||||
my $cache_files_dir = path(__FILE__)->parent->parent->parent->parent->child('cache/tiles/');
|
||||
my $cache_files_dir =
|
||||
path(__FILE__)->parent->parent->parent->parent->child('cache/tiles/');
|
||||
|
||||
sub tile($self) {
|
||||
my $zoom = $self->stash('zoom');
|
||||
my $x = $self->stash('x');
|
||||
my $y = $self->stash('y');
|
||||
sub _cache_response ($self) {
|
||||
my $tomorrow_same_hour_datetime = DateTime->now->add( days => 1 );
|
||||
$self->res->headers->cache_control("max_age=@{[3600*24]}");
|
||||
$self->res->headers->expires(
|
||||
DateTime::Format::HTTP->format_datetime($tomorrow_same_hour_datetime) );
|
||||
}
|
||||
|
||||
sub tile ($self) {
|
||||
my $zoom = $self->stash('zoom');
|
||||
my $x = $self->stash('x');
|
||||
my $y = $self->stash('y');
|
||||
my $candidate_file = $cache_files_dir->child("$zoom-$x-$y.png");
|
||||
if (-f $candidate_file) {
|
||||
if ( -f $candidate_file ) {
|
||||
$self->_cache_response;
|
||||
return $self->_render_png($candidate_file);
|
||||
}
|
||||
if (!defined $self->current_user) {
|
||||
return $self->render(status => 401, text => '¡¡No estás loggeado, no puedes cargar mapa nuevo.!!');
|
||||
if ( !defined $self->current_user ) {
|
||||
return $self->render(
|
||||
status => 401,
|
||||
text => '¡¡No estás loggeado, no puedes cargar mapa nuevo.!!'
|
||||
);
|
||||
}
|
||||
$self->_cache_response;
|
||||
my $file_to_write = $candidate_file;
|
||||
my $ua = Mojo::UserAgent->new;
|
||||
my $png_tile = $ua->get("https://tile.openstreetmap.org/$zoom/$x/$y.png")->result->body;
|
||||
open my $fh, '|-', 'convert', '/dev/stdin', '-channel', 'RGB', '-negate', $file_to_write;
|
||||
my $ua = Mojo::UserAgent->new;
|
||||
my $png_tile =
|
||||
$ua->get("https://tile.openstreetmap.org/$zoom/$x/$y.png")->result->body;
|
||||
open my $fh, '|-', 'convert', '/dev/stdin', '-channel', 'RGB', '-negate',
|
||||
$file_to_write;
|
||||
print $fh $png_tile;
|
||||
close $fh;
|
||||
$self->_render_png($file_to_write);
|
||||
$self->_delete_extra_files();
|
||||
}
|
||||
|
||||
sub _delete_extra_files($self) {
|
||||
my @files = $cache_files_dir->children;
|
||||
if (scalar @files < 20001) {
|
||||
sub _delete_extra_files ($self) {
|
||||
my @files = $cache_files_dir->children;
|
||||
if ( scalar @files < 20001 ) {
|
||||
return;
|
||||
}
|
||||
@files = sort { -M $a <=> -M $b } @files;
|
||||
for (my $i = 0; $i < (scalar @files) - 20000; $i++) {
|
||||
for ( my $i = 0 ; $i < ( scalar @files ) - 20000 ; $i++ ) {
|
||||
system 'rm', '-v', $files[$i];
|
||||
}
|
||||
}
|
||||
|
||||
sub _render_png($self, $file) {
|
||||
sub _render_png ( $self, $file ) {
|
||||
system 'touch', $file;
|
||||
return $self->render(data => $file->slurp_raw, status => 200, format => 'png');
|
||||
return $self->render( data => $file->slurp_raw, status => 200,
|
||||
format => 'png' );
|
||||
}
|
||||
1;
|
||||
|
@ -10,10 +10,12 @@ use Mojo::Base 'Mojolicious::Controller', '-signatures';
|
||||
|
||||
sub index($self) {
|
||||
return $self->render(text => <<"EOF");
|
||||
Esta aplicación no almacena datos que puedan identificar
|
||||
de forma única a los usuarios.\r\n
|
||||
Con fines analíticos y técnicos se almacenan la cantidad
|
||||
de visitas a cada página.\r\n
|
||||
La dirección IP, Agente de Usuario y parametros GET con los
|
||||
que se visita la página es almacenado de forma temporal
|
||||
(90 días) para detectar posibles ciberataques, tras ese tiempo
|
||||
es sustituido por un hash.
|
||||
Esta política puede cambiar en un futuro si se
|
||||
requieren funcionalidades como registros.\r\n
|
||||
EOF
|
||||
|
@ -25,7 +25,9 @@
|
||||
"dependencies": {
|
||||
"babel-loader": "^9.1.3",
|
||||
"ol": "^8.1.0",
|
||||
"protoc-gen-js": "^3.21.2",
|
||||
"tablesort": "^5.3.0",
|
||||
"ts-loader": "^9.5.0"
|
||||
"ts-loader": "^9.5.0",
|
||||
"ts-protoc-gen": "^0.15.0"
|
||||
}
|
||||
}
|
||||
|
8
proto/v1/packet/open-new-node.proto
Normal file
8
proto/v1/packet/open-new-node.proto
Normal file
@ -0,0 +1,8 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package proto.v1.packet;
|
||||
|
||||
message OpenNewNode {
|
||||
double latitude = 1;
|
||||
double longitude = 2;
|
||||
}
|
@ -105,6 +105,7 @@ body {
|
||||
body .conquer-display-none {
|
||||
display: none; }
|
||||
body div.conquer-container {
|
||||
background: black;
|
||||
height: 100dvh;
|
||||
width: 100%; }
|
||||
body div.ol-control {
|
||||
@ -216,15 +217,15 @@ body {
|
||||
body div.carousel {
|
||||
position: fixed;
|
||||
top: 80%;
|
||||
height: calc(20% - 6px);
|
||||
width: calc(100% - 6px); }
|
||||
height: 20%;
|
||||
width: 100%; }
|
||||
body div.carousel a {
|
||||
position: fixed;
|
||||
top: 80%;
|
||||
border: solid 3px black;
|
||||
width: calc(100%-6px);
|
||||
width: calc(100% - 6px);
|
||||
height: calc(20% - 6px);
|
||||
left: calc(100% + 3px);
|
||||
left: 100%;
|
||||
transition: left 1s ease-in;
|
||||
font-size: 13px;
|
||||
background: #f2eb8c;
|
||||
@ -235,9 +236,9 @@ body {
|
||||
align-items: center;
|
||||
text-decoration: none; }
|
||||
body div.carousel a.show {
|
||||
left: calc(0% + 3px); }
|
||||
left: 0%; }
|
||||
body div.carousel a.remove {
|
||||
left: calc(-100% - 3px); }
|
||||
left: -100%; }
|
||||
body div.carousel a:hover, body div.carousel a:focus {
|
||||
background: blueviolet;
|
||||
color: #f2eb8c; }
|
||||
|
@ -126,6 +126,7 @@ body {
|
||||
display: none;
|
||||
}
|
||||
div.conquer-container {
|
||||
background: black;
|
||||
height: 100dvh;
|
||||
width: 100%;
|
||||
}
|
||||
@ -289,22 +290,23 @@ body {
|
||||
div.carousel {
|
||||
position: fixed;
|
||||
top: 80%;
|
||||
height: calc(20% - 6px);
|
||||
width: calc(100% - 6px);
|
||||
height: 20%;
|
||||
width: 100%;
|
||||
|
||||
a {
|
||||
position: fixed;
|
||||
top: 80%;
|
||||
position: fixed;
|
||||
top: 80%;
|
||||
border: solid 3px black;
|
||||
width: calc(100%-6px);
|
||||
width: calc(100% - 6px);
|
||||
height: calc(20% - 6px);
|
||||
left: calc(100% + 3px);
|
||||
left: 100%;
|
||||
transition: left 1s ease-in;
|
||||
|
||||
&.show {
|
||||
left: calc(0% + 3px);
|
||||
left: 0%;
|
||||
}
|
||||
&.remove {
|
||||
left: calc(-100% - 3px);
|
||||
left: -100%;
|
||||
}
|
||||
font-size: 13px;
|
||||
background: $color_div;
|
||||
|
@ -105,6 +105,17 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "./js-src/conquer/interface/abstract-top-bar-interface.ts":
|
||||
/*!****************************************************************!*\
|
||||
!*** ./js-src/conquer/interface/abstract-top-bar-interface.ts ***!
|
||||
\****************************************************************/
|
||||
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
"use strict";
|
||||
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ AbstractTopBarInterface)\n/* harmony export */ });\n/* harmony import */ var _burguillosinfo_conquer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @burguillosinfo/conquer */ \"./js-src/conquer/index.ts\");\n/* harmony import */ var _burguillosinfo_conquer_interface__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @burguillosinfo/conquer/interface */ \"./js-src/conquer/interface.ts\");\n\n\nclass AbstractTopBarInterface extends _burguillosinfo_conquer_interface__WEBPACK_IMPORTED_MODULE_1__[\"default\"] {\n constructor() {\n super();\n const exitButton = this.getExitButton();\n exitButton.addEventListener('click', () => {\n this.runCallbacks('close');\n });\n }\n generateNodes() {\n const newNode = this.getNodeFromTemplateId('conquer-interface-with-top-bar-template');\n return [newNode];\n }\n getMainNode() {\n return this.getNodes()[0];\n }\n getExitButton() {\n const maybeExitButton = this.getMainNode().querySelector('.conquer-exit-button');\n if (maybeExitButton === null || !(maybeExitButton instanceof HTMLElement)) {\n _burguillosinfo_conquer__WEBPACK_IMPORTED_MODULE_0__[\"default\"].fail('No exit button.');\n }\n return maybeExitButton;\n }\n generateInterfaceElementCentered() {\n return this.getNodeFromTemplateId('conquer-interface-element-padded-template');\n }\n}\n\n\n//# sourceURL=webpack://BurguillosInfo/./js-src/conquer/interface/abstract-top-bar-interface.ts?");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "./js-src/conquer/interface/login.ts":
|
||||
/*!*******************************************!*\
|
||||
!*** ./js-src/conquer/interface/login.ts ***!
|
||||
@ -123,7 +134,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
|
||||
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
"use strict";
|
||||
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ SelfPlayerUI)\n/* harmony export */ });\n/* harmony import */ var _burguillosinfo_conquer_interface__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @burguillosinfo/conquer/interface */ \"./js-src/conquer/interface.ts\");\n/* harmony import */ var _burguillosinfo_conquer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @burguillosinfo/conquer */ \"./js-src/conquer/index.ts\");\n/* harmony import */ var _burguillosinfo_conquer_user__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @burguillosinfo/conquer/user */ \"./js-src/conquer/user.ts\");\n\n\n\nclass SelfPlayerUI extends _burguillosinfo_conquer_interface__WEBPACK_IMPORTED_MODULE_0__[\"default\"] {\n constructor() {\n super(...arguments);\n this.selfPlayer = null;\n this.userWelcome = null;\n }\n generateNodes() {\n const player = this.getNodeFromTemplateId('conquer-self-player-template');\n return [player];\n }\n getSelfPlayerNode() {\n return this.getNodes()[0];\n }\n getExitButton() {\n const maybeExitButton = this.getSelfPlayerNode().querySelector('.conquer-exit-button');\n if (maybeExitButton === null || !(maybeExitButton instanceof HTMLElement)) {\n _burguillosinfo_conquer__WEBPACK_IMPORTED_MODULE_1__[\"default\"].fail('No exit button.');\n }\n return maybeExitButton;\n }\n generateInterfaceElementCentered() {\n return this.getNodeFromTemplateId('conquer-interface-element-padded-template');\n }\n async run() {\n const selfPlayerNode = this.getSelfPlayerNode();\n selfPlayerNode.classList.remove('conquer-display-none');\n const exitButton = this.getExitButton();\n exitButton.addEventListener('click', () => {\n this.runCallbacks('close');\n });\n const user = await _burguillosinfo_conquer_user__WEBPACK_IMPORTED_MODULE_2__[\"default\"].getSelfUser();\n if (user === null) {\n this.runCallbacks('close');\n return;\n }\n this.selfPlayer = user;\n this.populateWelcome();\n this.populateCreateNodeOption();\n }\n populateCreateNodeOption() {\n if (!this.selfPlayer?.isAdmin()) {\n return;\n }\n const createNodeButton = document.createElement('button');\n createNodeButton.innerText = 'Crear Nuevo Nodo';\n createNodeButton.addEventListener('click', () => {\n this.runCallbacks('createNodeStart');\n // We close because it is a sensible thing to do.\n this.runCallbacks('close');\n });\n const createNodeButtonInterface = this.generateInterfaceElementCentered();\n createNodeButtonInterface.appendChild(createNodeButton);\n this.getSelfPlayerNode().appendChild(createNodeButtonInterface);\n }\n populateWelcome() {\n const userWelcome = this.getUserWelcome();\n const userWelcomeInterface = this.generateInterfaceElementCentered();\n userWelcomeInterface.appendChild(userWelcome);\n this.getSelfPlayerNode().appendChild(userWelcomeInterface);\n }\n getUserWelcome() {\n if (this.userWelcome !== null) {\n return this.userWelcome;\n }\n const element = document.createElement('h2');\n if (this.selfPlayer === null) {\n throw new Error('User still not set');\n }\n element.innerText = `¡Hola, ${this.selfPlayer.getUsername()}!`;\n this.userWelcome = element;\n return this.userWelcome;\n }\n}\n\n\n//# sourceURL=webpack://BurguillosInfo/./js-src/conquer/interface/self-player.ts?");
|
||||
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ SelfPlayerUI)\n/* harmony export */ });\n/* harmony import */ var _burguillosinfo_conquer_user__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @burguillosinfo/conquer/user */ \"./js-src/conquer/user.ts\");\n/* harmony import */ var _burguillosinfo_conquer_interface_abstract_top_bar_interface__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @burguillosinfo/conquer/interface/abstract-top-bar-interface */ \"./js-src/conquer/interface/abstract-top-bar-interface.ts\");\n\n\nclass SelfPlayerUI extends _burguillosinfo_conquer_interface_abstract_top_bar_interface__WEBPACK_IMPORTED_MODULE_1__[\"default\"] {\n constructor() {\n super(...arguments);\n this.selfPlayer = null;\n this.userWelcome = null;\n }\n generateNodes() {\n const player = this.getNodeFromTemplateId('conquer-interface-with-top-bar-template');\n return [player];\n }\n generateInterfaceElementCentered() {\n return this.getNodeFromTemplateId('conquer-interface-element-padded-template');\n }\n async run() {\n const selfPlayerNode = this.getMainNode();\n selfPlayerNode.classList.remove('conquer-display-none');\n const user = await _burguillosinfo_conquer_user__WEBPACK_IMPORTED_MODULE_0__[\"default\"].getSelfUser();\n if (user === null) {\n this.runCallbacks('close');\n return;\n }\n this.selfPlayer = user;\n this.populateWelcome();\n this.populateCreateNodeOption();\n }\n populateCreateNodeOption() {\n if (!this.selfPlayer?.isAdmin()) {\n return;\n }\n const createNodeButton = document.createElement('button');\n createNodeButton.innerText = 'Crear Nuevo Nodo';\n createNodeButton.addEventListener('click', () => {\n this.runCallbacks('createNodeStart');\n // We close because it is a sensible thing to do.\n this.runCallbacks('close');\n });\n const createNodeButtonInterface = this.generateInterfaceElementCentered();\n createNodeButtonInterface.appendChild(createNodeButton);\n this.getMainNode().appendChild(createNodeButtonInterface);\n }\n populateWelcome() {\n const userWelcome = this.getUserWelcome();\n const userWelcomeInterface = this.generateInterfaceElementCentered();\n userWelcomeInterface.appendChild(userWelcome);\n this.getMainNode().appendChild(userWelcomeInterface);\n }\n getUserWelcome() {\n if (this.userWelcome !== null) {\n return this.userWelcome;\n }\n const element = document.createElement('h2');\n if (this.selfPlayer === null) {\n throw new Error('User still not set');\n }\n element.innerText = `¡Hola, ${this.selfPlayer.getUsername()}!`;\n this.userWelcome = element;\n return this.userWelcome;\n }\n}\n\n\n//# sourceURL=webpack://BurguillosInfo/./js-src/conquer/interface/self-player.ts?");
|
||||
|
||||
/***/ }),
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
</div>
|
||||
<div id="conquer-interface-element-padded-template" class="conquer-interface-element-padded">
|
||||
</div>
|
||||
<div id="conquer-self-player-template" class="conquer-self-player conquer-display-none">
|
||||
<div id="conquer-interface-with-top-bar-template" class="conquer-self-player conquer-display-none">
|
||||
<div class="conquer-top-bar">
|
||||
<a href="#" class="conquer-exit-button">X</a>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user