commit
6b03ae1fee
1
.env
1
.env
|
@ -1,2 +1,3 @@
|
|||
VITE_CLIENT_NAME=Phanpy
|
||||
VITE_CLIENT_ID=social.phanpy
|
||||
VITE_WEBSITE=https://phanpy.social
|
28
src/app.css
28
src/app.css
|
@ -642,6 +642,34 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
|
|||
background-image: none;
|
||||
}
|
||||
|
||||
.timeline .show-more {
|
||||
padding-left: calc(var(--line-end) + var(--line-margin-end)) !important;
|
||||
text-align: left;
|
||||
background-color: transparent !important;
|
||||
backdrop-filter: none !important;
|
||||
position: relative;
|
||||
border-radius: 0;
|
||||
padding-block: 16px !important;
|
||||
}
|
||||
.timeline .show-more:hover {
|
||||
filter: none !important;
|
||||
color: var(--text-color) !important;
|
||||
background-color: var(--bg-faded-blur-color) !important;
|
||||
}
|
||||
.timeline .show-more:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: var(--line-start);
|
||||
width: var(--line-diameter);
|
||||
height: var(--line-diameter);
|
||||
border-radius: var(--line-radius);
|
||||
border-style: solid;
|
||||
border-width: var(--line-width);
|
||||
border-color: transparent transparent var(--comment-line-color) transparent;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.status-loading {
|
||||
text-align: center;
|
||||
color: var(--text-insignificant-color);
|
||||
|
|
|
@ -816,9 +816,14 @@ function Compose({
|
|||
skipThreading: true,
|
||||
});
|
||||
} else {
|
||||
newStatus = await masto.v1.statuses.create(params, {
|
||||
idempotencyKey: UID.current,
|
||||
});
|
||||
try {
|
||||
newStatus = await masto.v1.statuses.create(params, {
|
||||
idempotencyKey: UID.current,
|
||||
});
|
||||
} catch (_) {
|
||||
// If idempotency key fails, try again without it
|
||||
newStatus = await masto.v1.statuses.create(params);
|
||||
}
|
||||
}
|
||||
setUIState('default');
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ function resetScrollPosition(id) {
|
|||
function StatusPage(params) {
|
||||
const { id } = params;
|
||||
const { masto, instance } = api({ instance: params.instance });
|
||||
const snapStates = useSnapshot(states);
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const mediaParam = searchParams.get('media');
|
||||
const mediaOnlyParam = searchParams.get('media-only');
|
||||
|
@ -117,12 +118,16 @@ function StatusPage(params) {
|
|||
instance={instance}
|
||||
index={mediaIndex - 1}
|
||||
onClose={() => {
|
||||
if (showMediaOnly) {
|
||||
location.hash = closeLink;
|
||||
if (snapStates.prevLocation) {
|
||||
history.back();
|
||||
} else {
|
||||
searchParams.delete('media');
|
||||
searchParams.delete('mediaStatusID');
|
||||
setSearchParams(searchParams);
|
||||
if (showMediaOnly) {
|
||||
location.hash = closeLink;
|
||||
} else {
|
||||
searchParams.delete('media');
|
||||
searchParams.delete('mediaStatusID');
|
||||
setSearchParams(searchParams);
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
@ -337,6 +342,7 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
|
|||
},
|
||||
...nestedDescendants.map((s) => ({
|
||||
id: s.id,
|
||||
account: s.account,
|
||||
accountID: s.account.id,
|
||||
descendant: true,
|
||||
thread: s.account.id === heroStatus.account.id,
|
||||
|
@ -974,15 +980,27 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
|
|||
<li>
|
||||
<button
|
||||
type="button"
|
||||
class="plain block"
|
||||
class="plain block show-more"
|
||||
disabled={uiState === 'loading'}
|
||||
onClick={() => setLimit((l) => l + LIMIT)}
|
||||
style={{ marginBlockEnd: '6em' }}
|
||||
>
|
||||
Show more…{' '}
|
||||
<span class="tag">
|
||||
{showMore > LIMIT ? `${LIMIT}+` : showMore}
|
||||
</span>
|
||||
<div class="ib">
|
||||
{/* show avatars for first 5 statuses */}
|
||||
{statuses.slice(limit, limit + 5).map((status) => (
|
||||
<Avatar
|
||||
key={status.id}
|
||||
url={status.account.avatarStatic}
|
||||
// title={`${status.avatar.displayName} (@${status.avatar.acct})`}
|
||||
/>
|
||||
))}
|
||||
</div>{' '}
|
||||
<div class="ib">
|
||||
Show more…{' '}
|
||||
<span class="tag">
|
||||
{showMore > LIMIT ? `${LIMIT}+` : showMore}
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
</li>
|
||||
)}
|
||||
|
|
|
@ -9,8 +9,11 @@ import { VitePWA } from 'vite-plugin-pwa';
|
|||
import removeConsole from 'vite-plugin-remove-console';
|
||||
|
||||
const { NODE_ENV } = process.env;
|
||||
const { VITE_CLIENT_NAME: CLIENT_NAME, VITE_APP_ERROR_LOGGING: ERROR_LOGGING } =
|
||||
loadEnv('production', process.cwd());
|
||||
const {
|
||||
VITE_CLIENT_NAME: CLIENT_NAME,
|
||||
VITE_CLIENT_ID: CLIENT_ID,
|
||||
VITE_APP_ERROR_LOGGING: ERROR_LOGGING,
|
||||
} = loadEnv('production', process.cwd());
|
||||
|
||||
const now = new Date();
|
||||
const commitHash = execSync('git rev-parse --short HEAD').toString().trim();
|
||||
|
@ -51,6 +54,7 @@ export default defineConfig({
|
|||
]),
|
||||
VitePWA({
|
||||
manifest: {
|
||||
id: CLIENT_ID,
|
||||
name: CLIENT_NAME,
|
||||
short_name: CLIENT_NAME,
|
||||
description: 'Minimalistic opinionated Mastodon web client',
|
||||
|
|
Loading…
Reference in a new issue