[dw-free] Add extra icon purchasing
[commit: http://hg.dwscoalition.org/dw-free/rev/1ead40895ac9]
Add extra icon purchasing
This lets users purchase permanent extra icons for their accounts. They cost
$1 USD (or 10 points) each and never expire. This also includes a console
tool for admins to maintain them.
This does not yet support transferring between accounts. We will do that
soon.
Patch by
mark.
Files modified:
Add extra icon purchasing
This lets users purchase permanent extra icons for their accounts. They cost
$1 USD (or 10 points) each and never expire. This also includes a console
tool for admins to maintain them.
This does not yet support transferring between accounts. We will do that
soon.
Patch by
Files modified:
- bin/upgrading/en.dat
- bin/upgrading/proplists.dat
- cgi-bin/DW/Console/Command/BonusIcons.pm
- cgi-bin/DW/Controller/Shop.pm
- cgi-bin/DW/Shop.pm
- cgi-bin/DW/Shop/Item/Icons.pm
- cgi-bin/LJ/Global/Defaults.pm
- cgi-bin/LJ/User.pm
- cvs/multicvs.conf
- views/shop/icons.tt
- views/shop/icons.tt.text
- views/shop/index.tt
- views/shop/index.tt.text
--------------------------------------------------------------------------------
diff -r db1baaa9ddac -r 1ead40895ac9 bin/upgrading/en.dat
--- a/bin/upgrading/en.dat Thu Jul 19 21:58:03 2012 -0700
+++ b/bin/upgrading/en.dat Fri Jul 20 17:49:33 2012 -0700
@@ -3250,7 +3250,7 @@
[[gift]]
-
+[[extra]]
Regards,
The [[sitename]] Team
.
@@ -3264,7 +3264,7 @@
[[gift]]
-
+[[extra]]
Regards,
The [[sitename]] Team
.
@@ -3572,6 +3572,29 @@
shop.item.account.randomuser=Random active free user
+shop.item.icons.canbeadded.banned=You are restricted from making purchases for this journal.
+
+shop.item.icons.canbeadded.invalidjournaltype=You can only buy icons for a personal journal.
+
+shop.item.icons.canbeadded.itemerror=Could not add item to cart.
+
+shop.item.icons.canbeadded.notauser=You can only buy icons for an active account.
+
+shop.item.icons.canbeadded.notpaid=That account is ineligible for extra icons. These can only be purchased for a paid account.
+
+shop.item.icons.canbeadded.outofrange=You can only buy up to [[count]] icons for this journal.
+
+shop.item.icons.name=[[num]] [[sitename]] icons
+
+shop.item.icons.overlimit<<
+NOTE: This order has pushed your account over the [[sitename]] limit
+of [[max]] icons. If you would like to transfer the surplus icons to
+another account, or convert them into [[sitename]] Points, please
+contact us for assistance.
+
+
+.
+
shop.item.points.canbeadded.banned=You are restricted from making purchases for this journal.
shop.item.points.canbeadded.insufficient=You do not have enough points to do that.
diff -r db1baaa9ddac -r 1ead40895ac9 bin/upgrading/proplists.dat
--- a/bin/upgrading/proplists.dat Thu Jul 19 21:58:03 2012 -0700
+++ b/bin/upgrading/proplists.dat Fri Jul 20 17:49:33 2012 -0700
@@ -46,6 +46,14 @@
multihomed: 0
prettyname: Beta Features List
+userproplist.bonus_icons:
+ cldversion: 0
+ datatype: num
+ des: Count of permanent extra icon slots
+ indexed: 0
+ multihomed: 0
+ prettyname: How many bonus icon slots the user has purchased
+
userproplist.browselang:
cldversion: 4
datatype: char
diff -r db1baaa9ddac -r 1ead40895ac9 cgi-bin/DW/Console/Command/BonusIcons.pm
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cgi-bin/DW/Console/Command/BonusIcons.pm Fri Jul 20 17:49:33 2012 -0700
@@ -0,0 +1,81 @@
+#!/usr/bin/perl
+#
+# DW::Console::Command::BonusIcons
+#
+# Console commands for managing bonus icons.
+#
+# Authors:
+# Mark Smith <mark@dreamwidth.org>
+#
+# Copyright (c) 2012 by Dreamwidth Studios, LLC.
+#
+# This program is free software; you may redistribute it and/or modify it under
+# the same terms as Perl itself. For a copy of the license, please reference
+# 'perldoc perlartistic' or 'perldoc perlgpl'.
+#
+
+package DW::Console::Command::BonusIcons;
+use strict;
+
+use base qw/ LJ::Console::Command /;
+use Carp qw/ croak /;
+use List::Util qw/ max /;
+
+sub cmd { 'bonus_icons' }
+sub desc { 'Manage bonus icons for an account.' }
+sub args_desc {
+ [
+ 'command' => 'Subcommand: add, remove.',
+ 'username' => 'Username to act on.',
+ 'count' => 'How many icons to add or remove.',
+ ]
+}
+sub usage { '<username> [<subcommand> <count>]' }
+sub can_execute { 1 }
+
+sub execute {
+ my ( $self, $user, $cmd, $count ) = @_;
+
+ my $remote = LJ::get_remote();
+ return $self->error( 'You must be logged in!' )
+ unless $remote;
+ return $self->error( 'I\'m afraid I can\'t let you do that.' )
+ unless $remote->has_priv( 'payments' => 'bonus_icons' );
+
+ my $to_u = LJ::load_user( $user );
+ return $self->error( 'Invalid user.' )
+ unless $to_u;
+
+ unless ( defined $cmd ) {
+ # No subcommand to add or remove. Just print how many icons they have.
+ return $self->print( sprintf( '%s has %d bonus icons.',
+ $to_u->user, $to_u->prop( 'bonus_icons' ) ) );
+ }
+
+ return $self->error( 'Invalid subcommand.' )
+ if $cmd && $cmd !~ /^(?:add|remove)$/;
+
+ return $self->error( 'Count must be a positive integer.' )
+ unless $count =~ /^\d+$/;
+ $count += 0;
+
+ if ( $cmd eq 'add' ) {
+ my $new = max( $to_u->prop( 'bonus_icons' ) + $count, 0 );
+ $to_u->set_prop( bonus_icons => $new );
+ LJ::statushistory_add( $to_u, $remote, 'bonus_icons',
+ sprintf( 'Added %d icons, new total: %d.', $count, $new ) );
+ $self->print( sprintf( 'User now has %d icons.', $new ) );
+
+ } elsif ( $cmd eq 'remove' ) {
+ my $new = max( $to_u->prop( 'bonus_icons' ) - $count, 0 );
+ $to_u->set_prop( bonus_icons => $new );
+ LJ::statushistory_add( $to_u, $remote, 'bonus_icons',
+ sprintf( 'Removed %d icons, new total: %d.', $count, $new ) );
+ $self->print( sprintf( 'User now has %d icons.', $new ) );
+
+ }
+
+ return 1;
+}
+
+1;
diff -r db1baaa9ddac -r 1ead40895ac9 cgi-bin/DW/Controller/Shop.pm
--- a/cgi-bin/DW/Controller/Shop.pm Thu Jul 19 21:58:03 2012 -0700
+++ b/cgi-bin/DW/Controller/Shop.pm Fri Jul 20 17:49:33 2012 -0700
@@ -27,6 +27,7 @@
# routing directions
DW::Routing->register_string( '/shop', \&shop_index_handler, app => 1 );
DW::Routing->register_string( '/shop/points', \&shop_points_handler, app => 1 );
+DW::Routing->register_string( '/shop/icons', \&shop_icons_handler, app => 1 );
DW::Routing->register_string( '/shop/transferpoints', \&shop_transfer_points_handler, app => 1 );
# our basic shop controller, this does setup that is unique to all shop
@@ -238,5 +239,62 @@
return DW::Template->render_template( 'shop/points.tt', $rv );
}
+# handles the shop buy icons page
+sub shop_icons_handler {
+ my ( $ok, $rv ) = _shop_controller();
+ return $rv unless $ok;
+
+ my $remote = $rv->{remote};
+ my %errs;
+ $rv->{errs} = \%errs;
+
+ my $r = DW::Request->get;
+ if ( $r->did_post ) {
+ my $args = $r->post_args;
+ die "invalid auth\n" unless LJ::check_form_auth( $args->{lj_form_auth} );
+
+ my $u = LJ::load_user( $args->{foruser} );
+ my $icons = int( $args->{icons} + 0 );
+ my $item; # provisionally create the item to access object methods
+
+ if ( !$u ) {
+ $errs{foruser} = LJ::Lang::ml( 'shop.item.icons.canbeadded.notauser' );
+
+ } elsif ( $item = DW::Shop::Item::Icons->new( target_userid => $u->id, from_userid => $remote->id, icons => $icons ) ) {
+ # error check the user
+ if ( $item->can_be_added_user( errref => \$errs{foruser} ) ) {
+ $rv->{foru} = $u;
+ delete $errs{foruser}; # undefined
+ }
+
+ # error check the icons
+ if ( $item->can_be_added_icons( errref => \$errs{icons} ) ) {
+ $rv->{icons} = $icons;
+ delete $errs{icons}; # undefined
+ }
+
+ } else {
+ $errs{foruser} = LJ::Lang::ml( 'shop.item.icons.canbeadded.itemerror' );
+ }
+
+ # looks good, add it!
+ unless ( keys %errs ) {
+ $rv->{cart}->add_item( $item );
+ return $r->redirect( "$LJ::SITEROOT/shop" );
+ }
+
+ } else {
+ my $for = $r->get_args->{for};
+
+ if ( ! $for || $for eq 'self' ) {
+ $rv->{foru} = $remote;
+ } else {
+ $rv->{foru} = LJ::load_user( $for );
+ }
+ }
+
+ return DW::Template->render_template( 'shop/icons.tt', $rv );
+}
+
1;
diff -r db1baaa9ddac -r 1ead40895ac9 cgi-bin/DW/Shop.pm
--- a/cgi-bin/DW/Shop.pm Thu Jul 19 21:58:03 2012 -0700
+++ b/cgi-bin/DW/Shop.pm Fri Jul 20 17:49:33 2012 -0700
@@ -25,6 +25,7 @@
use DW::Shop::Item::Account;
use DW::Shop::Item::Points;
use DW::Shop::Item::Rename;
+use DW::Shop::Item::Icons;
# constants across the site
our $MIN_ORDER_COST = 3.00; # cost in USD minimum. this only comes into affect if
@@ -189,5 +190,4 @@
or confess 'tried to get shop without calling DW::Shop->initialize()';
}
-
1;
diff -r db1baaa9ddac -r 1ead40895ac9 cgi-bin/DW/Shop/Item/Icons.pm
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cgi-bin/DW/Shop/Item/Icons.pm Fri Jul 20 17:49:33 2012 -0700
@@ -0,0 +1,230 @@
+#!/usr/bin/perl
+#
+# DW::Shop::Item::Icons
+#
+# Represents Dreamwidth Icons that someone is buying.
+#
+# Authors:
+# Mark Smith <mark@dreamwidth.org>
+#
+# Copyright (c) 2012 by Dreamwidth Studios, LLC.
+#
+# This program is free software; you may redistribute it and/or modify it under
+# the same terms as Perl itself. For a copy of the license, please reference
+# 'perldoc perlartistic' or 'perldoc perlgpl'.
+#
+
+package DW::Shop::Item::Icons;
+
+use base 'DW::Shop::Item';
+
+use strict;
+use DW::InviteCodes;
+use DW::Pay;
+
+=head1 NAME
+
+DW::Shop::Item::Icons - Represents extra icons that someone is purchasing. See
+the documentation for DW::Shop::Item for usage examples and description of methods
+inherited from that base class.
+
+=head1 API
+
+=head2 C<< $class->new( [ %args ] ) >>
+
+Instantiates a block of icons to be purchased.
+
+Arguments:
+=item ( see DW::Shop::Item ),
+=item icons => number of icons to buy,
+
+=cut
+
+# override
+sub new {
+ my ( $class, %args ) = @_;
+
+ my $self = $class->SUPER::new( %args, type => 'icons' );
+ return unless $self;
+
+ # Set up our initial cost structure
+ $self->{cost_cash} = $self->{icons};
+ $self->{cost_points} = 0;
+
+ # for now, we can only apply to a user. in the future this is an obvious way
+ # to do gift certificates by allowing an email address here...
+ die "Can only give icons to an account.\n"
+ unless $self->t_userid;
+
+ return $self;
+}
+
+
+# override
+sub _apply {
+ my $self = $_[0];
+
+ return $self->_apply_userid if $self->t_userid;
+
+ # something weird, just kill this item!
+ $self->{applied} = 1;
+ return 1;
+}
+
+
+# internal application sub, do not call
+sub _apply_userid {
+ my $self = $_[0];
+ return 1 if $self->applied;
+
+ # will need this later
+ my $fu = LJ::load_userid( $self->from_userid );
+ unless ( $fu ) {
+ warn "Failed to apply: invalid from_userid!\n";
+ return 0;
+ }
+
+ # need this user
+ my $u = LJ::load_userid( $self->t_userid )
+ or return 0;
+
+ # validate that they can get this number of icons
+ my $cur = $u->prop( 'bonus_icons' ) // 0;
+ $u->set_prop( bonus_icons => $cur + $self->icons );
+ LJ::statushistory_add( $u, $fu, 'bonus_icons',
+ sprintf( '%d icons added; item #%d', $self->icons, $self->id ) );
+
+ # we're applied now, regardless of what happens with the email
+ $self->{applied} = 1;
+
+ # see if this has put the user over their limit
+ my $overlimit = '';
+ my $real_total = $self->icons + $u->get_cap( 'userpics' ) + $cur;
+ if ( $real_total > $LJ::USERPIC_MAXIMUM ) {
+ $overlimit = LJ::Lang::ml( 'shop.item.icons.overlimit',
+ { sitename => $LJ::SITENAMESHORT, max => $LJ::USERPIC_MAXIMUM,
+ overage => $real_total - $LJ::USERPIC_MAXIMUM } );
+ }
+
+ # now we have to mail this notification
+ my $word = $fu->equals( $u ) ? 'self' : 'other';
+ my $body = LJ::Lang::ml( "shop.email.gift.$word.body",
+ {
+ touser => $u->display_name,
+ fromuser => $fu->display_name,
+ sitename => $LJ::SITENAME,
+ gift => sprintf( '%d %s Extra Icons', $self->icons, $LJ::SITENAMESHORT ),
+ extra => $overlimit,
+ }
+ );
+ my $subj = LJ::Lang::ml( "shop.email.gift.$word.subject", { sitename => $LJ::SITENAME } );
+
+ # send the email to the user
+ LJ::send_mail( {
+ to => $u->email_raw,
+ from => $LJ::ACCOUNTS_EMAIL,
+ fromname => $LJ::SITENAME,
+ subject => $subj,
+ body => $body
+ } );
+
+ # tell the caller we're happy
+ return 1;
+}
+
+
+# override
+sub unapply {
+ my $self = $_[0];
+ return unless $self->applied;
+
+ # unapplying is not coded yet, as we don't have good automatic support for orders being
+ # reverted and refunded.
+ $self->{applied} = 0;
+ die "Unable to unapply right now.\n";
+
+ return 1;
+}
+
+
+# override
+sub can_be_added {
+ my ( $self, %opts ) = @_;
+
+ return 0 unless $self->can_be_added_user( %opts );
+ return 0 unless $self->can_be_added_icons( %opts );
+
+ return 1;
+}
+
+
+sub can_be_added_user {
+ my ( $self, %opts ) = @_;
+ my $errref = $opts{errref};
+
+ # if not a valid account, error
+ my $target_u = LJ::load_userid( $self->t_userid );
+ if ( ! LJ::isu( $target_u ) ) {
+ $$errref = LJ::Lang::ml( 'shop.item.icons.canbeadded.notauser' );
+ return 0;
+ }
+
+ # the receiving user must be a person for now
+ unless ( $target_u->is_personal && $target_u->is_visible ) {
+ $$errref = LJ::Lang::ml( 'shop.item.icons.canbeadded.invalidjournaltype' );
+ return 0;
+ }
+
+ # and they must be paid
+ unless ( $target_u->can_buy_icons ) {
+ $$errref = LJ::Lang::ml( 'shop.item.icons.canbeadded.notpaid' );
+ return 0;
+ }
+
+ # make sure no sysban is in effect here
+ my $fromu = LJ::load_userid( $self->from_userid );
+ if ( $fromu && $target_u->has_banned( $fromu ) ) {
+ $$errref = LJ::Lang::ml( 'shop.item.icons.canbeadded.banned' );
+ return 0;
+ }
+
+ return 1;
+}
+
+
+sub can_be_added_icons {
+ my ( $self, %opts ) = @_;
+ my $errref = $opts{errref};
+
+ # sanity check that the icons to add are within range
+ my $target_u = LJ::load_userid( $self->t_userid );
+ my $pics_left = $LJ::USERPIC_MAXIMUM - $target_u->userpic_quota;
+ unless ( $self->icons > 0 && $self->icons <= $pics_left ) {
+ $$errref = LJ::Lang::ml( 'shop.item.icons.canbeadded.outofrange',
+ { count => $pics_left });
+ return 0;
+ }
+
+ return 1;
+}
+
+
+# override
+sub name_text {
+ my $self = $_[0];
+
+ return LJ::Lang::ml( 'shop.item.icons.name',
+ { num => $self->icons, sitename => $LJ::SITENAMESHORT } );
+}
+
+
+=head2 C<< $self->icons >>
+
+Return how many icons this item is worth.
+
+=cut
+
+sub icons { $_[0]->{icons} }
+
+
+1;
diff -r db1baaa9ddac -r 1ead40895ac9 cgi-bin/LJ/Global/Defaults.pm
--- a/cgi-bin/LJ/Global/Defaults.pm Thu Jul 19 21:58:03 2012 -0700
+++ b/cgi-bin/LJ/Global/Defaults.pm Fri Jul 20 17:49:33 2012 -0700
@@ -371,6 +371,9 @@
# Secrets
%SECRETS = () unless defined %SECRETS;
+
+ # Userpic maximum. No user can have more than this.
+ $USERPIC_MAXIMUM ||= 500;
}
diff -r db1baaa9ddac -r 1ead40895ac9 cgi-bin/LJ/User.pm
--- a/cgi-bin/LJ/User.pm Thu Jul 19 21:58:03 2012 -0700
+++ b/cgi-bin/LJ/User.pm Fri Jul 20 17:49:33 2012 -0700
@@ -1,3 +1,6 @@
+#
+# NOTE: This module now requires Perl 5.10 or greater.
+#
# This code was forked from the LiveJournal project owned and operated
# by Live Journal, Inc. The code has been modified and expanded by
# Dreamwidth Studios, LLC. These files were originally licensed under
@@ -32,8 +35,8 @@
package LJ::User;
use Carp;
use Storable;
+use List::Util qw/ min /;
use lib "$LJ::HOME/cgi-bin";
-use List::Util ();
use LJ::Global::Constants;
use LJ::MemCache;
use LJ::Session;
@@ -1946,6 +1949,10 @@
return $_[0]->get_cap( 'beta_payments' ) ? 1 : 0;
}
+sub can_buy_icons {
+ return $_[0]->get_cap( 'bonus_icons' ) ? 1 : 0;
+}
+
sub can_create_feeds {
return $_[0]->get_cap( 'synd_create' ) ? 1 : 0;
}
@@ -2324,7 +2331,7 @@
}
sub count_max_userpics {
- return $_[0]->get_cap( 'userpics' );
+ return $_[0]->userpic_quota;
}
sub count_max_xpost_accounts {
@@ -3053,7 +3060,7 @@
=cut
sub shop_points {
- return $_[0]->prop( 'shop_points' )+0;
+ return $_[0]->prop( 'shop_points' ) // 0;
}
@@ -6412,7 +6419,6 @@
# active / inactive lists
my @active = ();
my @inactive = ();
- my $allow = LJ::get_cap($u, "userpics");
# get a database handle for reading/writing
my $dbh = LJ::get_db_writer();
@@ -6432,8 +6438,9 @@
}
# inactivate previously activated userpics
- if (@active > $allow) {
- my $to_ban = @active - $allow;
+ my $allowed = $u->userpic_quota;
+ if (scalar @active > $allowed) {
+ my $to_ban = scalar @active - $allowed;
# find first jitemid greater than time 2 months ago using rlogtime index
# ($LJ::EndOfTime - UnixTime)
@@ -6491,8 +6498,8 @@
}
# activate previously inactivated userpics
- if (@inactive && @active < $allow) {
- my $to_activate = $allow - @active;
+ if (scalar @inactive && scalar @active < $allowed) {
+ my $to_activate = $allowed - @active;
$to_activate = @inactive if $to_activate > @inactive;
# take the $to_activate newest (highest numbered) pictures
@@ -7217,17 +7224,17 @@
return $_[0]->dversion >= 9;
}
-
=head3 C<< $u->userpic_quota >>
-Returns the number of userpics the user can upload
+Returns the number of userpics the user can upload (base account type cap + bonus slots purchased)
=cut
sub userpic_quota {
my $u = shift or return undef;
- my $quota = $u->get_cap('userpics');
-
- return $quota;
+ my $ct = $u->get_cap( 'userpics' );
+ $ct += $u->prop('bonus_icons') // 0
+ if $u->is_paid; # paid accounts get bonus icons
+ return min( $ct, $LJ::USERPIC_MAXIMUM );
}
# Intentionally no POD here.
diff -r db1baaa9ddac -r 1ead40895ac9 cvs/multicvs.conf
--- a/cvs/multicvs.conf Thu Jul 19 21:58:03 2012 -0700
+++ b/cvs/multicvs.conf Fri Jul 20 17:49:33 2012 -0700
@@ -11,7 +11,7 @@
CVSDIR=$LJHOME/cvs
# DreamWidth repositories
-HG(dw-free) = http://hg.dwscoalition.org/dw-free @stable
+#HG(dw-free) = http://hg.dwscoalition.org/dw-free @stable
# stock/unchanged repositories pulled from external sources
SVN(gearman) = http://code.livejournal.org/svn/gearman/trunk/
diff -r db1baaa9ddac -r 1ead40895ac9 views/shop/icons.tt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/views/shop/icons.tt Fri Jul 20 17:49:33 2012 -0700
@@ -0,0 +1,38 @@
+[%- sections.title = '.title' | ml(sitename = site.nameshort) -%]
+
+[% cart_display %]
+
+<p>[% '.about' | ml(sitename = site.nameshort) %]</p>
+
+<form method='post'>
+[% dw.form_auth %]
+<table summary='' class='shop-table-gift'>
+[% IF foru %]
+ <tr><td>[% '.buying.for' | ml %]</td><td>[% foru.ljuser_display %]
+ <input type='hidden' name='foruser' value='[% foru.user %]' />
+ <input type='hidden' name='maxicons' value='[% maxicons %]' />
+ </td></tr>
+[% ELSE %]
+ <tr><td>[% '.buying.for' | ml %]</td><td><input type='text' name='foruser' maxlength='25' size='15' />
+ [% IF errs.foruser %]<br /><strong>[% errs.foruser %][% END %]
+ </td></tr>
+[% END %]
+<tr><td>[% '.buying.icons' | ml %]</td>
+ <td><input type='text' name='icons' id='icons' maxlength='3' size='10' value='[% icons %]' />
+ [% IF errs.icons %]<br /><strong>[% errs.icons %][% END %]
+</td></tr>
+<tr><td><span id='icons-cost'></span></td><td><input type='submit' value='[% '.addtocart' | ml %]' /></td></tr>
+</table>
+</form>
+
+<p id='icons-about'>[% '.about2' | ml %]</p>
+
+[%# FIXME: move this to shop.js or something %]
+<script type='text/javascript'>
+ jQuery( function($) {
+ setInterval(
+ function() {
+ $('#icons-cost').html( 'Cost: <strong>$' + ($('#icons').val() / 1).toFixed(2) + ' USD</strong>' );
+ }, 250 );
+ } );
+</script>
diff -r db1baaa9ddac -r 1ead40895ac9 views/shop/icons.tt.text
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/views/shop/icons.tt.text Fri Jul 20 17:49:33 2012 -0700
@@ -0,0 +1,13 @@
+;; -*- coding: utf-8 -*-
+.about=This page allows you to buy extra icons for a [[sitename]] account.
+
+.about2=Extra icons purchased for an account never expire. Each extra icon you purchase will cost $1.00 USD.
+
+.addtocart=Add To Cart
+
+.buying.for=Buying for Account:
+
+.buying.icons=Extra Icons to Purchase:
+
+.title=[[sitename]] Extra Icons Shop
+
diff -r db1baaa9ddac -r 1ead40895ac9 views/shop/index.tt
--- a/views/shop/index.tt Thu Jul 19 21:58:03 2012 -0700
+++ b/views/shop/index.tt Fri Jul 20 17:49:33 2012 -0700
@@ -45,6 +45,19 @@
</div>
</div>
+<div class='shop-category'>
+ <div class='shop-category-title'>[% '.title.icons' | ml %]</div>
+ <div class='shop-category-items'>
+[% IF remote AND remote.is_personal %]
+ <span class='shop-category-item'><a href="[% site.root %]/shop/icons?for=self">[% '.for.self' | ml %]</a> ([% remote.ljuser_display %])</span>
+[% END %]
+[% IF remote AND remote.is_personal %]
+ <span class='shop-category-item'><a href="[% site.root %]/shop/icons?for=gift">[% '.for.different' | ml %]</a></span>
+[% ELSE %]
+ <span class='shop-category-item'><a href="[% site.root %]/shop/icons?for=gift">[% '.for.existing' | ml %]</a></span>
+[% END %]
+ </div>
+</div>
[%#
Here for future expansion ...
diff -r db1baaa9ddac -r 1ead40895ac9 views/shop/index.tt.text
--- a/views/shop/index.tt.text Thu Jul 19 21:58:03 2012 -0700
+++ b/views/shop/index.tt.text Fri Jul 20 17:49:33 2012 -0700
@@ -19,6 +19,8 @@
.title=[[sitename]] Shop
+.title.icons=Buy extra icons for...
+
.title.paidacc=Buy paid services for...
.title.points=Buy [[site]] Points for...
--------------------------------------------------------------------------------
