Migrated dashboard share modal to modern pattern (#19950)

closes https://linear.app/tryghost/issue/IPC-92/add-logic-for-completing-steps
closes https://linear.app/tryghost/issue/IPC-111/re-work-share-modal-to-use-the-right-pattern

- migrated code over to the modern ember-promise-modals pattern
- added share step completion when opening modal
- removed unnecessary 1sec timeout when clicking "Copy" button
- moved various share URLs into the template so there's less need to look back-and-forth between template and backing class
This commit is contained in:
Kevin Ansfield 2024-03-28 15:35:35 +00:00 committed by GitHub
parent 1c219fdcb6
commit 63fa7b1952
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 99 additions and 118 deletions

View File

@ -45,7 +45,7 @@
/>
</LinkTo>
{{!-- Step 5 --}}
<div role="button" {{on "click" (toggle-action "showShareModal" this)}} class="gh-onboarding-item {{onboarding-step-class "share-publication"}}">
<div role="button" {{on "click" this.openShareModal}} class="gh-onboarding-item {{onboarding-step-class "share-publication"}}">
<Dashboard::Onboarding::Step
@icon="megaphone"
@title="Share your publication"
@ -66,11 +66,4 @@
{{#unless this.onboarding.allStepsCompleted}}
<a href="#" class="gh-onboarding-skip" {{on "click" this.onboarding.dismissChecklist}}>Skip onboarding</a>
{{/unless}}
</div>
{{#if this.showShareModal}}
<GhFullscreenModal @modal="share"
@close={{this.close}}
@modifier="action wide"
/>
{{/if}}
</div>

View File

@ -1,16 +1,31 @@
import Component from '@glimmer/component';
import ShareModal from './onboarding/share-modal';
import {action} from '@ember/object';
import {inject} from 'ghost-admin/decorators/inject';
import {inject as service} from '@ember/service';
import {tracked} from '@glimmer/tracking';
export default class OnboardingChecklist extends Component {
@service modals;
@service onboarding;
@inject config;
@tracked showMemberTierModal = false;
shareModal = null;
willDestroy() {
super.willDestroy(...arguments);
if (this.shareModal) {
this.shareModal.close();
}
}
get siteUrl() {
return this.config.blogTitle;
}
@action
openShareModal() {
this.onboarding.markStepCompleted('share-publication');
this.shareModal = this.modals.open(ShareModal);
}
}

View File

@ -0,0 +1,62 @@
<div class="modal-content" data-test-modal="onboarding-share">
<header class="modal-header">
<h1>Share your publication</h1>
</header>
<button type="button" class="close" title="Close" {{on "click" @close}}>{{svg-jar "close"}}<span class="hidden">Close</span></button>
<div class="share-card-container">
{{#let (get-setting "coverImage") as |imageUrl|}}
{{#if imageUrl}}
<div class="share-card-image">
<img src={{imageUrl}} alt="" role="presentation" />
</div>
{{else}}
<div class="share-card-image placeholder">{{svg-jar "picture"}}</div>
{{/if}}
<div class="share-card-content">
<div class="share-card-title">{{get-setting "title"}}</div>
<div class="share-card-description">
{{get-setting "description"}}
</div>
</div>
{{/let}}
</div>
<span class="tip">Set your publications cover image and description in <a href="settings/design/edit/?ref=share-modal" title="Adjust settings">Settings</a></span>
<div class="copy-publication-link">
<span>{{this.config.blogUrl}}</span>
<GhTaskButton
data-test-button="copy-share-link"
@buttonText="Copy"
@task={{this.copySiteUrl}}
@successText="Copied!"
@successClass="gh-share-link-success"
@class="gh-btn-icon"
/>
</div>
<ul class="share-links">
<li>
<a href="https://twitter.com/intent/tweet?url={{this.encodedUrl}}" target="_blank" rel="noopener noreferrer" class="share-link" title="Share your publication on X">
<span>{{svg-jar "social-x"}}</span>
</a>
</li>
<li>
<a href="https://www.facebook.com/sharer/sharer.php?u={{this.encodedUrl}}" target="_blank" rel="noopener noreferrer" class="gh-share-link" title="Share your publication on Facebook">
<div class="share-link-content">
<span>{{svg-jar "social-facebook"}}</span>
</div>
</a>
</li>
<li>
<a href="https://www.linkedin.com/sharing/share-offsite/?url={{this.encodedUrl}}" target="_blank" rel="noopener noreferrer" class="gh-share-link" title="Share your publication on LinkedIn">
<div class="share-link-content">
<span>{{svg-jar "social-linkedin"}}</span>
</div>
</a>
</li>
</ul>
</div>

View File

@ -0,0 +1,18 @@
import Component from '@glimmer/component';
import copyTextToClipboard from 'ghost-admin/utils/copy-text-to-clipboard';
import {inject} from 'ghost-admin/decorators/inject';
import {task} from 'ember-concurrency';
export default class OnboardingShareModal extends Component {
@inject config;
get encodedUrl() {
return encodeURIComponent(this.config.blogUrl);
}
@task
*copySiteUrl() {
yield copyTextToClipboard(this.config.blogUrl);
return true;
}
}

View File

@ -1,76 +0,0 @@
<header class="modal-header">
<h1>Share your publication</h1>
</header>
<a class="close" href="" role="button" title="Close">
{{svg-jar "close"}}
<span class="hidden">Close</span>
</a>
<div class="share-card-container">
{{#let (or @post.featureImage (get-setting "coverImage")) as |imageUrl|}}
{{#if imageUrl}}
<div class="share-card-image">
<img src={{imageUrl}} alt="" role="presentation" />
</div>
{{else}}
<div class="share-card-image placeholder">
{{svg-jar "picture"}}
</div>
{{/if}}
<div class="share-card-content">
<div class="share-card-title">
{{get-setting "title"}}
</div>
<div class="share-card-description">
{{ get-setting "description"}}
</div>
</div>
{{/let}}
</div>
<span class="tip">Set your publications cover image and description in <a href="settings/design/edit/?ref=share-modal" title="Adjust settings">Settings</a></span>
<div class="copy-publication-link">
<span>
{{ this.config.blogUrl }}
</span>
<GhTaskButton
data-test-button="copy-share-link"
@buttonText="Copy"
@task={{this.copySiteUrl}}
@successText="Copied!"
@successClass="gh-share-link-success"
@class="gh-btn-icon" />
</div>
<ul class="share-links">
<li>
<a href="{{this.xShareUrl}}" target="_blank" rel="noopener noreferrer" class="share-link" title="Share your publication on X">
<span>
{{svg-jar "social-x"}}
</span>
</a>
</li>
<li>
<a href="{{this.facebookShareUrl}}" target="_blank" rel="noopener noreferrer" class="gh-share-link" title="Share your publication on Facebook">
<div class="share-link-content">
<span>
{{svg-jar "social-facebook"}}
</span>
</div>
</a>
</li>
<li>
<a href="{{this.linkedInShareUrl}}" target="_blank" rel="noopener noreferrer" class="gh-share-link" title="Share your publication on LinkedIn">
<div class="share-link-content">
<span>
{{svg-jar "social-linkedin"}}
</span>
</div>
</a>
</li>
</ul>

View File

@ -1,31 +0,0 @@
import ModalComponent from 'ghost-admin/components/modal-base';
import copyTextToClipboard from 'ghost-admin/utils/copy-text-to-clipboard';
import {inject} from 'ghost-admin/decorators/inject';
import {task, timeout} from 'ember-concurrency';
export default ModalComponent.extend({
config: inject(),
copySiteUrl: task(function* () {
copyTextToClipboard(this.config.blogUrl);
yield timeout(1000);
return true;
}),
get encodedUrl() {
return encodeURIComponent(this.config.blogUrl);
},
get facebookShareUrl() {
return `https://www.facebook.com/sharer/sharer.php?u=${this.encodedUrl}`;
},
get linkedInShareUrl() {
return `https://www.linkedin.com/sharing/share-offsite/?url=${this.encodedUrl}`;
},
get xShareUrl() {
return `https://twitter.com/intent/tweet?url=${this.encodedUrl}`;
}
});