Allow logging in with Discord in horde-map

master
Nikola Forró 6 years ago
parent fc0e42dede
commit d772ffecbc

@ -5,16 +5,17 @@
min-height: 600px;
}
.add-control {
.discord-control {
top: 4em;
left: 0.5em;
}
.ol-touch .add-control {
.ol-touch .discord-control {
top: 5em;
}
.add-control button {
width: 8em;
.discord-control button {
width: auto;
padding: 0.5em;
font-size: 11pt;
}

@ -1,7 +1,11 @@
const apiUrl = '/horde-members/api/features';
const membersApiUrl = 'https://lilia.mraveniste.cc/horde-members/api/members';
const featuresApiUrl = 'https://lilia.mraveniste.cc/horde-members/api/features';
const apiKey = 'eyJhbGciOiJIUzUxMiIsImlhdCI6MTU1Mzg5MjYwNSwiZXhwIjoxODY5MjUyNjA1fQ.ImNsaWVudCI.iX2EEEsKbMYpbeU-HB_FcqeepwZn8rkq8XdyfUmr6RJk2-64I744xLdKfrikxskF6_IlJbjBH3jNNcVfWyvswQ';
var nick = '';
const discordClientId = '562565397451374593';
const cheeseHordeGuildId = '285154599038353408';
var discordUser = undefined;
function store(feature) {
var writer = new ol.format.GeoJSON({
@ -10,7 +14,7 @@ function store(feature) {
});
$.ajax({
url: apiUrl,
url: featuresApiUrl,
type: 'post',
contentType: 'application/json',
data: writer.writeFeature(feature),
@ -18,6 +22,14 @@ function store(feature) {
});
}
function remove(id) {
$.ajax({
url: `${membersApiUrl}/${id}`,
type: 'delete',
headers: {'X-Members-API-Key': apiKey}
});
}
function getColor(nick, alpha) {
var r = 0;
var g = 0;
@ -53,15 +65,55 @@ function getColor(nick, alpha) {
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
}
var AddControl = (function (Control) {
function AddControl(opt_options) {
var discord = new LoginWithDiscord({
clientID: discordClientId,
scopes: [
Scope.Identify,
Scope.Guilds
],
cache: true
});
discord.onlogin = async () => {
var user = await discord.fetchUser();
var guilds = await discord.fetchGuilds();
var horde = guilds.find((guild) => guild.id == cheeseHordeGuildId);
if (horde !== undefined) {
discordUser = user;
var button = discordControl.element.firstElementChild;
button.innerHTML = `${discordUser.username}: Log out`;
button.style.display = null;
}
}
discord.onlogout = async () => {
discordUser = undefined;
var button = discordControl.element.firstElementChild;
button.innerHTML = 'Log in with Discord';
button.style.display = null;
};
async function discordLogin() {
await discord.login();
}
async function discordLogout() {
await discord.logout();
}
var DiscordControl = (function(Control) {
function DiscordControl(opt_options) {
var options = opt_options || {};
var button = document.createElement('button');
button.innerHTML = 'Add yourself';
button.style.display = 'none';
var element = document.createElement('div');
element.className = 'add-control ol-unselectable ol-control';
element.className = 'discord-control ol-unselectable ol-control';
element.appendChild(button);
Control.call(this, {
@ -69,24 +121,29 @@ var AddControl = (function (Control) {
target: options.target
});
button.addEventListener('click', this.handleAdd.bind(this), false);
button.addEventListener('click', this.handleClick.bind(this), false);
}
if (Control)
AddControl.__proto__ = Control;
DiscordControl.__proto__ = Control;
AddControl.prototype = Object.create(Control && Control.prototype);
AddControl.prototype.constructor = AddControl;
DiscordControl.prototype = Object.create(Control && Control.prototype);
DiscordControl.prototype.constructor = DiscordControl;
AddControl.prototype.handleAdd = function handleAdd() {
nick = prompt('Please enter your nickname', '');
DiscordControl.prototype.handleClick = function() {
if (!discordUser)
discordLogin();
else
discordLogout();
};
return AddControl;
return DiscordControl;
}(ol.control.Control));
var discordControl = new DiscordControl();
var source = new ol.source.Vector({
url: apiUrl,
url: featuresApiUrl,
wrapX: false,
format: new ol.format.GeoJSON({
dataProjection: 'EPSG:4326',
@ -136,7 +193,7 @@ var map = new ol.Map({
zoom: 2
}),
controls: ol.control.defaults().extend([
new AddControl()
discordControl
])
});
@ -149,7 +206,7 @@ map.addInteraction(snap);
var modify = new ol.interaction.Modify({
source: source,
condition: (evt) => {
if (!nick)
if (!discordUser)
return false;
var feature = source.getClosestFeatureToCoordinate(evt.coordinate);
@ -157,7 +214,7 @@ var modify = new ol.interaction.Modify({
if (!feature)
return false;
return feature.get('current') !== undefined;
return feature.get('id') == discordUser.id;
}
});
@ -173,23 +230,20 @@ var draw = new ol.interaction.Draw({
source: source,
type: 'Point',
condition: (evt) => {
if (!nick)
if (!discordUser)
return false;
var feature = source.forEachFeature((feature) => {
if (feature.get('nick') == nick)
if (feature.get('id') == discordUser.id)
return feature;
});
if (feature === undefined) {
if (feature === undefined)
return true;
}
if (feature.get('current') === undefined)
return false;
var features = [];
// FIXME: allows duplication
map.forEachFeatureAtPixel(evt.pixel, (feature) => {
features.push(feature);
});
@ -199,18 +253,33 @@ var draw = new ol.interaction.Draw({
});
draw.on('drawend', (evt) => {
evt.feature.set('id', discordUser.id);
evt.feature.set('nick', discordUser.username);
store(evt.feature);
});
map.addInteraction(draw);
document.addEventListener('keydown', (evt) => {
if (evt.code != 'Delete')
return;
if (!discordUser)
return;
var feature = source.forEachFeature((feature) => {
if (feature.get('nick') == nick)
if (feature.get('id') == discordUser.id)
return feature;
});
if (feature !== undefined)
source.removeFeature(feature);
if (feature === undefined)
return;
evt.feature.set('nick', nick);
evt.feature.set('current', true);
if (confirm('Are you sure you want to remove yourself?'))
{
source.removeFeature(feature);
store(evt.feature);
remove(discordUser.id);
}
});
map.addInteraction(draw);

@ -37,7 +37,7 @@ api = flask_restful.Api(app)
member_fields = {
'id': flask_restful.fields.Integer(),
'id': flask_restful.fields.String(),
'nick': flask_restful.fields.String(),
'x': flask_restful.fields.Float(),
'y': flask_restful.fields.Float(),
@ -49,6 +49,7 @@ geometry_fields = {
'coordinates': flask_restful.fields.List(flask_restful.fields.Float()),
}
properties_fields = {
'id': flask_restful.fields.String(),
'nick': flask_restful.fields.String(),
}
feature_fields = {
@ -63,7 +64,7 @@ features_fields = {
member_parser = flask_restful.reqparse.RequestParser()
member_parser.add_argument('id', type=int)
member_parser.add_argument('id', type=str, required=True)
member_parser.add_argument('nick', type=str, required=True)
member_parser.add_argument('x', type=float, required=True)
member_parser.add_argument('y', type=float, required=True)
@ -86,6 +87,7 @@ geometry_parser.add_argument('coordinates', type=float, action='append',
location=('geometry',), required=True)
properties_parser = flask_restful.reqparse.RequestParser()
properties_parser.add_argument('id', type=str, location=('properties',), required=True)
properties_parser.add_argument('nick', type=str, location=('properties',), required=True)
@ -112,6 +114,7 @@ def member2feature(member):
],
},
'properties': {
'id': member.id,
'nick': member.nick,
},
}
@ -187,6 +190,8 @@ class MembersResource(flask_restful.Resource):
@flask_restful.marshal_with(member_fields)
def post(self):
args = member_parser.parse_args()
if not args['id']:
flask_restful.abort(400, message='Missing required parameter id')
if not args['nick']:
flask_restful.abort(400, message='Missing required parameter nick')
if not args['x']:
@ -194,11 +199,12 @@ class MembersResource(flask_restful.Resource):
if not args['y']:
flask_restful.abort(400, message='Missing required parameter y')
now = sqlalchemy.func.now()
q = db.session.query(Member).filter(Member.user == args['nick'])
q = db.session.query(Member).filter(Member.id == args['id'])
member = q.first()
if not member:
member = Member(created_at=now)
member.user = args['nick']
member.id = args['id']
member.nick = args['nick']
member.x, member.y = normalize(args['x'], args['y'])
member.updated_at = now
db.session.add(member)
@ -235,10 +241,11 @@ class FeaturesResource(flask_restful.Resource):
if geometry_args['type'] != 'Point':
flask_restful.abort(400, message='Unexpected geometry type')
now = sqlalchemy.func.now()
q = db.session.query(Member).filter(Member.nick == properties_args['nick'])
q = db.session.query(Member).filter(Member.id == properties_args['id'])
member = q.first()
if not member:
member = Member(created_at=now)
member.id = properties_args['id']
member.nick = properties_args['nick']
member.x, member.y = normalize(*geometry_args['coordinates'])
member.updated_at = now

@ -7,7 +7,7 @@ db = flask_sqlalchemy.SQLAlchemy(session_options=dict(autoflush=False))
class Member(db.Model):
__tablename__ = 'members'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
id = db.Column(db.String, primary_key=True)
nick = db.Column(db.String)
x = db.Column(db.Float)
y = db.Column(db.Float)

Loading…
Cancel
Save