Compare commits

..

5 commits

Author SHA1 Message Date
f3803e95f6 Remove leftover references
Some checks failed
ci/woodpecker/push/build Pipeline failed
ci/woodpecker/push/tests Pipeline was successful
2025-03-26 09:59:11 +01:00
b0ec30d18b Fix url usages in templates
Some checks failed
ci/woodpecker/push/build Pipeline failed
ci/woodpecker/push/tests Pipeline failed
2025-03-26 09:54:16 +01:00
bcb98efeca Add missing migrations
Some checks failed
ci/woodpecker/push/build Pipeline failed
ci/woodpecker/push/tests Pipeline failed
2025-03-26 09:47:52 +01:00
497364c126 Remove reddit code
Some checks failed
ci/woodpecker/push/build Pipeline failed
ci/woodpecker/push/tests Pipeline failed
2025-03-26 09:31:04 +01:00
1b0671b34c Initial commit 2025-03-24 09:18:53 +01:00
2 changed files with 108 additions and 105 deletions

View file

@ -3,7 +3,9 @@ import React from 'react';
class Messages extends React.Component { class Messages extends React.Component {
state = { messages: this.props.messages }; state = { messages: this.props.messages };
close = (index) => { close = ::this.close;
close(index) {
const newMessages = this.state.messages.filter((message, currentIndex) => { const newMessages = this.state.messages.filter((message, currentIndex) => {
return currentIndex != index; return currentIndex != index;
}); });

View file

@ -7,131 +7,132 @@ import { SAVED_TYPE } from '../constants.js';
import { formatDatetime } from '../../../utils.js'; import { formatDatetime } from '../../../utils.js';
class PostModal extends React.Component { class PostModal extends React.Component {
readTimer = null; modalListener = ::this.modalListener;
readTimer = null;
componentDidMount() { componentDidMount() {
const post = { ...this.props.post }; const post = { ...this.props.post };
const markPostRead = this.props.markPostRead; const markPostRead = this.props.markPostRead;
const token = Cookies.get('csrftoken'); const token = Cookies.get('csrftoken');
if (this.props.autoMarking && this.props.selectedType != SAVED_TYPE && !post.read) { if (this.props.autoMarking && this.props.selectedType != SAVED_TYPE && !post.read) {
this.readTimer = setTimeout(markPostRead, 3000, post, token); this.readTimer = setTimeout(markPostRead, 3000, post, token);
}
window.addEventListener('click', this.modalListener);
} }
componentWillUnmount() { window.addEventListener('click', this.modalListener);
if (this.readTimer) { }
clearTimeout(this.readTimer);
}
this.readTimer = null; componentWillUnmount() {
if (this.readTimer) {
window.removeEventListener('click', this.modalListener); clearTimeout(this.readTimer);
} }
modalListener = (e) => { this.readTimer = null;
const targetClassName = e.target.className;
if (this.props.post && targetClassName == 'modal post-modal') { window.removeEventListener('click', this.modalListener);
this.props.unSelectPost(); }
}
modalListener(e) {
const targetClassName = e.target.className;
if (this.props.post && targetClassName == 'modal post-modal') {
this.props.unSelectPost();
}
}
render() {
const post = this.props.post;
const token = Cookies.get('csrftoken');
const publicationDate = formatDatetime(post.publicationDate);
const titleClassName = post.read ? 'post__title post__title--read' : 'post__title';
const readButtonDisabled =
post.read || this.props.isUpdating || this.props.selectedType === SAVED_TYPE;
const savedIconClass = post.saved
? 'post__save post__save--saved saved-icon saved-icon--saved'
: 'post__save saved-icon';
let ruleUrl = '';
switch (this.props.rule.type) {
default:
ruleUrl = `${this.props.feedUrl}/${this.props.rule.id}/`;
break;
} }
render() { return (
const post = this.props.post; <div className="modal post-modal">
const token = Cookies.get('csrftoken'); <div className="post">
const publicationDate = formatDatetime(post.publicationDate); <div className="post__container">
const titleClassName = post.read ? 'post__title post__title--read' : 'post__title'; <div className="post__header">
const readButtonDisabled = <div className="post__actions">
post.read || this.props.isUpdating || this.props.selectedType === SAVED_TYPE; <button
const savedIconClass = post.saved className={`button read-button ${readButtonDisabled &&
? 'post__save post__save--saved saved-icon saved-icon--saved' 'button--disabled'}`}
: 'post__save saved-icon'; onClick={() =>
!readButtonDisabled && this.props.markPostRead(post, token)
}
>
<i className="fas fa-check" /> Mark as read
</button>
<button
className="button post__close-button"
onClick={() => this.props.unSelectPost()}
>
<i className="fas fa-times"></i> Close
</button>
</div>
<div className="post__heading">
<h2 className={titleClassName}>{`${post.title} `}</h2>
<div className="post__meta">
<div className="post__text">
<span className="post__date">{publicationDate}</span>
{post.author && <span className="post__author">{post.author}</span>}
</div>
let ruleUrl = ''; <div className="post__buttons">
{this.props.category && (
switch (this.props.rule.type) { <span
default: className="badge post__category"
ruleUrl = `${this.props.feedUrl}/${this.props.rule.id}/`; title={this.props.category.name}
break; >
} <a
href={`${this.props.categoriesUrl}/${this.props.category.id}/`}
return ( target="_blank"
<div className="modal post-modal"> rel="noopener noreferrer"
<div className="post">
<div className="post__container">
<div className="post__header">
<div className="post__actions">
<button
className={`button read-button ${readButtonDisabled &&
'button--disabled'}`}
onClick={() =>
!readButtonDisabled && this.props.markPostRead(post, token)
}
>
<i className="fas fa-check" /> Mark as read
</button>
<button
className="button post__close-button"
onClick={() => this.props.unSelectPost()}
>
<i className="fas fa-times"></i> Close
</button>
</div>
<div className="post__heading">
<h2 className={titleClassName}>{`${post.title} `}</h2>
<div className="post__meta">
<div className="post__text">
<span className="post__date">{publicationDate}</span>
{post.author && <span className="post__author">{post.author}</span>}
</div>
<div className="post__buttons">
{this.props.category && (
<span
className="badge post__category"
title={this.props.category.name}
> >
<a {this.props.category.name}
href={`${this.props.categoriesUrl}/${this.props.category.id}/`}
target="_blank"
rel="noopener noreferrer"
>
{this.props.category.name}
</a>
</span>
)}
<span className="badge post__rule" title={this.props.rule.name}>
<a href={ruleUrl} target="_blank" rel="noopener noreferrer">
{this.props.rule.name}
</a> </a>
</span> </span>
<a )}
className="post__link" <span className="badge post__rule" title={this.props.rule.name}>
href={post.url} <a href={ruleUrl} target="_blank" rel="noopener noreferrer">
target="_blank" {this.props.rule.name}
rel="noopener noreferrer"
>
<i className="fas fa-external-link-alt" />
</a> </a>
<span </span>
className={savedIconClass} <a
onClick={() => this.props.toggleSaved(post, token)} className="post__link"
/> href={post.url}
</div> target="_blank"
rel="noopener noreferrer"
>
<i className="fas fa-external-link-alt" />
</a>
<span
className={savedIconClass}
onClick={() => this.props.toggleSaved(post, token)}
/>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{/* HTML is sanitized by the collectors */}
<div className="post__body" dangerouslySetInnerHTML={{ __html: post.body }} />
</div> </div>
{/* HTML is sanitized by the collectors */}
<div className="post__body" dangerouslySetInnerHTML={{ __html: post.body }} />
</div> </div>
); </div>
} );
}
} }
const mapDispatchToProps = dispatch => ({ const mapDispatchToProps = dispatch => ({