Skip to content

Commit

Permalink
reactivate clan-list/view with the new m2m client (#519)
Browse files Browse the repository at this point in the history
* reactivate clan-list/view with the new m2m2 client

* update clanview and remove cache for single views
  • Loading branch information
fcaps committed Dec 3, 2023
1 parent d231e86 commit c8ccf5d
Show file tree
Hide file tree
Showing 21 changed files with 514 additions and 232 deletions.
3 changes: 3 additions & 0 deletions package.json
Expand Up @@ -24,12 +24,14 @@
"request": "2.88.2",
"session-file-store": "^1.5.0",
"showdown": "^2.1.0",
"simple-datatables": "^9.0.0",
"simple-oauth2": "^5.0.0",
"supertest-session": "^5.0.1",
"url-slug": "^4.0.1"
},
"devDependencies": {
"awesomplete": "^1.1.5",
"css-loader": "^6.8.1",
"dart-sass": "^1.25.0",
"eslint": "^8.54.0",
"eslint-config-standard": "^17.1.0",
Expand All @@ -49,6 +51,7 @@
"load-grunt-tasks": "5.1.0",
"nock": "^13.3.8",
"octokit": "^3.1.2",
"style-loader": "^3.3.3",
"supertest": "^6.3.3",
"typescript": "^5.3.2",
"webpack": "^5.89.0",
Expand Down
230 changes: 31 additions & 199 deletions public/styles/site/clans.sass
@@ -1,204 +1,36 @@
@use '../abstracts/variables'
@use '../abstracts/mixins'

// Background of the whole thing
.clanBackground
padding: 7.5vw 11vw
background-image: url("/../../images/fafbgpattern0.5.jpg")
ul
list-style: none
li
padding: 0.5em 0

// This is the searchbar input form
input
margin: 1em 1em 2px 1em
background-color: variables.$background-tertiary
color: variables.$color-active
font-size: var(--paragraph-font-size)
border: 0.5em solid variables.$background-secondary
border-radius: 10px
z-index: 2
position: relative



// The main box with all the names, tags, ranks, etc.
.mainClanContainer
@include mixins.gridMainContainer
padding: 0
p
padding: 0.2em

.clanContainer
font-family: variables.$family-paragraph
padding: 0em
.clanItem

ul
font-size: var(--paragraph-font-size)
padding: 1em 0
font-weight: 700

// ACTUAL LISTS
// There is a double li element here because the js creates a li parent element and then puts another li child element (which the child is all the names you see like ANZ and so on)
li
list-style: none
font-weight: normal
padding: 0em 0
li
font-size: var(--paragraph-font-size)
padding: 1em 0

.clanBorder
border: 1px solid variables.$color-active
padding: 0px
background-color: variables.$background-primary

// Change background colors on items in the leaderboard
.clanItem
li:nth-child(odd)
background-color: mix(variables.$background-tertiary, variables.$background-primary, 25%)
li:nth-child(even)
background-color: variables.$background-secondary

// First page last page, etc
.clanButton
padding: 1em 0.25em
display: inline-block
place-items: start
font-family: variables.$family-paragraph
font-size: var(--paragraph-font-size)
letter-spacing: 0em
ul
padding: 0.5em
font-weight: 900
li

display: inline-block
padding: 0.6em 1em
border: 0.05em solid variables.$color-inactive
background-color: variables.$background-tertiary
cursor: pointer
transition: 0.4s
&:hover
border: 0.05em solid variables.$color-active
filter: brightness(2)
.exhaustedButton
border: 0.05em solid variables.$color-inactive
background-color: variables.$background-secondary
color: variables.$color-inactive-plus
pointer-events: none
cursor: default

#searchResults
margin: 1em 0 0 0
.appearWhenSearching
display: none
.centerYourself
display: grid
justify-items: center
position: relative

.searchBar
ul
background-color: variables.$background-secondary
color: variables.$color-inactive
font-size: calc(var(--paragraph-font-size) * 0.9)
border-radius: 0 0 10px 10px
#clan-view
text-align: left
li
padding: 0.5em 1em

.clearButton
li
cursor: pointer
margin: 1em 1em 0 1em
border-radius: 10px
background-color: variables.$background-tertiary
color: variables.$color-inactive
transition: 0.4s
&:hover
background-color: variables.$color-inactive-plus
color: variables.$color-active
.fa-trash-alt
padding: 0.5em

@media (max-width: 800px)
.clanFilter
font-size: 10px
.clanContainer
ul
font-size: 10px
padding: 1em 0 0 0

li
text-overflow: ellipsis
font-size: 10px
padding: 1em 0

.clearButton
left: 90%
top: 68%
.clanBackground
padding: 1vw
.clanButton
padding: 1vw
font-size: var(--paragraph-font-size)
ul
li
padding: 0.65em
.clanDelete
font-size: 10px


@media (max-width: 1600px)
.clanContainer
ul
font-size: 14px
li
font-size: 14px
.clanFilter
font-size: 14px



// Below are classes that depend
.clanManagement
@include mixins.gridMainContainer
padding: 0vw 15vw
margin: 1em 0
.clanManagementItem
padding: 1.5em 0
display: inline-block
justify-self: center
align-self: center

//clan Description
textarea
width: 40vw

.clanManagementDanger
background-color: variables.$Cybran-dark
border-radius: 20px
ul
text-align: center
li
display: inline-block
list-style: none
text-align: left
.clanManagementTable
padding: 1.5em
display: inline-block
justify-self: center
align-self: center
th
padding: 4em

@media (max-width: 800px)
.clanManagement
padding: 5px
.bigButton
font-size: 1.25em


margin: 20px 60px
#clan-info
text-align: left
td
padding: 10px
#clan-table
button
margin: 0
padding: 0
.datatable-sorter::before
border-top: 4px solid white
.datatable-sorter::after
border-bottom: 4px solid white
tbody
tr:hover
background-color: #1f2349
cursor: pointer
td
text-align: left
#clan-members
button
margin: 0
padding: 0
.datatable-sorter::before
border-top: 4px solid white
.datatable-sorter::after
border-bottom: 4px solid white
tbody
td
text-align: left
9 changes: 9 additions & 0 deletions src/backend/dependency-injection/AppContainer.js
Expand Up @@ -4,6 +4,8 @@ const { LeaderboardService } = require('../services/LeaderboardService')
const { JavaApiM2MClient } = require('../services/JavaApiM2MClient')
const { WordpressService } = require('../services/WordpressService')
const { WordpressRepository } = require('../services/WordpressRepository')
const { DataRepository } = require('../services/DataRepository')
const { ClanService } = require('../services/ClanService')
const NodeCache = require('node-cache')
const { Axios } = require('axios')
const fs = require('fs')
Expand Down Expand Up @@ -50,5 +52,12 @@ module.exports.appContainer = function (appConfig) {
.addArgument(new Reference('NodeCache'))
.addArgument(new Reference('LeaderboardRepository'))

container.register('DataRepository', DataRepository)
.addArgument(new Reference('JavaApiM2MClient'))

container.register('ClanService', ClanService)
.addArgument(new Reference('NodeCache'))
.addArgument(new Reference('DataRepository'))

return container
}
10 changes: 10 additions & 0 deletions src/backend/routes/views/clanRouter.js
Expand Up @@ -2,6 +2,16 @@ const express = require('../../ExpressApp')
const router = express.Router()

// This will be replaced soon, therefor I did not spend time on it
router.get('/', (req, res) => res.render('clans/clans'))
router.get('/view/:id', async (req, res) => {
const clanId = parseInt(req.params.id || null)
if (!clanId) {
return res.redirect('/clans')
}

return res.render('clans/clan', { clan: await req.appContainer.get('ClanService').getClan(clanId) })
})

router.get('*', (req, res) => res.status(503).render('errors/503-known-issue'))

module.exports = router
15 changes: 15 additions & 0 deletions src/backend/routes/views/clans/get/clan.js
@@ -0,0 +1,15 @@
const { query, validationResult, matchedData } = require('express-validator')

module.exports = [
query('id').notEmpty().isInt(),

async (req, res) => {
const result = validationResult(req)

if (result.isEmpty()) return res.redirect('/clans')

const data = matchedData(req)

return res.render('clans/clan', { clan: await req.appContainer.get('ClanService').getClan(data.id) })
}
]
18 changes: 18 additions & 0 deletions src/backend/routes/views/dataRouter.js
Expand Up @@ -43,4 +43,22 @@ router.get('/recent-players.json', async (req, res) => {
getData(req, res, 'content-creators', data)
})

router.get('/clans.json', async (req, res) => {
try {
return res.json(await req.appContainer.get('ClanService').getAll())
} catch (e) {
if (e instanceof AcquireTimeoutError) {
return res.status(503).json({ error: 'timeout reached' })
}

console.error('[error] dataRouter::get:clans.json failed with "' + e.toString() + '"')

if (!res.headersSent) {
return res.status(500).json({ error: 'unexpected error' })
}

throw e
}
})

module.exports = router
5 changes: 4 additions & 1 deletion src/backend/routes/views/defaultRouter.js
Expand Up @@ -12,7 +12,10 @@ router.get('/faf-teams', (req, res) => res.render('faf-teams'))
router.get('/contribution', (reqd, res) => res.render('contribution'))
router.get('/content-creators', (reqd, res) => res.render('content-creators'))
router.get('/play', (reqd, res) => res.render('play'))

// redirect for the game-client https://github.com/FAForever/website/issues/459
router.get('/clan/:id', (req, res) => {
res.redirect('/clans/view/' + req.params.id)
})
// https://github.com/search?q=org%3AFAForever+account_activated&type=code
router.get('/account_activated', (req, res) => res.redirect('/account/register'))

Expand Down
42 changes: 42 additions & 0 deletions src/backend/services/ClanService.js
@@ -0,0 +1,42 @@
const { MutexService } = require('./MutexService')
const clanTTL = 60 * 5

class ClanService {
constructor (cacheService, dataRepository, lockTimeout = 3000) {
this.lockTimeout = lockTimeout
this.cacheService = cacheService
this.mutexService = new MutexService()
this.dataRepository = dataRepository
}

getCacheKey (name) {
return 'ClanService_' + name
}

async getClan (id, ignoreCache = false) {
return await this.dataRepository.fetchClan(id)
}

async getAll () {
const cacheKey = this.getCacheKey('all')

if (this.cacheService.has(cacheKey)) {
return this.cacheService.get(cacheKey)
}

if (this.mutexService.locked) {
await this.mutexService.acquire(() => {
}, this.lockTimeout)
return this.getAll()
}

await this.mutexService.acquire(async () => {
const result = await this.dataRepository.fetchAllClans()
this.cacheService.set(cacheKey, result, clanTTL)
})

return this.getAll()
}
}

module.exports.ClanService = ClanService

0 comments on commit c8ccf5d

Please sign in to comment.