mirror of
https://github.com/cheeaun/phanpy.git
synced 2024-11-22 09:15:33 +03:00
Allow instance-based hashtags
Also change design a little
This commit is contained in:
parent
eebb55ba38
commit
959ac468d8
5 changed files with 117 additions and 40 deletions
|
@ -26,6 +26,8 @@
|
|||
#shortcuts-settings-container .shortcuts-list li .shortcut-text {
|
||||
flex-grow: 1;
|
||||
min-width: 0;
|
||||
line-height: 1;
|
||||
word-break: break-word;
|
||||
}
|
||||
#shortcuts-settings-container .shortcuts-list li .shortcut-actions {
|
||||
flex-shrink: 0;
|
||||
|
|
|
@ -94,6 +94,13 @@ const TYPE_PARAMS = {
|
|||
placeholder: 'e.g. PixelArt (Max 5, space-separated)',
|
||||
pattern: '[^#]+',
|
||||
},
|
||||
{
|
||||
text: 'Instance',
|
||||
name: 'instance',
|
||||
type: 'text',
|
||||
placeholder: 'Optional, e.g. mastodon.social',
|
||||
notRequired: true,
|
||||
},
|
||||
],
|
||||
};
|
||||
export const SHORTCUTS_META = {
|
||||
|
@ -131,14 +138,15 @@ export const SHORTCUTS_META = {
|
|||
},
|
||||
public: {
|
||||
id: 'public',
|
||||
title: ({ local, instance }) =>
|
||||
`${local ? 'Local' : 'Federated'} (${instance})`,
|
||||
title: ({ local }) => (local ? 'Local' : 'Federated'),
|
||||
subtitle: ({ instance }) => instance,
|
||||
path: ({ local, instance }) => `/${instance}/p${local ? '/l' : ''}`,
|
||||
icon: ({ local }) => (local ? 'group' : 'earth'),
|
||||
},
|
||||
trending: {
|
||||
id: 'trending',
|
||||
title: 'Trending',
|
||||
subtitle: ({ instance }) => instance,
|
||||
path: ({ instance }) => `/${instance}/trending`,
|
||||
icon: 'chart',
|
||||
},
|
||||
|
@ -177,6 +185,7 @@ export const SHORTCUTS_META = {
|
|||
hashtag: {
|
||||
id: 'hashtag',
|
||||
title: ({ hashtag }) => hashtag,
|
||||
subtitle: ({ instance }) => instance,
|
||||
path: ({ hashtag }) => `/t/${hashtag.split(/\s+/).join('+')}`,
|
||||
icon: 'hashtag',
|
||||
},
|
||||
|
@ -307,10 +316,13 @@ function ShortcutsSettings() {
|
|||
const key = i + Object.values(shortcut);
|
||||
const { type } = shortcut;
|
||||
if (!SHORTCUTS_META[type]) return null;
|
||||
let { icon, title } = SHORTCUTS_META[type];
|
||||
let { icon, title, subtitle } = SHORTCUTS_META[type];
|
||||
if (typeof title === 'function') {
|
||||
title = title(shortcut, i);
|
||||
}
|
||||
if (typeof subtitle === 'function') {
|
||||
subtitle = subtitle(shortcut, i);
|
||||
}
|
||||
if (typeof icon === 'function') {
|
||||
icon = icon(shortcut, i);
|
||||
}
|
||||
|
@ -319,6 +331,12 @@ function ShortcutsSettings() {
|
|||
<Icon icon={icon} />
|
||||
<span class="shortcut-text">
|
||||
<AsyncText>{title}</AsyncText>
|
||||
{subtitle && (
|
||||
<>
|
||||
{' '}
|
||||
<small class="ib insignificant">{subtitle}</small>
|
||||
</>
|
||||
)}
|
||||
</span>
|
||||
<span class="shortcut-actions">
|
||||
<button
|
||||
|
@ -468,13 +486,17 @@ function ShortcutForm({
|
|||
</label>
|
||||
</p>
|
||||
{TYPE_PARAMS[currentType]?.map?.(
|
||||
({ text, name, type, placeholder, pattern }) => {
|
||||
({ text, name, type, placeholder, pattern, notRequired }) => {
|
||||
if (currentType === 'list') {
|
||||
return (
|
||||
<p>
|
||||
<label>
|
||||
<span>List</span>
|
||||
<select name="id" required disabled={disabled}>
|
||||
<select
|
||||
name="id"
|
||||
required={!notRequired}
|
||||
disabled={disabled}
|
||||
>
|
||||
{lists.map((list) => (
|
||||
<option value={list.id}>{list.title}</option>
|
||||
))}
|
||||
|
@ -492,7 +514,7 @@ function ShortcutForm({
|
|||
type={type}
|
||||
name={name}
|
||||
placeholder={placeholder}
|
||||
required={type === 'text'}
|
||||
required={type === 'text' && !notRequired}
|
||||
disabled={disabled}
|
||||
list={
|
||||
currentType === 'hashtag'
|
||||
|
|
|
@ -134,6 +134,14 @@ shortcuts .tab-bar[hidden] {
|
|||
#app[data-shortcuts-view-mode='tab-menu-bar'] .deck-container {
|
||||
padding-bottom: 52px;
|
||||
}
|
||||
#shortcuts .tab-bar li a.has-subtitle .icon,
|
||||
#shortcuts .tab-bar li a.has-subtitle .icon svg {
|
||||
width: 14px !important;
|
||||
height: 14px !important;
|
||||
}
|
||||
#shortcuts .tab-bar li a span {
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 40em) {
|
||||
|
@ -172,6 +180,10 @@ shortcuts .tab-bar[hidden] {
|
|||
height: 44px;
|
||||
gap: 4px;
|
||||
}
|
||||
#shortcuts .tab-bar li a span {
|
||||
text-align: left;
|
||||
line-height: 1;
|
||||
}
|
||||
#app:has(#home-page):not(:has(#home-page ~ .deck-container)):has(
|
||||
header[hidden]
|
||||
)
|
||||
|
|
|
@ -30,7 +30,7 @@ function Shortcuts() {
|
|||
.map((pin, i) => {
|
||||
const { type, ...data } = pin;
|
||||
if (!SHORTCUTS_META[type]) return null;
|
||||
let { id, path, title, icon } = SHORTCUTS_META[type];
|
||||
let { id, path, title, subtitle, icon } = SHORTCUTS_META[type];
|
||||
|
||||
if (typeof id === 'function') {
|
||||
id = id(data, i);
|
||||
|
@ -41,6 +41,9 @@ function Shortcuts() {
|
|||
if (typeof title === 'function') {
|
||||
title = title(data, i);
|
||||
}
|
||||
if (typeof subtitle === 'function') {
|
||||
subtitle = subtitle(data, i);
|
||||
}
|
||||
if (typeof icon === 'function') {
|
||||
icon = icon(data, i);
|
||||
}
|
||||
|
@ -49,6 +52,7 @@ function Shortcuts() {
|
|||
id,
|
||||
path,
|
||||
title,
|
||||
subtitle,
|
||||
icon,
|
||||
};
|
||||
})
|
||||
|
@ -73,35 +77,44 @@ function Shortcuts() {
|
|||
{snapStates.settings.shortcutsViewMode === 'tab-menu-bar' ? (
|
||||
<nav class="tab-bar">
|
||||
<ul>
|
||||
{formattedShortcuts.map(({ id, path, title, icon }, i) => {
|
||||
return (
|
||||
<li key={i + title}>
|
||||
<Link
|
||||
to={path}
|
||||
onClick={(e) => {
|
||||
if (e.target.classList.contains('is-active')) {
|
||||
e.preventDefault();
|
||||
const page = document.getElementById(`${id}-page`);
|
||||
console.log(id, page);
|
||||
if (page) {
|
||||
page.scrollTop = 0;
|
||||
const updatesButton =
|
||||
page.querySelector('.updates-button');
|
||||
if (updatesButton) {
|
||||
updatesButton.click();
|
||||
{formattedShortcuts.map(
|
||||
({ id, path, title, subtitle, icon }, i) => {
|
||||
return (
|
||||
<li key={i + title}>
|
||||
<Link
|
||||
class={subtitle ? 'has-subtitle' : ''}
|
||||
to={path}
|
||||
onClick={(e) => {
|
||||
if (e.target.classList.contains('is-active')) {
|
||||
e.preventDefault();
|
||||
const page = document.getElementById(`${id}-page`);
|
||||
console.log(id, page);
|
||||
if (page) {
|
||||
page.scrollTop = 0;
|
||||
const updatesButton =
|
||||
page.querySelector('.updates-button');
|
||||
if (updatesButton) {
|
||||
updatesButton.click();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Icon icon={icon} size="xl" alt={title} />
|
||||
<span>
|
||||
<AsyncText>{title}</AsyncText>
|
||||
</span>
|
||||
</Link>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
}}
|
||||
>
|
||||
<Icon icon={icon} size="xl" alt={title} />
|
||||
<span>
|
||||
<AsyncText>{title}</AsyncText>
|
||||
{subtitle && (
|
||||
<>
|
||||
<br />
|
||||
<small>{subtitle}</small>
|
||||
</>
|
||||
)}
|
||||
</span>
|
||||
</Link>
|
||||
</li>
|
||||
);
|
||||
},
|
||||
)}
|
||||
</ul>
|
||||
</nav>
|
||||
) : (
|
||||
|
@ -132,12 +145,20 @@ function Shortcuts() {
|
|||
</button>
|
||||
}
|
||||
>
|
||||
{formattedShortcuts.map(({ path, title, icon }, i) => {
|
||||
{formattedShortcuts.map(({ path, title, subtitle, icon }, i) => {
|
||||
return (
|
||||
<MenuLink to={path} key={i + title} class="glass-menu-item">
|
||||
<Icon icon={icon} size="l" />{' '}
|
||||
<span class="menu-grow">
|
||||
<AsyncText>{title}</AsyncText>
|
||||
<span>
|
||||
<AsyncText>{title}</AsyncText>
|
||||
</span>
|
||||
{subtitle && (
|
||||
<>
|
||||
{' '}
|
||||
<small class="more-insignificant">{subtitle}</small>
|
||||
</>
|
||||
)}
|
||||
</span>
|
||||
<span class="menu-shortcut hide-until-focus-visible">
|
||||
{i + 1}
|
||||
|
|
|
@ -32,8 +32,10 @@ function Hashtags(props) {
|
|||
hashtags.sort();
|
||||
hashtag = hashtags[0];
|
||||
|
||||
const { masto, instance } = api({ instance: params.instance });
|
||||
const { authenticated } = api();
|
||||
const { masto, instance, authenticated } = api({
|
||||
instance: props?.instance || params.instance,
|
||||
});
|
||||
const { authenticated: currentAuthenticated } = api();
|
||||
const hashtagTitle = hashtags.map((t) => `#${t}`).join(' ');
|
||||
const title = instance ? `${hashtagTitle} on ${instance}` : hashtagTitle;
|
||||
useTitle(title, `/:instance?/t/:hashtag`);
|
||||
|
@ -99,7 +101,7 @@ function Hashtags(props) {
|
|||
|
||||
return (
|
||||
<Timeline
|
||||
key={hashtagTitle}
|
||||
key={instance + hashtagTitle}
|
||||
title={title}
|
||||
titleComponent={
|
||||
!!instance && (
|
||||
|
@ -232,6 +234,7 @@ function Hashtags(props) {
|
|||
{hashtags.map((t, i) => (
|
||||
<MenuItem
|
||||
key={t}
|
||||
disabled={hashtags.length === 1}
|
||||
onClick={(e) => {
|
||||
hashtags.splice(i, 1);
|
||||
hashtags.sort();
|
||||
|
@ -252,7 +255,7 @@ function Hashtags(props) {
|
|||
</MenuGroup>
|
||||
<MenuDivider />
|
||||
<MenuItem
|
||||
disabled={!authenticated}
|
||||
disabled={!currentAuthenticated}
|
||||
onClick={() => {
|
||||
const shortcut = {
|
||||
type: 'hashtag',
|
||||
|
@ -281,6 +284,23 @@ function Hashtags(props) {
|
|||
>
|
||||
<Icon icon="shortcut" /> <span>Add to Shorcuts</span>
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
let newInstance = prompt(
|
||||
'Enter a new instance e.g. "mastodon.social"',
|
||||
);
|
||||
if (!/\./.test(newInstance)) {
|
||||
if (newInstance) alert('Invalid instance');
|
||||
return;
|
||||
}
|
||||
if (newInstance) {
|
||||
newInstance = newInstance.toLowerCase().trim();
|
||||
navigate(`/${newInstance}/t/${hashtags.join('+')}`);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Icon icon="bus" /> <span>Go to another instance…</span>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
}
|
||||
/>
|
||||
|
|
Loading…
Reference in a new issue