Move avatar from options to profile.
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Wed, 7 Dec 2011 14:03:28 +0000 (15:03 +0100)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Wed, 7 Dec 2011 14:04:12 +0000 (15:04 +0100)
17 files changed:
src/main/java/net/pterodactylus/sone/core/Core.java
src/main/java/net/pterodactylus/sone/core/SoneDownloader.java
src/main/java/net/pterodactylus/sone/core/SoneInserter.java
src/main/java/net/pterodactylus/sone/data/Profile.java
src/main/java/net/pterodactylus/sone/data/Sone.java
src/main/java/net/pterodactylus/sone/template/SoneAccessor.java
src/main/java/net/pterodactylus/sone/web/EditProfilePage.java
src/main/java/net/pterodactylus/sone/web/OptionsPage.java
src/main/resources/i18n/sone.en.properties
src/main/resources/static/css/sone.css
src/main/resources/templates/editProfile.html
src/main/resources/templates/include/head.html
src/main/resources/templates/include/soneMenu.html
src/main/resources/templates/include/viewPost.html
src/main/resources/templates/include/viewReply.html
src/main/resources/templates/insert/sone.xml
src/main/resources/templates/options.html

index 093761e..0ae7206 100644 (file)
@@ -1442,7 +1442,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
                String lastInsertFingerprint = configuration.getStringValue(sonePrefix + "/LastInsertFingerprint").getValue("");
 
                /* load profile. */
-               Profile profile = new Profile();
+               Profile profile = new Profile(sone);
                profile.setFirstName(configuration.getStringValue(sonePrefix + "/Profile/FirstName").getValue(null));
                profile.setMiddleName(configuration.getStringValue(sonePrefix + "/Profile/MiddleName").getValue(null));
                profile.setLastName(configuration.getStringValue(sonePrefix + "/Profile/LastName").getValue(null));
@@ -1593,7 +1593,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
                /* load avatar. */
                String avatarId = configuration.getStringValue(sonePrefix + "/Profile/Avatar").getValue(null);
                if (avatarId != null) {
-                       sone.setAvatar(getImage(avatarId, false));
+                       profile.setAvatar(getImage(avatarId, false));
                }
 
                /* load options. */
@@ -2141,7 +2141,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
                        configuration.getIntValue(sonePrefix + "/Profile/BirthDay").setValue(profile.getBirthDay());
                        configuration.getIntValue(sonePrefix + "/Profile/BirthMonth").setValue(profile.getBirthMonth());
                        configuration.getIntValue(sonePrefix + "/Profile/BirthYear").setValue(profile.getBirthYear());
-                       configuration.getStringValue(sonePrefix + "/Profile/Avatar").setValue(sone.getAvatar());
+                       configuration.getStringValue(sonePrefix + "/Profile/Avatar").setValue(profile.getAvatar());
 
                        /* save profile fields. */
                        int fieldCounter = 0;
index d8b924f..5024ab9 100644 (file)
@@ -330,7 +330,7 @@ public class SoneDownloader extends AbstractService {
                Integer profileBirthDay = Numbers.safeParseInteger(profileXml.getValue("birth-day", null));
                Integer profileBirthMonth = Numbers.safeParseInteger(profileXml.getValue("birth-month", null));
                Integer profileBirthYear = Numbers.safeParseInteger(profileXml.getValue("birth-year", null));
-               Profile profile = new Profile().setFirstName(profileFirstName).setMiddleName(profileMiddleName).setLastName(profileLastName);
+               Profile profile = new Profile(sone).setFirstName(profileFirstName).setMiddleName(profileMiddleName).setLastName(profileLastName);
                profile.setBirthDay(profileBirthDay).setBirthMonth(profileBirthMonth).setBirthYear(profileBirthYear);
                /* avatar is processed after images are loaded. */
                String avatarId = profileXml.getValue("avatar", null);
@@ -499,7 +499,7 @@ public class SoneDownloader extends AbstractService {
 
                /* process avatar. */
                if (avatarId != null) {
-                       sone.setAvatar(core.getImage(avatarId, false));
+                       profile.setAvatar(core.getImage(avatarId, false));
                }
 
                /* okay, apparently everything was parsed correctly. Now import. */
index f6bf6e0..4d9878f 100644 (file)
@@ -307,7 +307,6 @@ public class SoneInserter extends AbstractService {
                        soneProperties.put("likedPostIds", new HashSet<String>(sone.getLikedPostIds()));
                        soneProperties.put("likedReplyIds", new HashSet<String>(sone.getLikedReplyIds()));
                        soneProperties.put("albums", sone.getAllAlbums());
-                       soneProperties.put("avatar", sone.getAvatar());
                }
 
                //
index 6b44d10..aa6ff46 100644 (file)
@@ -32,6 +32,9 @@ import net.pterodactylus.util.validation.Validation;
  */
 public class Profile implements Fingerprintable {
 
+       /** The Sone this profile belongs to. */
+       private final Sone sone;
+
        /** The first name. */
        private volatile String firstName;
 
@@ -50,14 +53,20 @@ public class Profile implements Fingerprintable {
        /** The year of the birth date. */
        private volatile Integer birthYear;
 
+       /** The ID of the avatar image. */
+       private volatile String avatar;
+
        /** Additional fields in the profile. */
        private final List<Field> fields = Collections.synchronizedList(new ArrayList<Field>());
 
        /**
         * Creates a new empty profile.
+        *
+        * @param sone
+        *            The Sone this profile belongs to
         */
-       public Profile() {
-               /* do nothing. */
+       public Profile(Sone sone) {
+               this.sone = sone;
        }
 
        /**
@@ -67,15 +76,14 @@ public class Profile implements Fingerprintable {
         *            The profile to copy
         */
        public Profile(Profile profile) {
-               if (profile == null) {
-                       return;
-               }
+               this.sone = profile.sone;
                this.firstName = profile.firstName;
                this.middleName = profile.middleName;
                this.lastName = profile.lastName;
                this.birthDay = profile.birthDay;
                this.birthMonth = profile.birthMonth;
                this.birthYear = profile.birthYear;
+               this.avatar = profile.avatar;
                this.fields.addAll(profile.fields);
        }
 
@@ -198,6 +206,34 @@ public class Profile implements Fingerprintable {
        }
 
        /**
+        * Returns the ID of the currently selected avatar image.
+        *
+        * @return The ID of the currently selected avatar image, or {@code null} if
+        *         no avatar is selected.
+        */
+       public String getAvatar() {
+               return avatar;
+       }
+
+       /**
+        * Sets the avatar image.
+        *
+        * @param avatar
+        *            The new avatar image, or {@code null} to not select an avatar
+        *            image.
+        * @return This Sone
+        */
+       public Profile setAvatar(Image avatar) {
+               if (avatar == null) {
+                       this.avatar = null;
+                       return this;
+               }
+               Validation.begin().isEqual("Image Owner", avatar.getSone(), sone).check();
+               this.avatar = avatar.getId();
+               return this;
+       }
+
+       /**
         * Sets the year of the birth date.
         *
         * @param birthYear
@@ -367,6 +403,9 @@ public class Profile implements Fingerprintable {
                if (birthYear != null) {
                        fingerprint.append("BirthYear(").append(birthYear).append(')');
                }
+               if (avatar != null) {
+                       fingerprint.append("Avatar(").append(avatar).append(')');
+               }
                fingerprint.append("ContactInformation(");
                for (Field field : fields) {
                        fingerprint.append(field.getName()).append('(').append(field.getValue()).append(')');
index e36a306..9d7ca82 100644 (file)
@@ -147,7 +147,7 @@ public class Sone implements Fingerprintable, Comparable<Sone> {
        private volatile long time;
 
        /** The profile of this Sone. */
-       private volatile Profile profile = new Profile();
+       private volatile Profile profile = new Profile(this);
 
        /** The client used by the Sone. */
        private volatile Client client;
@@ -173,9 +173,6 @@ public class Sone implements Fingerprintable, Comparable<Sone> {
        /** Sone-specific options. */
        private final Options options = new Options();
 
-       /** The avatar of this Sone. */
-       private volatile String avatar;
-
        /**
         * Creates a new Sone.
         *
@@ -767,34 +764,6 @@ public class Sone implements Fingerprintable, Comparable<Sone> {
        }
 
        /**
-        * Returns the ID of the currently selected avatar image.
-        *
-        * @return The ID of the currently selected avatar image, or {@code null} if
-        *         no avatar is selected.
-        */
-       public String getAvatar() {
-               return avatar;
-       }
-
-       /**
-        * Sets the avatar image.
-        *
-        * @param avatar
-        *            The new avatar image, or {@code null} to not select an avatar
-        *            image.
-        * @return This Sone
-        */
-       public Sone setAvatar(Image avatar) {
-               if (avatar == null) {
-                       this.avatar = null;
-                       return this;
-               }
-               Validation.begin().isEqual("Image Owner", avatar.getSone(), this).check();
-               this.avatar = avatar.getId();
-               return this;
-       }
-
-       /**
         * Returns Sone-specific options.
         *
         * @return The options of this Sone
@@ -851,8 +820,6 @@ public class Sone implements Fingerprintable, Comparable<Sone> {
                }
                fingerprint.append(')');
 
-               fingerprint.append("Avatar(").append(avatar).append(')');
-
                return fingerprint.toString();
        }
 
index bc72776..ead6066 100644 (file)
@@ -112,12 +112,6 @@ public class SoneAccessor extends ReflectionAccessor {
                                return new Trust(null, null, null);
                        }
                        return trust;
-               } else if (member.equals("avatar")) {
-                       String avatarId = sone.getAvatar();
-                       if (avatarId == null) {
-                               return null;
-                       }
-                       return core.getImage(avatarId);
                }
                return super.get(templateContext, object, member);
        }
index 59c7e3e..422004b 100644 (file)
@@ -67,6 +67,7 @@ public class EditProfilePage extends SoneTemplatePage {
                Integer birthDay = profile.getBirthDay();
                Integer birthMonth = profile.getBirthMonth();
                Integer birthYear = profile.getBirthYear();
+               String avatarId = profile.getAvatar();
                List<Field> fields = profile.getFields();
                if (request.getMethod() == Method.POST) {
                        if (request.getHttpRequest().getPartAsStringFailsafe("save-profile", 4).equals("true")) {
@@ -76,10 +77,12 @@ public class EditProfilePage extends SoneTemplatePage {
                                birthDay = Numbers.safeParseInteger(request.getHttpRequest().getPartAsStringFailsafe("birth-day", 256).trim());
                                birthMonth = Numbers.safeParseInteger(request.getHttpRequest().getPartAsStringFailsafe("birth-month", 256).trim());
                                birthYear = Numbers.safeParseInteger(request.getHttpRequest().getPartAsStringFailsafe("birth-year", 256).trim());
+                               avatarId = request.getHttpRequest().getPartAsStringFailsafe("avatar-id", 36);
                                profile.setFirstName(firstName.length() > 0 ? firstName : null);
                                profile.setMiddleName(middleName.length() > 0 ? middleName : null);
                                profile.setLastName(lastName.length() > 0 ? lastName : null);
                                profile.setBirthDay(birthDay).setBirthMonth(birthMonth).setBirthYear(birthYear);
+                               profile.setAvatar(webInterface.getCore().getImage(avatarId, false));
                                for (Field field : fields) {
                                        String value = request.getHttpRequest().getPartAsStringFailsafe("field-" + field.getId(), 400);
                                        field.setValue(value);
@@ -136,6 +139,7 @@ public class EditProfilePage extends SoneTemplatePage {
                templateContext.set("birthDay", birthDay);
                templateContext.set("birthMonth", birthMonth);
                templateContext.set("birthYear", birthYear);
+               templateContext.set("avatar-id", avatarId);
                templateContext.set("fields", fields);
        }
 
index 2a23236..49b1275 100644 (file)
@@ -73,8 +73,6 @@ public class OptionsPage extends SoneTemplatePage {
                                currentSone.getOptions().getBooleanOption("ShowNotification/NewPosts").set(showNotificationNewPosts);
                                boolean showNotificationNewReplies = request.getHttpRequest().isPartSet("show-notification-new-replies");
                                currentSone.getOptions().getBooleanOption("ShowNotification/NewReplies").set(showNotificationNewReplies);
-                               String avatarId =request.getHttpRequest().getPartAsStringFailsafe("avatar-image", 36);
-                               currentSone.setAvatar(webInterface.getCore().getImage(avatarId, false));
                                webInterface.getCore().touchConfiguration();
                        }
                        Integer insertionDelay = Numbers.safeParseInteger(request.getHttpRequest().getPartAsStringFailsafe("insertion-delay", 16));
@@ -141,7 +139,6 @@ public class OptionsPage extends SoneTemplatePage {
                        templateContext.set("show-notification-new-sones", currentSone.getOptions().getBooleanOption("ShowNotification/NewSones").get());
                        templateContext.set("show-notification-new-posts", currentSone.getOptions().getBooleanOption("ShowNotification/NewPosts").get());
                        templateContext.set("show-notification-new-replies", currentSone.getOptions().getBooleanOption("ShowNotification/NewReplies").get());
-                       templateContext.set("avatar-image", currentSone.getAvatar());
                }
                templateContext.set("insertion-delay", preferences.getInsertionDelay());
                templateContext.set("posts-per-page", preferences.getPostsPerPage());
index c7bd539..845327e 100644 (file)
@@ -43,7 +43,8 @@ Page.Options.Option.EnableSoneInsertNotifications.Description=If enabled, this w
 Page.Options.Option.ShowNotificationNewSones.Description=Show notifications for new Sones.
 Page.Options.Option.ShowNotificationNewPosts.Description=Show notifications for new posts.
 Page.Options.Option.ShowNotificationNewReplies.Description=Show notifications for new replies.
-Page.Options.Option.Avatar.Delete=No avatar
+Page.Options.Section.AvatarOptions.Title=Avatar Options
+
 Page.Options.Section.RuntimeOptions.Title=Runtime Behaviour
 Page.Options.Option.InsertionDelay.Description=The number of seconds the Sone inserter waits after a modification of a Sone before it is being inserted.
 Page.Options.Option.PostsPerPage.Description=The number of posts to display on a page before pagination controls are being shown.
@@ -118,6 +119,9 @@ Page.EditProfile.Birthday.Title=Birthday
 Page.EditProfile.Birthday.Label.Day=Day:
 Page.EditProfile.Birthday.Label.Month=Month:
 Page.EditProfile.Birthday.Label.Year=Year:
+Page.EditProfile.Avatar.Title=Avatar
+Page.EditProfile.Avatar.Description=You can select one of your uploaded images to be shown as avatar. It should not be larger than 64×64 pixels because that is the largest size shown for other people (80×80 pixels is used for the page header).
+Page.EditProfile.Avatar.Delete=No avatar
 Page.EditProfile.Fields.Title=Custom Fields
 Page.EditProfile.Fields.Description=Here you can enter custom fields into your profile. These fields can contain anything you want and be as terse or as verbose as you wish. Just remember that when it comes to anonymity, sometimes less is more.
 Page.EditProfile.Fields.Button.Edit=edit
index 2d9d503..d065f78 100644 (file)
@@ -856,5 +856,9 @@ textarea {
 
 #sone #avatar-selection li .post-avatar {
        vertical-align: middle;
-       margin-bottom: 0.5em;
+       margin-top: 0.5em;
+}
+
+#sone #avatar-selection li#no-avatar {
+       display: block;
 }
index fea58a8..e140ac4 100644 (file)
                        <input type="text" name="birth-year" value="<% birthYear|html>" />
                </div>
 
+               <h1><%= Page.EditProfile.Avatar.Title|l10n|html></h1>
+
+               <p><%= Page.EditProfile.Avatar.Description|l10n|html></p>
+
+               <ul id="avatar-selection">
+                       <li id="no-avatar">
+                               <input type="radio" name="avatar-id" value="none"<%ifnull avatar-image> checked="checked"<%/if>/>
+                               <%= Page.EditProfile.Avatar.Delete|l10n|html>
+                       </li>
+                       <%foreach currentSone.allImages image>
+                               <li>
+                                       <input type="radio" name="avatar-id" value="<%image.id|html>"<%if avatar-id|match key=image.id> checked="checked"<%/if>/>
+                                       <div class="post-avatar"><% image|image-link max-width=48 max-height=48 mode=enlarge title==image.title></div>
+                               </li>
+                       <%/foreach>
+               </ul>
+
                <div>
                        <button type="submit" name="save-profile" value="true"><%= Page.EditProfile.Button.Save|l10n|html></button>
                </div>
index efb5ddf..9988e68 100644 (file)
@@ -43,8 +43,8 @@
                        <div class="avatar profile-avatar">
                                <a class="picture" href="index.html">
                                        <%ifnull !currentSone>
-                                               <%ifnull !currentSone.avatar>
-                                                       <%currentSone.avatar|image-link max-width=80 max-height=80 mode=enlarge title="Profile Avatar">
+                                               <%ifnull !currentSone.profile.avatar>
+                                                       <%currentSone.profile.avatar|image-link max-width=80 max-height=80 mode=enlarge title="Profile Avatar">
                                                <%else>
                                                        <img src="/WebOfTrust/GetIdenticon?identity=<% currentSone.id|html>&amp;width=80&amp;height=80" width="80" height="80" alt="Profile Avatar" />
                                                <%/if>
index 6684ee6..9fa982f 100644 (file)
@@ -1,8 +1,8 @@
 <div class="sone-menu <% class|css|html>">
        <div class="sone-menu-id hidden"><%sone.id|html></div>
        <div class="avatar menu-avatar">
-               <%ifnull !sone.avatar>
-                       <%sone.avatar|image-link max-width=64 max-height=64 mode=enlarge title==sone.niceName>
+               <%ifnull !sone.profile.avatar>
+                       <%sone.profile.avatar|image-link max-width=64 max-height=64 mode=enlarge title==sone.niceName>
                <%else>
                        <img src="/WebOfTrust/GetIdenticon?identity=<%sone.id|html>&amp;width=64&amp;height=64" width="64" height="64" alt="Avatar Image" />
                <%/if>
index fd54e5d..396fa6e 100644 (file)
@@ -6,8 +6,8 @@
        <%include include/soneMenu.html class=="sone-post-menu" sone=post.sone>
        <div class="avatar post-avatar" >
                <%if post.loaded>
-                       <%ifnull !post.sone.avatar>
-                               <%post.sone.avatar|image-link max-width=48 max-height=48 mode=enlarge title="Avatar Image">
+                       <%ifnull !post.sone.profile.avatar>
+                               <%post.sone.profile.avatar|image-link max-width=48 max-height=48 mode=enlarge title="Avatar Image">
                        <%else>
                                <img src="/WebOfTrust/GetIdenticon?identity=<% post.sone.id|html>&amp;width=48&height=48" width="48" height="48" alt="Avatar Image" />
                        <%/if>
index 3d9c33e..ca07cf7 100644 (file)
@@ -5,8 +5,8 @@
        <div class="reply-author-local hidden"><% reply.sone.local></div>
        <%include include/soneMenu.html class=="sone-reply-menu" sone=reply.sone>
        <div class="avatar reply-avatar">
-               <%ifnull !reply.sone.avatar>
-                       <% reply.sone.avatar|image-link max-width=36 max-height=36 mode=enlarge title="Avatar Image">
+               <%ifnull !reply.sone.profile.avatar>
+                       <% reply.sone.profile.avatar|image-link max-width=36 max-height=36 mode=enlarge title="Avatar Image">
                <%else>
                        <img src="/WebOfTrust/GetIdenticon?identity=<% reply.sone.id|html>&amp;width=36&height=36" width="36" height="36" alt="Avatar Image" />
                <%/if>
index fbacd19..e615725 100644 (file)
@@ -16,6 +16,7 @@
                <birth-day><% currentSone.profile.birthDay|xml></birth-day>
                <birth-month><% currentSone.profile.birthMonth|xml></birth-month>
                <birth-year><% currentSone.profile.birthYear|xml></birth-year>
+               <avatar><%currentSone.profile.avatar|xml></avatar>
                <fields>
                        <%foreach currentSone.profile.fields field>
                        <field>
@@ -24,7 +25,6 @@
                        </field>
                        <%/foreach>
                </fields>
-               <avatar><%currentSone.avatar|xml></avatar>
        </profile>
 
        <posts>
index 76954eb..86c1388 100644 (file)
                </p>
 
                <%ifnull !currentSone>
-                       <ul id="avatar-selection">
-                               <li><input type="radio" name="avatar-image" value="none"<%ifnull avatar-image> checked="checked"<%/if>/><%= Page.Options.Option.Avatar.Delete|l10n|html></input></li>
-                               <%foreach currentSone.allImages image>
-                                       <li>
-                                               <input type="radio" name="avatar-image" value="<%image.id|html>"<%if avatar-image|match key=image.id> checked="checked"<%/if>/>
-                                               <div class="post-avatar"><% image|image-link max-width=48 max-height=48 mode=enlarge title==image.title></div>
-                                       </li>
-                               <%/foreach>
-                       </ul>
                <%/if>
 
                <h2><%= Page.Options.Section.RuntimeOptions.Title|l10n|html></h2>