From ad7bdf1ff7ffd413894ea179631eda505a139249 Mon Sep 17 00:00:00 2001 From: Chris Van Date: Sat, 12 Feb 2011 19:25:33 -0500 Subject: [PATCH] activity feed icons (bug 613039) --- apps/amo/log.py | 44 ++++++++++++++++++ apps/devhub/helpers.py | 8 ++++ .../templates/devhub/addons/activity.html | 8 +++- apps/devhub/tests/test_helpers.py | 10 ++++ media/css/zamboni/developers.css | 33 ++++++++++++- media/img/zamboni/icons/feed-icons.png | Bin 844 -> 1759 bytes media/img/zamboni/icons/subscribe-icons.png | Bin 0 -> 844 bytes 7 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 media/img/zamboni/icons/subscribe-icons.png diff --git a/apps/amo/log.py b/apps/amo/log.py index 56433e742f..fbfed5c448 100644 --- a/apps/amo/log.py +++ b/apps/amo/log.py @@ -12,6 +12,7 @@ class _LOG(object): class CREATE_ADDON(_LOG): id = 1 + action_class = None format = _(u'{addon} was created.') keep = True @@ -19,28 +20,33 @@ class CREATE_ADDON(_LOG): class EDIT_PROPERTIES(_LOG): """ Expects: addon """ id = 2 + action_class = 'edit' format = _(u'{addon} properties edited.') class EDIT_DESCRIPTIONS(_LOG): id = 3 + action_class = 'edit' format = _(u'{addon} description edited.') # TODO(gkoberger): Log this type class EDIT_CATEGORIES(_LOG): id = 4 + action_class = 'edit' format = _(u'Categories edited for {addon}.') class ADD_USER_WITH_ROLE(_LOG): id = 5 + action_class = 'add' format = _(u'{0.name} ({1}) added to {addon}.') keep = True class REMOVE_USER_WITH_ROLE(_LOG): id = 6 + action_class = 'delete' # L10n: {0} is the user being removed, {1} is their role. format = _(u'{0.name} ({1}) removed from {addon}.') keep = True @@ -48,17 +54,20 @@ class REMOVE_USER_WITH_ROLE(_LOG): class EDIT_CONTRIBUTIONS(_LOG): id = 7 + action_class = 'edit' format = _(u'Contributions for {addon}.') class USER_DISABLE(_LOG): id = 8 + action_class = None format = _(u'{addon} set inactive.') keep = True class USER_ENABLE(_LOG): id = 9 + action_class = None format = _(u'{addon} activated.') keep = True @@ -66,6 +75,7 @@ class USER_ENABLE(_LOG): # TODO(davedash): Log these types when pages are present class SET_PUBLIC_STATS(_LOG): id = 10 + action_class = None format = _(u'Stats set public for {addon}.') keep = True @@ -73,6 +83,7 @@ class SET_PUBLIC_STATS(_LOG): # TODO(davedash): Log these types when pages are present class UNSET_PUBLIC_STATS(_LOG): id = 11 + action_class = None format = _(u'{addon} stats set to private.') keep = True @@ -80,6 +91,7 @@ class UNSET_PUBLIC_STATS(_LOG): # TODO(gkoberger): Log these types when editing statuses class CHANGE_STATUS(_LOG): id = 12 + action_class = None # L10n: {0} is the status format = _(u'{addon} status changed to {0}.') keep = True @@ -88,34 +100,40 @@ class CHANGE_STATUS(_LOG): # TODO(gkoberger): Do this in 604152 class ADD_PREVIEW(_LOG): id = 13 + action_class = 'add' format = _(u'Preview added to {addon}.') # TODO(gkoberger): Do this in 604152 class EDIT_PREVIEW(_LOG): id = 14 + action_class = 'edit' format = _(u'Preview edited for {addon}.') # TODO(gkoberger): Do this in 604152 class DELETE_PREVIEW(_LOG): id = 15 + action_class = 'delete' format = _(u'Preview deleted from {addon}.') class ADD_VERSION(_LOG): id = 16 + action_class = 'add' format = _(u'{version} added to {addon}.') keep = True class EDIT_VERSION(_LOG): id = 17 + action_class = 'edit' format = _(u'{version} edited for {addon}.') class DELETE_VERSION(_LOG): id = 18 + action_class = 'delete' # Note, {0} is a string not a version since the version is deleted. # L10n: {0} is the version number format = _(u'Version {0} deleted from {addon}.') @@ -124,6 +142,7 @@ class DELETE_VERSION(_LOG): class ADD_FILE_TO_VERSION(_LOG): id = 19 + action_class = 'add' format = _(u'File {0.name} added to {version} of {addon}.') @@ -134,11 +153,13 @@ class DELETE_FILE_FROM_VERSION(_LOG): should be strings and not the object. """ id = 20 + action_class = 'delete' format = _(u'File {0} deleted from {version} of {addon}.') class APPROVE_VERSION(_LOG): id = 21 + action_class = 'approve' format = _(u'{addon} ({version}) approved.') keep = True review_queue = True @@ -146,6 +167,7 @@ class APPROVE_VERSION(_LOG): class PRELIMINARY_VERSION(_LOG): id = 42 + action_class = None format = _(u'{addon} ({version}) given preliminary review.') keep = True review_queue = True @@ -154,6 +176,7 @@ class PRELIMINARY_VERSION(_LOG): class REJECT_VERSION(_LOG): # takes add-on, version, reviewtype id = 43 + action_class = 'reject' format = _(u'{addon} ({version}) rejected.') keep = True review_queue = True @@ -162,6 +185,7 @@ class REJECT_VERSION(_LOG): class RETAIN_VERSION(_LOG): # takes add-on, version, reviewtype id = 22 + action_class = None format = _(u'{addon} ({version}) retained.') keep = True review_queue = True @@ -170,6 +194,7 @@ class RETAIN_VERSION(_LOG): class ESCALATE_VERSION(_LOG): # takes add-on, version, reviewtype id = 23 + action_class = None format = _(u'Review escalated for {addon} ({version}).') keep = True review_queue = True @@ -178,6 +203,7 @@ class ESCALATE_VERSION(_LOG): class REQUEST_VERSION(_LOG): # takes add-on, version, reviewtype id = 24 + action_class = None format = _(u'More information regarding {addon} {version} was requested.') keep = True review_queue = True @@ -185,56 +211,66 @@ class REQUEST_VERSION(_LOG): class ADD_TAG(_LOG): id = 25 + action_class = 'tag' format = _(u'{tag} added to {addon}.') class REMOVE_TAG(_LOG): id = 26 + action_class = 'tag' format = _(u'{tag} removed from {addon}.') class ADD_TO_COLLECTION(_LOG): id = 27 + action_class = 'collection' format = _(u'{addon} added to {collection}.') class REMOVE_FROM_COLLECTION(_LOG): id = 28 + action_class = 'collection' format = _(u'{addon} removed from {collection}.') class ADD_REVIEW(_LOG): id = 29 + action_class = 'review' format = _(u'{review} for {addon} written.') # TODO(davedash): Add these when we do the admin site class ADD_RECOMMENDED_CATEGORY(_LOG): id = 31 + action_class = 'edit' # L10n: {0} is a category name. format = _(u'{addon} featured in {0}.') class REMOVE_RECOMMENDED_CATEGORY(_LOG): id = 32 + action_class = 'edit' # L10n: {0} is a category name. format = _(u'{addon} no longer featured in {0}.') class ADD_RECOMMENDED(_LOG): id = 33 + action_class = None format = _(u'{addon} is now featured.') keep = True class REMOVE_RECOMMENDED(_LOG): id = 34 + action_class = None format = _(u'{addon} is no longer featured.') keep = True class ADD_APPVERSION(_LOG): id = 35 + action_class = 'add' # L10n: {0} is the application, {1} is the version of the app format = _(u'{0} {1} added.') @@ -242,6 +278,7 @@ class ADD_APPVERSION(_LOG): class CHANGE_USER_WITH_ROLE(_LOG): """ Expects: author.user, role, addon """ id = 36 + action_class = None # L10n: {0} is a user, {1} is their role format = _(u'{0.name} role changed to {1} for {addon}.') keep = True @@ -250,21 +287,25 @@ class CHANGE_USER_WITH_ROLE(_LOG): class CHANGE_LICENSE(_LOG): """ Expects: license, addon """ id = 37 + action_class = 'edit' format = _(u'{addon} is now licensed under {0.name}.') class CHANGE_POLICY(_LOG): id = 38 + action_class = 'edit' format = _(u'{addon} policy changed.') class CHANGE_ICON(_LOG): id = 39 + action_class = 'edit' format = _(u'{addon} icon changed.') class APPROVE_REVIEW(_LOG): id = 40 + action_class = 'approve' format = _(u'{review} for {addon} approved.') editor_format = _(u'{user} approved {review} for {addon}.') keep = True @@ -274,6 +315,7 @@ class APPROVE_REVIEW(_LOG): class DELETE_REVIEW(_LOG): """Requires review.id and add-on objects.""" id = 41 + action_class = 'review' format = _(u'Review {0} for {addon} deleted.') editor_format = _(u'{user} deleted review {0}.') keep = True @@ -282,11 +324,13 @@ class DELETE_REVIEW(_LOG): class CUSTOM_TEXT(_LOG): id = 98 + action_class = None format = '{0}' class CUSTOM_HTML(_LOG): id = 99 + action_class = None format = '{0}' diff --git a/apps/devhub/helpers.py b/apps/devhub/helpers.py index 2c72b07afb..ac38b5f8cc 100644 --- a/apps/devhub/helpers.py +++ b/apps/devhub/helpers.py @@ -136,6 +136,14 @@ def status_class(addon): return 'status-' + cls +@register.function +def log_action_class(action_id): + if action_id in amo.LOG_BY_ID: + cls = amo.LOG_BY_ID[action_id].action_class + if cls is not None: + return 'action-' + cls + + @register.function def summarize_validation(validation): """Readable summary of add-on validation results.""" diff --git a/apps/devhub/templates/devhub/addons/activity.html b/apps/devhub/templates/devhub/addons/activity.html index 27473442e7..817fe9060d 100644 --- a/apps/devhub/templates/devhub/addons/activity.html +++ b/apps/devhub/templates/devhub/addons/activity.html @@ -21,14 +21,18 @@ {% endif %} -
+
{% if pager.object_list %} {% for item in pager.object_list %}
-

{{ item }}

+

+ + {{ item }} +

+

{% trans user=item.user|user_link, ago=item.created|timesince, iso=item.created|isotime, pretty=item.created|babel_datetime %} diff --git a/apps/devhub/tests/test_helpers.py b/apps/devhub/tests/test_helpers.py index 66566682da..5734631f12 100644 --- a/apps/devhub/tests/test_helpers.py +++ b/apps/devhub/tests/test_helpers.py @@ -127,6 +127,16 @@ def test_summarize_validation(): u'2 errors, 2 warnings') +def test_log_action_class(): + v = Mock() + for k, v in amo.LOG_BY_ID.iteritems(): + if v.action_class is not None: + cls = 'action-' + v.action_class + else: + cls = '' + eq_(render('{{ log_action_class(id) }}', {'id': v.id}), cls) + + class TestDisplayUrl(unittest.TestCase): def setUp(self): diff --git a/media/css/zamboni/developers.css b/media/css/zamboni/developers.css index 1537e5ad11..a917a308e5 100644 --- a/media/css/zamboni/developers.css +++ b/media/css/zamboni/developers.css @@ -805,7 +805,7 @@ a.more-actions:after:hover { } h3 a.subscribe-feed { - background: url(../../img/zamboni/icons/feed-icons.png) no-repeat; + background: url(../../img/zamboni/icons/subscribe-icons.png) no-repeat; display: inline-block; line-height: 16px; height: 16px; @@ -1246,6 +1246,37 @@ a.extra { .secondary-feed .subscribe { padding: 2px 0 0 24px; } + +#recent-activity .listing .item img.icon { + top: 1em; +} + +#recent-activity .listing .item p { + padding-left: 7px; +} + +.listing .item .action { + background: url(../../img/zamboni/icons/feed-icons.png) no-repeat; + display: block; + float: left; + margin-top: 3px; + height: 32px; + width: 23px; +} +.listing .item .action.action-review { background-position: 0 -32px; } +.listing .item .action.action-tag { background-position: 0 -64px; } +.listing .item .action.action-collection { background-position: 0 -96px; } +.listing .item .action.action-edit { background-position: 0 -128px; } +.listing .item .action.action-add { background-position: 0 -160px; } +.listing .item .action.action-delete { background-position: 0 -192px; } +.listing .item .action.action-approve { background-position: 0 -224px; } +.listing .item .action.action-reject { background-position: 0 -256px; } + +#recent-activity .listing .item .timestamp { + color: #555; + font-size: 0.9em; +} + /* @end */ /* @group Header and main navigation bar */ diff --git a/media/img/zamboni/icons/feed-icons.png b/media/img/zamboni/icons/feed-icons.png index 12a7893e1eb44c8e81591f262735ed66fd437e32..b692153c56701e60a8d791bf544e92f77722f98b 100644 GIT binary patch delta 1722 zcmV;r21WVI2Hy>k77GC&2nGNE0KNY6c#$C|e+Gd`L_t(|+U#6^WZhR3zqxrvq=Zm1 znGiCW%&ODKY~H+BnN(-9YOOk(MQVSIkytc3nMEsfGNZFuY(gqwHmk)*tQs%+Y{ZMz zrse4)lt&1mym(Y2y{GTo*YiEO_xru?eYYjc?&WB{_j^8{@BMM!_ndpa_qHybP76!< ze^beG`1fB*4w;lB`TKy9pOth9d+9`-1DpUV=9Rpz>vuON?uY@ z#OoiG{Gj9{USC%7p(Z$DXyO$D)@70qe>7>FwDhswP`72XgB29|#P^jPWQ6C*by4G> z3*A`xrjnoVZvg*+%`T!1(5}9#2R1=0>@sT|%=xF5E`siDme8$vpztz&dSg8N^fwpr6N-%qcmlWLC*tW_h!CZw_^fbPP1f8xc*=S~-($dmD+Jb5AL~9{v#@G27=Bb?tlIT!CUaW%TQG&{`LjG=BrVidAog9!kpU!tdZ7Cnz^`5rNI zlCXjAJAr=CRyI)Qv~D$@g{v4Jf7wcr2V9(>%@Q-w`#oUpZh6DGSlFvyuk|u%%1YE@Ew8TQZA&g22Gz_Hi0f3*1nExv%K0fdS zp5Q;{-v1VY!??)$1-;lECEGd;kca^H;Zm@Hd8BKY2AED%2^Q#77M1*}emfa|E~^9!bn`GCEhd5}FfVH|2Kdo>QpNy--T*0Pa;|h{&xPWax=N0TuJ_;O`KLC=aeg41`cmhwb zD=|{7FNHc81N`X0m3Lxye|NWNY;1HwZEkLgY&IJl16MHDt+b%lcrpGg=s!}aR8>IT zVsFZOVH&-2^#q>4=MQ$R3$SjU5|)Id3wT;Q{$v0d@hw>c7|J{PI#C0d)n^883$~eMrW{zpeisYs2WTO;FG{N)q*JjWbB6xN}*tCf671rp8+PRkwk%Y z3m_v^z$JeZuGUK~U`+sDEbfc){ul;!`CoV-lERSq0cgB5^)%gp76}grq}ae(Cg$p;voz!U5hf`C4j(pT4{m6BXnY;OFIcur}5 ztG91)adL3=wH8Ic|M2#ifOHt#rmQd3Pq>ivgLzfPUIdgt?(uixLi{qPG}4=5dgqA`+ze{}E* zm=4-NUbqRwAILD^GIAKq0^(OBXub->n~}rd8xT(eVi6z~CZPEyN+A9VI)lttgBrj{ ztRXNLSOM_{AQmOk3p;_>133&x(F_8he6bQ{Ks<`(oJ|Z2PPq&W%2tF7@q&558bw&& z7lJ|H3$W;0n#I6yW;HegcwjF0e~%(O(UXB;V;uv-iyJ^Cz(`47#lR5OhtnAtnTbKm z4WhZro`GR`F0_y+#Ayho0U*U7TbqDs2jvNM{>KYWu8qh3_4E{r-8Wvld ektG2F3;>;#`P_EeEFk~@3IG5}MNUMnLSTXq++P6z diff --git a/media/img/zamboni/icons/subscribe-icons.png b/media/img/zamboni/icons/subscribe-icons.png new file mode 100644 index 0000000000000000000000000000000000000000..12a7893e1eb44c8e81591f262735ed66fd437e32 GIT binary patch literal 844 zcmV-S1GD^zP)+& z`02~j51+og6%!TY72xOPcd$0rHZ#`YShi-zU33HL%hL`pp$ob?S}5PR{osv*Px^ux z^Ve<%iFvwMS!`W7(H)yBFbn`Gt}jasJ+pst)~!1a-xXH%E`f>rdf18)Gyr7lrK`7Z zadC2R^|cm7zyI+0*UI&~_k-k`t1_Jk8u0S#ifOHt#rmQd3Pq>ivgLzfPUIdgt?(uixLi{qPG}4=5dgqA`+zbnpw94%$Fo zxCz7`$S~kCav014;#VYSz6!*fk;C8{5KjYQ5g-;Op!p_BApQ$FgUnZh8o)@bAutzM z0r3VP7A4XPJAv2(ISfeA3<98hu@YuLJc{O=O$-c9xeN@-R)h@kf_cFjMOfb#f zq6WmqRUR