Merge lp:~mvo/software-center/lp968974 into lp:software-center

Proposed by Michael Vogt
Status: Work in progress
Proposed branch: lp:~mvo/software-center/lp968974
Merge into: lp:software-center
Diff against target: 148 lines (+48/-5)
4 files modified
softwarecenter/enums.py (+4/-0)
softwarecenter/ui/gtk3/models/appstore2.py (+2/-2)
softwarecenter/ui/gtk3/views/appdetailsview.py (+21/-3)
test/gtk3/test_appdetailsview.py (+21/-0)
To merge this branch: bzr merge lp:~mvo/software-center/lp968974
Reviewer Review Type Date Requested Status
Matthew Paul Thomas design Needs Fixing
Natalia Bidart Approve
Review via email: mp+101710@code.launchpad.net

Description of the change

This branch changes the label/button in the appdetailsview for gratis/zero-dollar apps to show "Free" and "Install"
instead of USD$0 and Buy… (LP: #968974).

To avoid a string break its using "Install" instead of "Install…" but once 12.04 is released we should change
the string to include the "…".

To post a comment you must log in.
Revision history for this message
Natalia Bidart (nataliabidart) wrote :

Looks great! I tested it IRL as well.

review: Approve
Revision history for this message
Kiwinote (kiwinote) wrote :

Just a few quick comments based purely on ui testing rather than the code:
- in the list views 0$ apps don't have an install button (free apps have install and for purchase apps have buy) *

clicking on install for a 0$ app:
- displays a spinner view with 'connecting to payment service' (this scares people - 'i thought it was free') *
- then requires an sso login ('bit odd, but ok')
- then another spinner comes up with 'payment authorised' ('wait, why did it charge me') *
- then an auth dialog pops up with the text 'to install purchased software, authenticate'
- the text in the status bar is 'installing purchase'
- the progress pane says 'installing purchase'
- another auth dialog 'to install or remove software'

clicking on reinstall previous purchases we see:
- appname (already purchased) (shouldn't appear at all as it isn't a purchase)
- clicking on it gives a status bar 'purchased on 2012-04-12'

I think what it comes down to is that until the majority of the points above are fixed (or at a realistic minimum the ones marked *), in my opinion 'buying' something for 0$ is a lot less confusing and scary than being confronted with 'connecting to payment service' and 'payment authorised' messages.

I do of course agree that we do want to have free/install instead of 0$/buy, it just seems that the behaviour in this branch is more confusing/scary than the current situation?

Revision history for this message
Michael Vogt (mvo) wrote :

Based on the excellent comments from Kiwinote I set this back to Work-in-Progress and will talk with MPT about the points you mentioned.

Revision history for this message
Matthew Paul Thomas (mpt) wrote :

Kiwinote, you make a good case for leaving this as it is until we can fix more of the strings.

review: Needs Fixing (design)

Unmerged revisions

2961. By Michael Vogt

do not show "USD$0"/buy for gratis apps, but instead show "Free" and "Install" (LP: #968974)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'softwarecenter/enums.py'
--- softwarecenter/enums.py 2012-03-21 20:54:46 +0000
+++ softwarecenter/enums.py 2012-04-12 10:19:20 +0000
@@ -68,6 +68,10 @@
68# the server size "page" for ratings&reviews68# the server size "page" for ratings&reviews
69REVIEWS_BATCH_PAGE_SIZE = 1069REVIEWS_BATCH_PAGE_SIZE = 10
7070
71# the values that a price property can have when a app is gratis
72# this is used for e.g. demo apps in the for-purchase channel
73PRICE_GRATIS = ("0.00", "0", "")
74
7175
72# the various "views" that the app has76# the various "views" that the app has
73class ViewPages:77class ViewPages:
7478
=== modified file 'softwarecenter/ui/gtk3/models/appstore2.py'
--- softwarecenter/ui/gtk3/models/appstore2.py 2012-03-30 09:11:08 +0000
+++ softwarecenter/ui/gtk3/models/appstore2.py 2012-04-12 10:19:20 +0000
@@ -25,6 +25,7 @@
25from gettext import gettext as _25from gettext import gettext as _
2626
27from softwarecenter.enums import (Icons,27from softwarecenter.enums import (Icons,
28 PRICE_GRATIS,
28 XapianValues)29 XapianValues)
2930
3031
@@ -47,7 +48,6 @@
4748
4849
49LOG = logging.getLogger(__name__)50LOG = logging.getLogger(__name__)
50_FREE_AS_IN_BEER = ("0.00", "")
5151
5252
53class CategoryRowReference:53class CategoryRowReference:
@@ -168,7 +168,7 @@
168 def is_purchasable(self, doc):168 def is_purchasable(self, doc):
169 if doc.purchasable is None:169 if doc.purchasable is None:
170 doc.purchasable = (doc.get_value(XapianValues.PRICE) not in170 doc.purchasable = (doc.get_value(XapianValues.PRICE) not in
171 _FREE_AS_IN_BEER)171 PRICE_GRATIS)
172 return doc.purchasable172 return doc.purchasable
173173
174 def get_pkgname(self, doc):174 def get_pkgname(self, doc):
175175
=== modified file 'softwarecenter/ui/gtk3/views/appdetailsview.py'
--- softwarecenter/ui/gtk3/views/appdetailsview.py 2012-03-27 14:40:22 +0000
+++ softwarecenter/ui/gtk3/views/appdetailsview.py 2012-04-12 10:19:20 +0000
@@ -40,6 +40,7 @@
40from softwarecenter.enums import (AppActions,40from softwarecenter.enums import (AppActions,
41 PkgStates,41 PkgStates,
42 Icons,42 Icons,
43 PRICE_GRATIS,
43 SOFTWARE_CENTER_PKGNAME)44 SOFTWARE_CENTER_PKGNAME)
44from softwarecenter.utils import (is_unity_running,45from softwarecenter.utils import (is_unity_running,
45 upstream_version,46 upstream_version,
@@ -374,12 +375,29 @@
374 # translatable when hardcoded, since it (currently)375 # translatable when hardcoded, since it (currently)
375 # won't vary based on locale and as such we don't want376 # won't vary based on locale and as such we don't want
376 # it translated377 # it translated
377 self.set_label("US$ %s" % app_details.price)378 # label
379 if app_details.price in PRICE_GRATIS:
380 self.set_label(_("Free"))
381 else:
382 self.set_label("US$ %s" % app_details.price)
383 # button
378 if (app_details.hardware_requirements_satisfied and384 if (app_details.hardware_requirements_satisfied and
379 app_details.region_requirements_satisfied):385 app_details.region_requirements_satisfied):
380 self.set_button_label(_(u'Buy\u2026'))386 if app_details.price in PRICE_GRATIS:
387 # FIXME: once the 12.04 string freeze is over, we can
388 # change this to include the "..."
389 #self.set_button_label(_(u"Install\u2026"))
390 self.set_button_label(_(u"Install"))
391 else:
392 self.set_button_label(_(u'Buy\u2026'))
381 else:393 else:
382 self.set_button_label(_(u'Buy Anyway\u2026'))394 if app_details.price in PRICE_GRATIS:
395 # FIXME: once the 12.04 string freeze is over, we can
396 # change this to include the "..."
397 #self.set_button_label(_(u"Install Anyway\u2026"))
398 self.set_button_label(_(u"Install Anyway"))
399 else:
400 self.set_button_label(_(u'Buy Anyway\u2026'))
383 elif state == PkgStates.FORCE_VERSION:401 elif state == PkgStates.FORCE_VERSION:
384 self.set_button_label(_('Change'))402 self.set_button_label(_('Change'))
385 elif state in (403 elif state in (
386404
=== modified file 'test/gtk3/test_appdetailsview.py'
--- test/gtk3/test_appdetailsview.py 2012-03-15 21:19:02 +0000
+++ test/gtk3/test_appdetailsview.py 2012-04-12 10:19:20 +0000
@@ -375,6 +375,7 @@
375 self.assertEqual(375 self.assertEqual(
376 self.view.pkg_statusbar.button.get_label(), "Install Anyway")376 self.view.pkg_statusbar.button.get_label(), "Install Anyway")
377 # and again for purchase377 # and again for purchase
378 self.app_mock.details.price = "1.00"
378 self.app_mock.details.pkg_state = PkgStates.NEEDS_PURCHASE379 self.app_mock.details.pkg_state = PkgStates.NEEDS_PURCHASE
379 self.view.show_app(self.app_mock)380 self.view.show_app(self.app_mock)
380 self.assertEqual(381 self.assertEqual(
@@ -385,6 +386,15 @@
385 self.assertEqual(self.view.pkg_warningbar.label.get_text(),386 self.assertEqual(self.view.pkg_warningbar.label.get_text(),
386 _('This software requires a GPS, '387 _('This software requires a GPS, '
387 'but the computer does not have one.'))388 'but the computer does not have one.'))
389 # and again for gratis "purchase"
390 self.app_mock.details.price = "0.00"
391 self.app_mock.details.pkg_state = PkgStates.NEEDS_PURCHASE
392 self.view.show_app(self.app_mock)
393 self.assertEqual(
394 self.view.pkg_statusbar.button.get_label(),
395 # FIXME: update once the string freeze is over
396 #_(u"Install Anyway\u2026").encode("utf-8"))
397 _(u"Install Anyway").encode("utf-8"))
388398
389 def test_no_show_hardware_requirements(self):399 def test_no_show_hardware_requirements(self):
390 self.app_mock.details.hardware_requirements = {}400 self.app_mock.details.hardware_requirements = {}
@@ -398,6 +408,7 @@
398 self.assertEqual(408 self.assertEqual(
399 self.view.pkg_statusbar.button.get_label(), _("Install"))409 self.view.pkg_statusbar.button.get_label(), _("Install"))
400 # and again for purchase410 # and again for purchase
411 self.app_mock.details.price = "1.00"
401 self.app_mock.details.pkg_state = PkgStates.NEEDS_PURCHASE412 self.app_mock.details.pkg_state = PkgStates.NEEDS_PURCHASE
402 self.view.show_app(self.app_mock)413 self.view.show_app(self.app_mock)
403 self.assertEqual(414 self.assertEqual(
@@ -405,6 +416,15 @@
405 _(u'Buy\u2026').encode("utf-8"))416 _(u'Buy\u2026').encode("utf-8"))
406 # check if the warning bar is invisible417 # check if the warning bar is invisible
407 self.assertFalse(self.view.pkg_warningbar.get_property("visible"))418 self.assertFalse(self.view.pkg_warningbar.get_property("visible"))
419 # and again for "gratis" purchase
420 self.app_mock.details.price = "0.00"
421 self.app_mock.details.pkg_state = PkgStates.NEEDS_PURCHASE
422 self.view.show_app(self.app_mock)
423 self.assertEqual(
424 self.view.pkg_statusbar.button.get_label(),
425 # FIXME: update once the string freeze is over
426 #_(u'Install\u2026').encode("utf-8"))
427 _(u'Install').encode("utf-8"))
408428
409class RegionRequirementsTestCase(unittest.TestCase):429class RegionRequirementsTestCase(unittest.TestCase):
410 430
@@ -435,6 +455,7 @@
435 self.assertEqual(455 self.assertEqual(
436 self.view.pkg_statusbar.button.get_label(), "Install Anyway")456 self.view.pkg_statusbar.button.get_label(), "Install Anyway")
437 # and again for purchase457 # and again for purchase
458 self.app_mock.details.price = "1.0"
438 self.app_mock.details.pkg_state = PkgStates.NEEDS_PURCHASE459 self.app_mock.details.pkg_state = PkgStates.NEEDS_PURCHASE
439 self.view.show_app(self.app_mock)460 self.view.show_app(self.app_mock)
440 self.assertEqual(461 self.assertEqual(

Subscribers

People subscribed via source and target branches