mirror of
https://github.com/discourse/discourse.git
synced 2025-03-20 13:27:52 +08:00
DEV: upgrade avatar-selector modal to glimmer component (#24192)
* DEV: upgrade avatar-selector modal * DEV: add system test for avatar selection in account preferences
This commit is contained in:
parent
39e1b97a5d
commit
4a21411de2
@ -0,0 +1,141 @@
|
||||
<DModal
|
||||
@bodyClass="avatar-selector"
|
||||
@closeModal={{@closeModal}}
|
||||
@title={{i18n "user.change_avatar.title"}}
|
||||
class="avatar-selector-modal"
|
||||
>
|
||||
<:body>
|
||||
{{#if this.showSelectableAvatars}}
|
||||
<div class="selectable-avatars">
|
||||
{{#each this.selectableAvatars as |avatar|}}
|
||||
<a
|
||||
href
|
||||
class="selectable-avatar"
|
||||
{{on "click" (fn this.selectAvatar avatar)}}
|
||||
>
|
||||
{{bound-avatar-template avatar "huge"}}
|
||||
</a>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{#if this.showAvatarUploader}}
|
||||
<h4>{{i18n "user.change_avatar.use_custom"}}</h4>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{#if this.showAvatarUploader}}
|
||||
{{#if this.user.use_logo_small_as_avatar}}
|
||||
<div class="avatar-choice">
|
||||
<RadioButton
|
||||
@id="logo-small"
|
||||
@name="logo"
|
||||
@value="logo"
|
||||
@selection={{this.selected}}
|
||||
@onChange={{this.onSelectedChanged}}
|
||||
/>
|
||||
<label class="radio" for="logo-small">
|
||||
{{bound-avatar-template
|
||||
this.siteSettings.site_logo_small_url
|
||||
"large"
|
||||
}}
|
||||
{{i18n "user.change_avatar.logo_small"}}
|
||||
</label>
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="avatar-choice">
|
||||
<RadioButton
|
||||
@id="system-avatar"
|
||||
@name="avatar"
|
||||
@value="system"
|
||||
@selection={{this.selected}}
|
||||
@onChange={{this.onSelectedChanged}}
|
||||
/>
|
||||
<label class="radio" for="system-avatar">
|
||||
{{bound-avatar-template this.user.system_avatar_template "large"}}
|
||||
{{i18n "user.change_avatar.letter_based"}}
|
||||
</label>
|
||||
</div>
|
||||
{{#if this.allowAvatarUpload}}
|
||||
<div class="avatar-choice">
|
||||
<RadioButton
|
||||
@id="gravatar"
|
||||
@name="avatar"
|
||||
@value="gravatar"
|
||||
@selection={{this.selected}}
|
||||
@onChange={{this.onSelectedChanged}}
|
||||
/>
|
||||
<label class="radio" for="gravatar">
|
||||
{{bound-avatar-template this.user.gravatar_avatar_template "large"}}
|
||||
<span>
|
||||
{{html-safe
|
||||
(i18n
|
||||
"user.change_avatar.gravatar"
|
||||
gravatarName=this.siteSettings.gravatar_name
|
||||
gravatarBaseUrl=this.siteSettings.gravatar_base_url
|
||||
gravatarLoginUrl=this.siteSettings.gravatar_login_url
|
||||
)
|
||||
}}
|
||||
{{this.user.email}}
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<DButton
|
||||
@action={{this.refreshGravatar}}
|
||||
@translatedTitle={{i18n
|
||||
"user.change_avatar.refresh_gravatar_title"
|
||||
gravatarName=this.siteSettings.gravatar_name
|
||||
}}
|
||||
@disabled={{this.gravatarRefreshDisabled}}
|
||||
@icon="sync"
|
||||
class="btn-default avatar-selector-refresh-gravatar"
|
||||
/>
|
||||
|
||||
{{#if this.gravatarFailed}}
|
||||
<p class="error">
|
||||
{{i18n
|
||||
"user.change_avatar.gravatar_failed"
|
||||
gravatarName=this.siteSettings.gravatar_name
|
||||
}}
|
||||
</p>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="avatar-choice">
|
||||
<RadioButton
|
||||
@id="uploaded-avatar"
|
||||
@name="avatar"
|
||||
@value="custom"
|
||||
@selection={{this.selected}}
|
||||
@onChange={{this.onSelectedChanged}}
|
||||
/>
|
||||
<label class="radio" for="uploaded-avatar">
|
||||
{{#if this.user.custom_avatar_template}}
|
||||
{{bound-avatar-template this.user.custom_avatar_template "large"}}
|
||||
{{i18n "user.change_avatar.uploaded_avatar"}}
|
||||
{{else}}
|
||||
{{i18n "user.change_avatar.uploaded_avatar_empty"}}
|
||||
{{/if}}
|
||||
</label>
|
||||
<AvatarUploader
|
||||
@user_id={{this.user.id}}
|
||||
@uploadedAvatarTemplate={{this.user.custom_avatar_template}}
|
||||
@uploadedAvatarId={{this.user.custom_avatar_upload_id}}
|
||||
@uploading={{this.uploading}}
|
||||
@class="avatar-uploader"
|
||||
@id="avatar-uploader"
|
||||
@done={{this.uploadComplete}}
|
||||
/>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</:body>
|
||||
|
||||
<:footer>
|
||||
{{#if this.showAvatarUploader}}
|
||||
<DButton
|
||||
@action={{this.saveAvatarSelection}}
|
||||
@disabled={{this.submitDisabled}}
|
||||
@label="save"
|
||||
class="btn-primary"
|
||||
/>
|
||||
<DModalCancel @close={{@closeModal}} />
|
||||
{{/if}}
|
||||
</:footer>
|
||||
</DModal>
|
@ -0,0 +1,175 @@
|
||||
import Component from "@glimmer/component";
|
||||
import { tracked } from "@glimmer/tracking";
|
||||
import { action } from "@ember/object";
|
||||
import { inject as service } from "@ember/service";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
import { allowsImages } from "discourse/lib/uploads";
|
||||
import { isTesting } from "discourse-common/config/environment";
|
||||
|
||||
export default class AvatarSelectorModal extends Component {
|
||||
@service currentUser;
|
||||
@service siteSettings;
|
||||
@tracked gravatarRefreshDisabled = false;
|
||||
@tracked gravatarFailed = false;
|
||||
@tracked uploading = false;
|
||||
@tracked _selected = null;
|
||||
|
||||
get user() {
|
||||
return this.args.model.user;
|
||||
}
|
||||
|
||||
get selected() {
|
||||
return this._selected ?? this.defaultSelection;
|
||||
}
|
||||
|
||||
set selected(value) {
|
||||
this._selected = value;
|
||||
}
|
||||
|
||||
get submitDisabled() {
|
||||
return this.selected === "logo" || this.uploading;
|
||||
}
|
||||
|
||||
get selectableAvatars() {
|
||||
const mode = this.siteSettings.selectable_avatars_mode;
|
||||
const list = this.siteSettings.selectable_avatars;
|
||||
return mode !== "disabled" ? (list ? list.split("|") : []) : null;
|
||||
}
|
||||
|
||||
get showSelectableAvatars() {
|
||||
return this.siteSettings.selectable_avatars_mode !== "disabled";
|
||||
}
|
||||
|
||||
get showAvatarUploader() {
|
||||
const mode = this.siteSettings.selectable_avatars_mode;
|
||||
switch (mode) {
|
||||
case "no_one":
|
||||
return false;
|
||||
case "tl1":
|
||||
case "tl2":
|
||||
case "tl3":
|
||||
case "tl4":
|
||||
const allowedTl = parseInt(mode.replace("tl", ""), 10);
|
||||
return (
|
||||
this.user.admin ||
|
||||
this.user.moderator ||
|
||||
this.user.trust_level >= allowedTl
|
||||
);
|
||||
case "staff":
|
||||
return this.user.admin || this.user.moderator;
|
||||
case "everyone":
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
get defaultSelection() {
|
||||
if (this.user.use_logo_small_as_avatar) {
|
||||
return "logo";
|
||||
} else if (this.user.avatar_template === this.user.system_avatar_template) {
|
||||
return "system";
|
||||
} else if (
|
||||
this.user.avatar_template === this.user.gravatar_avatar_template
|
||||
) {
|
||||
return "gravatar";
|
||||
} else {
|
||||
return "custom";
|
||||
}
|
||||
}
|
||||
|
||||
get selectedUploadId() {
|
||||
const selected = this.selected;
|
||||
switch (selected) {
|
||||
case "system":
|
||||
return this.user.system_avatar_upload_id;
|
||||
case "gravatar":
|
||||
return this.user.gravatar_avatar_upload_id;
|
||||
default:
|
||||
return this.user.custom_avatar_upload_id;
|
||||
}
|
||||
}
|
||||
|
||||
get allowAvatarUpload() {
|
||||
return (
|
||||
this.siteSettingMatches &&
|
||||
allowsImages(this.currentUser.staff, this.siteSettings)
|
||||
);
|
||||
}
|
||||
|
||||
get siteSettingMatches() {
|
||||
const allowUploadedAvatars = this.siteSettings.allow_uploaded_avatars;
|
||||
switch (allowUploadedAvatars) {
|
||||
case "disabled":
|
||||
return false;
|
||||
case "staff":
|
||||
return this.currentUser.staff;
|
||||
case "admin":
|
||||
return this.currentUser.admin;
|
||||
default:
|
||||
return (
|
||||
this.currentUser.trust_level >= parseInt(allowUploadedAvatars, 10) ||
|
||||
this.currentUser.staff
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
onSelectedChanged(value) {
|
||||
this.selected = value;
|
||||
}
|
||||
|
||||
@action
|
||||
async selectAvatar(url, event) {
|
||||
event?.preventDefault();
|
||||
try {
|
||||
await this.user.selectAvatar(url);
|
||||
window.location.reload();
|
||||
} catch (error) {
|
||||
popupAjaxError(error);
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
uploadComplete() {
|
||||
this.selected = "custom";
|
||||
}
|
||||
|
||||
@action
|
||||
async refreshGravatar() {
|
||||
this.gravatarRefreshDisabled = true;
|
||||
|
||||
try {
|
||||
const result = await ajax(
|
||||
`/user_avatar/${this.user.username}/refresh_gravatar.json`,
|
||||
{
|
||||
type: "POST",
|
||||
}
|
||||
);
|
||||
|
||||
if (!result.gravatar_upload_id) {
|
||||
this.gravatarFailed = true;
|
||||
} else {
|
||||
this.gravatarFailed = false;
|
||||
this.user.setProperties({
|
||||
gravatar_avatar_upload_id: result.gravatar_upload_id,
|
||||
gravatar_avatar_template: result.gravatar_avatar_template,
|
||||
});
|
||||
}
|
||||
} finally {
|
||||
this.gravatarRefreshDisabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
async saveAvatarSelection() {
|
||||
try {
|
||||
await this.user.pickAvatar(this.selectedUploadId, this.selected);
|
||||
if (!isTesting()) {
|
||||
window.location.reload();
|
||||
}
|
||||
} catch (error) {
|
||||
popupAjaxError(error);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,200 +0,0 @@
|
||||
import { tracked } from "@glimmer/tracking";
|
||||
import Controller from "@ember/controller";
|
||||
import { action } from "@ember/object";
|
||||
import { dependentKeyCompat } from "@ember/object/compat";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
import { setting } from "discourse/lib/computed";
|
||||
import { allowsImages } from "discourse/lib/uploads";
|
||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
import { isTesting } from "discourse-common/config/environment";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
gravatarName: setting("gravatar_name"),
|
||||
gravatarBaseUrl: setting("gravatar_base_url"),
|
||||
gravatarLoginUrl: setting("gravatar_login_url"),
|
||||
|
||||
@discourseComputed("selected", "uploading")
|
||||
submitDisabled(selected, uploading) {
|
||||
return selected === "logo" || uploading;
|
||||
},
|
||||
|
||||
@discourseComputed(
|
||||
"siteSettings.selectable_avatars_mode",
|
||||
"siteSettings.selectable_avatars"
|
||||
)
|
||||
selectableAvatars(mode, list) {
|
||||
if (mode !== "disabled") {
|
||||
return list ? list.split("|") : [];
|
||||
}
|
||||
},
|
||||
|
||||
@discourseComputed("siteSettings.selectable_avatars_mode")
|
||||
showSelectableAvatars(mode) {
|
||||
return mode !== "disabled";
|
||||
},
|
||||
|
||||
@discourseComputed("siteSettings.selectable_avatars_mode")
|
||||
showAvatarUploader(mode) {
|
||||
switch (mode) {
|
||||
case "no_one":
|
||||
return false;
|
||||
case "tl1":
|
||||
case "tl2":
|
||||
case "tl3":
|
||||
case "tl4":
|
||||
const allowedTl = parseInt(mode.replace("tl", ""), 10);
|
||||
return (
|
||||
this.user.admin ||
|
||||
this.user.moderator ||
|
||||
this.user.trust_level >= allowedTl
|
||||
);
|
||||
case "staff":
|
||||
return this.user.admin || this.user.moderator;
|
||||
case "everyone":
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
@tracked _selected: null,
|
||||
|
||||
@dependentKeyCompat
|
||||
get selected() {
|
||||
return this._selected ?? this.defaultSelection;
|
||||
},
|
||||
|
||||
set selected(value) {
|
||||
this._selected = value;
|
||||
},
|
||||
|
||||
@action
|
||||
onSelectedChanged(value) {
|
||||
this._selected = value;
|
||||
},
|
||||
|
||||
get defaultSelection() {
|
||||
if (this.get("user.use_logo_small_as_avatar")) {
|
||||
return "logo";
|
||||
} else if (
|
||||
this.get("user.avatar_template") ===
|
||||
this.get("user.system_avatar_template")
|
||||
) {
|
||||
return "system";
|
||||
} else if (
|
||||
this.get("user.avatar_template") ===
|
||||
this.get("user.gravatar_avatar_template")
|
||||
) {
|
||||
return "gravatar";
|
||||
} else {
|
||||
return "custom";
|
||||
}
|
||||
},
|
||||
|
||||
@discourseComputed(
|
||||
"selected",
|
||||
"user.system_avatar_upload_id",
|
||||
"user.gravatar_avatar_upload_id",
|
||||
"user.custom_avatar_upload_id"
|
||||
)
|
||||
selectedUploadId(selected, system, gravatar, custom) {
|
||||
switch (selected) {
|
||||
case "system":
|
||||
return system;
|
||||
case "gravatar":
|
||||
return gravatar;
|
||||
default:
|
||||
return custom;
|
||||
}
|
||||
},
|
||||
|
||||
@discourseComputed(
|
||||
"selected",
|
||||
"user.system_avatar_template",
|
||||
"user.gravatar_avatar_template",
|
||||
"user.custom_avatar_template"
|
||||
)
|
||||
selectedAvatarTemplate(selected, system, gravatar, custom) {
|
||||
switch (selected) {
|
||||
case "system":
|
||||
return system;
|
||||
case "gravatar":
|
||||
return gravatar;
|
||||
default:
|
||||
return custom;
|
||||
}
|
||||
},
|
||||
|
||||
siteSettingMatches(value, user) {
|
||||
switch (value) {
|
||||
case "disabled":
|
||||
return false;
|
||||
case "staff":
|
||||
return user.staff;
|
||||
case "admin":
|
||||
return user.admin;
|
||||
default:
|
||||
return user.trust_level >= parseInt(value, 10) || user.staff;
|
||||
}
|
||||
},
|
||||
|
||||
@discourseComputed("siteSettings.allow_uploaded_avatars")
|
||||
allowAvatarUpload(allowUploadedAvatars) {
|
||||
return (
|
||||
this.siteSettingMatches(allowUploadedAvatars, this.currentUser) &&
|
||||
allowsImages(this.currentUser.staff, this.siteSettings)
|
||||
);
|
||||
},
|
||||
|
||||
@action
|
||||
selectAvatar(url, event) {
|
||||
event?.preventDefault();
|
||||
this.user
|
||||
.selectAvatar(url)
|
||||
.then(() => window.location.reload())
|
||||
.catch(popupAjaxError);
|
||||
},
|
||||
|
||||
actions: {
|
||||
uploadComplete() {
|
||||
this.set("selected", "custom");
|
||||
},
|
||||
|
||||
refreshGravatar() {
|
||||
this.set("gravatarRefreshDisabled", true);
|
||||
|
||||
return ajax(
|
||||
`/user_avatar/${this.get("user.username")}/refresh_gravatar.json`,
|
||||
{ type: "POST" }
|
||||
)
|
||||
.then((result) => {
|
||||
if (!result.gravatar_upload_id) {
|
||||
this.set("gravatarFailed", true);
|
||||
} else {
|
||||
this.set("gravatarFailed", false);
|
||||
|
||||
this.user.setProperties({
|
||||
gravatar_avatar_upload_id: result.gravatar_upload_id,
|
||||
gravatar_avatar_template: result.gravatar_avatar_template,
|
||||
});
|
||||
}
|
||||
})
|
||||
.finally(() => this.set("gravatarRefreshDisabled", false));
|
||||
},
|
||||
|
||||
saveAvatarSelection() {
|
||||
const selectedUploadId = this.selectedUploadId;
|
||||
const type = this.selected;
|
||||
|
||||
this.user
|
||||
.pickAvatar(selectedUploadId, type)
|
||||
.then(() => {
|
||||
if (!isTesting()) {
|
||||
window.location.reload();
|
||||
}
|
||||
})
|
||||
.catch(popupAjaxError);
|
||||
},
|
||||
},
|
||||
});
|
@ -1,10 +1,12 @@
|
||||
import { action } from "@ember/object";
|
||||
import showModal from "discourse/lib/show-modal";
|
||||
import { inject as service } from "@ember/service";
|
||||
import AvatarSelectorModal from "discourse/components/modal/avatar-selector";
|
||||
import UserBadge from "discourse/models/user-badge";
|
||||
import RestrictedUserRoute from "discourse/routes/restricted-user";
|
||||
import I18n from "discourse-i18n";
|
||||
|
||||
export default RestrictedUserRoute.extend({
|
||||
modal: service(),
|
||||
model() {
|
||||
const user = this.modelFor("user");
|
||||
if (this.siteSettings.enable_badges) {
|
||||
@ -37,6 +39,8 @@ export default RestrictedUserRoute.extend({
|
||||
|
||||
@action
|
||||
showAvatarSelector(user) {
|
||||
showModal("avatar-selector").setProperties({ user });
|
||||
this.modal.show(AvatarSelectorModal, {
|
||||
model: { user },
|
||||
});
|
||||
},
|
||||
});
|
||||
|
@ -1,130 +0,0 @@
|
||||
<DModalBody @title="user.change_avatar.title" @class="avatar-selector">
|
||||
{{#if this.showSelectableAvatars}}
|
||||
<div class="selectable-avatars">
|
||||
{{#each this.selectableAvatars as |avatar|}}
|
||||
<a
|
||||
href
|
||||
class="selectable-avatar"
|
||||
{{on "click" (fn this.selectAvatar avatar)}}
|
||||
>
|
||||
{{bound-avatar-template avatar "huge"}}
|
||||
</a>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{#if this.showAvatarUploader}}
|
||||
<h4>{{html-safe (i18n "user.change_avatar.use_custom")}}</h4>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{#if this.showAvatarUploader}}
|
||||
{{#if this.user.use_logo_small_as_avatar}}
|
||||
<div class="avatar-choice">
|
||||
<RadioButton
|
||||
@id="logo-small"
|
||||
@name="logo"
|
||||
@value="logo"
|
||||
@selection={{this.selected}}
|
||||
@onChange={{this.onSelectedChanged}}
|
||||
/>
|
||||
<label class="radio" for="logo-small">{{bound-avatar-template
|
||||
this.siteSettings.site_logo_small_url
|
||||
"large"
|
||||
}}
|
||||
{{html-safe (i18n "user.change_avatar.logo_small")}}</label>
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="avatar-choice">
|
||||
<RadioButton
|
||||
@id="system-avatar"
|
||||
@name="avatar"
|
||||
@value="system"
|
||||
@selection={{this.selected}}
|
||||
@onChange={{this.onSelectedChanged}}
|
||||
/>
|
||||
<label class="radio" for="system-avatar">{{bound-avatar-template
|
||||
this.user.system_avatar_template
|
||||
"large"
|
||||
}}
|
||||
{{html-safe (i18n "user.change_avatar.letter_based")}}</label>
|
||||
</div>
|
||||
{{#if this.allowAvatarUpload}}
|
||||
<div class="avatar-choice">
|
||||
<RadioButton
|
||||
@id="gravatar"
|
||||
@name="avatar"
|
||||
@value="gravatar"
|
||||
@selection={{this.selected}}
|
||||
@onChange={{this.onSelectedChanged}}
|
||||
/>
|
||||
<label class="radio" for="gravatar">{{bound-avatar-template
|
||||
this.user.gravatar_avatar_template
|
||||
"large"
|
||||
}}
|
||||
<span>{{html-safe
|
||||
(i18n
|
||||
"user.change_avatar.gravatar"
|
||||
gravatarName=this.gravatarName
|
||||
gravatarBaseUrl=this.gravatarBaseUrl
|
||||
gravatarLoginUrl=this.gravatarLoginUrl
|
||||
)
|
||||
}}
|
||||
{{this.user.email}}</span></label>
|
||||
|
||||
<DButton
|
||||
@action={{action "refreshGravatar"}}
|
||||
@translatedTitle={{i18n
|
||||
"user.change_avatar.refresh_gravatar_title"
|
||||
gravatarName=this.gravatarName
|
||||
}}
|
||||
@disabled={{this.gravatarRefreshDisabled}}
|
||||
@icon="sync"
|
||||
class="btn-default avatar-selector-refresh-gravatar"
|
||||
/>
|
||||
|
||||
{{#if this.gravatarFailed}}
|
||||
<p class="error">{{I18n
|
||||
"user.change_avatar.gravatar_failed"
|
||||
gravatarName=this.gravatarName
|
||||
}}</p>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="avatar-choice">
|
||||
<RadioButton
|
||||
@id="uploaded-avatar"
|
||||
@name="avatar"
|
||||
@value="custom"
|
||||
@selection={{this.selected}}
|
||||
@onChange={{this.onSelectedChanged}}
|
||||
/>
|
||||
<label class="radio" for="uploaded-avatar">
|
||||
{{#if this.user.custom_avatar_template}}
|
||||
{{bound-avatar-template this.user.custom_avatar_template "large"}}
|
||||
{{i18n "user.change_avatar.uploaded_avatar"}}
|
||||
{{else}}
|
||||
{{i18n "user.change_avatar.uploaded_avatar_empty"}}
|
||||
{{/if}}
|
||||
</label>
|
||||
<AvatarUploader
|
||||
@user_id={{this.user.id}}
|
||||
@uploadedAvatarTemplate={{this.user.custom_avatar_template}}
|
||||
@uploadedAvatarId={{this.user.custom_avatar_upload_id}}
|
||||
@uploading={{this.uploading}}
|
||||
@class="avatar-uploader"
|
||||
@id="avatar-uploader"
|
||||
@done={{action "uploadComplete"}}
|
||||
/>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</DModalBody>
|
||||
|
||||
{{#if this.showAvatarUploader}}
|
||||
<div class="modal-footer">
|
||||
<DButton
|
||||
@action={{action "saveAvatarSelection"}}
|
||||
@disabled={{this.submitDisabled}}
|
||||
@label="save"
|
||||
class="btn-primary"
|
||||
/>
|
||||
<DModalCancel @close={{route-action "closeModal"}} />
|
||||
</div>
|
||||
{{/if}}
|
@ -1,42 +0,0 @@
|
||||
import EmberObject from "@ember/object";
|
||||
import { setupTest } from "ember-qunit";
|
||||
import { module, test } from "qunit";
|
||||
|
||||
module("Unit | Controller | avatar-selector", function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test("avatarTemplate", function (assert) {
|
||||
const user = EmberObject.create({
|
||||
avatar_template: "avatar",
|
||||
system_avatar_template: "system",
|
||||
gravatar_avatar_template: "gravatar",
|
||||
|
||||
system_avatar_upload_id: 1,
|
||||
gravatar_avatar_upload_id: 2,
|
||||
custom_avatar_upload_id: 3,
|
||||
});
|
||||
const controller = this.owner.lookup("controller:avatar-selector");
|
||||
controller.setProperties({ user });
|
||||
|
||||
user.set("avatar_template", "system");
|
||||
assert.strictEqual(
|
||||
controller.selectedUploadId,
|
||||
1,
|
||||
"we are using system by default"
|
||||
);
|
||||
|
||||
user.set("avatar_template", "gravatar");
|
||||
assert.strictEqual(
|
||||
controller.selectedUploadId,
|
||||
2,
|
||||
"we are using gravatar when set"
|
||||
);
|
||||
|
||||
user.set("avatar_template", "avatar");
|
||||
assert.strictEqual(
|
||||
controller.selectedUploadId,
|
||||
3,
|
||||
"we are using custom when set"
|
||||
);
|
||||
});
|
||||
});
|
25
spec/system/page_objects/modals/avatar_selector.rb
Normal file
25
spec/system/page_objects/modals/avatar_selector.rb
Normal file
@ -0,0 +1,25 @@
|
||||
# frozen_string_literal: true
|
||||
module PageObjects
|
||||
module Modals
|
||||
class AvatarSelector < PageObjects::Modals::Base
|
||||
BODY_SELECTOR = ".avatar-selector"
|
||||
MODAL_SELECTOR = ".avatar-selector-modal"
|
||||
|
||||
def select_avatar_upload_option
|
||||
body.choose("avatar", option: "custom")
|
||||
end
|
||||
|
||||
def select_system_assigned_option
|
||||
body.choose("avatar", option: "system")
|
||||
end
|
||||
|
||||
def click_avatar_upload_button
|
||||
body.find_button(I18n.t("js.user.change_avatar.upload_title")).click
|
||||
end
|
||||
|
||||
def has_user_avatar_image_uploaded?
|
||||
body.has_css?(".avatar[src*='uploads/default']")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
28
spec/system/page_objects/pages/user_preferences_account.rb
Normal file
28
spec/system/page_objects/pages/user_preferences_account.rb
Normal file
@ -0,0 +1,28 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module PageObjects
|
||||
module Pages
|
||||
class UserPreferencesAccount < PageObjects::Pages::Base
|
||||
def visit(user)
|
||||
page.visit("/u/#{user.username}/preferences/account")
|
||||
self
|
||||
end
|
||||
|
||||
def click_edit_avatar_button
|
||||
page.find_button("edit-avatar").click
|
||||
end
|
||||
|
||||
def open_avatar_selector_modal(user)
|
||||
visit(user).click_edit_avatar_button
|
||||
end
|
||||
|
||||
def has_custom_uploaded_avatar_image?
|
||||
has_css?(".pref-avatar img.avatar[src*='user_avatar']")
|
||||
end
|
||||
|
||||
def has_system_avatar_image?
|
||||
has_css?(".pref-avatar img.avatar[src*='letter_avatar']")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
29
spec/system/user_page/user_preferences_account_spec.rb
Normal file
29
spec/system/user_page/user_preferences_account_spec.rb
Normal file
@ -0,0 +1,29 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
describe "User preferences for Account", type: :system do
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
let(:user_account_preferences_page) { PageObjects::Pages::UserPreferencesAccount.new }
|
||||
let(:avatar_selector_modal) { PageObjects::Modals::AvatarSelector.new }
|
||||
before { sign_in(user) }
|
||||
|
||||
describe "avatar-selector modal" do
|
||||
it "saves custom picture and system assigned pictures" do
|
||||
user_account_preferences_page.open_avatar_selector_modal(user)
|
||||
expect(avatar_selector_modal).to be_open
|
||||
|
||||
avatar_selector_modal.select_avatar_upload_option
|
||||
file_path = File.absolute_path(file_from_fixtures("logo.jpg"))
|
||||
attach_file(file_path) { avatar_selector_modal.click_avatar_upload_button }
|
||||
expect(avatar_selector_modal).to have_user_avatar_image_uploaded
|
||||
avatar_selector_modal.click_primary_button
|
||||
expect(avatar_selector_modal).to be_closed
|
||||
expect(user_account_preferences_page).to have_custom_uploaded_avatar_image
|
||||
|
||||
user_account_preferences_page.open_avatar_selector_modal(user)
|
||||
avatar_selector_modal.select_system_assigned_option
|
||||
avatar_selector_modal.click_primary_button
|
||||
expect(avatar_selector_modal).to be_closed
|
||||
expect(user_account_preferences_page).to have_system_avatar_image
|
||||
end
|
||||
end
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user