Skip to content

Commit

Permalink
Minimal posting threads views (#1778)
Browse files Browse the repository at this point in the history
  • Loading branch information
rafalp authored Aug 7, 2024
1 parent 281d09d commit c65d601
Show file tree
Hide file tree
Showing 92 changed files with 3,368 additions and 160 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ A function implemented by a plugin that can be registered in this hook.

A standard Misago function used to check if the user has permission to browse a category. It also checks if the user can see the category. It raises Django's `Http404` if they can't see it or `PermissionDenied` with an error message if they can't browse it.

Browse the [action](#action) section for details.
See the [action](#action) section for details.


#### `user_permissions: UserPermissionsProxy`
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# `check_post_in_closed_category_permission_hook`

This hook wraps the standard function that Misago uses to check if the user has permission to post in a closed category. It raises Django's `PermissionDenied` with an error message if category is closed and they can't post in it.


## Location

This hook can be imported from `misago.permissions.hooks`:

```python
from misago.permissions.hooks import check_post_in_closed_category_permission_hook
```


## Filter

```python
def custom_check_post_in_closed_category_permission_filter(
action: CheckPostInClosedCategoryPermissionHookAction,
permissions: 'UserPermissionsProxy',
category: Category,
) -> None:
...
```

A function implemented by a plugin that can be registered in this hook.


### Arguments

#### `action: CheckPostInClosedCategoryPermissionHookAction`

A standard Misago function used to check if the user has permission to post in a closed category. It raises Django's `PermissionDenied` with an error message if category is closed and they can't post in it.

See the [action](#action) section for details.


#### `user_permissions: UserPermissionsProxy`

A proxy object with the current user's permissions.


#### `category: Category`

A category to check permissions for.


## Action

```python
def check_post_in_closed_category_permission_action(
permissions: 'UserPermissionsProxy', category: Category
) -> None:
...
```

A standard Misago function used to check if the user has permission to post in a closed category. It raises Django's `PermissionDenied` with an error message if category is closed and they can't post in it.


### Arguments

#### `user_permissions: UserPermissionsProxy`

A proxy object with the current user's permissions.


#### `category: Category`

A category to check permissions for.


## Example

The code below implements a custom filter function that permits a user to post in the specific category if they have a custom flag set on their account.

```python
from misago.categories.models import Category
from misago.permissions.hooks import check_post_in_closed_category_permission_hook
from misago.permissions.proxy import UserPermissionsProxy

@check_post_in_closed_category_permission_hook.append_filter
def check_user_can_post_in_closed_category(
action,
permissions: UserPermissionsProxy,
category: Category,
) -> None:
user = permissions.user
if user.is_authenticated:
post_in_closed_categories = (
user.plugin_data.get("post_in_closed_categories") or []
)
else:
post_in_closed_categories = None

if (
not post_in_closed_categories
or category.id not in post_in_closed_categories
):
action(permissions, category)
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# `check_start_private_threads_permission_hook`

This hook wraps the standard function that Misago uses to check if the user has a permission to start bew private threads. Raises Django's `PermissionDenied` with an error message if they don't.


## Location

This hook can be imported from `misago.permissions.hooks`:

```python
from misago.permissions.hooks import check_start_private_threads_permission_hook
```


## Filter

```python
def custom_check_start_private_threads_permission_filter(
action: CheckStartPrivateThreadsPermissionHookAction,
permissions: 'UserPermissionsProxy',
) -> None:
...
```

A function implemented by a plugin that can be registered in this hook.


### Arguments

#### `action: CheckStartPrivateThreadsPermissionHookAction`

A standard Misago function used to check if the user has a permission to start new private threads. Raises Django's `PermissionDenied` with an error message if they don't.

See the [action](#action) section for details.


#### `user_permissions: UserPermissionsProxy`

A proxy object with the current user's permissions.


## Action

```python
def check_start_private_threads_permission_action(permissions: 'UserPermissionsProxy') -> None:
...
```

A standard Misago function used to check if the user has a permission to start new private threads. Raises Django's `PermissionDenied` with an error message if they don't.


### Arguments

#### `user_permissions: UserPermissionsProxy`

A proxy object with the current user's permissions.


## Example

The code below implements a custom filter function that blocks user from starting new private threads if there's a custom flag set on their account.

```python
from django.core.exceptions import PermissionDenied
from django.utils.translation import pgettext
from misago.permissions.hooks import check_start_private_threads_permission_hook
from misago.permissions.proxy import UserPermissionsProxy

@check_start_private_threads_permission_hook.append_filter
def check_user_is_banned_from_starting_private_threads(
action,
permissions: UserPermissionsProxy,
) -> None:
# Run standard permission checks
action(permissions)

if permissions.user.plugin_data.get("ban_start_private_threads"):
raise PermissionDenied(
pgettext(
"private threads permission error",
"Site admin has removed your option to start private threads."
)
)
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# `check_start_thread_in_category_permission_hook`

This hook wraps the standard Misago function used to check if the user has permission to start a new thread in a category. It raises Django's `PermissionDenied` with an error message if they can't start thread in a category.


## Location

This hook can be imported from `misago.permissions.hooks`:

```python
from misago.permissions.hooks import check_start_thread_in_category_permission_hook
```


## Filter

```python
def custom_check_start_thread_in_category_permission_filter(
action: CheckStartThreadInCategoryPermissionHookAction,
permissions: 'UserPermissionsProxy',
category: Category,
) -> None:
...
```

A function implemented by a plugin that can be registered in this hook.


### Arguments

#### `action: CheckStartThreadInCategoryPermissionHookAction`

A standard Misago function used to check if the user has permission to start a new thread in a category. It raises Django's `PermissionDenied` with an error message if they can't start thread in a category.

See the [action](#action) section for details.


#### `user_permissions: UserPermissionsProxy`

A proxy object with the current user's permissions.


#### `category: Category`

A category to check permissions for.


## Action

```python
def check_start_thread_in_category_permission_action(
permissions: 'UserPermissionsProxy', category: Category
) -> None:
...
```

A standard Misago function used to check if the user has permission to start a new thread in a category. It raises Django's `PermissionDenied` with an error message if they can't start thread in a category.


### Arguments

#### `user_permissions: UserPermissionsProxy`

A proxy object with the current user's permissions.


#### `category: Category`

A category to check permissions for.


## Example

The code below implements a custom filter function that prevents the user from starting a thread in category if their account is newer than 7 days.

```python
from datetime import timedelta

from django.core.exceptions import PermissionDenied
from django.utils import timezone
from misago.categories.models import Category
from misago.permissions.hooks import check_start_thread_in_category_permission_hook
from misago.permissions.proxy import UserPermissionsProxy

@check_start_thread_in_category_permission_hook.append_filter
def check_user_can_start_thread(
action,
permissions: UserPermissionsProxy,
category: Category,
) -> None:
action(permissions, category)

user = permissions.user
if (
user.is_authenticated
and user.joined_on > timezone.now() - timedelta(days=7):
):
raise PermissionDenied(
"Your account was created less than 7 days ago. "
"You can't start threads yet."
)
```
3 changes: 3 additions & 0 deletions dev-docs/plugins/hooks/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,11 @@ Hooks instances are importable from the following Python modules:
- [`build_user_category_permissions_hook`](./build-user-category-permissions-hook.md)
- [`build_user_permissions_hook`](./build-user-permissions-hook.md)
- [`check_browse_category_permission_hook`](./check-browse-category-permission-hook.md)
- [`check_post_in_closed_category_permission_hook`](./check-post-in-closed-category-permission-hook.md)
- [`check_private_threads_permission_hook`](./check-private-threads-permission-hook.md)
- [`check_see_category_permission_hook`](./check-see-category-permission-hook.md)
- [`check_start_private_threads_permission_hook`](./check-start-private-threads-permission-hook.md)
- [`check_start_thread_in_category_permission_hook`](./check-start-thread-in-category-permission-hook.md)
- [`copy_category_permissions_hook`](./copy-category-permissions-hook.md)
- [`copy_group_permissions_hook`](./copy-group-permissions-hook.md)
- [`filter_private_threads_queryset_hook`](./filter-private-threads-queryset-hook.md)
Expand Down
18 changes: 14 additions & 4 deletions dev-docs/plugins/template-outlets-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ On the admin dashboard page, above all other content.

## `CATEGORIES_LIST_END`

On the categories page, under the list.
On the categories page, below the list.


## `CATEGORIES_LIST_START`
Expand All @@ -35,7 +35,7 @@ On the categories page, above the list.

## `CATEGORY_THREADS_LIST_END`

On the category threads page, under the list.
On the category threads page, below the list.


## `CATEGORY_THREADS_LIST_MIDDLE`
Expand All @@ -48,9 +48,19 @@ On the category threads page, between the subcategories and the list.
On the category threads page, above the list.


## `LOGIN_PAGE_END`

On the sign in page, below the form.


## `LOGIN_PAGE_START`

On the sign in page, above the form.


## `PRIVATE_THREADS_LIST_END`

On the private threads page, under the list.
On the private threads page, below the list.


## `PRIVATE_THREADS_LIST_START`
Expand All @@ -65,7 +75,7 @@ Used in some tests.

## `THREADS_LIST_END`

On the threads page, under the list.
On the threads page, below the list.


## `THREADS_LIST_MIDDLE`
Expand Down
6 changes: 1 addition & 5 deletions frontend/src/components/Timestamp/Timestamp.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import React from "react"
import {
dateRelative,
dateRelativeShort,
fullDateTime,
} from "../../formats"
import { dateRelative, dateRelativeShort, fullDateTime } from "../../formats"

class Timestamp extends React.Component {
constructor(props) {
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/post-feed/post/body.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default function (props) {
export function Default(props) {
return (
<div className="post-body">
<MisagoMarkup markup={props.post.content} />
<MisagoMarkup markup={props.post.headline || props.post.content} />
</div>
)
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/search-route/threads/post.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default function (props) {
<div className="post-border">
<div className="post-body">
<div className="panel panel-default panel-post">
<PostBody content={props.post.content} />
<PostBody content={props.post.headline || props.post.content} />
<PostFooter
category={props.post.category}
post={props.post}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/search/SearchResultPost.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default function SearchResultPost({ post }) {
<div className="search-result-name">{post.thread.title}</div>
<div
className="search-result-summary"
dangerouslySetInnerHTML={{ __html: post.content }}
dangerouslySetInnerHTML={{ __html: post.headline || post.content }}
/>
<ul className="search-result-details">
<li>
Expand Down
Loading

0 comments on commit c65d601

Please sign in to comment.