Skip to content
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
4 changes: 0 additions & 4 deletions .docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,13 @@ COPY ghost/email-service/package.json ghost/email-service/package.json
COPY ghost/html-to-plaintext/package.json ghost/html-to-plaintext/package.json
COPY ghost/i18n/package.json ghost/i18n/package.json
COPY ghost/job-manager/package.json ghost/job-manager/package.json
COPY ghost/link-replacer/package.json ghost/link-replacer/package.json
COPY ghost/member-attribution/package.json ghost/member-attribution/package.json
COPY ghost/members-csv/package.json ghost/members-csv/package.json
COPY ghost/mw-error-handler/package.json ghost/mw-error-handler/package.json
COPY ghost/mw-vhost/package.json ghost/mw-vhost/package.json
COPY ghost/offers/package.json ghost/offers/package.json
COPY ghost/post-events/package.json ghost/post-events/package.json
COPY ghost/post-revisions/package.json ghost/post-revisions/package.json
COPY ghost/prometheus-metrics/package.json ghost/prometheus-metrics/package.json
COPY ghost/security/package.json ghost/security/package.json
COPY ghost/tiers/package.json ghost/tiers/package.json
COPY ghost/webmentions/package.json ghost/webmentions/package.json

## Install dependencies
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ jobs:
- run: yarn nx affected -t test:unit --base=${{ needs.job_setup.outputs.BASE_COMMIT }}

- uses: actions/upload-artifact@v4
if: startsWith(matrix.node, '18')
if: startsWith(matrix.node, '20')
with:
name: unit-coverage
path: ghost/*/coverage/cobertura-coverage.xml
Expand Down Expand Up @@ -582,7 +582,7 @@ jobs:
echo "test_time=$(($endTime-$startTime))" >> $GITHUB_ENV

- uses: actions/upload-artifact@v4
if: startsWith(matrix.node, '18') && contains(matrix.env.DB, 'mysql')
if: startsWith(matrix.node, '20') && contains(matrix.env.DB, 'mysql')
with:
name: e2e-coverage
path: |
Expand Down
19 changes: 19 additions & 0 deletions apps/admin-x-activitypub/src/api/activitypub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export interface Account {
followsMe: boolean;
followedByMe: boolean;
blockedByMe: boolean;
domainBlockedByMe: boolean;
attachment: { name: string; value: string }[];
}

Expand Down Expand Up @@ -202,6 +203,24 @@ export class ActivityPubAPI {
return json;
}

async blockDomain(domain: URL): Promise<boolean> {
const url = new URL(
`.ghost/activitypub/actions/block/domain/${encodeURIComponent(domain.href)}`,
this.apiUrl
);
await this.fetchJSON(url, 'POST');
return true;
}

async unblockDomain(domain: URL): Promise<boolean> {
const url = new URL(
`.ghost/activitypub/actions/unblock/domain/${encodeURIComponent(domain.href)}`,
this.apiUrl
);
await this.fetchJSON(url, 'POST');
return true;
}

async block(id: URL): Promise<boolean> {
const url = new URL(
`.ghost/activitypub/actions/block/${encodeURIComponent(id.href)}`,
Expand Down
56 changes: 56 additions & 0 deletions apps/admin-x-activitypub/src/hooks/use-activity-pub-queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,62 @@ export function useUnlikeMutationForUser(handle: string) {
});
}

export function useBlockDomainMutationForUser(handle: string) {
const queryClient = useQueryClient();

return useMutation({
async mutationFn(account: Account) {
const siteUrl = await getSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);

return api.blockDomain(new URL(account.apId));
},
onMutate: (account: Account) => {
queryClient.setQueryData(
QUERY_KEYS.account(account.handle),
(currentAccount?: Account) => {
if (!currentAccount) {
return currentAccount;
}
return {
...currentAccount,
domainBlockedByMe: true,
followedByMe: false,
followsMe: false
};
}
);
}
});
}

export function useUnblockDomainMutationForUser(handle: string) {
const queryClient = useQueryClient();

return useMutation({
async mutationFn(account: Account) {
const siteUrl = await getSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);

return api.unblockDomain(new URL(account.apId));
},
onMutate: (account: Account) => {
queryClient.setQueryData(
QUERY_KEYS.account(account.handle),
(currentAccount?: Account) => {
if (!currentAccount) {
return currentAccount;
}
return {
...currentAccount,
domainBlockedByMe: false
};
}
);
}
});
}

export function useBlockMutationForUser(handle: string) {
const queryClient = useQueryClient();

Expand Down
1 change: 1 addition & 0 deletions apps/admin-x-framework/src/api/newsletters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export type Newsletter = {
divider_color: string | null;
button_corners: string | null;
button_style: string | null;
image_corners: string | null;
link_style: string | null;
divider_style: string | null;
created_at: string;
Expand Down
35 changes: 35 additions & 0 deletions apps/admin-x-framework/src/api/stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,38 @@ export type PostReferrersResponseType = {
meta: Meta;
};

export type PostGrowthStatItem = {
post_id: string;
free_members: number;
paid_members: number;
mrr: number;
};

export type PostGrowthStatsResponseType = {
stats: PostGrowthStatItem[];
meta: Meta;
};

export type MrrHistoryItem = {
date: string;
mrr: number;
currency: string;
};
export type MrrHistoryResponseType = {
stats: MrrHistoryItem[];
meta: Meta;
};

// Requests

const dataType = 'TopContentResponseType';
const memberCountHistoryDataType = 'MemberCountHistoryResponseType';
const topPostsStatsDataType = 'TopPostsStatsResponseType';
const postReferrersDataType = 'PostReferrersResponseType';

const postGrowthStatsDataType = 'PostGrowthStatsResponseType';
const mrrHistoryDataType = 'MrrHistoryResponseType';

export const useTopContent = createQuery<TopContentResponseType>({
dataType,
path: '/stats/top-content/'
Expand All @@ -85,3 +111,12 @@ export const usePostReferrers = createQueryWithId<PostReferrersResponseType>({
dataType: postReferrersDataType,
path: id => `/stats/posts/${id}/top-referrers`
});

export const usePostGrowthStats = createQueryWithId<PostGrowthStatsResponseType>({
dataType: postGrowthStatsDataType,
path: id => `/stats/posts/${id}/growth`
});
export const useMrrHistory = createQuery<MrrHistoryResponseType>({
dataType: mrrHistoryDataType,
path: '/stats/mrr/'
});
2 changes: 2 additions & 0 deletions apps/admin-x-framework/src/test/responses/newsletters.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"button_color": null,
"button_style": "fill",
"button_corners": null,
"image_corners": null,
"link_color": null,
"link_style": null,
"divider_style": null,
Expand Down Expand Up @@ -81,6 +82,7 @@
"button_color": null,
"button_style": "fill",
"button_corners": null,
"image_corners": null,
"link_color": null,
"link_style": null,
"divider_style": null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ const Sidebar: React.FC<{

const fontWeightOptions: SelectOption[] = [
{value: 'normal', label: 'Normal'},
{value: 'medium', label: 'Medium'},
{value: 'semibold', label: 'Semi-bold'},
{value: 'bold', label: 'Bold'}
];

Expand Down Expand Up @@ -603,6 +605,31 @@ const Sidebar: React.FC<{
}
]} clearBg={false} />
</div>
<div className='flex w-full justify-between'>
<div>Image corners</div>
<ButtonGroup activeKey={newsletter.image_corners || 'square'} buttons={[
{
key: 'square',
icon: 'square',
label: 'Square',
tooltip: 'Squared',
hideLabel: true,
link: false,
size: 'sm',
onClick: () => updateNewsletter({image_corners: 'square'})
},
{
key: 'squircle',
icon: 'squircle',
label: 'Squircle',
tooltip: 'Rounded',
hideLabel: true,
link: false,
size: 'sm',
onClick: () => updateNewsletter({image_corners: 'squircle'})
}
]} clearBg={false} />
</div>
<div className='flex w-full justify-between'>
<div>Link style</div>
<ButtonGroup activeKey={newsletter.link_style || 'underline'} buttons={[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ const NewsletterPreview: React.FC<{newsletter: Newsletter}> = ({newsletter}) =>
headerImage={newsletter.header_image}
headerSubtitle={headerSubtitle}
headerTitle={headerTitle}
imageCorners={newsletter.image_corners || 'square'}
linkStyle={newsletter.link_style || 'underline'}
senderEmail={renderSenderEmail(newsletter, config, defaultEmailAddress)}
senderName={newsletter.sender_name || title}
Expand Down
Loading
Loading