Skip to content

Commit

Permalink
Merge pull request #223 from cheeaun/main
Browse files Browse the repository at this point in the history
Update from main
  • Loading branch information
cheeaun authored Sep 1, 2023
2 parents def1e8d + 0b04e01 commit b8d92bc
Show file tree
Hide file tree
Showing 13 changed files with 183 additions and 23 deletions.
2 changes: 1 addition & 1 deletion src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -1099,7 +1099,7 @@ button.carousel-dot {
font-weight: bold;
color: var(--text-color);
background-color: var(--bg-faded-blur-color);
border: var(--hairline-width) solid var(--outline-color);
border: 1px solid var(--outline-color);
box-shadow: 0 4px 32px var(--drop-shadow-color);
transition: all 0.2s ease-out;
}
Expand Down
7 changes: 4 additions & 3 deletions src/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ import {
import { getAccessToken } from './utils/auth';
import openCompose from './utils/open-compose';
import showToast from './utils/show-toast';
import states, { getStatus, saveStatus } from './utils/states';
import states, { initStates, saveStatus } from './utils/states';
import store from './utils/store';
import { getCurrentAccount } from './utils/store-utils';
import useInterval from './utils/useInterval';
Expand Down Expand Up @@ -111,7 +111,7 @@ function App() {
if (code) {
console.log({ code });
// Clear the code from the URL
window.history.replaceState({}, document.title, '/');
window.history.replaceState({}, document.title, location.pathname || '/');

const clientID = store.session.get('clientID');
const clientSecret = store.session.get('clientSecret');
Expand All @@ -130,6 +130,7 @@ function App() {
initInstance(masto, instanceURL),
initAccount(masto, instanceURL, accessToken),
]);
initStates();
initPreferences(masto);

setIsLoggedIn(true);
Expand Down Expand Up @@ -389,7 +390,7 @@ function App() {
<AccountSheet
account={snapStates.showAccount?.account || snapStates.showAccount}
instance={snapStates.showAccount?.instance}
onClose={({ destination }) => {
onClose={({ destination } = {}) => {
states.showAccount = false;
if (destination) {
states.showAccounts = false;
Expand Down
16 changes: 16 additions & 0 deletions src/components/menu-confirm.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Menu, MenuItem, SubMenu } from '@szhsin/react-menu';
import { cloneElement } from 'preact';
import { useRef } from 'preact/hooks';

function MenuConfirm({
subMenu = false,
Expand All @@ -20,8 +21,10 @@ function MenuConfirm({
return children;
}
const Parent = subMenu ? SubMenu : Menu;
const menuRef = useRef();
return (
<Parent
instanceRef={menuRef}
openTrigger="clickOnly"
direction="bottom"
overflow="auto"
Expand All @@ -31,6 +34,19 @@ function MenuConfirm({
{...restProps}
menuButton={subMenu ? undefined : children}
label={subMenu ? children : undefined}
// Test fix for bug; submenus not opening on Android
itemProps={{
onPointerMove: (e) => {
if (e.pointerType === 'touch') {
menuRef.current?.openMenu?.();
}
},
onPointerLeave: (e) => {
if (e.pointerType === 'touch') {
menuRef.current?.openMenu?.();
}
},
}}
>
<MenuItem className={menuItemClassName} onClick={onClick}>
{confirmLabel}
Expand Down
37 changes: 32 additions & 5 deletions src/components/notification.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,25 @@ const contentText = {
mention: 'mentioned you in their post.',
status: 'published a post.',
reblog: 'boosted your post.',
'reblog+account': (count) => `boosted ${count} of your posts.`,
reblog_reply: 'boosted your reply.',
follow: 'followed you.',
follow_request: 'requested to follow you.',
favourite: 'favourited your post.',
'favourite+account': (count) => `favourited ${count} of your posts.`,
favourite_reply: 'favourited your reply.',
poll: 'A poll you have voted in or created has ended.',
'poll-self': 'A poll you have created has ended.',
'poll-voted': 'A poll you have voted in has ended.',
update: 'A post you interacted with has been edited.',
'favourite+reblog': 'boosted & favourited your post.',
'favourite+reblog+account': (count) =>
`boosted & favourited ${count} of your posts.`,
'favourite+reblog_reply': 'boosted & favourited your reply.',
};

function Notification({ notification, instance, reload }) {
const { id, status, account, _accounts } = notification;
const { id, status, account, _accounts, _statuses } = notification;
let { type } = notification;

// status = Attached when type of the notification is favourite, reblog, status, mention, poll, or update
Expand Down Expand Up @@ -90,12 +94,19 @@ function Notification({ notification, instance, reload }) {
type === 'favourite' ||
type === 'favourite+reblog'
) {
text =
contentText[isReplyToOthers ? `${type}_reply` : type] ||
contentText[type];
if (_statuses?.length > 1) {
text = contentText[`${type}+account`];
} else if (isReplyToOthers) {
text = contentText[`${type}_reply`];
} else {
text = contentText[type];
}
} else {
text = contentText[type];
}
if (typeof text === 'function') {
text = text(_statuses?.length || _accounts?.length);
}

if (type === 'mention' && !status) {
// Could be deleted
Expand Down Expand Up @@ -206,7 +217,23 @@ function Notification({ notification, instance, reload }) {
))}
</p>
)}
{status && (
{_statuses?.length > 1 && (
<ul class="notification-group-statuses">
{_statuses.map((status) => (
<li key={status.id}>
<Link
class={`status-link status-type-${type}`}
to={
instance ? `/${instance}/s/${status.id}` : `/s/${status.id}`
}
>
<Status status={status} size="s" />
</Link>
</li>
))}
</ul>
)}
{status && (!_statuses?.length || _statuses?.length <= 1) && (
<Link
class={`status-link status-type-${type}`}
to={
Expand Down
7 changes: 5 additions & 2 deletions src/components/status.css
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,14 @@
.status-card > * {
pointer-events: none;
}
.status-card :is(.content, .poll, .media-container) {
.status-card:not(.status-carousel .status)
:is(.content, .poll, .media-container) {
max-height: 160px !important;
overflow: hidden;
}
.status.small .status-card :is(.content, .poll, .media-container) {
.status.small:not(.status-carousel .status)
.status-card
:is(.content, .poll, .media-container) {
max-height: 80px !important;
}
.status-card :is(.content, .poll) {
Expand Down
7 changes: 4 additions & 3 deletions src/components/status.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -1170,9 +1170,7 @@ function Status({
(option) =>
`- ${option.title}${
option.votesCount >= 0
? ` (${option.votesCount} vote${
option.votesCount !== 1 ? 's' : ''
})`
? ` (${option.votesCount})`
: ''
}`,
)
Expand Down Expand Up @@ -1436,6 +1434,7 @@ function Card({ card, instance }) {
url,
type,
embedUrl,
language,
} = card;

/* type
Expand Down Expand Up @@ -1499,6 +1498,7 @@ function Card({ card, instance }) {
target={cardStatusURL ? null : '_blank'}
rel="nofollow noopener noreferrer"
class={`card link ${blurhashImage ? '' : size}`}
lang={language}
>
<div class="card-image">
<img
Expand Down Expand Up @@ -1567,6 +1567,7 @@ function Card({ card, instance }) {
target={cardStatusURL ? null : '_blank'}
rel="nofollow noopener noreferrer"
class={`card link no-image`}
lang={language}
>
<div class="meta-container">
<p class="meta domain">
Expand Down
2 changes: 1 addition & 1 deletion src/pages/accounts.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ function Accounts({ onClose }) {
accounts.splice(i, 1);
store.local.setJSON('accounts', accounts);
// location.reload();
location.href = '/';
location.href = location.pathname || '/';
}}
>
<Icon icon="exit" />
Expand Down
33 changes: 33 additions & 0 deletions src/pages/notifications.css
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
filter: saturate(0.25);
}
.notification .status-link:not(.status-type-mention) > .status {
font-size: calc(var(--text-size) * 0.9);
max-height: 160px;
overflow: hidden;
/* fade out mask gradient bottom */
Expand Down Expand Up @@ -134,6 +135,38 @@
margin-bottom: 8px;
}

.notification-group-statuses {
margin: 0;
padding: 0;
list-style: none;
}
.notification-group-statuses > li {
margin: 0;
padding: 0;
list-style: none;
position: relative;
counter-increment: index;
}
.notification-group-statuses > li:before {
content: counter(index);
position: absolute;
left: 0;
font-size: 10px;
padding: 8px;
font-weight: bold;
}
.notification-group-statuses > li + li {
margin-top: -1px;
}
.notification-group-statuses > li:not(:last-child) .status-link {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.notification-group-statuses > li:not(:first-child) .status-link {
border-top-left-radius: 0;
border-top-right-radius: 0;
}

#mentions-option {
float: right;
margin-top: 0.5em;
Expand Down
29 changes: 25 additions & 4 deletions src/pages/status.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
ancestor: true,
isThread: ancestorsIsThread,
accountID: s.account.id,
account: s.account,
repliesCount: s.repliesCount,
weight: calcStatusWeight(s),
})),
Expand Down Expand Up @@ -705,6 +706,7 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
block: 'start',
});
}}
title="Go to main post"
>
<Icon
icon={heroPointer === 'down' ? 'arrow-down' : 'arrow-up'}
Expand All @@ -727,12 +729,31 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
});
}}
hidden={!ancestors.length || nearReachStart}
title={`${ancestors.length} posts above ‒ Go to top`}
>
<Icon icon="arrow-up" />
<Icon icon="comment" />{' '}
<span class="insignificant">
{shortenNumber(ancestors.length)}
</span>
{ancestors
.filter(
(a, i, arr) =>
arr.findIndex((b) => b.accountID === a.accountID) === i,
)
.slice(0, 3)
.map((ancestor) => (
<Avatar
key={ancestor.account.id}
url={ancestor.account.avatar}
alt={ancestor.account.displayName}
/>
))}
{/* <Icon icon="comment" />{' '} */}
{ancestors.length > 3 && (
<>
{' '}
<span class="insignificant">
{shortenNumber(ancestors.length)}
</span>
</>
)}
</button>
</>
)}
Expand Down
6 changes: 3 additions & 3 deletions src/utils/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ const { VITE_CLIENT_NAME: CLIENT_NAME, VITE_WEBSITE: WEBSITE } = import.meta
export async function registerApplication({ instanceURL }) {
const registrationParams = new URLSearchParams({
client_name: CLIENT_NAME,
redirect_uris: location.origin,
scopes: 'read write follow',
redirect_uris: location.origin + location.pathname,
website: WEBSITE,
});
const registrationResponse = await fetch(
Expand All @@ -27,7 +27,7 @@ export async function getAuthorizationURL({ instanceURL, client_id }) {
const authorizationParams = new URLSearchParams({
client_id,
scope: 'read write follow',
redirect_uri: location.origin,
redirect_uri: location.origin + location.pathname,
// redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
response_type: 'code',
});
Expand All @@ -44,7 +44,7 @@ export async function getAccessToken({
const params = new URLSearchParams({
client_id,
client_secret,
redirect_uri: location.origin,
redirect_uri: location.origin + location.pathname,
grant_type: 'authorization_code',
code,
scope: 'read write follow',
Expand Down
35 changes: 34 additions & 1 deletion src/utils/group-notifications.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,40 @@ function groupNotifications(notifications) {
cleanNotifications[j++] = n;
}
}
return cleanNotifications;

// 2nd pass to group "favourite+reblog"-type notifications by account if _accounts.length <= 1
// This means one acount has favourited and reblogged the multiple statuses
// The grouped notification
// - type: "favourite+reblog+account"
// - _statuses: [status, status, ...]
const notificationsMap2 = {};
const cleanNotifications2 = [];
for (let i = 0, j = 0; i < cleanNotifications.length; i++) {
const notification = cleanNotifications[i];
const { account, _accounts, type, createdAt } = notification;
const date = new Date(createdAt).toLocaleDateString();
if (type === 'favourite+reblog' && account && _accounts.length === 1) {
const key = `${account?.id}-${type}-${date}`;
const mappedNotification = notificationsMap2[key];
if (mappedNotification) {
mappedNotification._statuses.push(notification.status);
} else {
let n = (notificationsMap2[key] = {
...notification,
type,
_statuses: [notification.status],
});
cleanNotifications2[j++] = n;
}
} else {
cleanNotifications2[j++] = notification;
}
}

console.log({ notifications, cleanNotifications, cleanNotifications2 });

// return cleanNotifications;
return cleanNotifications2;
}

export default groupNotifications;
Loading

0 comments on commit b8d92bc

Please sign in to comment.