From e83ba78d3aabd02a348eb2be79c4edade2b61430 Mon Sep 17 00:00:00 2001 From: Sendou Date: Tue, 26 Nov 2019 23:33:49 +0200 Subject: [PATCH] user page update --- .prettierrc.json | 2 +- index.js | 16 +- models/user.js | 21 +- package-lock.json | 253 +++++++++--------- package.json | 6 +- react-ui/package-lock.json | 172 +++++++++++- react-ui/package.json | 7 +- react-ui/src/components/root/MainMenu.js | 7 +- react-ui/src/components/user/UserPage.js | 42 ++- react-ui/src/graphql/queries/searchForUser.js | 22 +- react-ui/src/graphql/queries/userLean.js | 17 +- schemas/user.js | 120 +++++++-- utils/countries.js | 251 +++++++++++++++++ 13 files changed, 737 insertions(+), 199 deletions(-) create mode 100644 utils/countries.js diff --git a/.prettierrc.json b/.prettierrc.json index 73878ae6a..932cff883 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -4,4 +4,4 @@ "semi": false, "singleQuote": false, "prettier.semi": false -} \ No newline at end of file +} diff --git a/index.js b/index.js index 1ad0ac446..49dd529c5 100644 --- a/index.js +++ b/index.js @@ -31,7 +31,6 @@ passport.use( const userToSave = { username: profile.username, discriminator: profile.discriminator, - avatar: profile.avatar, discord_id: profile.id, } for (var i = 0; i < profile.connections.length; i++) { @@ -62,6 +61,7 @@ passport.serializeUser(function(user, done) { }) passport.deserializeUser(function(discord_id, done) { + console.log("de") User.findOne({ discord_id }, function(err, user) { done(err, user) }) @@ -85,6 +85,20 @@ mongoose const server = new ApolloServer({ schema, context: ({ req }) => { + if (process.env.NODE_ENV === "development") { + return { + user: { + _id: "5cee8f73d1120d4315c55011", + discord_id: "79237403620945920", + __v: 0, + avatar: "2e292c1b5d1366c24a9e4b6c1cffc700", + discriminator: "0043", + twitch_name: "sendou", + twitter_name: "sendouc", + username: "Sendou", + }, + } + } return { user: req.user } }, }) diff --git a/models/user.js b/models/user.js index 8dd436751..29850bb5c 100644 --- a/models/user.js +++ b/models/user.js @@ -1,12 +1,17 @@ -const mongoose = require('mongoose') +const mongoose = require("mongoose") const userSchema = new mongoose.Schema({ - username: {type: String, required: true}, - discriminator: {type: String, required: true}, - avatar: {type: String}, - discord_id: {type: String, required: true}, - twitch_name: {type: String}, - twitter_name: {type: String}, + username: { type: String, required: true }, + discriminator: { type: String, required: true }, + discord_id: { type: String, required: true }, + twitch_name: String, + twitter_name: String, + country: String, + sens: { + sticks: { type: Number, min: -5, max: 5 }, + motion: { type: Number, min: -5, max: 5 }, + }, + weapons: [String], }) -module.exports = mongoose.model('User', userSchema) \ No newline at end of file +module.exports = mongoose.model("User", userSchema) diff --git a/package-lock.json b/package-lock.json index e8aa03a72..f0dc64d0f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,12 +4,39 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@apollographql/apollo-tools": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@apollographql/apollo-tools/-/apollo-tools-0.4.0.tgz", - "integrity": "sha512-7wEO+S+zgz/wVe3ilFQqICufRBYYDSNUkd1V03JWvXuSydbYq2SM5EgvWmFF+04iadt+aQ0XCCsRzCzRPQODfQ==", + "@apollo/protobufjs": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.0.3.tgz", + "integrity": "sha512-gqeT810Ect9WIqsrgfUvr+ljSB5m1PyBae9HGdrRyQ3HjHjTcjVvxpsMYXlUk4rUHnrfUqyoGvLSy2yLlRGEOw==", "requires": { - "apollo-env": "0.5.1" + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.0", + "@types/node": "^10.1.0", + "long": "^4.0.0" + }, + "dependencies": { + "@types/node": { + "version": "10.17.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.5.tgz", + "integrity": "sha512-RElZIr/7JreF1eY6oD5RF3kpmdcreuQPjg5ri4oQ5g9sq7YWU8HkfB3eH8GwAwxf5OaCh0VPi7r4N/yoTGelrA==" + } + } + }, + "@apollographql/apollo-tools": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@apollographql/apollo-tools/-/apollo-tools-0.4.1.tgz", + "integrity": "sha512-9NaTBPX+YYCsio6AqnLHlLiqYBszgTBul2qzG2+YNZ/1RQ2owhO/7xB5XJyQz76NGOefORaZt5idwvTJXpg/Sg==", + "requires": { + "apollo-env": "^0.6.0" } }, "@apollographql/graphql-playground-html": { @@ -126,9 +153,9 @@ } }, "@types/express-serve-static-core": { - "version": "4.16.11", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.16.11.tgz", - "integrity": "sha512-K8d2M5t3tBQimkyaYTXxtHYyoJPUEhy2/omVRnTAKw5FEdT+Ft6lTaTOpoJdHeG+mIwQXXtqiTcYZ6IR8LTzjQ==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.0.tgz", + "integrity": "sha512-Xnub7w57uvcBqFdIGoRg1KhNOeEj0vB6ykUM7uFWyxvbdE89GFyqgmUcanAriMr4YOxNFZBAWkfcWIb4WBPt3g==", "requires": { "@types/node": "*", "@types/range-parser": "*" @@ -195,9 +222,9 @@ "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==" }, "@types/node": { - "version": "12.12.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.7.tgz", - "integrity": "sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w==" + "version": "12.12.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.12.tgz", + "integrity": "sha512-MGuvYJrPU0HUwqF7LqvIj50RZUX23Z+m583KBygKYUZLlZ88n6w28XRNJRJgsHukLEnLz6w6SvxZoLgbr5wLqQ==" }, "@types/range-parser": { "version": "1.2.3", @@ -290,12 +317,12 @@ } }, "apollo-cache-control": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/apollo-cache-control/-/apollo-cache-control-0.8.5.tgz", - "integrity": "sha512-2yQ1vKgJQ54SGkoQS/ZLZrDX3La6cluAYYdruFYJMJtL4zQrSdeOCy11CQliCMYEd6eKNyE70Rpln51QswW2Og==", + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/apollo-cache-control/-/apollo-cache-control-0.8.8.tgz", + "integrity": "sha512-hpIJg3Tmb6quA111lrVO+d3qcyYRlJ8JqbeQdcgwLT3fb2VQzk21SrBZYl2oMM4ZqSOWCZWg4/Cn9ARYqdWjKA==", "requires": { "apollo-server-env": "^2.4.3", - "graphql-extensions": "^0.10.4" + "graphql-extensions": "^0.10.7" } }, "apollo-datasource": { @@ -308,31 +335,31 @@ } }, "apollo-engine-reporting": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/apollo-engine-reporting/-/apollo-engine-reporting-1.4.7.tgz", - "integrity": "sha512-qsKDz9VkoctFhojM3Nj3nvRBO98t8TS2uTgtiIjUGs3Hln2poKMP6fIQ37Nm2Q2B3JJst76HQtpPwXmRJd1ZUg==", + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/apollo-engine-reporting/-/apollo-engine-reporting-1.4.10.tgz", + "integrity": "sha512-0nEawO9cudbXHCxRvnDUWKqCxPAGEstghUFd5sB67lIGuh91MYeLuwN1iTfqUdwF1feEGHn636zVVUYlXGOlvQ==", "requires": { - "apollo-engine-reporting-protobuf": "^0.4.1", + "apollo-engine-reporting-protobuf": "^0.4.4", "apollo-graphql": "^0.3.4", "apollo-server-caching": "^0.5.0", "apollo-server-env": "^2.4.3", - "apollo-server-types": "^0.2.5", + "apollo-server-types": "^0.2.8", "async-retry": "^1.2.1", - "graphql-extensions": "^0.10.4" + "graphql-extensions": "^0.10.7" } }, "apollo-engine-reporting-protobuf": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.4.1.tgz", - "integrity": "sha512-d7vFFZ2oUrvGaN0Hpet8joe2ZG0X0lIGilN+SwgVP38dJnOuadjsaYMyrD9JudGQJg0bJA5wVQfYzcCVy0slrw==", + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.4.4.tgz", + "integrity": "sha512-SGrIkUR7Q/VjU8YG98xcvo340C4DaNUhg/TXOtGsMlfiJDzHwVau/Bv6zifAzBafp2lj0XND6Daj5kyT/eSI/w==", "requires": { - "protobufjs": "^6.8.6" + "@apollo/protobufjs": "^1.0.3" } }, "apollo-env": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/apollo-env/-/apollo-env-0.5.1.tgz", - "integrity": "sha512-fndST2xojgSdH02k5hxk1cbqA9Ti8RX4YzzBoAB4oIe1Puhq7+YlhXGXfXB5Y4XN0al8dLg+5nAkyjNAR2qZTw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/apollo-env/-/apollo-env-0.6.0.tgz", + "integrity": "sha512-DttHOpLISRej8STjbXjQCXq3YeE2pATaC4UEd2YE7TjjYhQmp9yxohlkHfSR78BvPzczhyDs6WQQEzasHv0M0A==", "requires": { "core-js": "^3.0.1", "node-fetch": "^2.2.0", @@ -340,11 +367,11 @@ } }, "apollo-graphql": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/apollo-graphql/-/apollo-graphql-0.3.4.tgz", - "integrity": "sha512-w+Az1qxePH4oQ8jvbhQBl5iEVvqcqynmU++x/M7MM5xqN1C7m1kyIzpN17gybXlTJXY4Oxej2WNURC2/hwpfYw==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/apollo-graphql/-/apollo-graphql-0.3.5.tgz", + "integrity": "sha512-X2N/LREJSAkI0RhMEJ6d0kGjdJSI4SFyf6soLvLLTQn0Bhi/52hMLf8k4kO5t0SCKuWc1+Pw/tdCniK4Gc1IdA==", "requires": { - "apollo-env": "^0.5.1", + "apollo-env": "^0.6.0", "lodash.sortby": "^4.7.0" } }, @@ -360,12 +387,12 @@ } }, "apollo-server": { - "version": "2.9.7", - "resolved": "https://registry.npmjs.org/apollo-server/-/apollo-server-2.9.7.tgz", - "integrity": "sha512-maGGCsK4Ft5ucox5ZJf6oaKhgPvzHY3jXWbA1F/mn0/EYX8e1RVO3Qtj8aQQ0/vCKx8r4vYgj+ctqBVaN/nr4A==", + "version": "2.9.12", + "resolved": "https://registry.npmjs.org/apollo-server/-/apollo-server-2.9.12.tgz", + "integrity": "sha512-Q+qaBTgTxb2vwqyh7NTHs9rOmadbuKw34SgeAOLsCnr3MLVjisa50fL3nQrGbhOGfRaroF8SSZYgya0tvnefig==", "requires": { - "apollo-server-core": "^2.9.7", - "apollo-server-express": "^2.9.7", + "apollo-server-core": "^2.9.12", + "apollo-server-express": "^2.9.12", "express": "^4.0.0", "graphql-subscriptions": "^1.0.0", "graphql-tools": "^4.0.0" @@ -380,25 +407,25 @@ } }, "apollo-server-core": { - "version": "2.9.7", - "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-2.9.7.tgz", - "integrity": "sha512-EqKyROy+21sM93YHjGpy6wlnzK/vH0fnZh7RCf3uB69aQ3OjgdP4AQ5oWRQ62NDN+aoic7OLhChSDJeDonq/NQ==", + "version": "2.9.12", + "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-2.9.12.tgz", + "integrity": "sha512-jhGr2R655PSwUUBweXDl+0F3oa74Elu5xXF+88ymUUej34EwBUCqz97wPqR07BEuyxaAlRfZwPMvKaHhMUKg5g==", "requires": { "@apollographql/apollo-tools": "^0.4.0", "@apollographql/graphql-playground-html": "1.6.24", "@types/graphql-upload": "^8.0.0", "@types/ws": "^6.0.0", - "apollo-cache-control": "^0.8.5", + "apollo-cache-control": "^0.8.8", "apollo-datasource": "^0.6.3", - "apollo-engine-reporting": "^1.4.7", + "apollo-engine-reporting": "^1.4.10", "apollo-server-caching": "^0.5.0", "apollo-server-env": "^2.4.3", "apollo-server-errors": "^2.3.4", - "apollo-server-plugin-base": "^0.6.5", - "apollo-server-types": "^0.2.5", - "apollo-tracing": "^0.8.5", + "apollo-server-plugin-base": "^0.6.8", + "apollo-server-types": "^0.2.8", + "apollo-tracing": "^0.8.8", "fast-json-stable-stringify": "^2.0.0", - "graphql-extensions": "^0.10.4", + "graphql-extensions": "^0.10.7", "graphql-tag": "^2.9.2", "graphql-tools": "^4.0.0", "graphql-upload": "^8.0.2", @@ -422,9 +449,9 @@ "integrity": "sha512-Y0PKQvkrb2Kd18d1NPlHdSqmlr8TgqJ7JQcNIfhNDgdb45CnqZlxL1abuIRhr8tiw8OhVOcFxz2KyglBi8TKdA==" }, "apollo-server-express": { - "version": "2.9.7", - "resolved": "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-2.9.7.tgz", - "integrity": "sha512-+DuJk1oq34Zx0bLYzgBgJH/eXS0JNxw2JycHQvV0+PAQ0Qi01oomJRA2r1S5isnfnSAnHb2E9jyBTptoHdw3MQ==", + "version": "2.9.12", + "resolved": "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-2.9.12.tgz", + "integrity": "sha512-4Ev8MY7m23mSzwO/BvLTy97a/68IP/wZoCRBn2R81OoZt9/GxlvvYZGvozJCXYsQt1qAbIT4Sn05LmqawsI98w==", "requires": { "@apollographql/graphql-playground-html": "1.6.24", "@types/accepts": "^1.3.5", @@ -432,8 +459,8 @@ "@types/cors": "^2.8.4", "@types/express": "4.17.1", "accepts": "^1.3.5", - "apollo-server-core": "^2.9.7", - "apollo-server-types": "^0.2.5", + "apollo-server-core": "^2.9.12", + "apollo-server-types": "^0.2.8", "body-parser": "^1.18.3", "cors": "^2.8.4", "express": "^4.17.1", @@ -457,30 +484,30 @@ } }, "apollo-server-plugin-base": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.6.5.tgz", - "integrity": "sha512-z2ve7HEPWmZI3EzL0iiY9qyt1i0hitT+afN5PzssCw594LB6DfUQWsI14UW+W+gcw8hvl8VQUpXByfUntAx5vw==", + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.6.8.tgz", + "integrity": "sha512-0pKCjcg9gHBK8qlb280+N0jl99meixQtxXnMJFyIfD+45OpKQ+WolHIbO0oZgNEt7r/lNWwH8v3l5yYm1ghz1A==", "requires": { - "apollo-server-types": "^0.2.5" + "apollo-server-types": "^0.2.8" } }, "apollo-server-types": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-0.2.5.tgz", - "integrity": "sha512-6iJQsPh59FWu4K7ABrVmpnQVgeK8Ockx8BcawBh+saFYWTlVczwcLyGSZPeV1tPSKwFwKZutyEslrYSafcarXQ==", + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-0.2.8.tgz", + "integrity": "sha512-5OclxkAqjhuO75tTNHpSO/+doJZ+VlRtTefnrPJdK/uwVew9U/VUCWkYdryZWwEyVe1nvQ/4E7RYR4tGb8l8wA==", "requires": { - "apollo-engine-reporting-protobuf": "^0.4.1", + "apollo-engine-reporting-protobuf": "^0.4.4", "apollo-server-caching": "^0.5.0", "apollo-server-env": "^2.4.3" } }, "apollo-tracing": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.8.5.tgz", - "integrity": "sha512-lZn10/GRBZUlMxVYLghLMFsGcLN0jTYDd98qZfBtxw+wEWUx+PKkZdljDT+XNoOm/kDvEutFGmi5tSLhArIzWQ==", + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.8.8.tgz", + "integrity": "sha512-aIwT2PsH7VZZPaNrIoSjzLKMlG644d2Uf+GYcoMd3X6UEyg1sXdWqkKfCeoS6ChJKH2khO7MXAvOZC03UnCumQ==", "requires": { "apollo-server-env": "^2.4.3", - "graphql-extensions": "^0.10.4" + "graphql-extensions": "^0.10.7" } }, "apollo-utilities": { @@ -949,9 +976,9 @@ "dev": true }, "core-js": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.4.0.tgz", - "integrity": "sha512-lQxb4HScV71YugF/X28LtePZj9AB7WqOpcB+YztYxusvhrgZiQXPmCYfPC5LHsw/+ScEtDbXU3xbqH3CjBRmYA==" + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.4.2.tgz", + "integrity": "sha512-bUTfqFWtNKWp73oNIfRkqwYZJeNT3lstzZcAkhhiuvDraRSgOH1/+F9ZklbpR4zpdKuo4cpXN8tKP7s61yjX+g==" }, "core-util-is": { "version": "1.0.2", @@ -2103,13 +2130,13 @@ } }, "graphql-extensions": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.10.4.tgz", - "integrity": "sha512-lE6MroluEYocbR/ICwccv39w+Pz4cBPadJ11z1rJkbZv5wstISEganbDOwl9qN21rcZGiWzh7QUNxUiFUXXEDw==", + "version": "0.10.7", + "resolved": "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.10.7.tgz", + "integrity": "sha512-YuP7VQxNePG4bWRQ5Vk+KRMbZ9r1IWCqCCogOMz/1ueeQ4gZe93eGRcb0vhpOdMFnCX6Vyvd4+sC+N6LR3YFOQ==", "requires": { "@apollographql/apollo-tools": "^0.4.0", "apollo-server-env": "^2.4.3", - "apollo-server-types": "^0.2.5" + "apollo-server-types": "^0.2.8" } }, "graphql-subscriptions": { @@ -2163,9 +2190,9 @@ "dev": true }, "has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" }, "has-value": { "version": "1.0.0", @@ -2483,11 +2510,11 @@ "dev": true }, "is-symbol": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", - "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", "requires": { - "has-symbols": "^1.0.0" + "has-symbols": "^1.0.1" } }, "is-windows": { @@ -2650,16 +2677,16 @@ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" }, "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", + "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==" }, "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "version": "2.1.25", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", + "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", "requires": { - "mime-db": "1.40.0" + "mime-db": "1.42.0" } }, "minimatch": { @@ -2710,13 +2737,13 @@ } }, "mongoose": { - "version": "5.7.9", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.7.9.tgz", - "integrity": "sha512-wXYY4+IEvplbEEeOxLVOHBGosBDNn/DYgwKzBFgsamCTvRQZHbdw88m9xUH8Srza+jdKND73/4XbQLynPseRAQ==", + "version": "5.7.12", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.7.12.tgz", + "integrity": "sha512-TqRiJPUeHN1u7Xs/zQmiMHcrzEb1/uKjK3uGzZhyqw25RKQiMV2vSBeBTMt5HXoYlUuDEWXE75FMjpK9X9kD0w==", "requires": { "bson": "~1.1.1", "kareem": "2.3.1", - "mongodb": "3.3.3", + "mongodb": "3.3.4", "mongoose-legacy-pluralize": "1.0.2", "mpath": "0.6.0", "mquery": "3.2.2", @@ -2727,6 +2754,17 @@ "sliced": "1.0.1" }, "dependencies": { + "mongodb": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.3.4.tgz", + "integrity": "sha512-6fmHu3FJTpeZxacJcfjUGIP3BSteG0l2cxLkSrf1nnnS1OrlnVGiP9P/wAC4aB6dM6H4vQ2io8YDjkuPkje7AA==", + "requires": { + "bson": "^1.1.1", + "require_optional": "^1.0.1", + "safe-buffer": "^5.1.2", + "saslprep": "^1.0.0" + } + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -2933,9 +2971,9 @@ } }, "object-inspect": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", - "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==" + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==" }, "object-keys": { "version": "1.1.1", @@ -3108,33 +3146,6 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, - "protobufjs": { - "version": "6.8.8", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz", - "integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==", - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.0", - "@types/node": "^10.1.0", - "long": "^4.0.0" - }, - "dependencies": { - "@types/node": { - "version": "10.17.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.5.tgz", - "integrity": "sha512-RElZIr/7JreF1eY6oD5RF3kpmdcreuQPjg5ri4oQ5g9sq7YWU8HkfB3eH8GwAwxf5OaCh0VPi7r4N/yoTGelrA==" - } - } - }, "proxy-addr": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", @@ -4084,9 +4095,9 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "zen-observable": { - "version": "0.8.14", - "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.14.tgz", - "integrity": "sha512-kQz39uonEjEESwh+qCi83kcC3rZJGh4mrZW7xjkSQYXkq//JZHTtKo+6yuVloTgMtzsIWOJrjIrKvk/dqm0L5g==" + "version": "0.8.15", + "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz", + "integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==" }, "zen-observable-ts": { "version": "0.8.20", diff --git a/package.json b/package.json index 1637d6cdb..adc7a7168 100644 --- a/package.json +++ b/package.json @@ -12,8 +12,8 @@ "author": "Sendou", "license": "ISC", "dependencies": { - "apollo-server": "^2.9.7", - "apollo-server-express": "^2.9.7", + "apollo-server": "^2.9.12", + "apollo-server-express": "^2.9.12", "axios": "^0.19.0", "btoa": "^1.2.1", "connect-mongo": "^3.1.2", @@ -22,7 +22,7 @@ "express-session": "^1.17.0", "graphql": "^14.5.8", "lodash": "^4.17.15", - "mongoose": "^5.7.9", + "mongoose": "^5.7.12", "mongoose-unique-validator": "^2.0.3", "node-fetch": "^2.6.0", "passport": "^0.4.0", diff --git a/react-ui/package-lock.json b/react-ui/package-lock.json index 58125c711..09e183862 100644 --- a/react-ui/package-lock.json +++ b/react-ui/package-lock.json @@ -1753,6 +1753,23 @@ } } }, + "airbnb-prop-types": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/airbnb-prop-types/-/airbnb-prop-types-2.15.0.tgz", + "integrity": "sha512-jUh2/hfKsRjNFC4XONQrxo/n/3GG4Tn6Hl0WlFQN5PY9OMC9loSCoAYKnZsWaP8wEfd5xcrPloK0Zg6iS1xwVA==", + "requires": { + "array.prototype.find": "^2.1.0", + "function.prototype.name": "^1.1.1", + "has": "^1.0.3", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object.assign": "^4.1.0", + "object.entries": "^1.1.0", + "prop-types": "^15.7.2", + "prop-types-exact": "^1.2.0", + "react-is": "^16.9.0" + } + }, "ajv": { "version": "6.10.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", @@ -2002,6 +2019,15 @@ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" }, + "array.prototype.find": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.1.0.tgz", + "integrity": "sha512-Wn41+K1yuO5p7wRZDl7890c3xvv5UBrfVXTVIe28rSQb6LS0fZMDrQB6PAcxQFRFy6vJTLDc3A2+3CjQdzVKRg==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.13.0" + } + }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", @@ -4740,6 +4766,63 @@ "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" }, + "enzyme-adapter-react-16": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.15.1.tgz", + "integrity": "sha512-yMPxrP3vjJP+4wL/qqfkT6JAIctcwKF+zXO6utlGPgUJT2l4tzrdjMDWGd/Pp1BjHBcljhN24OzNEGRteibJhA==", + "requires": { + "enzyme-adapter-utils": "^1.12.1", + "enzyme-shallow-equal": "^1.0.0", + "has": "^1.0.3", + "object.assign": "^4.1.0", + "object.values": "^1.1.0", + "prop-types": "^15.7.2", + "react-is": "^16.10.2", + "react-test-renderer": "^16.0.0-0", + "semver": "^5.7.0" + }, + "dependencies": { + "react-is": { + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", + "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "enzyme-adapter-utils": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/enzyme-adapter-utils/-/enzyme-adapter-utils-1.12.1.tgz", + "integrity": "sha512-KWiHzSjZaLEoDCOxY8Z1RAbUResbqKN5bZvenPbfKtWorJFVETUw754ebkuCQ3JKm0adx1kF8JaiR+PHPiP47g==", + "requires": { + "airbnb-prop-types": "^2.15.0", + "function.prototype.name": "^1.1.1", + "object.assign": "^4.1.0", + "object.fromentries": "^2.0.1", + "prop-types": "^15.7.2", + "semver": "^5.7.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "enzyme-shallow-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.0.tgz", + "integrity": "sha512-VUf+q5o1EIv2ZaloNQQtWCJM9gpeux6vudGVH6vLmfPXFLRuxl5+Aq3U260wof9nn0b0i+P5OEUXm1vnxkRpXQ==", + "requires": { + "has": "^1.0.3", + "object-is": "^1.0.1" + } + }, "errno": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", @@ -5998,11 +6081,27 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, + "function.prototype.name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.1.tgz", + "integrity": "sha512-e1NzkiJuw6xqVH7YSdiW/qDHebcmMhPNe6w+4ZYYEg0VA+LaLzx37RimbPLuonHhYGFGPx1ME2nSi74JiaCr/Q==", + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1", + "functions-have-names": "^1.1.1", + "is-callable": "^1.1.4" + } + }, "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" }, + "functions-have-names": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.0.tgz", + "integrity": "sha512-zKXyzksTeaCSw5wIX79iCA40YAa6CJMJgNg9wdkU/ERBrIdPSimPICYiLp65lRbSBqtiHql/HZfS2DyI/AH6tQ==" + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -10532,6 +10631,16 @@ "react-is": "^16.8.1" } }, + "prop-types-exact": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/prop-types-exact/-/prop-types-exact-1.2.0.tgz", + "integrity": "sha512-K+Tk3Kd9V0odiXFP9fwDHUYRyvK3Nun3GVyPapSIs5OBkITAm15W0CPFD/YKTkMUAbc0b9CUwRQp2ybiBIq+eA==", + "requires": { + "has": "^1.0.3", + "object.assign": "^4.1.0", + "reflect.ownkeys": "^0.2.0" + } + }, "proxy-addr": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", @@ -10682,9 +10791,9 @@ } }, "react": { - "version": "16.11.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.11.0.tgz", - "integrity": "sha512-M5Y8yITaLmU0ynd0r1Yvfq98Rmll6q8AxaEe88c8e7LxO8fZ2cNgmFt0aGAS9wzf1Ao32NKXtCl+/tVVtkxq6g==", + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.12.0.tgz", + "integrity": "sha512-fglqy3k5E+81pA8s+7K0/T3DBCF0ZDOher1elBFzF7O6arXJgzyu/FW+COxFvAWXJoJN9KIZbT2LXlukwphYTA==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -10859,14 +10968,14 @@ } }, "react-dom": { - "version": "16.11.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.11.0.tgz", - "integrity": "sha512-nrRyIUE1e7j8PaXSPtyRKtz+2y9ubW/ghNgqKFHHAHaeP0fpF5uXR+sq8IMRHC+ZUxw7W9NyCDTBtwWxvkb0iA==", + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.12.0.tgz", + "integrity": "sha512-LMxFfAGrcS3kETtQaCkTKjMiifahaMySFDn71fZUNpPHZQEzmk/GiAeIT8JSOrHB23fnuCOMruL2a8NYlw+8Gw==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", "prop-types": "^15.6.2", - "scheduler": "^0.17.0" + "scheduler": "^0.18.0" } }, "react-error-overlay": { @@ -10897,6 +11006,11 @@ "warning": "^4.0.2" } }, + "react-proptype-conditional-require": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/react-proptype-conditional-require/-/react-proptype-conditional-require-1.0.4.tgz", + "integrity": "sha1-acLVdB5t9eCPIw82u8KUTuEiJVU=" + }, "react-resize-detector": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-2.3.0.tgz", @@ -11026,6 +11140,17 @@ "react-transition-group": "^2.5.0" } }, + "react-test-renderer": { + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.12.0.tgz", + "integrity": "sha512-Vj/teSqt2oayaWxkbhQ6gKis+t5JrknXfPVo+aIJ8QwYAqMPH77uptOdrlphyxl8eQI/rtkOYg86i/UWkpFu0w==", + "requires": { + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "react-is": "^16.8.6", + "scheduler": "^0.18.0" + } + }, "react-transition-group": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", @@ -11037,6 +11162,17 @@ "react-lifecycles-compat": "^3.0.4" } }, + "react-twitter-embed": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/react-twitter-embed/-/react-twitter-embed-3.0.3.tgz", + "integrity": "sha512-kF1Srlb1TqnZUqKA0FC4I/E+m+RUBCMZeU20hDRzmYLAjR1EA/6tr/PMZ22s7rd6wjQpIBLXNZjt0rfUpY8Chw==", + "requires": { + "enzyme-adapter-react-16": "^1.11.0", + "exenv": "^1.2.2", + "react-proptype-conditional-require": "^1.0.4", + "scriptjs": "^2.5.9" + } + }, "reactcss": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz", @@ -11182,6 +11318,11 @@ "balanced-match": "^1.0.0" } }, + "reflect.ownkeys": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz", + "integrity": "sha1-dJrO7H8/34tj+SegSAnpDFwLNGA=" + }, "regenerate": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", @@ -11688,9 +11829,9 @@ } }, "scheduler": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.17.0.tgz", - "integrity": "sha512-7rro8Io3tnCPuY4la/NuI5F2yfESpnfZyT6TtkXnSWVkcu0BCDJ+8gk5ozUaFaxpIyNuWAPXrH0yFcSi28fnDA==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.18.0.tgz", + "integrity": "sha512-agTSHR1Nbfi6ulI0kYNK0203joW2Y5W4po4l+v03tOoiJKpTBbxpNhWDvqc/4IcOw+KLmSiQLTasZ4cab2/UWQ==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -11706,6 +11847,11 @@ "ajv-keywords": "^3.1.0" } }, + "scriptjs": { + "version": "2.5.9", + "resolved": "https://registry.npmjs.org/scriptjs/-/scriptjs-2.5.9.tgz", + "integrity": "sha512-qGVDoreyYiP1pkQnbnFAUIS5AjenNwwQBdl7zeos9etl+hYKWahjRTfzAZZYBv5xNHx7vNKCmaLDQZ6Fr2AEXg==" + }, "select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -13170,9 +13316,9 @@ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" }, "use-query-params": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/use-query-params/-/use-query-params-0.4.4.tgz", - "integrity": "sha512-Vd7FWfI0gvfDoV8XpLzDHhmHWvklbrIxZesC+wkzE4E6hsZlvOWQVXC/ACLqo/Guz0FburTPh3tn9jwHUF9vSw==", + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/use-query-params/-/use-query-params-0.4.5.tgz", + "integrity": "sha512-HeSgLvEj26pkNRGeAIq+uTo6Z22iaAqDMosq+Be5lab4v57gwVIUKsS3iZ1BBgsUbLEKKpoqcVvqd9MUg+lkIw==", "requires": { "serialize-query-params": "^0.1.4" } diff --git a/react-ui/package.json b/react-ui/package.json index e66038fb7..97aad1479 100644 --- a/react-ui/package.json +++ b/react-ui/package.json @@ -8,15 +8,16 @@ "apollo-boost": "^0.4.4", "graphql": "^14.5.8", "jstz": "^2.1.1", - "react": "^16.11.0", + "react": "^16.12.0", "react-color": "^2.17.3", - "react-dom": "^16.11.0", + "react-dom": "^16.12.0", "react-router-dom": "^5.1.2", "react-scripts": "^3.2.0", + "react-twitter-embed": "^3.0.3", "recharts": "^1.8.5", "semantic-ui-css": "^2.4.1", "semantic-ui-react": "^0.88.1", - "use-query-params": "^0.4.4" + "use-query-params": "^0.4.5" }, "scripts": { "start": "react-scripts start", diff --git a/react-ui/src/components/root/MainMenu.js b/react-ui/src/components/root/MainMenu.js index 7d14a298e..8c844504c 100644 --- a/react-ui/src/components/root/MainMenu.js +++ b/react-ui/src/components/root/MainMenu.js @@ -48,8 +48,13 @@ const MainMenu = () => { {user.username} + console.error( + `Couldn't fetch avatar image of ${user.twitter_name}.` + ) + } />{" "} ) diff --git a/react-ui/src/components/user/UserPage.js b/react-ui/src/components/user/UserPage.js index 7b3aaf9bb..cffb14c43 100644 --- a/react-ui/src/components/user/UserPage.js +++ b/react-ui/src/components/user/UserPage.js @@ -1,4 +1,4 @@ -import React, { useEffect } from "react" +import React, { useState, useEffect } from "react" import { Tab, Image, List, Grid } from "semantic-ui-react" import { Redirect } from "react-router-dom" import { useQuery } from "@apollo/react-hooks" @@ -9,16 +9,20 @@ import PlayerXRankStats from "../xsearch/PlayerXRankStats" import BuildTab from "./BuildTab" import Loading from "../common/Loading" import Error from "../common/Error" +import { useQueryParam, NumberParam } from "use-query-params" const UserPage = () => { const { id } = useParams() + const [tab, setTab] = useQueryParam("tab", NumberParam) const { data, error, loading } = useQuery(searchForUser, { variables: { discord_id: id }, }) const userLeanQuery = useQuery(userLean) + const [activeIndex, setActiveIndex] = useState(tab ? tab : 0) + useEffect(() => { - if (loading || !data.searchForUser) return + if (loading || !data || !data.searchForUser) return document.title = `${data.searchForUser.username} - sendou.ink` }, [loading, data]) @@ -32,7 +36,7 @@ const UserPage = () => { const userData = data.searchForUser if (!userData) return - const twitchDiscord = () => { + const twitterDiscord = () => { if (userData.twitch_name && userData.twitter_name) { return ( <> @@ -98,19 +102,27 @@ const UserPage = () => { }, ] + const handleTabChange = (e, { activeIndex }) => { + setActiveIndex(activeIndex) + setTab(activeIndex) + } + return ( <> <> - + {userData.twitter_name && ( + + console.error( + `Couldn't fetch avatar image of ${userData.twitter_name}.` + ) + } + /> + )} @@ -118,13 +130,17 @@ const UserPage = () => { {`${userData.username}#${userData.discriminator}`} - {twitchDiscord()} + {twitterDiscord()}
- +
) diff --git a/react-ui/src/graphql/queries/searchForUser.js b/react-ui/src/graphql/queries/searchForUser.js index cd2043a97..d89d973fd 100644 --- a/react-ui/src/graphql/queries/searchForUser.js +++ b/react-ui/src/graphql/queries/searchForUser.js @@ -1,14 +1,14 @@ -import { gql } from 'apollo-boost' +import { gql } from "apollo-boost" export const searchForUser = gql` -query searchForUser($discord_id: String) { - searchForUser(discord_id: $discord_id) { - username - discriminator - discord_id - avatar - twitch_name - twitter_name + query searchForUser($discord_id: String) { + searchForUser(discord_id: $discord_id) { + id + username + discriminator + discord_id + twitch_name + twitter_name + } } -} -` \ No newline at end of file +` diff --git a/react-ui/src/graphql/queries/userLean.js b/react-ui/src/graphql/queries/userLean.js index 039883f51..48e6218e5 100644 --- a/react-ui/src/graphql/queries/userLean.js +++ b/react-ui/src/graphql/queries/userLean.js @@ -1,11 +1,12 @@ -import { gql } from 'apollo-boost' +import { gql } from "apollo-boost" export const userLean = gql` -{ - user { - username - avatar - discord_id + { + user { + id + username + twitter_name + discord_id + } } -} -` \ No newline at end of file +` diff --git a/schemas/user.js b/schemas/user.js index ae02d7d69..c4b24acad 100644 --- a/schemas/user.js +++ b/schemas/user.js @@ -1,50 +1,138 @@ -const { UserInputError, gql } = require('apollo-server-express') -const User = require('../models/user') +const { UserInputError, gql } = require("apollo-server-express") +const User = require("../models/user") +const countries = require("../utils/countries") +const weapons = require("../utils/weapons") +require("dotenv").config() const typeDef = gql` extend type Query { "Returns the current logged in user or null if not logged in." user: User "Returns user. Either discord_id or twitter has to provided or error is thrown." - searchForUser(discord_id: String twitter: String): User + searchForUser(discord_id: String, twitter: String): User + } + extend type Mutation { + updateUser( + country: String + stick_sens: Float + motion_sens: Float + weapons: [String] + ): Boolean + } + "The control sensitivity used in Splatoon 2" + type Sens { + stick: Float + motion: Float } "Represents user account. Also includes info regarding solo ladder." type User { + id: ID! "User's username. This is the same as their name on Discord. Updated on every log-in." username: String! "Discord discriminator. For example with Sendou#0043 0043 is the discriminator." discriminator: String! "String that allows finding users avatar on Discord." - avatar: String discord_id: String! twitch_name: String twitter_name: String + country: String + sens: Sens + weapons: [String]! } ` const resolvers = { Query: { user: (root, args, ctx) => { + if (process.env.NODE_ENV === "development") { + return { + id: "5cee8f73d1120d4315c55011", + discord_id: "79237403620945920", + __v: 0, + avatar: "2e292c1b5d1366c24a9e4b6c1cffc700", + discriminator: "0043", + twitch_name: "sendou", + twitter_name: "sendouc", + username: "Sendou", + } + } return ctx.user }, searchForUser: (root, args) => { let searchCriteria = {} - if (args.twitter) searchCriteria = {twitter_name: args.twitter} - else if (args.discord_id) searchCriteria = {discord_id: args.discord_id} - else throw new UserInputError('no twitter or discord id provided', { - invalidArgs: args, + if (args.twitter) searchCriteria = { twitter_name: args.twitter } + else if (args.discord_id) searchCriteria = { discord_id: args.discord_id } + else + throw new UserInputError("no twitter or discord id provided", { + invalidArgs: args, + }) + return User.findOne(searchCriteria).catch(e => { + throw new UserInputError(e.message, { + invalidArgs: args, + }) }) - return User - .findOne(searchCriteria) - .catch(e => { - throw new UserInputError(e.message, { + }, + }, + Mutation: { + updateUser: async (root, args, ctx) => { + if (!ctx.user) throw new AuthenticationError("not authenticated") + if (args.country) + if ( + countries + .map(countryObj => countryObj.Code) + .indexOf(args.country.toUpperCase() === -1) + ) { + throw new UserInputError("Invalid country ID", { invalidArgs: args, }) + } + + if (args.motion_sens) { + const number = Math.floor(args.motion_sens * 10) + if (number < -50 || number > 50 || number % 5 != 0) { + throw new UserInputError("Invalid motion sensitivity", { + invalidArgs: args, + }) + } + } + + if (args.stick_sens) { + const number = Math.floor(args.stick_sens * 10) + if (number < -50 || number > 50 || number % 5 != 0) { + throw new UserInputError("Invalid motion sensitivity", { + invalidArgs: args, + }) + } + } + + if (args.weapons) { + if (args.weapons.some(weapon => weapons.indexOf(weapon) === -1)) { + throw new UserInputError("Invalid weapon in the pool", { + invalidArgs: args, + }) + } + } + + const user = await User.findById(args.id) + if (!user) + throw new UserInputError("No user found with the id", { + invalidArgs: args, }) - } - } + + if (ctx.user.discord_id !== user.discord_id) + throw new AuthenticationError("No privileges to edit the user") + + await User.findByIdAndUpdate(build._id, { ...user, ...args }).catch(e => { + throw new UserInputError(error.message, { + invalidArgs: args, + }) + }) + + return true + }, + }, } module.exports = { User: typeDef, - userResolvers: resolvers -} \ No newline at end of file + userResolvers: resolvers, +} diff --git a/utils/countries.js b/utils/countries.js new file mode 100644 index 000000000..0309e8e2d --- /dev/null +++ b/utils/countries.js @@ -0,0 +1,251 @@ +const countries = [ + { Code: "AF", Name: "Afghanistan" }, + { Code: "AX", Name: "\u00c5land Islands" }, + { Code: "AL", Name: "Albania" }, + { Code: "DZ", Name: "Algeria" }, + { Code: "AS", Name: "American Samoa" }, + { Code: "AD", Name: "Andorra" }, + { Code: "AO", Name: "Angola" }, + { Code: "AI", Name: "Anguilla" }, + { Code: "AQ", Name: "Antarctica" }, + { Code: "AG", Name: "Antigua and Barbuda" }, + { Code: "AR", Name: "Argentina" }, + { Code: "AM", Name: "Armenia" }, + { Code: "AW", Name: "Aruba" }, + { Code: "AU", Name: "Australia" }, + { Code: "AT", Name: "Austria" }, + { Code: "AZ", Name: "Azerbaijan" }, + { Code: "BS", Name: "Bahamas" }, + { Code: "BH", Name: "Bahrain" }, + { Code: "BD", Name: "Bangladesh" }, + { Code: "BB", Name: "Barbados" }, + { Code: "BY", Name: "Belarus" }, + { Code: "BE", Name: "Belgium" }, + { Code: "BZ", Name: "Belize" }, + { Code: "BJ", Name: "Benin" }, + { Code: "BM", Name: "Bermuda" }, + { Code: "BT", Name: "Bhutan" }, + { Code: "BO", Name: "Bolivia, Plurinational State of" }, + { Code: "BQ", Name: "Bonaire, Sint Eustatius and Saba" }, + { Code: "BA", Name: "Bosnia and Herzegovina" }, + { Code: "BW", Name: "Botswana" }, + { Code: "BV", Name: "Bouvet Island" }, + { Code: "BR", Name: "Brazil" }, + { Code: "IO", Name: "British Indian Ocean Territory" }, + { Code: "BN", Name: "Brunei Darussalam" }, + { Code: "BG", Name: "Bulgaria" }, + { Code: "BF", Name: "Burkina Faso" }, + { Code: "BI", Name: "Burundi" }, + { Code: "KH", Name: "Cambodia" }, + { Code: "CM", Name: "Cameroon" }, + { Code: "CA", Name: "Canada" }, + { Code: "CV", Name: "Cape Verde" }, + { Code: "KY", Name: "Cayman Islands" }, + { Code: "CF", Name: "Central African Republic" }, + { Code: "TD", Name: "Chad" }, + { Code: "CL", Name: "Chile" }, + { Code: "CN", Name: "China" }, + { Code: "CX", Name: "Christmas Island" }, + { Code: "CC", Name: "Cocos (Keeling) Islands" }, + { Code: "CO", Name: "Colombia" }, + { Code: "KM", Name: "Comoros" }, + { Code: "CG", Name: "Congo" }, + { Code: "CD", Name: "Congo, the Democratic Republic of the" }, + { Code: "CK", Name: "Cook Islands" }, + { Code: "CR", Name: "Costa Rica" }, + { Code: "CI", Name: "C\u00f4te d'Ivoire" }, + { Code: "HR", Name: "Croatia" }, + { Code: "CU", Name: "Cuba" }, + { Code: "CW", Name: "Cura\u00e7ao" }, + { Code: "CY", Name: "Cyprus" }, + { Code: "CZ", Name: "Czech Republic" }, + { Code: "DK", Name: "Denmark" }, + { Code: "DJ", Name: "Djibouti" }, + { Code: "DM", Name: "Dominica" }, + { Code: "DO", Name: "Dominican Republic" }, + { Code: "EC", Name: "Ecuador" }, + { Code: "EG", Name: "Egypt" }, + { Code: "SV", Name: "El Salvador" }, + { Code: "GQ", Name: "Equatorial Guinea" }, + { Code: "ER", Name: "Eritrea" }, + { Code: "EE", Name: "Estonia" }, + { Code: "ET", Name: "Ethiopia" }, + { Code: "FK", Name: "Falkland Islands (Malvinas)" }, + { Code: "FO", Name: "Faroe Islands" }, + { Code: "FJ", Name: "Fiji" }, + { Code: "FI", Name: "Finland" }, + { Code: "FR", Name: "France" }, + { Code: "GF", Name: "French Guiana" }, + { Code: "PF", Name: "French Polynesia" }, + { Code: "TF", Name: "French Southern Territories" }, + { Code: "GA", Name: "Gabon" }, + { Code: "GM", Name: "Gambia" }, + { Code: "GE", Name: "Georgia" }, + { Code: "DE", Name: "Germany" }, + { Code: "GH", Name: "Ghana" }, + { Code: "GI", Name: "Gibraltar" }, + { Code: "GR", Name: "Greece" }, + { Code: "GL", Name: "Greenland" }, + { Code: "GD", Name: "Grenada" }, + { Code: "GP", Name: "Guadeloupe" }, + { Code: "GU", Name: "Guam" }, + { Code: "GT", Name: "Guatemala" }, + { Code: "GG", Name: "Guernsey" }, + { Code: "GN", Name: "Guinea" }, + { Code: "GW", Name: "Guinea-Bissau" }, + { Code: "GY", Name: "Guyana" }, + { Code: "HT", Name: "Haiti" }, + { Code: "HM", Name: "Heard Island and McDonald Islands" }, + { Code: "VA", Name: "Holy See (Vatican City State)" }, + { Code: "HN", Name: "Honduras" }, + { Code: "HK", Name: "Hong Kong" }, + { Code: "HU", Name: "Hungary" }, + { Code: "IS", Name: "Iceland" }, + { Code: "IN", Name: "India" }, + { Code: "ID", Name: "Indonesia" }, + { Code: "IR", Name: "Iran, Islamic Republic of" }, + { Code: "IQ", Name: "Iraq" }, + { Code: "IE", Name: "Ireland" }, + { Code: "IM", Name: "Isle of Man" }, + { Code: "IL", Name: "Israel" }, + { Code: "IT", Name: "Italy" }, + { Code: "JM", Name: "Jamaica" }, + { Code: "JP", Name: "Japan" }, + { Code: "JE", Name: "Jersey" }, + { Code: "JO", Name: "Jordan" }, + { Code: "KZ", Name: "Kazakhstan" }, + { Code: "KE", Name: "Kenya" }, + { Code: "KI", Name: "Kiribati" }, + { Code: "KP", Name: "Korea, Democratic People's Republic of" }, + { Code: "KR", Name: "Korea, Republic of" }, + { Code: "KW", Name: "Kuwait" }, + { Code: "KG", Name: "Kyrgyzstan" }, + { Code: "LA", Name: "Lao People's Democratic Republic" }, + { Code: "LV", Name: "Latvia" }, + { Code: "LB", Name: "Lebanon" }, + { Code: "LS", Name: "Lesotho" }, + { Code: "LR", Name: "Liberia" }, + { Code: "LY", Name: "Libya" }, + { Code: "LI", Name: "Liechtenstein" }, + { Code: "LT", Name: "Lithuania" }, + { Code: "LU", Name: "Luxembourg" }, + { Code: "MO", Name: "Macao" }, + { Code: "MK", Name: "Macedonia, the Former Yugoslav Republic of" }, + { Code: "MG", Name: "Madagascar" }, + { Code: "MW", Name: "Malawi" }, + { Code: "MY", Name: "Malaysia" }, + { Code: "MV", Name: "Maldives" }, + { Code: "ML", Name: "Mali" }, + { Code: "MT", Name: "Malta" }, + { Code: "MH", Name: "Marshall Islands" }, + { Code: "MQ", Name: "Martinique" }, + { Code: "MR", Name: "Mauritania" }, + { Code: "MU", Name: "Mauritius" }, + { Code: "YT", Name: "Mayotte" }, + { Code: "MX", Name: "Mexico" }, + { Code: "FM", Name: "Micronesia, Federated States of" }, + { Code: "MD", Name: "Moldova, Republic of" }, + { Code: "MC", Name: "Monaco" }, + { Code: "MN", Name: "Mongolia" }, + { Code: "ME", Name: "Montenegro" }, + { Code: "MS", Name: "Montserrat" }, + { Code: "MA", Name: "Morocco" }, + { Code: "MZ", Name: "Mozambique" }, + { Code: "MM", Name: "Myanmar" }, + { Code: "NA", Name: "Namibia" }, + { Code: "NR", Name: "Nauru" }, + { Code: "NP", Name: "Nepal" }, + { Code: "NL", Name: "Netherlands" }, + { Code: "NC", Name: "New Caledonia" }, + { Code: "NZ", Name: "New Zealand" }, + { Code: "NI", Name: "Nicaragua" }, + { Code: "NE", Name: "Niger" }, + { Code: "NG", Name: "Nigeria" }, + { Code: "NU", Name: "Niue" }, + { Code: "NF", Name: "Norfolk Island" }, + { Code: "MP", Name: "Northern Mariana Islands" }, + { Code: "NO", Name: "Norway" }, + { Code: "OM", Name: "Oman" }, + { Code: "PK", Name: "Pakistan" }, + { Code: "PW", Name: "Palau" }, + { Code: "PS", Name: "Palestine, State of" }, + { Code: "PA", Name: "Panama" }, + { Code: "PG", Name: "Papua New Guinea" }, + { Code: "PY", Name: "Paraguay" }, + { Code: "PE", Name: "Peru" }, + { Code: "PH", Name: "Philippines" }, + { Code: "PN", Name: "Pitcairn" }, + { Code: "PL", Name: "Poland" }, + { Code: "PT", Name: "Portugal" }, + { Code: "PR", Name: "Puerto Rico" }, + { Code: "QA", Name: "Qatar" }, + { Code: "RE", Name: "R\u00e9union" }, + { Code: "RO", Name: "Romania" }, + { Code: "RU", Name: "Russian Federation" }, + { Code: "RW", Name: "Rwanda" }, + { Code: "BL", Name: "Saint Barth\u00e9lemy" }, + { Code: "SH", Name: "Saint Helena, Ascension and Tristan da Cunha" }, + { Code: "KN", Name: "Saint Kitts and Nevis" }, + { Code: "LC", Name: "Saint Lucia" }, + { Code: "MF", Name: "Saint Martin (French part)" }, + { Code: "PM", Name: "Saint Pierre and Miquelon" }, + { Code: "VC", Name: "Saint Vincent and the Grenadines" }, + { Code: "WS", Name: "Samoa" }, + { Code: "SM", Name: "San Marino" }, + { Code: "ST", Name: "Sao Tome and Principe" }, + { Code: "SA", Name: "Saudi Arabia" }, + { Code: "SN", Name: "Senegal" }, + { Code: "RS", Name: "Serbia" }, + { Code: "SC", Name: "Seychelles" }, + { Code: "SL", Name: "Sierra Leone" }, + { Code: "SG", Name: "Singapore" }, + { Code: "SX", Name: "Sint Maarten (Dutch part)" }, + { Code: "SK", Name: "Slovakia" }, + { Code: "SI", Name: "Slovenia" }, + { Code: "SB", Name: "Solomon Islands" }, + { Code: "SO", Name: "Somalia" }, + { Code: "ZA", Name: "South Africa" }, + { Code: "GS", Name: "South Georgia and the South Sandwich Islands" }, + { Code: "SS", Name: "South Sudan" }, + { Code: "ES", Name: "Spain" }, + { Code: "LK", Name: "Sri Lanka" }, + { Code: "SD", Name: "Sudan" }, + { Code: "SR", Name: "Suriname" }, + { Code: "SJ", Name: "Svalbard and Jan Mayen" }, + { Code: "SZ", Name: "Swaziland" }, + { Code: "SE", Name: "Sweden" }, + { Code: "CH", Name: "Switzerland" }, + { Code: "SY", Name: "Syrian Arab Republic" }, + { Code: "TW", Name: "Taiwan, Province of China" }, + { Code: "TJ", Name: "Tajikistan" }, + { Code: "TZ", Name: "Tanzania, United Republic of" }, + { Code: "TH", Name: "Thailand" }, + { Code: "TL", Name: "Timor-Leste" }, + { Code: "TG", Name: "Togo" }, + { Code: "TK", Name: "Tokelau" }, + { Code: "TO", Name: "Tonga" }, + { Code: "TT", Name: "Trinidad and Tobago" }, + { Code: "TN", Name: "Tunisia" }, + { Code: "TR", Name: "Turkey" }, + { Code: "TM", Name: "Turkmenistan" }, + { Code: "TC", Name: "Turks and Caicos Islands" }, + { Code: "TV", Name: "Tuvalu" }, + { Code: "UG", Name: "Uganda" }, + { Code: "UA", Name: "Ukraine" }, + { Code: "AE", Name: "United Arab Emirates" }, + { Code: "GB", Name: "United Kingdom" }, + { Code: "US", Name: "United States" }, + { Code: "UM", Name: "United States Minor Outlying Islands" }, + { Code: "UY", Name: "Uruguay" }, + { Code: "UZ", Name: "Uzbekistan" }, + { Code: "VU", Name: "Vanuatu" }, + { Code: "VE", Name: "Venezuela, Bolivarian Republic of" }, + { Code: "VN", Name: "Viet Nam" }, + { Code: "VG", Name: "Virgin Islands, British" }, + { Code: "VI", Name: "Virgin Islands, U.S." }, + { Code: "WF", Name: "Wallis and Futuna" }, + { Code: "EH", Name: "Western Sahara" }, + { Code: "YE", Name: "Yemen" }, + { Code: "ZM", Name: "Zambia" }, + { Code: "ZW", Name: "Zimbabwe" }, +]