diff --git a/src/App.tsx b/src/App.tsx index b9efc6e..0f186f6 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -11,6 +11,7 @@ import ProfilePage from "./pages/ProfilePage"; import TimelinePage from "./pages/Timeline"; import Conversation from "./pages/Conversation"; import NotificationsPage from "./pages/Notifications"; +import AnnouncementsPage from "./pages/Announcements"; import SearchPage from "./pages/Search"; import Composer from "./pages/Compose"; import WelcomePage from "./pages/Welcome"; @@ -138,6 +139,10 @@ class App extends Component { )} /> + {
Account + + + + + + {
+ + + + + { + /** + * The Mastodon object to perform notification operations on. + */ + client: Mastodon; + + /** + * The stream listener for tuning in to notifications. + */ + streamListener: any; + + /** + * Construct the notifications page. + * @param props The properties to pass in + */ + constructor(props: any) { + super(props); + + // Create the Mastodon object. + this.client = new Mastodon( + localStorage.getItem("access_token") as string, + localStorage.getItem("baseurl") + "/api/v1" + ); + + // Initialize the state. + this.state = { + viewIsLoading: true + }; + } + + /** + * Perform pre-mount tasks + */ + async componentWillMount() { + try { + // Get the list of notifications + let resp: any = await this.client.get("/announcements"); + let announcements: [Announcement] = resp.data; + + this.setState({ + announcements, + viewIsLoading: false, + viewDidLoad: true + }); + } catch (e) { + this.setState({ + viewDidLoad: true, + viewIsLoading: false, + viewDidError: true, + viewDidErrorCode: e.message + }); + } + } + + /** + * Render the announcements page. + */ + render() { + const { classes } = this.props; + return ( +
+ {this.state.viewDidLoad ? ( + this.state.announcements && + this.state.announcements.length > 0 ? ( +
+ Current announcements + {this.state.announcements.map( + (announcement: Announcement) => { + return ( + + + + + } + title={`Published on ${moment( + announcement.published_at + ).format( + "MMMM Do, YYYY [at] hh:mmA" + )}`} + subheader={ + announcement.ends_at + ? `Expires ${moment( + announcement.ends_at + ).format( + "MMMM Do, YYYY" + )}` + : "" + } + > + + + + + ); + } + )} +
+ ) : ( +
+ + + No server announcements + + + There aren't any announcements in your + community. Announcements that use the + announcement feature on Mastodon will appear + here. + +
+
+ ) + ) : null} + {this.state.viewDidError ? ( + + Bummer. + + Something went wrong when loading announcements. + + + {this.state.viewDidErrorCode + ? this.state.viewDidErrorCode + : ""} + + + ) : ( + + )} + {this.state.viewIsLoading ? ( +
+ +
+ ) : ( + + )} +
+ ); + } +} + +export default withStyles(styles)(withSnackbar(AnnouncementsPage)); diff --git a/src/types/Announcement.tsx b/src/types/Announcement.tsx new file mode 100644 index 0000000..b15a9d0 --- /dev/null +++ b/src/types/Announcement.tsx @@ -0,0 +1,17 @@ +import { Account } from "./Account"; +import { Tag } from "./Tag"; +import { MastodonEmoji } from "./Emojis"; + +export type Announcement = { + id: string; + content: string; + starts_at?: string; + ends_at?: string; + all_day: boolean; + published_at: string; + updated_at: string; + read: boolean; + mentions: [Account]; + tags: [Tag]; + emojis: [MastodonEmoji]; +};