Animated.sequence([
Animated.timing(value, {
- toValue: 0.2,
+ toValue: 0.0,
duration: 800,
delay: 200 * i,
easing: Easing.out(Easing.sin),
diff --git a/mobile/src/ui/Geolocation.js b/mobile/src/ui/Geolocation.js
index 51cdab9..68829fd 100644
--- a/mobile/src/ui/Geolocation.js
+++ b/mobile/src/ui/Geolocation.js
@@ -1,6 +1,7 @@
import React, { Component } from "react"
-import { Image, View } from "react-native"
import PropTypes from "prop-types"
+import { config } from "../config"
+import { reactAutoBind } from "auto-bind2"
export class Geolocation extends Component {
static propTypes = {
@@ -14,29 +15,36 @@ export class Geolocation extends Component {
constructor(props) {
super(props)
- this.watchId = -1
+ reactAutoBind(this)
+
+ if (props.watch) {
+ this.intervalId = setInterval(this.updateLocation, config.geoSampleDelay)
+ } else {
+ this.intervalId = -1
+ }
}
componentDidMount() {
- navigator.geolocation.getCurrentPosition((position) => {
- this.props.onUpdate(position)
-
- if (this.props.watch) {
- this.watchId = navigator.geolocation.watchPosition((position) =>
- this.props.onUpdate(position)
- )
- }
- })
+ this.updateLocation()
}
componentWillUnmount() {
- if (this.watchId !== -1) {
- navigator.geolocation.clearWatch(this.watchId)
- navigator.geolocation.stopObserving()
- this.watchId = -1
+ if (this.intervalId !== -1) {
+ clearInterval(this.intervalId)
+ this.intervalId = -1
}
}
+ updateLocation() {
+ navigator.geolocation.getCurrentPosition(
+ (position) => {
+ this.props.onUpdate(position)
+ },
+ null,
+ { distanceFilter: 5, maximumAge: 0, enableHighAccuracy: true }
+ )
+ }
+
render() {
return null
}
diff --git a/mobile/src/util.js b/mobile/src/util.js
index ed73071..fa7c636 100644
--- a/mobile/src/util.js
+++ b/mobile/src/util.js
@@ -1,13 +1,13 @@
export const geoDistance = (lat1, lng1, lat2, lng2, unit) => {
- var radlat1 = Math.PI * lat1 / 180
- var radlat2 = Math.PI * lat2 / 180
+ var radlat1 = (Math.PI * lat1) / 180
+ var radlat2 = (Math.PI * lat2) / 180
var theta = lng1 - lng2
- var radtheta = Math.PI * theta / 180
+ var radtheta = (Math.PI * theta) / 180
var dist =
Math.sin(radlat1) * Math.sin(radlat2) +
Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta)
dist = Math.acos(dist)
- dist = dist * 180 / Math.PI
+ dist = (dist * 180) / Math.PI
dist = dist * 60 * 1.1515
if (unit == "K") {
dist = dist * 1.609344
@@ -56,13 +56,22 @@ export const pad = (num, size) => {
return s
}
-export const dotify = (s) => {
+export const dotify = (s, len = 30) => {
+ let pre = false
+
+ if (len < 0) {
+ pre = true
+ len = -len
+ }
+
if (!s) {
return "..."
- } else if (s.length < 30) {
+ } else if (s.length < len) {
return s
+ } else if (pre) {
+ return "..." + s.slice(s.length - len - 3)
} else {
- return s.substring(0, 26) + "..."
+ return s.slice(0, len - 3) + "..."
}
}
diff --git a/server/src/api/routes/UserRoutes.js b/server/src/api/routes/UserRoutes.js
index 6328342..a168ed2 100644
--- a/server/src/api/routes/UserRoutes.js
+++ b/server/src/api/routes/UserRoutes.js
@@ -112,7 +112,7 @@ export class UserRoutes {
const isSelf = _id === req.user._id
const isAdmin = req.user.administrator
- // User can see themselves, otherwise must be super user
+ // User can see themselves, otherwise must be admin
if (!isSelf && !isAdmin) {
throw createError.Forbidden()
}
@@ -185,8 +185,8 @@ export class UserRoutes {
throw createError.Forbidden()
}
- if (isSelf && !isAdmin) {
- throw createError.BadRequest("Cannot modify own administrator level")
+ if (isSelf && isAdmin && !req.body.administrator) {
+ throw createError.BadRequest("Cannot remove own administrator level")
}
const User = this.db.User
@@ -199,7 +199,7 @@ export class UserRoutes {
// We don't allow direct updates to the email field so remove it if present
const userUpdates = new User(req.body)
- delete userUpdates.email
+ userUpdates.email = undefined
user.merge(userUpdates)
const savedUser = await user.save()
diff --git a/website/src/ui/Loader.js b/website/src/ui/Loader.js
index 644dac4..c11964b 100644
--- a/website/src/ui/Loader.js
+++ b/website/src/ui/Loader.js
@@ -1,7 +1,7 @@
-import React from 'react'
-import Radium from 'radium'
-import { colorInfo, sizeInfo } from 'ui/style'
-import anime from 'animejs'
+import React from "react"
+import Radium from "radium"
+import { colorInfo, sizeInfo } from "ui/style"
+import anime from "animejs"
@Radium
export class Loader extends React.Component {
@@ -13,30 +13,31 @@ export class Loader extends React.Component {
anime({
targets: elem,
scale: [
- { value: 0.2, duration: 800, easing: 'easeOutSine', delay: 200 * i },
- { value: 1.0, duration: 800, easing: 'easeOutSine' },
- { value: 1.0, duration: 200 * (2 - i) }
+ { value: 0.0, duration: 800, easing: "easeOutSine", delay: 200 * i },
+ { value: 1.0, duration: 800, easing: "easeOutSine" },
+ { value: 1.0, duration: 200 * (2 - i) },
],
- loop: true
+ loop: true,
})
}
return (
- {
- [0, 1, 2].map((i) => (
- addAnimation(elem, i)}
- style={{
- display: 'inline-block',
- marginLeft: i > 0 ? spacing : 0,
- width: size,
- height: size,
- background: colorInfo.textInverse,
- borderSize: 0,
- borderRadius: '100%'
- }} />
- ))
- }
+ {[0, 1, 2].map((i) => (
+ addAnimation(elem, i)}
+ style={{
+ display: "inline-block",
+ marginLeft: i > 0 ? spacing : 0,
+ width: size,
+ height: size,
+ background: colorInfo.textInverse,
+ borderSize: 0,
+ borderRadius: "100%",
+ }}
+ />
+ ))}
)
}