Skip to content

Commit

Permalink
doneso
Browse files Browse the repository at this point in the history
  • Loading branch information
fatfingers23 committed Apr 20, 2024
1 parent a6920bd commit 09b6859
Show file tree
Hide file tree
Showing 15 changed files with 359 additions and 42 deletions.
7 changes: 4 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

47 changes: 45 additions & 2 deletions trackscape-discord-api/src/controllers/clan_controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use actix_web::{get, web, Error, HttpResponse, Scope};
use log::{error, info};
use serde::{Deserialize, Serialize};
use std::str::FromStr;
use tokio::time::sleep;
use trackscape_discord_shared::database::clan_mate_collection_log_totals::ClanMateCollectionLogTotals;
use trackscape_discord_shared::database::clan_mates::{ClanMateModel, ClanMates};
use trackscape_discord_shared::database::BotMongoDb;
Expand Down Expand Up @@ -106,7 +105,6 @@ async fn collection_log(
mongodb: Data<BotMongoDb>,
path: web::Path<(String,)>,
) -> Result<HttpResponse, Error> {
sleep(std::time::Duration::from_secs(1)).await;
let id = path.into_inner().0;
let possible_parsed_id = bson::oid::ObjectId::from_str(id.as_str());
let id = match possible_parsed_id {
Expand Down Expand Up @@ -148,9 +146,54 @@ async fn collection_log(
}
}

#[derive(Deserialize)]
struct BroadcastRequest {
id: String,
limit: i64,
}

#[get("/{id}/broadcasts/{limit}")]
async fn broadcasts(
mongodb: Data<BotMongoDb>,
path: web::Path<BroadcastRequest>,
) -> Result<HttpResponse, Error> {
let possible_parsed_id = bson::oid::ObjectId::from_str(path.id.as_str());
let id = match possible_parsed_id {
Ok(parsed_id) => parsed_id,
Err(_) => {
return Ok(HttpResponse::BadRequest().body("Invalid id format."));
}
};
let registered_guild_query = mongodb.guilds.get_by_id(id).await;
match registered_guild_query {
Ok(possible_guild) => match possible_guild {
Some(guild) => {
let limit_to_use = if path.limit > 100 { 100 } else { path.limit };
let broadcasts = mongodb
.broadcasts
.get_latest_broadcasts(guild.guild_id, limit_to_use)
.await;
match broadcasts {
Ok(broadcasts) => Ok(HttpResponse::Ok().json(broadcasts)),
Err(err) => {
error!("Failed to get broadcasts: {}", err);
Ok(HttpResponse::BadRequest().body("There was an issue with the request"))
}
}
}
None => Ok(HttpResponse::BadRequest().body("There is not a clan with that id")),
},
Err(err) => {
error!("Failed to get clan by id: {}", err);
Ok(HttpResponse::BadRequest().body("There was an issue with the request"))
}
}
}

pub fn clan_controller() -> Scope {
web::scope("/clans")
.service(list_clans)
.service(detail)
.service(collection_log)
.service(broadcasts)
}
1 change: 1 addition & 0 deletions trackscape-discord-shared/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ edition = "2021"

[dependencies]
async-recursion = "1.0.5"
bson = { version = "2.10.0", features = ["chrono-0_4"] }
tracing = "0.1.37"
num-format = "0.4.4"
futures = "0.3.28"
Expand Down
28 changes: 25 additions & 3 deletions trackscape-discord-shared/src/database/broadcasts.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::database::BroadcastsDb;
use crate::osrs_broadcast_handler::BroadcastMessageToDiscord;
use bson::DateTime;
use futures::TryStreamExt;
use mockall::predicate::*;
use mongodb::bson::{doc, DateTime};
use mongodb::bson::doc;
use mongodb::{bson, Database};
use serde::{Deserialize, Serialize};

Expand All @@ -11,7 +13,11 @@ pub struct BroadcastModel {
pub id: bson::oid::ObjectId,
pub guild_id: u64,
pub broadcast: BroadcastMessageToDiscord,
pub created_at: Option<DateTime>,
#[serde(serialize_with = "bson::serde_helpers::serialize_bson_datetime_as_rfc3339_string")]
#[serde(
deserialize_with = "bson::serde_helpers::deserialize_bson_datetime_from_rfc3339_string"
)]
pub created_at: DateTime,
}

impl BroadcastsDb {
Expand All @@ -30,11 +36,27 @@ impl BroadcastsDb {
id: bson::oid::ObjectId::new(),
guild_id,
broadcast,
created_at: Some(DateTime::now()),
created_at: DateTime::now(),
};
collection.insert_one(model, None).await?;
Ok(())
}

pub async fn get_latest_broadcasts(
&self,
guild_id: u64,
limit: i64,
) -> Result<Vec<BroadcastModel>, anyhow::Error> {
let collection = self.db.collection(Self::COLLECTION_NAME);
let filter = doc! { "guild_id": bson::to_bson(&guild_id).unwrap() };
let options = mongodb::options::FindOptions::builder()
.sort(doc! { "created_at": -1 })
.limit(limit)
.build();
let cursor = collection.find(filter, options).await?;
let broadcasts: Vec<BroadcastModel> = cursor.try_collect().await?;
Ok(broadcasts)
}
}

impl BroadcastsDb {
Expand Down
39 changes: 39 additions & 0 deletions trackscape-discord-ui/src/components/BroadcastItem.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<script setup lang="ts">
import type { Broadcast } from '@/services/TrackscapeApiTypes'
import { type PropType, ref } from 'vue'

Check warning on line 3 in trackscape-discord-ui/src/components/BroadcastItem.vue

View workflow job for this annotation

GitHub Actions / Check Frontend

'ref' is defined but never used

Check warning on line 3 in trackscape-discord-ui/src/components/BroadcastItem.vue

View workflow job for this annotation

GitHub Actions / Check Frontend

'ref' is defined but never used
const props = defineProps({
broadcast: {
type: Object as PropType<Broadcast>,
required: true
}
})
</script>

<template>
<div class="p-2 shadow-xl bg-base-100">
<div class="flex items-center gap-x-7">
<div class="flex items-center">
<img v-if="props.broadcast.broadcast.icon_url !== null"
class="w-10 h-10 rounded-full object-contain mr-1"
:src="props.broadcast.broadcast.icon_url"
onerror="this.src = '/src/assets/img/Trackscape_Logo_icon.png'"
alt=""
/>

<div>
<p class="text-md font-bold">{{ props.broadcast.broadcast.title }}</p>
<p class="text-sm text-gray-500">{{ props.broadcast.created_at }}</p>
</div>
</div>
</div>
<div class="mt-1">
<p>{{ props.broadcast.broadcast.message }}</p>
</div>
</div>
</template>

<style scoped>
</style>
105 changes: 105 additions & 0 deletions trackscape-discord-ui/src/components/BroadcastList.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<script setup lang="ts">
import BroadcastItem from '@/components/BroadcastItem.vue'
import { ref } from 'vue'
import type { Broadcast } from '@/services/TrackscapeApiTypes'
import TrackscapeApiClient from '@/services/TrackscapeApiClient'
let broadcasts = ref<Broadcast[]>()
let loading = ref(true)
let props = defineProps({
clanId: {
type: String,
required: true
},
limit: {
type: Number,
required: false,
default: 10
},
showHeader: {
type: Boolean,
required: false,
default: true
}
})
let client = new TrackscapeApiClient(import.meta.env.VITE_API_BASE_URL)
client.getBroadcasts(props.clanId, props.limit).then((broadcastsResult) => {
broadcastsResult.forEach((broadcast) => {
broadcast.created_at = new Date(broadcast.created_at).toLocaleString()
broadcast.broadcast.title = broadcast.broadcast.title.replace(/:.*:/, '')
})
broadcasts.value = broadcastsResult
loading.value = false
})
</script>

<template>
<TransitionGroup name="slide-fade">

<div v-if="loading">
<div class="flex items-center gap-x-2">
</div>
<div class="mt-2">
<div v-for="index in 10"
:key="index"
class="p-2 shadow-xl bg-base-100">
<div class="p-2 shadow-xl bg-base-100">
<div class="flex items-center ">
<div class="flex items-center">
<div class="skeleton w-10 h-10 rounded-full shrink-0"></div>
<div class="flex flex-col gap-1">
<div class="skeleton h-6 w-28"></div>
<div class="skeleton h-4 w-28"></div>
</div>
</div>
</div>
<div class="mt-1 flex flex-col gap-1">
<div class="skeleton h-4 w-3/4"></div>
<div class="skeleton h-4 w-3/4"></div>
</div>
</div>
</div>
</div>
</div>

<div v-else>
<div class="flex items-center gap-x-2">
<div v-if="props.showHeader"
class="flex items-center">
<div>
<p class="text-lg font-bold">Recent Broadcasts</p>
</div>
</div>
</div>
<div class="mt-2">
<div v-for="broadcast in broadcasts"
:key="broadcast.id"
class="p-5 shadow-xl bg-base-100">
<BroadcastItem :broadcast="broadcast" />
</div>
</div>
</div>
</TransitionGroup>


</template>

<style scoped>
.slide-fade-enter-active {
transition: all 0.1s ease-in;
}
.slide-fade-leave-active {
transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1);
}
.slide-fade-enter-from,
.slide-fade-leave-to {
transform: translateX(-20px);
opacity: 0;
}
</style>
9 changes: 7 additions & 2 deletions trackscape-discord-ui/src/router/clans.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,18 @@ export default [
{
path: "",
name: "members",
component: () => import('@/views/clans/clan/MembersView.vue'),
component: () => import('@/views/clans/clan/subviews/MembersView.vue'),

},
{
path: "collectionlog",
name: "collection-log",
component: () => import('@/views/clans/clan/CollectionLogLeaderboardView.vue'),
component: () => import('@/views/clans/clan/subviews/CollectionLogLeaderboardView.vue'),
},
{
path: "broadcasts",
name: "broadcasts",
component: () => import('@/views/clans/clan/subviews/RecentBroadcastsView.vue'),
}
]

Expand Down
12 changes: 11 additions & 1 deletion trackscape-discord-ui/src/services/TrackscapeApiClient.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import type {BotInfo, Clan, ClanDetail, ClanMateCollectionLogTotalsView} from "@/services/TrackscapeApiTypes";
import type {
BotInfo,
Broadcast,
Clan,
ClanDetail,
ClanMateCollectionLogTotalsView
} from '@/services/TrackscapeApiTypes'

export default class TrackscapeApiClient {

Expand Down Expand Up @@ -29,5 +35,9 @@ export default class TrackscapeApiClient {
return this.get<ClanMateCollectionLogTotalsView[]>(`/clans/${clanId}/collection-log`);
}

public async getBroadcasts(clanID: string, limit: number): Promise<Broadcast[]> {
return this.get<Broadcast[]>(`/clans/${clanID}/broadcasts/${limit}`);
}

}

Loading

0 comments on commit 09b6859

Please sign in to comment.