Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve mobile layout #30

Merged
merged 4 commits into from
May 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/defs.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def rel_path(path: str, from_path: str) -> str:
}

HEADER_LINKS = {
**{name: [text.replace(" ", " "), os.path.join(PAGES_DIR, name, "README.md")] for name, text in _pages.items()},
**{name: [text.replace(" ", " "), os.path.join(PAGES_DIR, name, "index.md")] for name, text in _pages.items()},
"contributing": ["Contributing", from_src("../CONTRIBUTING.md")]
}

Expand All @@ -58,3 +58,6 @@ def rel_path(path: str, from_path: str) -> str:
ICONS_COLS = 3

MAX_RECENTS = 3

COLUMN_WIDTH = 46
COLUMN_SPANNER = " " * COLUMN_WIDTH
82 changes: 48 additions & 34 deletions .github/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@

from defs import *

from utils import get_files, get_ordering, get_subdirs, urlencode, git_last_changed
from utils import get_files, get_lines, get_subdirs, urlencode, git_last_changed, git_commit_count, datetime
from validation import validate_theme
from generate_icons import generate_icon_pack_table, get_ordered_icons


icons_blacklist = get_ordering(ICONS_BLACKLIST)
icons_blacklist = get_lines(ICONS_BLACKLIST)
themes_featured = []
themes_icon_packs = []

recently_added = []
recently_updated = []


Expand All @@ -36,12 +37,12 @@ def main():
for file in get_files(RELEASE_DIR, "zip")]
is_released = lambda theme: theme in released_themes

themes_featured = list(filter(is_released, get_ordering(FEATURED_ORDERING)))
themes_featured = list(filter(is_released, get_lines(FEATURED_ORDERING)))

themes_custom = list(filter(is_released, get_ordering(CUSTOM_ORDERING)))
themes_custom = list(filter(is_released, get_lines(CUSTOM_ORDERING)))
themes_custom.reverse()

themes_remixed = list(filter(is_released, get_ordering(REMIXED_ORDERING)))
themes_remixed = list(filter(is_released, get_lines(REMIXED_ORDERING)))
themes_remixed.reverse()

standalone_icon_packs = get_ordered_icons()
Expand Down Expand Up @@ -76,23 +77,29 @@ def apply_template(path: str, data: dict) -> str:


def format_page_filename(page: int) -> str:
return "README.md" if page == 0 else f"README.p{page+1:02}.md"
return "index.md" if page == 0 else f"page-{page+1:02}.md"


def generate_index(counts: dict):
buffer = ""
return apply_template(INDEX_TEMPLATE, {
"HEADER": apply_template(HEADER_TEMPLATE, { "LINKS": generate_header_links(".") }),
"INDEX": generate_index_list(counts),
"THEMES_NEW": generate_recents_grid(recently_added),
"THEMES_RECENTS": generate_recents_grid(recently_updated)
})


def generate_index_list(counts: dict) -> str:
buffer = ""
for group_name, count in counts.items():
text, link = HEADER_LINKS[group_name]
buffer += f"### [{text} ({count})]({rel_path(link, '.')})\n\n"
return buffer

recently_updated.sort(key=lambda item: item["ts"], reverse=True)

return apply_template(INDEX_TEMPLATE, {
"HEADER": apply_template(HEADER_TEMPLATE, { "LINKS": generate_header_links(".") }),
"INDEX": buffer,
"RECENTS": apply_template(GRID_TEMPLATE, {"GRID_ITEMS": "\n\n".join(item["buffer"] for item in recently_updated[:MAX_RECENTS])})
})
def generate_recents_grid(items: list[dict]) -> str:
items.sort(key=lambda item: item["ts"], reverse=True)
return apply_template(GRID_TEMPLATE, {"GRID_ITEMS": "\n\n".join(generate_item(item["theme"]) for item in items[:MAX_RECENTS])})


def write_pages(items: list, group_name: str, group_header: str, item_grid_generator: Callable[[list], str], page_size: int = 12, **opts):
Expand Down Expand Up @@ -163,18 +170,18 @@ def generate_pagination(current_page: int, num_pages: int) -> str:
return buffer


def generate_table_grid(themes, cols: int = THEMES_COLS) -> str:
def generate_table_grid(themes) -> str:
buffer = ""

for i, theme in enumerate(themes):
if i > 0 and i % cols == 0:
if i > 0 and i % THEMES_COLS == 0:
buffer += "</tr><tr>\n"
buffer += generate_item(theme)
buffer += generate_item(theme, index=i, collect_data=True)

return apply_template(GRID_TEMPLATE, {"GRID_ITEMS": buffer})


def generate_item(theme: str) -> str:
def generate_item(theme: str, index: int = 0, collect_data: bool = False) -> str:
dir_path = os.path.join(THEME_DIR, theme)
is_valid, has_subdirs = validate_theme(dir_path)

Expand Down Expand Up @@ -215,6 +222,7 @@ def generate_item(theme: str) -> str:

last_changed_datetime = git_last_changed(dir_path)
last_updated = last_changed_datetime.strftime("%Y-%m-%d") if last_changed_datetime else ""
commit_count = git_commit_count(dir_path)

bgm_path = from_src(f"../{theme_subdirs[0]}/sound/bgm.mp3")
has_bgm = os.path.isfile(bgm_path)
Expand All @@ -240,30 +248,36 @@ def generate_item(theme: str) -> str:
"HAS_ICONPACK": f"&nbsp; <a href=\"{generate_icon_pack_url(theme, theme_subdirs)}\">{HAS_ICONPACK_ICON}</a>" if has_icon_pack else "",
"README": f"&nbsp;&nbsp;<a href=\"{urlencode(readme_path)}\">{README_ICON}</a>" if len(readme_path) != 0 else "",
"AUTHOR_BTN": f"&nbsp;&nbsp;<a href=\"https://github.com/search?l=ZIP&q=filename%3A%22{urlencode(author)}%22+repo%3AOnionUI%2FThemes\">{AUTHOR_ICON}</a>" if author else "",
"UPDATED": last_updated,
"UPDATED": f"{last_updated} (v{commit_count})" if commit_count > 1 else last_updated,
"PREVIEW_URL": preview_url,
"RELEASE_URL": release_url,
"HISTORY_URL": history_url
"HISTORY_URL": history_url,
"COLUMN_SPANNER": COLUMN_SPANNER if index < THEMES_COLS else ""
}

if has_icon_pack:
for subdir in theme_subdirs:
if os.path.isdir(f"{subdir}/icons") and os.path.basename(subdir) not in icons_blacklist:
themes_icon_packs.append({
"name": os.path.basename(subdir),
"path": from_src(os.path.join("..", subdir, "icons")),
"is_theme": True,
"theme": theme,
"release_url": release_url,
"preview_url": generate_icon_pack_url(theme, [subdir])
})
if collect_data:
if has_icon_pack:
for subdir in theme_subdirs:
if os.path.isdir(f"{subdir}/icons") and os.path.basename(subdir) not in icons_blacklist:
themes_icon_packs.append({
"name": os.path.basename(subdir),
"path": from_src(os.path.join("..", subdir, "icons")),
"is_theme": True,
"theme": theme,
"release_url": release_url,
"preview_url": generate_icon_pack_url(theme, [subdir])
})
if commit_count <= 1:
recents_maybe_append(recently_added, last_changed_datetime, theme)
else:
recents_maybe_append(recently_updated, last_changed_datetime, theme)

buffer = apply_template(ITEM_TEMPLATE, item)
return apply_template(ITEM_TEMPLATE, item)

if len(recently_updated) < MAX_RECENTS or any(last_changed_datetime > item["ts"] for item in recently_updated):
recently_updated.append({ "ts": last_changed_datetime, "buffer": buffer })

return buffer
def recents_maybe_append(recents: list[dict], timestamp: datetime, theme: str):
if len(recents) < MAX_RECENTS or any(timestamp > item["ts"] for item in recents):
recents.append({"ts": timestamp, "theme": theme})


def generate_icon_pack_url(theme: str, theme_subdirs: list[str]) -> str:
Expand Down
10 changes: 5 additions & 5 deletions .github/generate_icons.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from PIL import Image

from defs import *
from utils import get_ordering, urlencode
from utils import get_lines, urlencode


PREVIEW_ICONS = ["fc", "gb", "gba", "gbc", "md", "ms", "ps", "sfc"]
Expand All @@ -28,7 +28,7 @@ def get_ordered_icons() -> list[dict]:
"preview_url": f"https://onionui.github.io/iconpack_preview.html#{urlencode(dir_name)}"
})

for icon_pack in get_ordering(ICONS_ORDERING):
for icon_pack in get_lines(ICONS_ORDERING):
result = next((x for x in icon_packs if x['name'] == icon_pack), None)
if result is None:
continue
Expand All @@ -46,14 +46,14 @@ def generate_icon_pack_table(icon_packs: list[dict], cols: int = ICONS_COLS) ->
for i, icon_pack in enumerate(icon_packs):
if i > 0 and i % cols == 0:
output += "</tr><tr>\n"
output += generate_icon_pack_entry(current_path, **icon_pack)
output += generate_icon_pack_entry(current_path, **icon_pack, index=i)

output += "</tr></table>\n\n"

return output


def generate_icon_pack_entry(current_path: str, name, path, release_url, preview_url, is_theme: bool = False, theme: str = ""):
def generate_icon_pack_entry(current_path: str, name, path, release_url, preview_url, is_theme: bool = False, theme: str = "", index: int = 0):
preview_path = from_src(os.path.join(path, f"preview.png"))

ensure_has_icon_preview(path)
Expand Down Expand Up @@ -85,7 +85,7 @@ def generate_icon_pack_entry(current_path: str, name, path, release_url, preview
icon_count = sum(os.path.isfile(f"{path}/{icon}.png") for icon in ALL_ICONS)
output += f"<sub><sup>{icon_count}/{len(ALL_ICONS)} icons ({round(icon_count/len(ALL_ICONS)*100)}% complete)</sup> &nbsp;&nbsp; {readme}<a href=\"{preview_url}\">{PREVIEW_ICON}</a></sub>"

output += "\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/></td>\n\n"
output += f"\n\n{COLUMN_SPANNER if index < ICONS_COLS else ''}<br/></td>\n\n"

return output

Expand Down
10 changes: 5 additions & 5 deletions .github/release.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from defs import *

from utils import get_subdirs, get_ordering, set_ordering, git_last_changed
from utils import get_subdirs, get_lines, set_ordering, git_last_changed
from validation import validate_theme
from generate import main as generate_readme
from clean import clean_all, clean_unwanted_files
Expand All @@ -26,12 +26,12 @@ def main():
if not os.path.exists(RELEASE_DIR):
os.makedirs(RELEASE_DIR)

featured = get_ordering(FEATURED_ORDERING)
remixed = get_ordering(REMIXED_ORDERING)
custom = get_ordering(CUSTOM_ORDERING)
featured = get_lines(FEATURED_ORDERING)
remixed = get_lines(REMIXED_ORDERING)
custom = get_lines(CUSTOM_ORDERING)
all_existing = featured + remixed + custom

all_icons = get_ordering(ICONS_ORDERING)
all_icons = get_lines(ICONS_ORDERING)

clean_all()

Expand Down
11 changes: 9 additions & 2 deletions .github/template/index.template.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,18 @@ $INDEX
<p>&nbsp;</p>


## New or Updated Themes
## Recently Added Themes

Do you want to share your own custom themes with the community? <sup><sub>❤️</sub></sup> [Click here !](CONTRIBUTING.md)

$RECENTS
$THEMES_NEW

<p>&nbsp;</p>


## Recently Updated Themes

$THEMES_RECENTS

<p>&nbsp;</p>

Expand Down
4 changes: 2 additions & 2 deletions .github/template/item.template.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<td align="center" valign="top">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>
$COLUMN_SPANNER<br/>
<a href="$RELEASE_URL">
<img title="$TITLE" width="480px" src="$PREVIEW_URL" /><br/>
<b>$NAME</b>
Expand All @@ -8,4 +8,4 @@
<sub>
<sup><a title="Last updated: $UPDATED" href="$HISTORY_URL">$UPDATED</a></sup> $AUTHOR_BTN&nbsp;&nbsp;<a href="$PREVIEW_URL"><img title="View full-size preview" src="https://user-images.githubusercontent.com/44569252/194037184-ae453506-2536-4c6f-8a19-4a6c1de6ce32.png" width="16"></a>$README$HAS_BGM$HAS_ICONPACK
</sub>
</td>
</td>
33 changes: 31 additions & 2 deletions .github/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,15 @@ def has_extension(name: str, required_ext: str) -> bool:
return ext[1:].lower() == required_ext


def get_ordering(file_path: str) -> list[str]:
def get_lines(file_path: str) -> list[str]:
"""Reads a file and returns a list of lines (trailing whitespace removed)

Args:
file_path (str): The path to the text file

Returns:
list[str]: List of lines from the file
"""
if not os.path.exists(file_path):
return []
with open(file_path, "r", encoding="utf-8") as file:
Expand All @@ -48,9 +56,30 @@ def dir_has_files(dir_path: str, files: list[str]):


def git_last_changed(path: str) -> datetime:
"""Retrieves the timestamp of the last commit

Args:
path (str): The path to lookup in the git log

Returns:
datetime: Timestamp of the last commit
"""
git_result = subprocess.run(["git", "log", "-1", "--pretty=%cI", path], stdout=subprocess.PIPE, check=True)
datestr = git_result.stdout.decode('utf-8').strip()
datestr = git_result.stdout.decode("utf-8").strip()
try:
return datetime.fromisoformat(datestr)
except:
return None

def git_commit_count(path: str) -> int:
"""Count the number of unique commit dates

Args:
path (str): The path to lookup in the git log

Returns:
int: Number of unique commit dates
"""
git_result = subprocess.run(["git", "log", "--pretty=%cI", path], stdout=subprocess.PIPE, check=True)
commit_dates = set(datestr.strip().split("T")[0] for datestr in git_result.stdout.decode("utf-8").split("\n") if datestr)
return len(commit_dates)
Loading
Loading