Skip to content

Commit

Permalink
Merge pull request #879 from thunderstore-io/source-view
Browse files Browse the repository at this point in the history
Add a source tab to the package detail page
  • Loading branch information
MythicManiac committed Sep 26, 2023
2 parents c94f0f5 + a700466 commit 5ffb1bc
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 71 deletions.
4 changes: 4 additions & 0 deletions builder/src/scss/code-input.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
background-color: rgba(0, 0, 0, 0.2);
}

.code-input::-webkit-scrollbar-corner {
background-color: rgba(0, 0, 0, 0.6);
}

.code-input::-webkit-scrollbar-thumb {
background-color: rgba(255, 255, 255, 0.4);
cursor: pointer;
Expand Down
17 changes: 16 additions & 1 deletion django/poetry.lock

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

1 change: 1 addition & 0 deletions django/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ bleach = "^3.3.0"
markdown-it-py = {version = "2.1.0", extras = ["linkify"]}
abyss = {git = "https://github.com/akx/abyss.git", rev = "4352e557f25a303f718ec1bf82ea0ca545ebc077"}
lxml = "^4.9.1"
pygments = "^2.16.1"

[tool.poetry.group.plugins]
optional = true
Expand Down
21 changes: 20 additions & 1 deletion django/thunderstore/plugins/base.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
from abc import ABC
from typing import Any, ClassVar, Dict, List, Set
from typing import TYPE_CHECKING, Any, Callable, ClassVar, Dict, List, Set

from django.urls import URLPattern

from thunderstore.plugins.types import SettingsLink

if TYPE_CHECKING:
from thunderstore.community.models import PackageListing
from thunderstore.core.types import UserType
from thunderstore.repository.views.mixins import PartialTab


class BasePlugin(ABC):
INSTALLED_APPS: ClassVar[Set[str]] = set()
Expand All @@ -17,6 +22,20 @@ def get_settings_links(cls) -> List[SettingsLink]:
def get_settings_urls(cls) -> List[URLPattern]:
return []

@classmethod
def get_legacy_package_urls(cls) -> List[URLPattern]:
return []

@classmethod
def get_new_package_urls(cls) -> List[URLPattern]:
return []

@classmethod
def get_package_tabs(
cls,
) -> Dict[str, Callable[["UserType", "PackageListing"], "PartialTab"]]:
return {}

@classmethod
def get_django_settings(cls, settings: Dict[str, Any]) -> Dict[str, Any]:
return dict()
24 changes: 23 additions & 1 deletion django/thunderstore/plugins/registry.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import itertools
from typing import Any, Dict, List, Set, Type
from typing import TYPE_CHECKING, Any, Dict, List, Set, Type

from django.urls import URLPattern

from .base import BasePlugin
from .loading import load_ts_plugins
from .types import SettingsLink

if TYPE_CHECKING:
from ..community.models import PackageListing
from ..core.types import UserType
from ..repository.views.mixins import PartialTab


class PluginRegistry:
plugins: Set[Type[BasePlugin]]
Expand All @@ -31,6 +36,23 @@ def get_installed_apps(self, base_apps: List[str]) -> List[str]:
def get_settings_urls(self) -> List[URLPattern]:
return list(itertools.chain(*(x.get_settings_urls() for x in self.plugins)))

def get_legacy_package_urls(self) -> List[URLPattern]:
return list(
itertools.chain(*(x.get_legacy_package_urls() for x in self.plugins))
)

def get_new_package_urls(self) -> List[URLPattern]:
return list(itertools.chain(*(x.get_new_package_urls() for x in self.plugins)))

def get_package_tabs(
self, user: "UserType", listing: "PackageListing"
) -> Dict[str, "PartialTab"]:
result = {}
for entry in (x.get_package_tabs() for x in self.plugins):
for key, getter in entry.items():
result[key] = getter(user, listing)
return result

def get_settings_links(self) -> List[SettingsLink]:
return list(itertools.chain(*(x.get_settings_links() for x in self.plugins)))

Expand Down
122 changes: 64 additions & 58 deletions django/thunderstore/repository/urls.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.urls import include, path, re_path

from thunderstore.plugins.registry import plugin_registry
from thunderstore.repository.api.v1.urls import urls as v1_urls
from thunderstore.repository.views import (
PackageCreateOldView,
Expand Down Expand Up @@ -29,63 +30,68 @@
PackageWikiPageEditView,
)

legacy_package_urls = [
path("", PackageListView.as_view(), name="packages.list"),
path("create/", PackageCreateView.as_view(), name="packages.create"),
path(
"create/old/",
PackageCreateOldView.as_view(),
name="packages.create.old",
),
path("create/docs/", PackageDocsView.as_view(), name="packages.create.docs"),
path(
"download/<str:owner>/<str:name>/<str:version>/",
PackageDownloadView.as_view(),
name="packages.download",
),
path(
"<str:owner>/<str:name>/",
PackageDetailView.as_view(),
name="packages.detail",
),
path(
"<str:owner>/<str:name>/wiki/",
PackageWikiHomeView.as_view(),
name="packages.detail.wiki",
),
path(
"<str:owner>/<str:name>/wiki/new/",
PackageWikiPageEditView.as_view(),
name="packages.detail.wiki.page.new",
),
re_path(
# Regex pattern is used to resolve any variation of slug usage after
# page ID, even if the slug is completely incorrect.
r"(?P<owner>[\w_-]+)/(?P<name>[\w_]+)/wiki/(?P<page>[0-9]+)(?:-(?P<pslug>[\w-]*))?/$",
PackageWikiPageDetailView.as_view(),
name="packages.detail.wiki.page.detail",
),
path(
"<str:owner>/<str:name>/wiki/<int:page>-<slug:pslug>/edit/",
PackageWikiPageEditView.as_view(),
name="packages.detail.wiki.page.edit",
),
path(
"<str:owner>/<str:name>/dependants/",
PackageListByDependencyView.as_view(),
name="packages.list_by_dependency",
),
path(
"<str:owner>/<str:name>/<str:version>/",
PackageVersionDetailView.as_view(),
name="packages.version.detail",
),
path(
"<str:owner>/",
PackageListByOwnerView.as_view(),
name="packages.list_by_owner",
),
]
legacy_package_urls = (
[
path("", PackageListView.as_view(), name="packages.list"),
path("create/", PackageCreateView.as_view(), name="packages.create"),
path(
"create/old/",
PackageCreateOldView.as_view(),
name="packages.create.old",
),
path("create/docs/", PackageDocsView.as_view(), name="packages.create.docs"),
path(
"download/<str:owner>/<str:name>/<str:version>/",
PackageDownloadView.as_view(),
name="packages.download",
),
path(
"<str:owner>/<str:name>/",
PackageDetailView.as_view(),
name="packages.detail",
),
path(
"<str:owner>/<str:name>/wiki/",
PackageWikiHomeView.as_view(),
name="packages.detail.wiki",
),
path(
"<str:owner>/<str:name>/wiki/new/",
PackageWikiPageEditView.as_view(),
name="packages.detail.wiki.page.new",
),
re_path(
# Regex pattern is used to resolve any variation of slug usage after
# page ID, even if the slug is completely incorrect.
r"(?P<owner>[\w_-]+)/(?P<name>[\w_]+)/wiki/(?P<page>[0-9]+)(?:-(?P<pslug>[\w-]*))?/$",
PackageWikiPageDetailView.as_view(),
name="packages.detail.wiki.page.detail",
),
path(
"<str:owner>/<str:name>/wiki/<int:page>-<slug:pslug>/edit/",
PackageWikiPageEditView.as_view(),
name="packages.detail.wiki.page.edit",
),
path(
"<str:owner>/<str:name>/dependants/",
PackageListByDependencyView.as_view(),
name="packages.list_by_dependency",
),
path(
"<str:owner>/",
PackageListByOwnerView.as_view(),
name="packages.list_by_owner",
),
]
+ plugin_registry.get_legacy_package_urls()
+ [
path(
"<str:owner>/<str:name>/<str:version>/",
PackageVersionDetailView.as_view(),
name="packages.version.detail",
),
]
)

package_urls = [
path("", PackageListView.as_view(), name="packages.list"),
Expand Down Expand Up @@ -135,7 +141,7 @@
PackageListByOwnerView.as_view(),
name="packages.list_by_owner",
),
]
] + plugin_registry.get_new_package_urls()

settings_urls = [
path(
Expand Down
22 changes: 13 additions & 9 deletions django/thunderstore/repository/views/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@

from thunderstore.community.models import PackageListing
from thunderstore.core.types import UserType
from thunderstore.plugins.registry import plugin_registry

TabName = Union[Literal["details"], Literal["wiki"]]
TabName = Union[Literal["details"], Literal["wiki"], str]


@dataclasses.dataclass
Expand Down Expand Up @@ -35,15 +36,18 @@ def get_tab_context(
active_tab: TabName,
) -> TabContext:
tabs: Dict[TabName, PartialTab] = {
"details": PartialTab(url=listing.get_absolute_url(), title="Details"),
"wiki": PartialTab(
url=listing.get_wiki_url(),
title="Wiki",
is_disabled=(
not listing.package.has_wiki
and not listing.package.can_user_manage_wiki(user)
**{
"details": PartialTab(url=listing.get_absolute_url(), title="Details"),
"wiki": PartialTab(
url=listing.get_wiki_url(),
title="Wiki",
is_disabled=(
not listing.package.has_wiki
and not listing.package.can_user_manage_wiki(user)
),
),
),
},
**plugin_registry.get_package_tabs(user, listing),
}
return {
"tabs": [
Expand Down
2 changes: 2 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ x-django-service: &django-service
CACHE_S3_CUSTOM_DOMAIN: "localhost:9000/thunderstore"
CACHE_S3_SECURE_URLS: "False"
CACHE_S3_DEFAULT_ACL: "private"

SOURCE_VIEW_ENABLE_HIGHLIGHTING: "True"
env_file:
- .env
depends_on:
Expand Down
2 changes: 1 addition & 1 deletion python-packages

0 comments on commit 5ffb1bc

Please sign in to comment.