-
-
Notifications
You must be signed in to change notification settings - Fork 64
09. Further Customizing
In the sections below are details about how you can further customize ReactMap in a git friendly way.
- Don't like my implementation?
- Too lazy to write a configurable PR?
- Want to maintain custom files while keeping it git friendly?
You have the ability to replace every single file in the root src
folder with your own implementation!
For example, if you want to customize the Pokestop marker:
- Copy
src/components/markers/pokestop.jsx
- Name new file to
src/components/markers/pokestop.custom.jsx
- Make your changes
- Recompile
- Celebrate that you're no longer limited to my opinions and praise how generous I am
F.A.Q. Q. But Turtle, why would I want to write a custom component instead of relying on the config?
- The config is massive and overwhelming at this point. Most of the options only cater to a small handful of people.
- We all have opinions, just write your own code, please leave me alone.
- Performance. All of these unnecessary calculations for things like icon placement starts to impact performance when multiplying it by thousands.
Q. What do you mean this will never be officially supported?
- If you are writing custom files, it is imperative that you keep an eye on PRs to make sure that they don't break your custom implementations.
- I will not provide help with your custom implementations.
Q. How can you rudely break my custom component if it's git friendly?
- Custom components still rely on the props being passed through, using the example above:
export default function pokestopMarker(pokestop, hasQuest, hasLure, hasInvasion, filters, Icons, userSettings)
- You are still reliant on me passing all of these properties to the Pokestop marker, even in your custom implementation. If the inputs change, you must adjust your custom components.
- I will do my best to inform people of changes that can affect custom components
Q. What files can I edit?
- Any
.css
,.js
, or.jsx
file in the rootsrc
folder. This PR does not apply to files in theserver
orpublic
folders.
Q. How does this inject custom code while maintaining git friendly-ness??
- All files with the
.custom.[js,jsx,css]
ending are git ignored. The compiler checks if a custom file exists during the loading process, if it does, it replaces the contents of the standard file with the custom. Maintaining the original in the file structure while loading your custom file into the end bundle. Magic.
An example of a custom API endpoint that can be used to fetch PVP cache stats:
- You can create an unlimited number of git friendly, endpoints. They will stay git friendly as long as the main repo doesn't add a file of the same name at some point
- You would add this by placing a new file with the below contents in
server/src/routes/api/v1/
- Whatever you name the file, becomes the endpoint, so
cacheStats.js
would become https://www.your-map-url.com/api/v1/cacheStats - You should set your ReactMap Secret in your config, but you can create them without secret authentication if you'd like
- Example curl script
curl -H "react-map-secret: your_secret" https://www.your-map-url.com/api/v1/stats/api/v1/cacheStats
const router = require('express').Router()
const { api } = require('../../../services/config')
const { Pvp } = require('../../../services/initialization')
router.get('/', async (req, res) => {
try {
if (api.reactMapSecret && req.headers['react-map-secret'] === api.reactMapSecret) {
res.status(200).json(Pvp.rmCache.getStats())
} else {
throw new Error('Incorrect or missing API secret')
}
console.log('[API] api/v1/cache')
} catch (e) {
console.error('[API Error] api/v1/cache/', e)
res.status(500).json({ status: 'ServerError', reason: e.message })
}
})
module.exports = router
The following settings apply to in your config:
- Message of the Day
- Donor Page
- Login Page
You can add one time MotD's for your community to see upon opening the map from your config. Simply increment the index to make sure your users see the latest message, then add an many messages/components as you want in the message array. It accepts an array of strings or objects that have title
, body
, and footer
properties, all are optional. The map will display all messages in the components array, so you'll need to clear old ones out if you don't wish for them to display.
"messageOfTheDay": {
"index": 1,
"components": [
{
"title": "Title 1",
"body": "Body 1",
"footer": "Footer 1"
},
{
"title": "Title 2",
"body": "Body 2"
},
{
"footer": "Footer 3"
},
"I am a boring message"
]
}
The advanced MoTD allows you to customize the message entirely using Material UI Components:
- Each component you add into the
components
array, is wrapped in a Grid component. You set the grid sizes for each of these. A full row is 12 units. Read more about it here.
Components available:
- Typography (type: text)
- Divider (type: divider)
- Button (type: button)
- Standard html img tag (type: image)
- Discord, Telegram, and Local login components
- If you set the type to "parent", it creates a parent grid, which you can then populate with children components.
Styling:
- Style objects must be in JS form, see https://transform.tools/css-to-js for understanding how to convert CSS props to JS
"messageOfTheDay": {
"index": 2,
"settings": {
// Shows the MoTD every time upon login
"permanent": true,
// These are properties for the parent Grid component
"parentSpacing": 0,
// https://v4.mui.com/components/grid/#spacing
"parentAlignContent": "center",
// https://v4.mui.com/components/grid/#interactive
"parentJustifyContent": "center",
// CSS Properties in a JS Object, see below for examples
"parentStyle": {},
// Show MotD to non-donors only if true
"freeloaderOnly": false,
// Show MotD to donors only if true
"donorOnly": false
// Setting both to false will show to all
},
"titles": ["title1", "title2"],
"components": [
// Add an unlimited number of blocks here
{
"type": "button",
// Size of the grid for the button
"gridSizes": {
"xs": 12,
"sm": 6,
"md": 4,
"lg": 6,
"xl": 3
},
// Styling for the grid itself
"gridStyle": {
"padding": 10
},
// Decides if it should only show to users who have the donor perm (set in config)
"donorOnly": true,
// Decides if it should only show to users who do not have the donor perm
// Leave both false to show to everyone
// Setting both to true will show to no one
"freeloaderOnly": false,
// Choose a size
"size": "small/medium/large",
"variant": "contained/outlined/text",
// Choose a color or set a CSS color (hexcode, color name, etc)
"color": "primary/secondary/#353245",
// The actual text to display on the button
"content": "Button Text",
// Link for the button
"link": "https://www.github.com",
// Styling for the button, CSS properties in a JS Object
"style": {
"textAlign": "center",
"backgroundColor": "white",
"color": "black",
"margin": "10px 20px",
"otherCssProperties": "5px"
}
},
{
// Normal Text
"type": "text",
"gridSizes": {
"xs": 12,
"sm": 6,
"md": 4,
"lg": 6,
"xl": 3
},
// Choose a variant
// See https://v4.mui.com/components/typography/#typography
"variant": "h1/h2/h3/h4/h5/h6/subtitle1/subtitle2/body1/body2/caption/button",
"color": "primary/secondary/#323425",
"content": "This is a message with a hyperlink",
// Optional link
"link": "https://www.google.com",
"linkColor": "inherit/primary/secondary/textPrimary/textSecondary",
"underline": "none/hover/always",
"style": {
"textAlign": "right",
"padding": "10px"
}
},
{
"type": "img",
"gridSizes": {
"xs": 12,
"sm": 6,
"md": 4,
"lg": 6,
"xl": 3
},
// Src of the image to display
"src": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/81/Wikimedia-logo.svg/1024px-Wikimedia-logo.svg.png",
// Optional clickable link
"link": "https://www.discord.com",
// CSS Properties of the image
"style": {
"height": 50,
"width": 50
}
},
{
"type": "divider",
"gridSizes": {
"xs": 12,
"sm": 6,
"md": 4,
"lg": 6,
"xl": 3
},
// Displays a lighter Divider on dark backdrops, probably essential
"light": true,
// You can probably leave this false but if it's giving you trouble, you may need to set to true
"flexItem": false,
// Displays the divider horizontally or vertically
"orientation": "horizontal/vertical",
"style": {
"heigh": 10,
"margin": 3
}
},
{
"type": "parent",
// This is different from the others, this builds a parent Grid object
// In the components array you can add an unlimited number of components (including additional parents)
// These can be used to further split up the 12 row limit
"gridSizes": {
"xs": 12,
"sm": 6,
"md": 4,
"lg": 6,
"xl": 3
},
"spacing": 2,
"style": {
"margin": "10px 20px"
},
"alignItems": "center",
"justifyContent": "flex-start",
"components": [
// Discord Login Button example
{
"type": "discord",
"gridSizes": {
"xs": 6
},
"link": "/auth/discord/callback",
"text": "Login",
"style": {}
},
// PayPal button example
{
"type": "button",
"gridSizes": {
"xs": 6
},
"link": "https://www.paypal.com",
"content": "PayPal",
"icon": "fab fa-paypal",
"color": "secondary",
"variant": "contained",
"style": {
"margin": 20
}
},
// Telegram button example
{
"type": "telegram",
"gridSizes": {
"xs": 12
},
"telegramBotEnvRef": "TELEGRAM_BOT_NAME",
"telegramAuthUrl": "/auth/telegram",
"style": {
"marginBottom": 20
}
},
]
}
],
// If you would like to add additional action buttons in the footer, next to the "close" button
"footerButtons": [
{
"name": "Thing",
"link": "https://www.google.com",
"icon": "Help",
"align": "center",
"color": "primary",
"donorOnly": false,
"freeloaderOnly": false,
}
]
}
See Auth Page