diff --git a/assets/listings.css b/assets/listings.css index 8cd61bf..1618a1f 100644 --- a/assets/listings.css +++ b/assets/listings.css @@ -35,51 +35,54 @@ body { color: var(--text); } -body > .listing { - display: flex; - flex-flow: row nowrap; - justify-content: space-between; +#listings > .listing { + display: grid; + grid-template-columns: 3fr auto 2fr; + gap: 1em; padding: 1em; - margin-bottom: 1em; background-color: var(--row-background); } -body > .listing .left { - flex: 2 0 0; -} - -body > .listing .middle { - flex: 1 0 0 ; -} - -body > .listing:nth-child(2n) { +#listings > .listing:nth-child(2n) { background-color: var(--row-background-alternate); } -body > .listing .description { +#listings > .listing .description { white-space: pre-wrap; word-break: break-word; } -body > .listing .stat { +#listings > .listing .description .desc-green { + color: var(--green-text); +} + +#listings > .listing .description .desc-blue { + color: var(--light-blue-text); +} + +#listings > .listing .description .desc-yellow { + color: var(--gold-text); +} + +#listings > .listing .stat { color: var(--meta-text); } -body > .listing .duty { +#listings > .listing .duty { font-size: 1.2em; } -body > .listing .duty.cross { +#listings > .listing .duty.cross { color: var(--cross-duty-text); } -body > .listing .duty.local { +#listings > .listing .duty.local { color: var(--local-duty-text); } -body > .listing .meta { +#listings > .listing .meta { display: flex; flex-direction: column; @@ -89,13 +92,13 @@ body > .listing .meta { text-align: right; } -body > .listing .meta > .item { +#listings > .listing .meta > .item { display: flex; flex-flow: row nowrap; align-self: flex-end; } -body > .listing .meta > .item .icon { +#listings > .listing .meta > .item .icon { height: 1em; width: 1em; fill: var(--text); @@ -104,7 +107,7 @@ body > .listing .meta > .item .icon { justify-self: center; } -body > .listing .party { +#listings > .listing .party { margin-top: .5em; display: grid; @@ -112,19 +115,19 @@ body > .listing .party { gap: .5em; } -body > .listing .party > .total { +#listings > .listing .party > .total { align-self: center; justify-self: center; } -body > .listing .party > .slot { +#listings > .listing .party > .slot { width: 2em; height: 2em; border: 1px solid currentColor; margin-right: .5em; } -body > .listing .party > .slot:not(.filled).dps.tank { +#listings > .listing .party > .slot:not(.filled).dps.tank { background: linear-gradient( to bottom, var(--tank-blue) 0%, @@ -133,7 +136,7 @@ body > .listing .party > .slot:not(.filled).dps.tank { ); } -body > .listing .party > .slot:not(.filled).dps.healer { +#listings > .listing .party > .slot:not(.filled).dps.healer { background: linear-gradient( to bottom, var(--healer-green) 0%, @@ -142,7 +145,7 @@ body > .listing .party > .slot:not(.filled).dps.healer { ); } -body > .listing .party > .slot:not(.filled).tank.healer { +#listings > .listing .party > .slot:not(.filled).tank.healer { background: linear-gradient( to bottom, var(--tank-blue) 0%, @@ -151,7 +154,7 @@ body > .listing .party > .slot:not(.filled).tank.healer { ); } -body > .listing .party > .slot:not(.filled).tank.healer.dps { +#listings > .listing .party > .slot:not(.filled).tank.healer.dps { background: linear-gradient( to bottom, var(--tank-blue) 0%, @@ -162,70 +165,65 @@ body > .listing .party > .slot:not(.filled).tank.healer.dps { ); } -body > .listing .party > .slot:not(.filled).dps { +#listings > .listing .party > .slot:not(.filled).dps { background-color: var(--dps-red); } -body > .listing .party > .slot.filled { +#listings > .listing .party > .slot.filled { background-color: var(--slot-background); border-color: var(--icon-gold); } -body > .listing .party > .slot.empty { +#listings > .listing .party > .slot.empty { background-color: var(--slot-empty); } -body > .listing .party > .slot.dps { +#listings > .listing .party > .slot.dps { background-color: var(--dps-red); } -body > .listing .party > .slot.healer { +#listings > .listing .party > .slot.healer { background-color: var(--healer-green); } -body > .listing .party > .slot.tank { +#listings > .listing .party > .slot.tank { background-color: var(--tank-blue); } -body > .listing .party > .slot > svg { +#listings > .listing .party > .slot > svg { width: 100%; height: 100%; fill: var(--icon-gold); } -body > .listing .party > .slot.filled:not(.dps):not(.healer):not(.tank) > svg { +#listings > .listing .party > .slot.filled:not(.dps):not(.healer):not(.tank) > svg { fill: #C6C6C6; } -/* Really, this could be 26em */ -@media (max-width: 30em) { - body > .listing { - flex-flow: column nowrap; +@media (max-width: 50em) { + #listings > .listing { + grid-template-columns: repeat(auto-fit, 100%); } - body > .listing > :not(:first-child) { - margin-top: .5em; - margin-left: 0; + #listings > .listing > :not(:first-child) { + margin: 0; } - body > .listing .meta { - flex-grow: 1; - - margin-left: 0; + #listings > .listing .meta { text-align: unset; } - body > .listing .meta > .item { + #listings > .listing .meta > .item { align-self: unset; } - body > .listing .meta > .item .icon { + #listings > .listing .meta > .item .icon { order: 1; margin-left: 0; margin-right: .5em; } - body > .listing .meta > .item > .text { + #listings > .listing .meta > .item .text { order: 2; } } diff --git a/assets/listings.js b/assets/listings.js new file mode 100644 index 0000000..4829e4d --- /dev/null +++ b/assets/listings.js @@ -0,0 +1,41 @@ +(function () { + let select = document.getElementById('data-centre-filter'); + + let data_centres = []; + for (let elem of document.querySelectorAll('#listings > .listing')) { + let centre = elem.dataset['centre']; + if (data_centres.indexOf(centre) === -1) { + data_centres.push(centre); + let opt = document.createElement('option'); + opt.innerText = centre; + select.appendChild(opt); + } + } + + let options = { + valueNames: [ + 'duty', + 'creator', + 'description', + {data: ['centre']}, + ], + }; + let list = new List('container', options); + + select.addEventListener('change', () => { + let centre = select.value; + if (centre === 'All') { + list.filter(); + return; + } + + console.log(`looking for ${centre}`); + + list.filter(item => { + console.log(item.values().centre === centre) + return item.values().centre === centre; + // console.log(item.elm.dataset['centre']); + // return item.elm.dataset['centre'] === centre; + }); + }); +})(); diff --git a/src/listing.rs b/src/listing.rs index 4616206..c585ac1 100644 --- a/src/listing.rs +++ b/src/listing.rs @@ -109,6 +109,45 @@ impl PartyFinderListing { .map(|world| Cow::from(world.name())) .unwrap_or_else(|| Cow::from(self.home_world.to_string())) } + + pub fn prepend_flags(&self) -> (&'static str, String) { + let mut colour_class = ""; + let mut flags = Vec::new(); + + if self.objective.contains(ObjectiveFlags::PRACTICE) { + flags.push("[Practice]"); + colour_class = "desc-green"; + } + + if self.objective.contains(ObjectiveFlags::DUTY_COMPLETION) { + flags.push("[Duty Completion]"); + colour_class = "desc-blue"; + } + + if self.objective.contains(ObjectiveFlags::LOOT) { + flags.push("[Loot]"); + colour_class = "desc-yellow"; + } + + if self.conditions.contains(ConditionFlags::DUTY_COMPLETE) { + flags.push("[Duty Complete]"); + } + + if self.conditions.contains(ConditionFlags::DUTY_INCOMPLETE) { + flags.push("[Duty Incomplete]"); + } + + if self.search_area.contains(SearchAreaFlags::ONE_PLAYER_PER_JOB) { + flags.push("[One Player per Job]"); + } + + (colour_class, flags.join("")) + } + + pub fn data_centre_name(&self) -> Option<&'static str> { + crate::ffxiv::WORLDS.get(&u32::from(self.created_world)) + .map(|w| w.data_center().name()) + } } #[derive(Debug, Deserialize, Serialize, PartialEq)] diff --git a/src/web.rs b/src/web.rs index 8aca920..4486e51 100644 --- a/src/web.rs +++ b/src/web.rs @@ -79,6 +79,7 @@ fn assets() -> BoxedFilter<(impl Reply, )> { icons() .or(minireset()) .or(listings_css()) + .or(listings_js()) ) .boxed() } @@ -104,6 +105,13 @@ fn listings_css() -> BoxedFilter<(impl Reply, )> { .boxed() } +fn listings_js() -> BoxedFilter<(impl Reply, )> { + warp::path("listings.js") + .and(warp::path::end()) + .and(warp::fs::file("./assets/listings.js")) + .boxed() +} + fn index() -> BoxedFilter<(impl Reply, )> { let route = warp::path::end() .map(|| warp::redirect(Uri::from_static("/listings"))); diff --git a/templates/listings.html b/templates/listings.html index 88fd28d..e2b4cb2 100644 --- a/templates/listings.html +++ b/templates/listings.html @@ -6,99 +6,114 @@ Remote Party Finder {% block head %} + + {% endblock %} {% block body %} -{% for container in containers %} -{% let listing = container.listing.borrow() %} -