diff options
216 files changed, 6186 insertions, 7725 deletions
diff --git a/.gitignore b/.gitignore index c63d5e699..27d7ced66 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ tags *.mo FixMyStreet-EmptyHomes.po +FixMyBarangay.po /web/cobrands/fiksgatami/css.css /web/cobrands/southampton/css.css @@ -26,6 +27,7 @@ FixMyStreet-EmptyHomes.po /web/cobrands/default/*.css /web/cobrands/fixmystreet/*.css /web/cobrands/bromley/*.css +/web/cobrands/fixmybarangay/*.css /web/cobrands/stevenage/*.css /web/cobrands/barnet/*.css /web/cobrands/zurich/*.css diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..dcf35ab60 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,42 @@ +notifications: + email: false + irc: + channels: + - "irc.mysociety.org#fixmystreet" + use_notice: true + skip_join: true + +language: perl +perl: + - "5.14" + +branches: + only: + - master + +before_install: + - sudo apt-get update -qq + - sudo apt-get install -qq jhead +# A couple of other modules that normally come from packages, but no system stuff here + - cpanm -q Carton Locale::gettext Math::BigInt::GMP SOAP::Lite + - sudo locale-gen cy_GB.UTF-8 en_GB.UTF-8 nb_NO.UTF-8 +install: + - carton install --deployment +before_script: + - psql -c 'create database fms;' -U postgres + - psql fms postgres < db/schema.sql + - psql fms postgres < db/alert_types.sql + - psql fms postgres < db/generate_secret.sql + - > + sed -r -e "s,(FMS_DB_USER:) 'fms',\\1 'postgres'," + -e "s,cobrand_one,fixmystreet," + -e "s,cobrand_two: 'hostname_substring2',fixmystreet: 'localhost'," + -e "s,(BASE_URL:) 'http://www.example.org',\\1 'http://localhost'," + -e "s,(MAPIT_URL:) '',\\1 'http://mapit.mysociety.org/'," + -e "s,(CONTACT_EMAIL:) 'team,\\1 'person," + conf/general.yml-example > conf/general.yml + - ./bin/cron-wrapper ./bin/make_po FixMyStreet-EmptyHomes + - ./bin/cron-wrapper ./bin/make_emptyhomes_welsh_po + - commonlib/bin/gettext-makemo FixMyStreet +script: "bin/cron-wrapper perl /usr/bin/prove -rl t" + diff --git a/.tx/config b/.tx/config new file mode 100644 index 000000000..44db89d9e --- /dev/null +++ b/.tx/config @@ -0,0 +1,9 @@ +[main] +host = https://www.transifex.com +type = PO + +[fixmystreet.master] +file_filter = locale/<lang>.UTF-8/LC_MESSAGES/FixMyStreet.po +source_file = locale/FixMyStreet.po +source_lang = en + diff --git a/Makefile.PL b/Makefile.PL index aba781785..92f08e405 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -49,6 +49,8 @@ test_requires 'Test::More' => '0.88'; test_requires 'Test::WWW::Mechanize::Catalyst'; test_requires 'Sub::Override'; +tests 't/*.t t/*/*.t t/*/*/*.t t/*/*/*/*.t t/*/*/*/*/*.t'; + catalyst; install_script glob('script/*.pl'); @@ -13,12 +13,17 @@ already been reported and leave updates. Users can also subscribe to email or RSS alerts of problems in their area. It was created in 2007 by [mySociety](http://www.mysociety.org/) for reporting -problems to UK councils and has been copied around the world. +problems to UK councils and has been copied around the world. The FixMyStreet +Platform is now at version 1.0. + +## Releases + +* v1.0 (24th October 2012) - Official launch of the FixMyStreet platform ## Installation -We're working hard to make FixMyStreet Platform easy to install and re-use in -other countries - please see our site at <http://code.fixmystreet.com/> for +We've been working hard to make FixMyStreet Platform easy to install and re-use +in other countries - please see our site at <http://code.fixmystreet.com/> for help and documentation in installing FixMyStreet Platform. ## Examples diff --git a/bin/ec2-rewrite-conf b/bin/ec2-rewrite-conf new file mode 100755 index 000000000..0163ef511 --- /dev/null +++ b/bin/ec2-rewrite-conf @@ -0,0 +1,20 @@ +#!/bin/sh + +# This is a helper script for writing the current EC2 hostname into +# the FixMyStreet configuration file. Its intended usage is for lines +# like these to be added to /etc/rc.local: +# +# su -l -c /home/fms/fixmystreet/bin/ec2-rewrite-conf fms +# /etc/init.d/apache2 restart + +set -e + +BIN_DIR=$(dirname $(readlink -f $0)) +CONF_DIR=$BIN_DIR/../conf + +HOST=`curl -s http://169.254.169.254/latest/meta-data/public-hostname` + +sed -i -r \ + -e "s,^( *BASE_URL:).*,\\1 'http://$HOST'," \ + -e "s,^( *EMAIL_DOMAIN:).*,\\1 '$HOST'," \ + $CONF_DIR/general.yml diff --git a/bin/fetch-comments b/bin/fetch-comments index 4bbcc9d21..ef099fcc9 100755 --- a/bin/fetch-comments +++ b/bin/fetch-comments @@ -5,11 +5,13 @@ use warnings; require 5.8.0; use FixMyStreet::App; +use CronFns; +my ($verbose, $nomail) = CronFns::options(); use Open311; use Open311::GetServiceRequestUpdates; -my $updates = Open311::GetServiceRequestUpdates->new; +my $updates = Open311::GetServiceRequestUpdates->new( verbose => $verbose ); $updates->fetch; diff --git a/bin/gettext-extract b/bin/gettext-extract index 55623e86c..e77cf9cb0 100755 --- a/bin/gettext-extract +++ b/bin/gettext-extract @@ -31,23 +31,27 @@ rm -f $PO xgettext.pl --gnu-gettext --verbose --output $PO --plugin perl=* --plugin tt2 --directory perllib --directory templates/web --directory db --directory bin # Fix headers -TEMP=`tempfile` +# no such thing as tempfile on OS X +TEMP=`tempfile 2>/dev/null || mktemp /tmp/gettext-extract.XXXXXX` NOW=`date +"%Y-%m-%d %H:%M%z"` +# strictly POSIX sed on e.g. OS X doesn't let you used \n in replacements so we do this +nl=$'\n'; cat $PO | sed " s/SOME DESCRIPTIVE TITLE/FixMyStreet original .po file, autogenerated by gettext-extract/; s/YEAR THE PACKAGE'S COPYRIGHT HOLDER/2011 UK Citizens Online Democracy/; s/PACKAGE package/main FixMyStreet code/; s/FIRST AUTHOR <EMAIL@ADDRESS>, YEAR./Matthew Somerville <matthew@mysociety.org>, 2011-06-03./; - s/PACKAGE VERSION/1.0\\\n\"\n\"Report-Msgid-Bugs-To: matthew@mysociety.org/; + s/PACKAGE VERSION/1.0\\\n\"\\$nl\"Report-Msgid-Bugs-To: matthew@mysociety.org/; s/POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE/POT-Creation-Date: $NOW/; s/LL@li.org/team@fixmystreet.com/; s/charset=CHARSET/charset=UTF-8/; - s/8bit/8bit\\\n\"\n\"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;/; + s/8bit/8bit\\\n\"\\$nl\"Plural-Forms: nplurals=2; plural=n != 1;/; " >> $TEMP mv $TEMP $PO echo "$( bin/gettext-nget-patch )" >> $PO -bin/make_emptyhomes_po +bin/make_po FixMyStreet-EmptyHomes +bin/make_po FixMyBarangay diff --git a/bin/gettext-nget-patch b/bin/gettext-nget-patch index 223bcc816..5ebd8bbcb 100755 --- a/bin/gettext-nget-patch +++ b/bin/gettext-nget-patch @@ -9,6 +9,7 @@ my %out; find( sub { next unless -f; + next if $File::Find::name =~ /ttc$/; open (FP, $_) or die $!; while (<FP>) { next unless /nget/; @@ -17,16 +18,17 @@ find( sub { do { $text .= <FP>; } until $text =~ /\)/; - $text =~ /nget\(\s*"(.*?)"\s*,\s*"(.*?)"\s*,\s*(.*?)\s*\)/s; - $out{$1} = { - file => $File::Find::name, - line => $line, - s => $1, - p => $2, - }; + if ($text =~ /nget\(\s*"(.*?)"\s*,\s*"(.*?)"\s*,\s*(.*?)\s*\)/s) { + $out{$1} = { + file => $File::Find::name, + line => $line, + s => $1, + p => $2, + }; + } } close FP; -}, 'templates'); +}, 'templates', 'perllib'); foreach (values %out) { print <<EOF; diff --git a/bin/install-as-user b/bin/install-as-user new file mode 100755 index 000000000..2656195f4 --- /dev/null +++ b/bin/install-as-user @@ -0,0 +1,111 @@ +#!/bin/sh + +set -e +set -x + +if [ $# -ne 3 ] +then + cat >&2 <<EOUSAGE +Usage: $0 <UNIX-USER> <HOST> <INSTALLATION-DIRECTORY> +EOUSAGE + exit 1 +fi + +UNIX_USER="$1" +HOST="$2" +DIRECTORY="$3" +DB_NAME="fixmystreet" + +# Check that the arguments we've been passed are sensible: + +IP_ADDRESS_FOR_HOST="$(dig +short $HOST)" + +if [ x = x"$IP_ADDRESS_FOR_HOST" ] +then + echo "The hostname $HOST didn't resolve to an IP address" + exit 1 +fi + +if ! id "$UNIX_USER" 2> /dev/null > /dev/null +then + echo "The user '$UNIX_USER' didn't exist." + exit 1 +fi + +if [ "$(whoami)" != "$UNIX_USER" ] +then + echo "This script should be run by the user '$UNIX_USER'." + exit 1 +fi + +REPOSITORY="$DIRECTORY/fixmystreet" +LINK_DESTINATION="$HOME/fixmystreet" + +ln -sfn "$REPOSITORY" $LINK_DESTINATION +cd "$REPOSITORY" + +# Add regularly scheduled tasks to cron: + +TEMPORARY_CRONTAB=$(mktemp) + +echo crontab file is $TEMPORARY_CRONTAB + +cp "$REPOSITORY"/conf/crontab.example "$TEMPORARY_CRONTAB" + +sed -i \ + -e 's,$FMS,'"$REPOSITORY,g" \ + -e 's,$LOCK_DIR,'"$DIRECTORY,g" \ + "$TEMPORARY_CRONTAB" + +crontab $TEMPORARY_CRONTAB + +# Install the compass gem locally - it's required for generating the +# CSS: + +export GEM_HOME="$DIRECTORY/gems" +mkdir -p "$GEM_HOME" +export GEM_PATH= +export PATH="$GEM_HOME/bin:$PATH" + +gem install --no-ri --no-rdoc compass + +# Use compass to generate the CSS, if it doesn't seem to already +# exist: + +if [ ! -f web/cobrands/default/base.css ] +then + bin/make_css +fi + +# Write sensible values into the config file: + +sed -r \ + -e "s,^( *FMS_DB_HOST:).*,\\1 ''," \ + -e "s,^( *FMS_DB_NAME:).*,\\1 '$DB_NAME'," \ + -e "s,^( *FMS_DB_USER:).*,\\1 '$UNIX_USER'," \ + -e "s,^( *BASE_URL:).*,\\1 'http://$HOST'," \ + -e "s,^( *EMAIL_DOMAIN:).*,\\1 '$HOST'," \ + -e "s,^( *CONTACT_EMAIL:).*,\\1 'help@$HOST'," \ + conf/general.yml-example > conf/general.yml + +# Create the database if it doesn't exist: +if ! psql -l | egrep "^ *$DB_NAME *\|" > /dev/null +then + createdb --owner "$UNIX_USER" "$DB_NAME" + echo 'CREATE LANGUAGE plpgsql;' | psql -U "$UNIX_USER" "$DB_NAME" || true + psql -U "$UNIX_USER" "$DB_NAME" < "$REPOSITORY"/db/schema.sql + psql -U "$UNIX_USER" "$DB_NAME" < "$REPOSITORY"/db/alert_types.sql + psql -U "$UNIX_USER" "$DB_NAME" < "$REPOSITORY"/db/generate_secret.sql +fi + +# Install the required Perl modules - this may take a very long time: + +cd "$FMS_REPOSITORY" +bin/install_perl_modules + +# Generate po and mo files (these invocations taken from Kagee's script): + +bin/cron-wrapper bin/make_po FixMyStreet-EmptyHomes +bin/cron-wrapper bin/make_emptyhomes_welsh_po + +commonlib/bin/gettext-makemo FixMyStreet diff --git a/bin/install_perl_modules b/bin/install_perl_modules index 2df4ffbf8..2311ae5f1 100755 --- a/bin/install_perl_modules +++ b/bin/install_perl_modules @@ -1,5 +1,7 @@ #!/bin/bash +set -e + DIR="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd | sed -e 's/\/bin$//' )" $DIR/bin/cpanm -l $DIR/local Carton @@ -9,11 +11,7 @@ export PERL5LIB=$DIR/local/lib/perl5 carton install --deployment -perl -MImage::Magick -e 'exit()' >/dev/null 2>&1 - -HAVE_IM=$? - -if [ $HAVE_IM -ne 0 ] +if ! perl -MImage::Magick -e 'exit()' >/dev/null 2>&1 then read -p "Image::Magick is not installed. Do you want to attempt to install it?" yn case $yn in diff --git a/bin/make_css b/bin/make_css index 4494c92e7..a86fd4f0d 100755 --- a/bin/make_css +++ b/bin/make_css @@ -14,15 +14,19 @@ DIRECTORY=$(cd `dirname $0`/../web && pwd) # FixMyStreet uses compass -compass compile --output-style compressed $DIRECTORY/cobrands/fixmystreet -compass compile --output-style compressed $DIRECTORY/cobrands/bromley -compass compile --output-style compressed $DIRECTORY/cobrands/barnet -compass compile --output-style compressed $DIRECTORY/cobrands/zurich -compass compile --output-style compressed $DIRECTORY/cobrands/stevenage -compass compile --output-style compressed $DIRECTORY/cobrands/default +NEWSTYLE=${1:-"fixmystreet bromley fixmybarangay barnet zurich default stevenage"} +NEWSTYLE_REGEX=${NEWSTYLE// /\\|} +for site in $NEWSTYLE; do + compass compile --output-style compressed $DIRECTORY/cobrands/$site +done + +# If given a command line argument, assume was a compass directory and exit +if [ -n "$1" ]; then + exit 0 +fi # The rest are plain sass -for scss in `find $DIRECTORY -name "*.scss" -exec dirname {} \; | uniq | grep -v "cobrands/\(fixmystreet\|bromley\|barnet\|stevenage\|default\|zurich\)"` +for scss in `find $DIRECTORY -name "*.scss" -exec dirname {} \; | uniq | grep -v "cobrands/\($NEWSTYLE_REGEX\)"` do sass --scss --update --style compressed $scss done diff --git a/bin/make_emptyhomes_welsh_po b/bin/make_emptyhomes_welsh_po index b3dd441a0..f4f6850d6 100755 --- a/bin/make_emptyhomes_welsh_po +++ b/bin/make_emptyhomes_welsh_po @@ -87,15 +87,21 @@ while(<MAINPO>) { $new_buffer =~ s/"\n"//g; if ($lookup{$new_buffer} && $lookup{$new_buffer}[1]) { - print OUTPO "#, fuzzy\n"; - } + print OUTPO "#, fuzzy\n"; + } print OUTPO $buffer; if ($lookup{$new_buffer}) { print OUTPO $lookup{$new_buffer}[0]; } else { - print __LINE__ . "\n"; - die "Failed to find match with buffer: $new_buffer"; + if (m/^msgstr\[0\] ""/) { + $new_buffer =~ s/^msgid "/msgstr[0] "/m; + $new_buffer =~ s/^msgid_plural "/msgstr[1] "/m; + $_ = <MAINPO>; # skip untranslated plural + } else { + $new_buffer =~ s/^msgid "/msgstr "/; + } + print OUTPO $new_buffer; } $buffer = ""; diff --git a/bin/make_emptyhomes_po b/bin/make_po index 10e840599..76dc4566b 100755 --- a/bin/make_emptyhomes_po +++ b/bin/make_po @@ -1,8 +1,8 @@ #!/usr/bin/perl -w use strict; -# Generates EmptyHomes version of .po file, which is a translation -# into a language the same as English, only "problem" becomes "empty property". +# Generates a version of .po file, which is a translation +# into a language the same as English, with replacement as specified in PoChange use POSIX; use FindBin; @@ -13,14 +13,16 @@ chdir("$FindBin::Bin/../locale"); mkdir("en_GB.UTF-8"); mkdir("en_GB.UTF-8/LC_MESSAGES"); +my $pofile = shift; + open(MAINPO, "FixMyStreet.po") or die ""; -open(EHAPO, ">FixMyStreet-EmptyHomes.po") or die ""; -open(NEWPO, ">en_GB.UTF-8/LC_MESSAGES/FixMyStreet-EmptyHomes.po") or die ""; +open(EHAPO, ">$pofile.po") or die ""; +open(NEWPO, ">en_GB.UTF-8/LC_MESSAGES/$pofile.po") or die ""; -print NEWPO "# AUTOMATICALLY GENERATED by make_emptyhomes_po, do not edit\n"; +print NEWPO "# AUTOMATICALLY GENERATED by make_po, do not edit\n"; print NEWPO "#\n"; -print EHAPO "# AUTOMATICALLY GENERATED by make_emptyhomes_po, do not edit\n"; +print EHAPO "# AUTOMATICALLY GENERATED by make_po, do not edit\n"; print EHAPO "#\n"; my $buffer = ""; @@ -30,7 +32,7 @@ while(<MAINPO>) { s/#, fuzzy/#/; } if (m/"Last-Translator: FULL NAME/) { - $_ = '"Last-Translator: mysociety/bin/make_emptyhomes_po\\n"'."\n"; + $_ = '"Last-Translator: mysociety/bin/make_po\\n"'."\n"; } if (m/"PO-Revision-Date: YEAR-MO-DA/) { my $time = POSIX::strftime("%Y-%m-%d %H:%M%z", localtime(time())); @@ -56,7 +58,7 @@ while(<MAINPO>) { } elsif ($start && (m/^msgstr ""/ || m/^msgstr\[0\] ""/)) { # start of translated text - translate English into Empty Homes language - $buffer = PoChange::fixmystreet_to_reportemptyhomes($buffer); + $buffer = PoChange::translate($pofile, $buffer); print EHAPO $buffer; diff --git a/bin/open311-populate-service-list b/bin/open311-populate-service-list index 9588e4360..232b0a6d4 100755 --- a/bin/open311-populate-service-list +++ b/bin/open311-populate-service-list @@ -4,11 +4,22 @@ use strict; use warnings; use FixMyStreet::App; use Open311::PopulateServiceList; +use Getopt::Long::Descriptive; +my ($opt, $usage) = describe_options( + '%c %o', + ['verbose|v', "print out all services as they are found"], + ['warn|w', "output warnings about any issues"], + ['help', "print usage message and exit" ], +); +print($usage->text), exit if $opt->help; my $council_list = FixMyStreet::App->model('DB::Open311conf')->search( { send_method => 'Open311' } ); -my $p = Open311::PopulateServiceList->new( council_list => $council_list ); +my $verbose = 0; +$verbose = 1 if $opt->warn; +$verbose = 2 if $opt->verbose; +my $p = Open311::PopulateServiceList->new( council_list => $council_list, verbose => $verbose ); $p->process_councils; diff --git a/bin/problem-creation-graph b/bin/problem-creation-graph index 6692ae724..b96d45540 100755 --- a/bin/problem-creation-graph +++ b/bin/problem-creation-graph @@ -26,12 +26,12 @@ else DATE="2007-02-01" fi -SOURCEA=/tmp/bci-creation-rate-graph-data-$RANDOM$RANDOM -SOURCEB=/tmp/bci-creation-rate-graph-data-$RANDOM$RANDOM -SOURCEC=/tmp/bci-creation-rate-graph-data-$RANDOM$RANDOM -SOURCED=/tmp/bci-creation-rate-graph-data-$RANDOM$RANDOM -SOURCEE=/tmp/bci-creation-rate-graph-data-$RANDOM$RANDOM -GPSCRIPT=/tmp/bci-creation-rate-graph-script-$RANDOM$RANDOM +SOURCEA=/tmp/fms-creation-rate-graph-data-$RANDOM$RANDOM +SOURCEB=/tmp/fms-creation-rate-graph-data-$RANDOM$RANDOM +SOURCEC=/tmp/fms-creation-rate-graph-data-$RANDOM$RANDOM +SOURCED=/tmp/fms-creation-rate-graph-data-$RANDOM$RANDOM +SOURCEE=/tmp/fms-creation-rate-graph-data-$RANDOM$RANDOM +GPSCRIPT=/tmp/fms-creation-rate-graph-script-$RANDOM$RANDOM # where status in ('draft') @@ -104,6 +104,6 @@ END #echo "gpscript $GPSCRIPT" export GDFONTPATH=/usr/share/fonts/truetype/ttf-bitstream-vera -gnuplot < $GPSCRIPT > fixmystreet/web/bci-live-creation$EXTENSION 2>/dev/null +gnuplot < $GPSCRIPT > fixmystreet/web/fms-live-creation$EXTENSION 2>/dev/null diff --git a/bin/problems-filed-graph b/bin/problems-filed-graph index 8addacd62..e5946b078 100755 --- a/bin/problems-filed-graph +++ b/bin/problems-filed-graph @@ -20,8 +20,8 @@ source fixmystreet/commonlib/shlib/deployfns read_conf fixmystreet/conf/general.yml -SOURCEO=/tmp/bci-report-rate-graph-data-nonwmc-$RANDOM$RANDOM -GPSCRIPT=/tmp/bci-report-rate-graph-script-$RANDOM$RANDOM +SOURCEO=/tmp/fms-report-rate-graph-data-nonwmc-$RANDOM$RANDOM +GPSCRIPT=/tmp/fms-report-rate-graph-script-$RANDOM$RANDOM echo "select date(created), count(*) @@ -57,5 +57,5 @@ END #echo "gpscript $GPSCRIPT" export GDFONTPATH=/usr/share/fonts/truetype/ttf-bitstream-vera -gnuplot < $GPSCRIPT > fixmystreet/web/bci-live-line$EXTENSION 2>/dev/null +gnuplot < $GPSCRIPT > fixmystreet/web/fms-live-line$EXTENSION 2>/dev/null diff --git a/bin/rotate-photos b/bin/rotate-photos index faf2748e6..31a60ff6c 100755 --- a/bin/rotate-photos +++ b/bin/rotate-photos @@ -16,6 +16,8 @@ use FindBin; use lib "$FindBin::Bin/../perllib"; use lib "$FindBin::Bin/../commonlib/perllib"; +use Digest::SHA1 qw(sha1_hex); + use Utils; use mySociety::Config; use mySociety::DBHandle qw(dbh select_all); @@ -36,17 +38,27 @@ my $r = select_all("select id, photo from problem where service='iPhone'"); foreach (@$r) { my $id = $_->{id}; my $photo = $_->{photo}; - my ($fh, $filename) = mySociety::TempFiles::named_tempfile('.jpeg'); - print $fh $photo; - close $fh; - my $out = `jhead -autorot $filename`; - if ($out) { - open(FP, $filename) or die $!; - $photo = join('', <FP>); - close FP; - Utils::workaround_pg_bytea("update problem set photo=? where id=?", 1, $photo, $id); - dbh()->commit(); + + if (length($photo) == 40) { + # If photo field contains a hash + my $filename = mySociety::Config::get('UPLOAD_DIR') . "$photo.jpeg"; + `jhead -autorot $filename`; + } else { + my ($fh, $filename) = mySociety::TempFiles::named_tempfile('.jpeg'); + print $fh $photo; + close $fh; + my $out = `jhead -autorot $filename`; + if ($out) { + open(FP, $filename) or die $!; + $photo = join('', <FP>); + close FP; + my $fileid = sha1_hex($photo); + rename $filename, mySociety::Config::get('UPLOAD_DIR') . "$fileid.jpeg"; + dbh()->do('UPDATE problem SET photo=? WHERE id=?', {}, $fileid, $id); + dbh()->commit(); + } else { + unlink $filename; + } } - unlink $filename; } diff --git a/bin/site-specific-install.sh b/bin/site-specific-install.sh new file mode 100644 index 000000000..6ebac7970 --- /dev/null +++ b/bin/site-specific-install.sh @@ -0,0 +1,53 @@ +#!/bin/sh + +PARENT_SCRIPT_URL=https://github.com/mysociety/commonlib/blob/master/bin/install-site.sh + +misuse() { + echo The variable $1 was not defined, and it should be. + echo This script should not be run directly - instead, please run: + echo $PARENT_SCRIPT_URL + exit 1 +} + +# Strictly speaking we don't need to check all of these, but it might +# catch some errors made when changing install-site.sh + +[ -z "$DIRECTORY" ] && misuse DIRECTORY +[ -z "$UNIX_USER" ] && misuse UNIX_USER +[ -z "$REPOSITORY" ] && misuse REPOSITORY +[ -z "$REPOSITORY_URL" ] && misuse REPOSITORY_URL +[ -z "$BRANCH" ] && misuse BRANCH +[ -z "$SITE" ] && misuse SITE +[ -z "$DEFAULT_SERVER" ] && misuse DEFAULT_SERVER +[ -z "$HOST" ] && misuse HOST +[ -z "$DISTRIBUTION" ] && misuse DISTRIBUTION +[ -z "$VERSION" ] && misuse VERSION + +install_nginx + +install_website_packages + +su -l -c "touch '$DIRECTORY/admin-htpasswd'" "$UNIX_USER" + +add_website_to_nginx + +add_postgresql_user + +su -l -c "$REPOSITORY/bin/install-as-user '$UNIX_USER' '$HOST' '$DIRECTORY'" "$UNIX_USER" + +install_sysvinit_script + +if [ $DEFAULT_SERVER = true ] && [ x != x$EC2_HOSTNAME ] +then + # If we're setting up as the default on an EC2 instance, + # make sure the ec2-rewrite-conf script is called from + # /etc/rc.local + overwrite_rc_local +fi + +# Tell the user what to do next: + +echo Installation complete - you should now be able to view the site at: +echo http://$HOST/ +echo Or you can run the tests by switching to the "'$UNIX_USER'" user and +echo running: $REPOSITORY/bin/cron-wrapper prove -r t diff --git a/carton.lock b/carton.lock index cdca29bff..2d284b099 100644 --- a/carton.lock +++ b/carton.lock @@ -13615,6 +13615,84 @@ "target" : "Encode::Locale", "version" : "1.02" }, + "Error" : { + "dist" : "Error-0.17018", + "module" : "Error", + "mymeta" : { + "abstract" : "Error/exception handling in an OO-ish way", + "author" : [ + "Shlomi Fish <shlomif@iglu.org.il>" + ], + "dynamic_config" : 0, + "generated_by" : "Module::Build version 0.4002, CPAN::Meta::Converter version 2.112150", + "license" : [ + "perl_5" + ], + "meta-spec" : { + "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", + "version" : "2" + }, + "name" : "Error", + "prereqs" : { + "configure" : { + "requires" : { + "Module::Build" : "0.38" + } + }, + "runtime" : { + "requires" : { + "Scalar::Util" : 0, + "perl" : "v5.6.0", + "warnings" : 0 + } + } + }, + "provides" : { + "Error" : { + "file" : "lib/Error.pm", + "version" : "0.17018" + }, + "Error::Simple" : { + "file" : "lib/Error.pm", + "version" : "0.17018" + }, + "Error::WarnDie" : { + "file" : "lib/Error.pm", + "version" : 0 + }, + "Error::subs" : { + "file" : "lib/Error.pm", + "version" : 0 + } + }, + "release_status" : "stable", + "resources" : { + "license" : [ + "http://dev.perl.org/licenses/" + ] + }, + "version" : "0.17018" + }, + "name" : "Error", + "pathname" : "S/SH/SHLOMIF/Error-0.17018.tar.gz", + "provides" : { + "Error" : { + "file" : "Error.pm", + "version" : "0.17018" + }, + "Error::Simple" : { + "file" : "Error.pm", + "version" : "0.17018" + }, + "Error::WarnDie" : { + "file" : "Error.pm" + }, + "Error::subs" : { + "file" : "Error.pm" + } + }, + "version" : "0.17018" + }, "Eval::Closure" : { "dist" : "Eval-Closure-0.06", "mymeta" : { @@ -14600,6 +14678,52 @@ }, "version" : "0.22" }, + "File::Copy::Recursive" : { + "dist" : "File-Copy-Recursive-0.38", + "module" : "File::Copy::Recursive", + "mymeta" : { + "abstract" : "unknown", + "author" : [ + "unknown" + ], + "dynamic_config" : 0, + "generated_by" : "ExtUtils::MakeMaker version 6.30, CPAN::Meta::Converter version 2.112150", + "license" : [ + "unknown" + ], + "meta-spec" : { + "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", + "version" : "2" + }, + "name" : "File-Copy-Recursive", + "prereqs" : { + "build" : { + "requires" : { + "ExtUtils::MakeMaker" : 0 + } + }, + "runtime" : { + "requires" : { + "File::Copy" : 0, + "File::Spec" : 0 + } + } + }, + "release_status" : "stable", + "version" : "0.38", + "x_installdirs" : "site", + "x_version_from" : "Recursive.pm" + }, + "name" : "File::Copy::Recursive", + "pathname" : "D/DM/DMUEY/File-Copy-Recursive-0.38.tar.gz", + "provides" : { + "File::Copy::Recursive" : { + "file" : "File/Copy/Recursive.pm", + "version" : "0.38" + } + }, + "version" : "0.38" + }, "File::Find::Closures" : { "dist" : "File-Find-Closures-1.09", "mymeta" : { @@ -17259,6 +17383,163 @@ "target" : "IO::Scalar", "version" : "2.110" }, + "IO::Tty" : { + "dist" : "IO-Tty-1.10", + "module" : "IO::Pty", + "mymeta" : { + "abstract" : "Pseudo ttys and constants", + "author" : [ + "Roland Giersig <RGiersig@cpan.org>" + ], + "dynamic_config" : 0, + "generated_by" : "ExtUtils::MakeMaker version 6.56, CPAN::Meta::Converter version 2.112150", + "license" : [ + "perl_5" + ], + "meta-spec" : { + "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", + "version" : "2" + }, + "name" : "IO-Tty", + "no_index" : { + "directory" : [ + "t", + "inc" + ] + }, + "prereqs" : { + "build" : { + "requires" : { + "Test::More" : 0 + } + }, + "configure" : { + "requires" : { + "ExtUtils::MakeMaker" : 0 + } + }, + "runtime" : { + "requires" : {} + } + }, + "release_status" : "stable", + "resources" : { + "repository" : { + "url" : "https://expectperl.svn.sourceforge.net/svnroot/expectperl/IO-Tty/trunk" + } + }, + "version" : "1.10" + }, + "name" : "IO::Tty", + "pathname" : "T/TO/TODDR/IO-Tty-1.10.tar.gz", + "provides" : { + "IO::Pty" : { + "file" : "IO/Pty.pm", + "version" : "1.10" + }, + "IO::Tty" : { + "file" : "IO/Tty.pm", + "version" : "1.10" + }, + "IO::Tty::Constant" : { + "file" : "IO/Tty/Constant.pm" + } + }, + "version" : "1.10" + }, + "IPC::Run" : { + "dist" : "IPC-Run-0.92", + "module" : "IPC::Run", + "mymeta" : { + "abstract" : "system() and background procs w/ piping, redirs, ptys (Unix, Win32)", + "author" : [ + "Barrie Slaymaker <barries@slaysys.com>" + ], + "dynamic_config" : 0, + "generated_by" : "ExtUtils::MakeMaker version 6.62, CPAN::Meta::Converter version 2.120351, CPAN::Meta::Converter version 2.112150", + "license" : [ + "perl_5" + ], + "meta-spec" : { + "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", + "version" : "2" + }, + "name" : "IPC-Run", + "no_index" : { + "directory" : [ + "t", + "inc" + ] + }, + "prereqs" : { + "build" : { + "requires" : { + "ExtUtils::MakeMaker" : 0 + } + }, + "configure" : { + "requires" : { + "ExtUtils::MakeMaker" : 0 + } + }, + "runtime" : { + "recommends" : { + "IO::Pty" : "1.08" + }, + "requires" : { + "IO::Pty" : "1.08", + "Test::More" : "0.47" + } + } + }, + "release_status" : "stable", + "resources" : { + "bugtracker" : { + "web" : "https://rt.cpan.org/NoAuth/Bugs.html?Dist=IPC-Run" + }, + "license" : [ + "http://dev.perl.org/licenses/" + ], + "repository" : { + "url" : "https://github.com/toddr/IPC-Run" + } + }, + "version" : "0.92" + }, + "name" : "IPC::Run", + "pathname" : "T/TO/TODDR/IPC-Run-0.92.tar.gz", + "provides" : { + "IPC::Run" : { + "file" : "IPC/Run.pm", + "version" : "0.92" + }, + "IPC::Run::Debug" : { + "file" : "IPC/Run/Debug.pm", + "version" : "0.90" + }, + "IPC::Run::IO" : { + "file" : "IPC/Run/IO.pm", + "version" : "0.90" + }, + "IPC::Run::Timer" : { + "file" : "IPC/Run/Timer.pm", + "version" : "0.90" + }, + "IPC::Run::Win32Helper" : { + "file" : "IPC/Run/Win32Helper.pm", + "version" : "0.90" + }, + "IPC::Run::Win32IO" : { + "file" : "IPC/Run/Win32IO.pm", + "version" : "0.90" + }, + "IPC::Run::Win32Pump" : { + "file" : "IPC/Run/Win32Pump.pm", + "version" : "0.90" + } + }, + "version" : "0.92" + }, "IPC::Run3" : { "dist" : "IPC-Run3-0.044", "mymeta" : { @@ -20056,6 +20337,68 @@ }, "version" : "1.08" }, + "Module::Signature" : { + "dist" : "Module-Signature-0.68", + "module" : "Module::Signature", + "mymeta" : { + "abstract" : "Module signature file manipulation", + "author" : [ + "唐鳳 <cpan@audreyt.org>" + ], + "dynamic_config" : 0, + "generated_by" : "Module::Install version 1.00, CPAN::Meta::Converter version 2.112150", + "license" : [ + "unknown" + ], + "meta-spec" : { + "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", + "version" : "2" + }, + "name" : "Module-Signature", + "no_index" : { + "directory" : [ + "inc", + "t" + ] + }, + "prereqs" : { + "build" : { + "requires" : { + "ExtUtils::MakeMaker" : "6.42", + "IPC::Run" : 0, + "Test::More" : 0 + } + }, + "configure" : { + "requires" : { + "ExtUtils::MakeMaker" : "6.42" + } + }, + "runtime" : { + "requires" : { + "IO::Socket::INET" : 0, + "perl" : "5.005" + } + } + }, + "release_status" : "stable", + "resources" : { + "repository" : { + "url" : "http://github.com/audreyt/module-signature" + } + }, + "version" : "0.68" + }, + "name" : "Module::Signature", + "pathname" : "F/FL/FLORA/Module-Signature-0.68.tar.gz", + "provides" : { + "Module::Signature" : { + "file" : "Module/Signature.pm", + "version" : "0.68" + } + }, + "version" : "0.68" + }, "Moose" : { "dist" : "Moose-2.0401", "mymeta" : { @@ -31355,6 +31698,52 @@ "target" : "XML::SAX::Base", "version" : "1.08" }, + "XML::SAX::Expat" : { + "dist" : "XML-SAX-Expat-0.40", + "module" : "XML::SAX::Expat", + "mymeta" : { + "abstract" : "SAX Driver for Expat", + "author" : [ + "Robin Berjon" + ], + "dynamic_config" : 0, + "generated_by" : "ExtUtils::MakeMaker version 6.44, CPAN::Meta::Converter version 2.112150", + "license" : [ + "perl_5" + ], + "meta-spec" : { + "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", + "version" : "2" + }, + "name" : "XML-SAX-Expat", + "prereqs" : { + "build" : { + "requires" : { + "ExtUtils::MakeMaker" : 0 + } + }, + "runtime" : { + "requires" : { + "XML::NamespaceSupport" : "0.03", + "XML::Parser" : "2.27", + "XML::SAX" : "0.03", + "XML::SAX::Base" : "1.00" + } + } + }, + "release_status" : "stable", + "version" : "0.40" + }, + "name" : "XML::SAX::Expat", + "pathname" : "B/BJ/BJOERN/XML-SAX-Expat-0.40.tar.gz", + "provides" : { + "XML::SAX::Expat" : { + "file" : "XML/SAX/Expat.pm", + "version" : "0.40" + } + }, + "version" : "0.40" + }, "XML::Simple" : { "dist" : "XML-Simple-2.18", "mymeta" : { diff --git a/commonlib b/commonlib -Subproject f81ec03692fac90792fc102f88f0afbf3d2f73b +Subproject e832140e07bba7697726cae50ec0da26fb54788 diff --git a/conf/apache-vhost.conf.example b/conf/apache-vhost.conf.example new file mode 100644 index 000000000..97a34fe66 --- /dev/null +++ b/conf/apache-vhost.conf.example @@ -0,0 +1,34 @@ +# An example Apache virtualhost configuration file. +# +# See our installation help at http://code.fixmystreet.com/ + +<VirtualHost *:80> + ServerName fixmystreet.yourservername + DocumentRoot /home/yourname/fixmystreet/web/ + + # Pull in the specific config + Include /home/yourname/fixmystreet/conf/httpd.conf + + <Directory /home/yourname/fixmystreet/web> + # You also need to enable cgi files to run as CGI scripts. For example: + # on production servers these are run under fastcgi + Options +ExecCGI + AddHandler cgi-script .cgi + AllowOverride None + </Directory> + + <Location /admin> + # + # WARNING - enable auth here on production machine + # + </Location> + + Alias /admin/ /home/yourname/fixmystreet/web-admin/ + + Alias /jslib/ /home/yourname/fixmystreet/commonlib/jslib/ + <Location /jslib> + AddOutputFilter DEFLATE js + Header append Cache-Control "no-transform" + </Location> + +</VirtualHost> diff --git a/conf/crontab.example b/conf/crontab.example new file mode 100644 index 000000000..47c018573 --- /dev/null +++ b/conf/crontab.example @@ -0,0 +1,32 @@ +# Timed tasks for FixMyStreet. + +# This is an example crontab that you may want to use as a basis for +# one on your own server. You should replace $FMS with the path to the +# clone of the FixMyStreet repository that you are using. You should +# also replace $LOCK_DIR with a writeable directory for the lock files. + +# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved. +# Email: matthew@mysociety.org. WWW: http://www.mysociety.org/ + +PATH=/usr/local/bin:/usr/bin:/bin + +# send-reports has three rows so that its 8am entry can be run with --verbose to send a morning summary of anything that's gone wrong +5,10,15,20,25,30,35,40,45,50,55 * * * * "$FMS/commonlib/bin/run-with-lockfile.sh" -n "$FMS/send-reports.lock" "$FMS/bin/cron-wrapper send-reports" || echo "stalled?" +0 0-7,9-23 * * * "$FMS/commonlib/bin/run-with-lockfile.sh" -n "$LOCK_DIR/send-reports.lock" "$FMS/bin/cron-wrapper send-reports" || echo "stalled?" +0 8 * * * "$FMS/commonlib/bin/run-with-lockfile.sh" -n "$LOCK_DIR/send-reports.lock" "$FMS/bin/cron-wrapper send-reports --verbose" || echo "stalled?" + +2 * * * * "$FMS/commonlib/bin/run-with-lockfile.sh" -n "$LOCK_DIR/send-alerts.lock" "$FMS/bin/cron-wrapper send-alerts" || echo "stalled?" +0,30 * * * * "$FMS/commonlib/bin/run-with-lockfile.sh" -n "$LOCK_DIR/send-questionnaires.lock" "$FMS/bin/cron-wrapper send-questionnaires" || echo "stalled?" +5,10,15,20,25,30,35,40,45,50,55 * * * * "$FMS/commonlib/bin/run-with-lockfile.sh" -n "$LOCK_DIR/send-comments.lock" "$FMS/bin/cron-wrapper send-comments" || echo "stalled?" +5,10,15,20,25,30,35,40,45,50,55 * * * * "$FMS/commonlib/bin/run-with-lockfile.sh" -n "$LOCK_DIR/fetch-comments.lock" "$FMS/bin/cron-wrapper fetch-comments" || echo "stalled?" + +0 0-7,9-23 * * * "$FMS/commonlib/bin/run-with-lockfile.sh" -n "$LOCK_DIR/open311-populate-service-list.lock" "$FMS/bin/cron-wrapper open311-populate-service-list" || echo "stalled?" +0 8 * * * "$FMS/commonlib/bin/run-with-lockfile.sh" -n "$LOCK_DIR/open311-populate-service-list.lock" "$FMS/bin/cron-wrapper open311-populate-service-list --warn" || echo "stalled?" + +# Once an hour, update the all reports stats +13 * * * * "$FMS/bin/cron-wrapper" update-all-reports + +# Once a day on all servers +39 2 * * * "$FMS/bin/problems-filed-graph" +43 2 * * * "$FMS/bin/problem-creation-graph" +00 8 * * * "$FMS/bin/check-for-zombies" $UNIX_USER diff --git a/conf/crontab.ugly b/conf/crontab.ugly index 63f2bbdd9..1a7236a2d 100644 --- a/conf/crontab.ugly +++ b/conf/crontab.ugly @@ -16,23 +16,26 @@ MAILTO=!!(*= $user *)!!@mysociety.org # On only one server !!(* if ($vhost eq 'reportemptyhomes.com') { *)!! -5,10,15,20,25,30,35,40,45,50,55 * * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/send-reports.lock "/data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/cron-wrapper send-reports" || echo "stalled?" -0 0-11,13-23 * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/send-reports.lock "/data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/cron-wrapper send-reports" || echo "stalled?" -0 12 * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/send-reports.lock "/data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/cron-wrapper send-reports --verbose" || echo "stalled?" +*/5 * * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/send-reports.lock "/data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/cron-wrapper send-reports --verbose" || echo "stalled?" #2 * * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/send-alerts.lock "/data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/cron-wrapper send-alerts" || echo "stalled?" 0,30 * * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/send-questionnaires.lock "/data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/cron-wrapper send-questionnaires" || echo "stalled?" -!!(* } elsif (($vhost eq 'www.fixmystreet.com') || ($vhost eq 'bromley.test.mysociety.org') || ($vhost eq 'stevenage.test.mysociety.org') || ($vhost eq 'integration-staging.fixmystreet.com')) { *)!! +!!(* } elsif (($vhost eq 'www.fixmystreet.com') || ($vhost eq 'bromley.test.mysociety.org') || ($vhost eq 'barnet.fixmystreet.staging.mysociety.org') || ($vhost eq 'fixmybarangay.test.mysociety.org') || ($vhost eq 'demo.fixmybarangay.com') || ($vhost eq 'stevenage.test.mysociety.org')) { *)!! 5,10,15,20,25,30,35,40,45,50,55 * * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/send-reports.lock "/data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/cron-wrapper send-reports" || echo "stalled?" -0 0-8,10,11,13,14,16,17,19-23 * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/send-reports.lock "/data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/cron-wrapper send-reports" || echo "stalled?" -0 9,12,15,18 * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/send-reports.lock "/data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/cron-wrapper send-reports --verbose" || echo "stalled?" +0 0-7,9-11,13-15,17-23 * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/send-reports.lock "/data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/cron-wrapper send-reports" || echo "stalled?" +0 8,12,16 * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/send-reports.lock "/data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/cron-wrapper send-reports --verbose" || echo "stalled?" 2 * * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/send-alerts.lock "/data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/cron-wrapper send-alerts" || echo "stalled?" 0,30 * * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/send-questionnaires.lock "/data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/cron-wrapper send-questionnaires" || echo "stalled?" 5,10,15,20,25,30,35,40,45,50,55 * * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/send-comments.lock "/data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/cron-wrapper send-comments" || echo "stalled?" -5,10,15,20,25,30,35,40,45,50,55 0,2-23 * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/fetch-comments.lock "/data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/cron-wrapper fetch-comments" || echo "stalled?" -10,15,20,25,30,35,40,45,50,55 1 * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/fetch-comments.lock "/data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/cron-wrapper fetch-comments" || echo "stalled?" + +5,10,15,20,25,30,35,40,45,50,55 0-7,9-23 * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/fetch-comments.lock "/data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/cron-wrapper fetch-comments" || echo "stalled?" +10,15,20,25,30,35,40,45,50,55 8 * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/fetch-comments.lock "/data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/cron-wrapper fetch-comments" || echo "stalled?" +5 8 * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/fetch-comments.lock "/data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/cron-wrapper fetch-comments --verbose" || echo "stalled?" 5 1 * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/fetch-comments.lock "/data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/cron-wrapper fetch-comments-24hs" || echo "stalled?" -0,30 * * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/open311-populate-service-list.lock "/data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/cron-wrapper open311-populate-service-list" || echo "stalled?" + +30 * * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/open311-populate-service-list.lock "/data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/cron-wrapper open311-populate-service-list" || echo "stalled?" +0 0-7,9-23 * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/open311-populate-service-list.lock "/data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/cron-wrapper open311-populate-service-list" || echo "stalled?" +0 8 * * * !!(*= $user *)!! run-with-lockfile -n /data/vhost/!!(*= $vhost *)!!/open311-populate-service-list.lock "/data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/cron-wrapper open311-populate-service-list --warn" || echo "stalled?" !!(* } *)!! diff --git a/conf/general.yml-example b/conf/general.yml-example index fd9ecad21..8d5018362 100644 --- a/conf/general.yml-example +++ b/conf/general.yml-example @@ -36,6 +36,10 @@ EXAMPLE_PLACES: [ 'High Street', 'Main Street' ] LANGUAGES: - 'en-gb,English,en_GB' +# If you're running an installation that is being used in a different time zone +# from the server, you can set the time zone here (standard time zone string) +TIME_ZONE: "" + # File locations for uploaded photos and cached geocoding results. UPLOAD_DIR: '../upload/' GEO_CACHE: '../cache/' @@ -127,9 +131,12 @@ GAZE_URL: 'http://gaze.mysociety.org/gaze' # Should problem reports link to the council summary pages? AREA_LINKS_FROM_PROBLEMS: '0' -# Used to override the STAGING SERVER safety mechanism in send-reports +# used to override the STAGING SERVER safety mechanism in send-reports TESTING_COUNCILS: '' +# if you're using Message Manager, include the URL here (see https://github.com/mysociety/message-manager/) +MESSAGE_MANAGER_URL: '' + # ----------------------------------------------------------------------- # fixmystreet.com specific config variables. You won't need any of these. @@ -139,4 +146,3 @@ LONDON_REPORTIT_KEY: '' LONDON_REPORTIT_SECRET: '' AUTH_SHARED_SECRET: '' HEARFROMYOURMP_BASE_URL: '' - diff --git a/conf/httpd.conf-example b/conf/httpd.conf-example index e7900161e..ab17dcec3 100644 --- a/conf/httpd.conf-example +++ b/conf/httpd.conf-example @@ -1,42 +1,10 @@ # Apache configuration for FixMyStreet. # -# Add lines something like this to your /etc/apache2/sites-enabled/fixmystreet - -# replacing '/home/yourname/fixmystreet' with the path to your install +# This file should be included in an Apache <VirtualHost> section. An +# example of such a virtualhost configuration file can be found in the +# file apache-vhost.conf.example in this directory. # -# # FixMyStreet -# <VirtualHost *:80> -# ServerName fixmystreet.yourservername -# DocumentRoot /home/yourname/fixmystreet/web/ -# -# # Pull in the specific config -# Include /home/yourname/fixmystreet/conf/httpd.conf -# -# <Directory /home/yourname/fixmystreet/web> -# # You also need to enable cgi files to run as CGI scripts. For example: -# # on production servers these are run under fastcgi -# Options +ExecCGI -# AddHandler cgi-script .cgi -# AllowOverride None -# </Directory> -# -# <Location /admin> -# # -# # WARNING - enable auth here on production machine -# # -# Options +ExecCGI -# AddHandler cgi-script .cgi -# </Location> -# -# Alias /admin/ /home/yourname/fixmystreet/web-admin/ -# -# Alias /jslib/ "/home/yourname/fixmystreet/commonlib/jslib/" -# -# </VirtualHost> -# -# -# Copyright (c) 2011 UK Citizens Online Democracy. All rights reserved. -# Email: team@mysociety.org -# WWW: http://www.mysociety.org +# See our installation help at http://code.fixmystreet.com/ RewriteEngine on # RewriteLog /var/log/apache2/rewrite.log diff --git a/conf/nginx.conf.example b/conf/nginx.conf.example new file mode 100644 index 000000000..7b26afdbf --- /dev/null +++ b/conf/nginx.conf.example @@ -0,0 +1,75 @@ +# An example configuration for running FixMyStreet under nginx. You +# will also need to set up the FixMyStreet Catalyst FastCGI backend. +# An example sysvinit script to help with this is shown given in the file +# sysvinit-catalyst-fastcgi.example in this directory. +# +# See our installation help at http://code.fixmystreet.com/ + +server { + + access_log /var/www/fixmystreet/logs/access.log; + error_log /var/www/fixmystreet/logs/error.log; + + listen 80; + root /var/www/fixmystreet/fixmystreet/web; + error_page 503 /down.html; + + # Make sure that Javascript and CSS are compressed. (HTML is + # already compressed under the default configuration of the nginx + # package.) + + gzip on; + gzip_disable "msie6"; + gzip_types application/javascript application/x-javascript text/css; + + # Set a long expiry time for CSS and Javascript, and prevent + # the mangling of Javascript by proxies: + + location ~ \.css$ { + expires 10y; + } + + location ~ \.js$ { + add_header Cache-Control no-transform; + expires 10y; + try_files $uri @catalyst; + } + + # These rewrite rules are ported from the Apache configuration in + # conf/httpd.conf + + rewrite ^/rss/council/([0-9]+)$ /rss/reports/$1 permanent; + rewrite ^/report$ /reports permanent; + rewrite '^/{/rss/(.*)}$' /rss/$1 permanent; + rewrite '^/reports/{/rss/(.*)}$' /rss/$1 permanent; + rewrite ^/alerts/?$ /alert permanent; + + location /mapit { + proxy_pass http://mapit.mysociety.org/; + proxy_set_header X-Real-IP $remote_addr; + } + + location /admin { + auth_basic "FixMyStreet admin interface"; + auth_basic_user_file /var/www/fixmystreet/admin-htpasswd; + try_files $uri @catalyst; + } + + location / { + if (-f $document_root/down.html) { + return 503; + } + try_files $uri @catalyst; + } + + location /down.html { + internal; + } + + location @catalyst { + include /etc/nginx/fastcgi_params; + fastcgi_param PATH_INFO $fastcgi_script_name; + fastcgi_param SCRIPT_NAME ''; + fastcgi_pass 127.0.0.1:9000; + } +} diff --git a/conf/packages.ubuntu-precise b/conf/packages.ubuntu-precise new file mode 100644 index 000000000..fc8a7d511 --- /dev/null +++ b/conf/packages.ubuntu-precise @@ -0,0 +1,16 @@ +make +jhead +liberror-perl +liblocale-gettext-perl +libsoap-lite-perl +memcached +perl +perlmagick +libmath-bigint-gmp-perl +gettext +libhaml-ruby +postgresql-9.1 +postgresql-server-dev-9.1 +gnuplot +ttf-bitstream-vera +libexpat1-dev diff --git a/conf/sysvinit.example b/conf/sysvinit.example new file mode 100755 index 000000000..44424281b --- /dev/null +++ b/conf/sysvinit.example @@ -0,0 +1,53 @@ +#! /bin/sh +### BEGIN INIT INFO +# Provides: application-catalyst-fixmystreet +# Required-Start: $local_fs $network +# Required-Stop: $local_fs $network +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Starts the FastCGI app server for the "FixMyStreet" site +# Description: The FastCGI application server for the "FixMyStreet" site +### END INIT INFO + +# This example sysvinit script is based on the helpful example here: +# http://richard.wallman.org.uk/2010/02/howto-deploy-a-catalyst-application-using-fastcgi-and-nginx/ + +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin +SITE_HOME=/var/www/fixmystreet +NAME=fixmystreet +DESC="FixMyStreet app server" +USER=fms + +echo $DAEMON +test -f $DAEMON || exit 0 + +set -e + +start_daemon() { + su -l -c "cd $SITE_HOME/fixmystreet && bin/cron-wrapper web/fixmystreet_app_fastcgi.cgi -d -l :9000 -n 2" $USER +} + +stop_daemon() { + pkill -f perl-fcgi -u $USER || true +} + +case "$1" in + start) + start_daemon + ;; + stop) + stop_daemon + ;; + reload|restart|force-reload) + stop_daemon + sleep 5 + start_daemon + ;; + *) + N=/etc/init.d/$NAME + echo "Usage: $N {start|stop|reload|restart|force-reload}" >&2 + exit 1 + ;; +esac + +exit 0 diff --git a/db/generate_secret.sql b/db/generate_secret.sql new file mode 100644 index 000000000..ad4b48200 --- /dev/null +++ b/db/generate_secret.sql @@ -0,0 +1,8 @@ +-- assumes there's a secret table (from the schema.sql) +-- use your own secret if you have one :-) +-- otherwise you can use this to populate the secret table with a random secret + +-- empty the table in case it has a value already (i.e., this is *destructive*!) +delete from secret; + +insert into secret values (md5(random()::text)); diff --git a/db/migrate_from_osgb36_to_wgs84.pl b/db/migrate_from_osgb36_to_wgs84.pl index abd504fb8..676ffea9b 100644 --- a/db/migrate_from_osgb36_to_wgs84.pl +++ b/db/migrate_from_osgb36_to_wgs84.pl @@ -21,11 +21,11 @@ use Utils; BEGIN { mySociety::Config::set_file("$FindBin::Bin/../conf/general"); mySociety::DBHandle::configure( - Name => mySociety::Config::get('BCI_DB_NAME'), - User => mySociety::Config::get('BCI_DB_USER'), - Password => mySociety::Config::get('BCI_DB_PASS'), - Host => mySociety::Config::get( 'BCI_DB_HOST', undef ), - Port => mySociety::Config::get( 'BCI_DB_PORT', undef ) + Name => mySociety::Config::get('FMS_DB_NAME'), + User => mySociety::Config::get('FMS_DB_USER'), + Password => mySociety::Config::get('FMS_DB_PASS'), + Host => mySociety::Config::get( 'FMS_DB_HOST', undef ), + Port => mySociety::Config::get( 'FMS_DB_PORT', undef ) ); } diff --git a/db/schema.sql b/db/schema.sql index 6e9396f45..7cb2f3257 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -84,7 +84,13 @@ create table contacts ( extra text, -- for things like missed bin collections - non_public boolean default 'f' + non_public boolean default 'f', + + -- per contact endpoint configuration + endpoint text, + jurisdiction text default '', + api_key text default '', + send_method text ); create unique index contacts_area_id_category_idx on contacts(area_id, category); @@ -204,7 +210,14 @@ create table problem ( send_method_used text, -- for things like missed bin collections - non_public BOOLEAN default 'f' + non_public BOOLEAN default 'f', + + -- record details about messages from external sources, eg. message manager + external_source text, + external_source_id text, + + -- number of me toos + interest_count integer default 0 ); create index problem_state_latitude_longitude_idx on problem(state, latitude, longitude); create index problem_user_id_idx on problem ( user_id ); @@ -444,5 +457,6 @@ create table open311conf ( send_method text, send_comments boolean not null default 'f', comment_user_id int references users(id), - suppress_alerts boolean not null default 'f' + suppress_alerts boolean not null default 'f', + can_be_devolved boolean not null default 'f' ); diff --git a/db/schema_0021-add_external_source_columns_to_problem.sql b/db/schema_0021-add_external_source_columns_to_problem.sql new file mode 100644 index 000000000..a74bcce7d --- /dev/null +++ b/db/schema_0021-add_external_source_columns_to_problem.sql @@ -0,0 +1,8 @@ +begin; + +ALTER table problem + ADD column external_source TEXT; +ALTER table problem + ADD column external_source_id TEXT; + +commit; diff --git a/db/schema_0022-add_interest_count_to_problems.sql b/db/schema_0022-add_interest_count_to_problems.sql new file mode 100644 index 000000000..62092aa0a --- /dev/null +++ b/db/schema_0022-add_interest_count_to_problems.sql @@ -0,0 +1,6 @@ +begin; + +ALTER table problem + ADD COLUMN interest_count integer; + +commit; diff --git a/db/schema_0023-add_can_be_devolved_and_category_config.sql b/db/schema_0023-add_can_be_devolved_and_category_config.sql new file mode 100644 index 000000000..6eba0919a --- /dev/null +++ b/db/schema_0023-add_can_be_devolved_and_category_config.sql @@ -0,0 +1,13 @@ +begin; + +ALTER table open311conf + ADD column can_be_devolved BOOL NOT NULL DEFAULT 'f'; + +ALTER table contacts + ADD column endpoint TEXT, + ADD column jurisdiction TEXT DEFAULT '', + ADD column api_key TEXT DEFAULT '', + ADD column send_method TEXT +; + +commit; diff --git a/db/schema_0026-change_interest_count_default.sql b/db/schema_0026-change_interest_count_default.sql new file mode 100644 index 000000000..7c78f6fe8 --- /dev/null +++ b/db/schema_0026-change_interest_count_default.sql @@ -0,0 +1,9 @@ +BEGIN; + + ALTER TABLE problem + ALTER COLUMN interest_count SET DEFAULT 0; + + UPDATE problem SET interest_count = 0 + WHERE interest_count IS NULL; + +COMMIT; diff --git a/locale/FixMyStreet.po b/locale/FixMyStreet.po index e5d9ef692..dfe83f074 100644 --- a/locale/FixMyStreet.po +++ b/locale/FixMyStreet.po @@ -8,16 +8,16 @@ msgid "" msgstr "" "Project-Id-Version: 1.0\n" "Report-Msgid-Bugs-To: matthew@mysociety.org\n" -"POT-Creation-Date: 2012-08-21 09:54+0100\n" +"POT-Creation-Date: 2012-10-24 11:20+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <team@fixmystreet.com>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" -#: perllib/FixMyStreet/DB/Result/Problem.pm:555 perllib/FixMyStreet/DB/ResultSet/Problem.pm:337 +#: perllib/FixMyStreet/DB/Result/Problem.pm:563 perllib/FixMyStreet/DB/ResultSet/Problem.pm:339 msgid " and " msgstr "" @@ -41,78 +41,46 @@ msgstr "" msgid "%d council contacts – %d confirmed, %d unconfirmed" msgstr "" -#: perllib/Utils.pm:293 -msgid "%d day" -msgstr "" - -#: perllib/Utils.pm:293 -msgid "%d days" -msgstr "" - #: templates/web/default/admin/council_list.html:27 msgid "%d edits by %s" msgstr "" -#: perllib/Utils.pm:294 -msgid "%d hour" -msgstr "" - -#: perllib/Utils.pm:294 -msgid "%d hours" -msgstr "" - #: templates/web/default/admin/index.html:16 msgid "%d live updates" msgstr "" -#: perllib/Utils.pm:295 -msgid "%d minute" -msgstr "" - -#: perllib/Utils.pm:295 -msgid "%d minutes" -msgstr "" - #: templates/web/default/admin/index.html:18 msgid "%d questionnaires sent – %d answered (%s%%)" msgstr "" -#: perllib/Utils.pm:292 -msgid "%d week" -msgstr "" - -#: perllib/Utils.pm:292 -msgid "%d weeks" +#: templates/web/fixmystreet/report/_support.html:3 +msgid "%d supporters" msgstr "" #: templates/web/default/reports/council.html:0 templates/web/default/reports/council.html:26 templates/web/emptyhomes/reports/council.html:11 templates/web/emptyhomes/reports/council.html:13 msgid "%s - Summary reports" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:605 +#: perllib/FixMyStreet/DB/Result/Problem.pm:613 msgid "%s ref: %s" msgstr "" -#: perllib/FixMyStreet/Cobrand/UK.pm:288 perllib/FixMyStreet/Cobrand/UK.pm:300 +#: perllib/FixMyStreet/Cobrand/UK.pm:279 perllib/FixMyStreet/Cobrand/UK.pm:291 msgid "%s ward, %s" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:488 +#: perllib/FixMyStreet/DB/Result/Problem.pm:496 msgid "%s, reported anonymously at %s" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:490 +#: perllib/FixMyStreet/DB/Result/Problem.pm:498 msgid "%s, reported by %s at %s" msgstr "" -#: perllib/FixMyStreet/Cobrand/UK.pm:315 perllib/FixMyStreet/Cobrand/UK.pm:327 +#: perllib/FixMyStreet/Cobrand/UK.pm:306 perllib/FixMyStreet/Cobrand/UK.pm:318 msgid "%s, within %s ward" msgstr "" -#: templates/web/default/admin/stats.html:5 -msgid "%sreports between %s and %s" -msgstr "" - #: templates/web/default/email_sent.html:28 msgid "(Don't worry — %s)" msgstr "" @@ -137,7 +105,7 @@ msgstr "" msgid "(fixed)" msgstr "" -#: templates/web/default/index.html:12 templates/web/default/index.html:8 templates/web/fixmystreet/around/postcode_form.html:7 +#: templates/web/default/index.html:12 templates/web/default/index.html:8 templates/web/fixmystreet/around/postcode_form.html:10 msgid "(like graffiti, fly tipping, broken paving slabs, or street lighting)" msgstr "" @@ -161,15 +129,15 @@ msgstr "" msgid "(we never show your email)" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:284 +#: perllib/FixMyStreet/App/Controller/Admin.pm:285 msgid "*unknown*" msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:629 perllib/FixMyStreet/App/Controller/Report/New.pm:655 perllib/FixMyStreet/DB/Result/Problem.pm:345 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:630 perllib/FixMyStreet/App/Controller/Report/New.pm:658 perllib/FixMyStreet/DB/Result/Problem.pm:353 msgid "-- Pick a category --" msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:609 perllib/FixMyStreet/DB/Result/Problem.pm:351 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:610 perllib/FixMyStreet/DB/Result/Problem.pm:359 msgid "-- Pick a property type --" msgstr "" @@ -177,6 +145,10 @@ msgstr "" msgid ". You can <a href=\"%s%s\">view the problem on this site</a>." msgstr "" +#: templates/web/fixmystreet/report/_support.html:3 +msgid "1 supporter" +msgstr "" + #: templates/web/default/questionnaire/completed.html:20 msgid "<p style=\"font-size:150%\">Thank you very much for filling in our questionnaire; glad to hear it’s been fixed.</p>" msgstr "" @@ -241,7 +213,7 @@ msgid "" "site and leave an update.</p>" msgstr "" -#: templates/web/default/around/display_location.html:70 templates/web/default/around/display_location.html:72 templates/web/emptyhomes/around/display_location.html:36 templates/web/emptyhomes/around/display_location.html:38 +#: templates/web/default/around/_report_banner.html:3 templates/web/default/around/_report_banner.html:5 templates/web/emptyhomes/around/display_location.html:36 templates/web/emptyhomes/around/display_location.html:38 msgid "<small>If you cannot see the map, <a href='%s' rel='nofollow'>skip this step</a>.</small>" msgstr "" @@ -249,15 +221,15 @@ msgstr "" msgid "<strong>%d</strong> live problems" msgstr "" -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:172 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:182 msgid "<strong>No</strong> Let me confirm my report by email" msgstr "" -#: templates/web/fixmystreet/report/display.html:148 +#: templates/web/fixmystreet/report/display.html:170 msgid "<strong>No</strong> Let me confirm my update by email" msgstr "" -#: templates/web/fixmystreet/auth/general.html:46 +#: templates/web/fixmystreet/auth/general.html:50 msgid "<strong>No</strong> let me sign in by email" msgstr "" @@ -273,7 +245,7 @@ msgstr "" msgid "<strong>No</strong>, let me confirm my update by email:" msgstr "" -#: templates/web/default/auth/general.html:37 templates/web/default/report/display.html:142 templates/web/default/report/new/fill_in_details_form.html:140 templates/web/fixmystreet/auth/general.html:32 templates/web/fixmystreet/auth/general.html:34 templates/web/fixmystreet/report/display.html:131 templates/web/fixmystreet/report/new/fill_in_details_form.html:154 +#: templates/web/default/auth/general.html:37 templates/web/default/report/display.html:142 templates/web/default/report/new/fill_in_details_form.html:140 templates/web/fixmystreet/auth/general.html:36 templates/web/fixmystreet/auth/general.html:38 templates/web/fixmystreet/report/display.html:147 templates/web/fixmystreet/report/new/fill_in_details_form.html:158 msgid "<strong>Yes</strong> I have a password" msgstr "" @@ -281,11 +253,11 @@ msgstr "" msgid "About us" msgstr "" -#: templates/web/default/admin/council_contacts.html:66 +#: templates/web/default/admin/council_contacts.html:72 msgid "Add new category" msgstr "" -#: templates/web/default/my/my.html:56 templates/web/fixmystreet/my/my.html:56 +#: templates/web/default/my/my.html:56 templates/web/fixmystreet/my/my.html:60 msgid "Added %s" msgstr "" @@ -301,14 +273,10 @@ msgstr "" msgid "Alert %d disabled (created %s)" msgstr "" -#: templates/web/bromley/report/display.html:207 templates/web/default/report/display.html:214 templates/web/fixmystreet/report/display.html:189 +#: templates/web/bromley/report/display.html:207 templates/web/default/report/display.html:214 templates/web/fixmystreet/report/display.html:211 msgid "Alert me to future updates" msgstr "" -#: templates/web/default/admin/stats.html:5 -msgid "All" -msgstr "" - #: templates/web/default/reports/index.html:3 msgid "All Reports" msgstr "" @@ -317,10 +285,14 @@ msgstr "" msgid "All confirmed" msgstr "" -#: templates/web/barnet/footer.html:20 templates/web/bromley/footer.html:21 templates/web/bromley/header.html:77 templates/web/default/footer.html:11 templates/web/fiksgatami/footer.html:7 templates/web/fiksgatami/nn/footer.html:7 templates/web/fixmystreet/footer.html:49 templates/web/reading/footer.html:8 +#: templates/web/barnet/footer.html:20 templates/web/bromley/footer.html:21 templates/web/bromley/header.html:77 templates/web/default/footer.html:11 templates/web/fiksgatami/footer.html:7 templates/web/fiksgatami/nn/footer.html:7 templates/web/fixmybarangay/footer.html:20 templates/web/fixmystreet/footer.html:49 templates/web/reading/footer.html:8 msgid "All reports" msgstr "" +#: templates/web/default/admin/stats.html:5 +msgid "All reports between %s and %s" +msgstr "" + #: templates/web/default/report/new/councils_text_some.html:2 msgid "All the information you provide here will be sent to" msgstr "" @@ -377,6 +349,10 @@ msgstr "" msgid "Ban email address" msgstr "" +#: templates/web/fixmybarangay/report/new/notes.html:7 +msgid "Be sure to choose the right category, because we use that to determine to whom the report is sent." +msgstr "" + #: templates/web/fiksgatami/footer.html:16 templates/web/fiksgatami/nn/footer.html:16 msgid "Built by <a href=\"http://www.mysociety.org/\">mySociety</a> and maintained by <a href=\"http://www.nuug.no/\">NUUG</a>" msgstr "" @@ -385,11 +361,11 @@ msgstr "" msgid "By Date" msgstr "" -#: templates/web/fixmystreet/around/display_location.html:80 templates/web/fixmystreet/around/display_location.html:82 +#: templates/web/fixmystreet/around/_report_banner.html:10 templates/web/fixmystreet/around/_report_banner.html:8 msgid "Can't see the map? <a href='%s' rel='nofollow'>Skip this step</a>" msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:632 perllib/FixMyStreet/App/Controller/Report/New.pm:657 templates/web/bromley/report/new/fill_in_details_form.html:68 templates/web/default/admin/council_contacts.html:35 templates/web/default/admin/index.html:36 templates/web/default/admin/list_flagged.html:14 templates/web/default/admin/search_reports.html:17 templates/web/fixmystreet/report/new/fill_in_details_form.html:72 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:633 perllib/FixMyStreet/App/Controller/Report/New.pm:660 templates/web/bromley/report/new/fill_in_details_form.html:68 templates/web/default/admin/council_contacts.html:37 templates/web/default/admin/index.html:36 templates/web/default/admin/list_flagged.html:14 templates/web/default/admin/search_reports.html:17 templates/web/fixmystreet/report/new/fill_in_details_form.html:74 msgid "Category" msgstr "" @@ -397,11 +373,11 @@ msgstr "" msgid "Category fix rate for problems > 4 weeks old" msgstr "" -#: templates/web/default/admin/council_contacts.html:72 templates/web/default/admin/council_edit.html:23 templates/web/default/admin/report_edit.html:25 templates/web/default/report/new/fill_in_details_form.html:67 +#: templates/web/default/admin/council_contacts.html:78 templates/web/default/admin/council_edit.html:23 templates/web/default/admin/report_edit.html:25 templates/web/default/report/new/fill_in_details_form.html:67 msgid "Category:" msgstr "" -#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:334 +#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:336 msgid "Category: %s" msgstr "" @@ -409,19 +385,19 @@ msgstr "" msgid "Change Password" msgstr "" -#: templates/web/fixmystreet/around/display_location.html:72 templates/web/fixmystreet/around/display_location.html:73 +#: templates/web/fixmystreet/around/_report_banner.html:2 msgid "Click map to report a problem" msgstr "" -#: templates/web/bromley/report/display.html:80 templates/web/bromley/report/display.html:82 templates/web/default/admin/report_edit.html:18 templates/web/default/admin/report_edit.html:20 templates/web/default/dashboard/index.html:136 templates/web/default/dashboard/index.html:138 templates/web/default/report/display.html:79 templates/web/default/report/display.html:81 templates/web/fixmystreet/report/banner.html:15 templates/web/fixmystreet/report/display.html:74 templates/web/fixmystreet/report/display.html:76 +#: templates/web/bromley/report/display.html:80 templates/web/bromley/report/display.html:82 templates/web/default/admin/report_edit.html:18 templates/web/default/admin/report_edit.html:20 templates/web/default/dashboard/index.html:138 templates/web/default/dashboard/index.html:140 templates/web/default/report/display.html:79 templates/web/default/report/display.html:81 templates/web/fixmystreet/report/banner.html:15 templates/web/fixmystreet/report/display.html:90 templates/web/fixmystreet/report/display.html:92 msgid "Closed" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:690 +#: perllib/FixMyStreet/DB/Result/Problem.pm:698 msgid "Closed by council" msgstr "" -#: templates/web/default/my/my.html:32 templates/web/fixmystreet/my/my.html:32 +#: templates/web/default/my/my.html:32 templates/web/fixmystreet/my/my.html:36 msgid "Closed reports" msgstr "" @@ -429,7 +405,7 @@ msgstr "" msgid "Closed:" msgstr "" -#: templates/web/default/around/display_location.html:103 templates/web/default/around/display_location.html:105 +#: templates/web/default/around/tabbed_lists.html:10 templates/web/default/around/tabbed_lists.html:12 msgid "Closest nearby problems <small>(within %skm)</small>" msgstr "" @@ -449,23 +425,27 @@ msgstr "" msgid "Cobrand:" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:358 +#: perllib/FixMyStreet/App/Controller/Admin.pm:365 msgid "Configuration updated" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:372 +#: perllib/FixMyStreet/App/Controller/Admin.pm:380 msgid "Configuration updated - contacts will be generated automatically later" msgstr "" -#: templates/web/default/admin/council_contacts.html:153 +#: templates/web/default/admin/council_edit.html:34 +msgid "Configure Endpoint" +msgstr "" + +#: templates/web/default/admin/council_contacts.html:168 msgid "Configure Open311" msgstr "" -#: templates/web/default/admin/council_contacts.html:105 +#: templates/web/default/admin/council_contacts.html:116 msgid "Configure Open311 integration" msgstr "" -#: templates/web/default/admin/council_contacts.html:42 +#: templates/web/default/admin/council_contacts.html:46 msgid "Confirm" msgstr "" @@ -473,14 +453,22 @@ msgstr "" msgid "Confirm account" msgstr "" +#: templates/web/fixmystreet/report/display.html:165 templates/web/fixmystreet/report/new/fill_in_details_form.html:176 +msgid "Confirm by email below, providing a new password at that point. When you confirm, your password will be updated." +msgstr "" + #: templates/web/default/questionnaire/creator_fixed.html:1 templates/web/default/tokens/confirm_problem.html:1 templates/web/default/tokens/confirm_problem.html:3 templates/web/default/tokens/confirm_update.html:1 templates/web/default/tokens/confirm_update.html:3 templates/web/emptyhomes/tokens/confirm_problem.html:1 templates/web/emptyhomes/tokens/confirm_problem.html:3 msgid "Confirmation" msgstr "" -#: templates/web/default/admin/council_contacts.html:37 templates/web/default/admin/council_contacts.html:82 templates/web/default/admin/council_edit.html:28 templates/web/default/admin/council_edit.html:43 templates/web/default/admin/stats.html:5 +#: templates/web/default/admin/council_contacts.html:39 templates/web/default/admin/council_contacts.html:88 templates/web/default/admin/council_edit.html:28 templates/web/default/admin/council_edit.html:71 msgid "Confirmed" msgstr "" +#: templates/web/default/admin/stats.html:5 +msgid "Confirmed reports between %s and %s" +msgstr "" + #: templates/web/default/admin/problem_row.html:23 templates/web/default/admin/report_edit.html:34 msgid "Confirmed:" msgstr "" @@ -501,7 +489,7 @@ msgstr "" msgid "Contact the team" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1150 perllib/FixMyStreet/App/Controller/Admin.pm:1178 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1164 perllib/FixMyStreet/App/Controller/Admin.pm:1192 msgid "Could not find user" msgstr "" @@ -509,7 +497,7 @@ msgstr "" msgid "Council" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1022 templates/web/default/admin/council_list.html:1 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1036 templates/web/default/admin/council_list.html:1 msgid "Council contacts" msgstr "" @@ -533,7 +521,7 @@ msgstr "" msgid "Create a report" msgstr "" -#: templates/web/default/admin/council_contacts.html:96 +#: templates/web/default/admin/council_contacts.html:107 msgid "Create category" msgstr "" @@ -557,11 +545,11 @@ msgstr "" msgid "Dashboard" msgstr "" -#: templates/web/default/admin/council_contacts.html:38 templates/web/default/admin/council_contacts.html:85 templates/web/default/admin/council_edit.html:29 templates/web/default/admin/council_edit.html:44 +#: templates/web/default/admin/council_contacts.html:40 templates/web/default/admin/council_contacts.html:91 templates/web/default/admin/council_edit.html:29 templates/web/default/admin/council_edit.html:72 msgid "Deleted" msgstr "" -#: templates/web/bromley/report/new/fill_in_details_form.html:54 templates/web/fixmystreet/report/new/fill_in_details_form.html:64 +#: templates/web/bromley/report/new/fill_in_details_form.html:54 templates/web/fixmystreet/report/new/fill_in_details_form.html:66 msgid "Details" msgstr "" @@ -569,11 +557,19 @@ msgstr "" msgid "Details:" msgstr "" +#: templates/web/default/admin/council_contacts.html:41 +msgid "Devolved" +msgstr "" + #: templates/web/default/admin/council_list.html:23 msgid "Diligency prize league table" msgstr "" -#: templates/web/default/auth/general.html:32 templates/web/fixmystreet/auth/general.html:29 templates/web/fixmystreet/report/display.html:128 templates/web/fixmystreet/report/new/fill_in_details_form.html:150 +#: templates/web/fixmystreet/auth/general.html:30 +msgid "Do you have a FixMyBarangay password?" +msgstr "" + +#: templates/web/default/auth/general.html:32 templates/web/fixmystreet/auth/general.html:32 templates/web/fixmystreet/report/display.html:144 templates/web/fixmystreet/report/new/fill_in_details_form.html:154 msgid "Do you have a FixMyStreet password?" msgstr "" @@ -597,23 +593,23 @@ msgstr "" msgid "Editing user %d" msgstr "" -#: templates/web/default/admin/council_edit.html:45 +#: templates/web/default/admin/council_edit.html:73 msgid "Editor" msgstr "" -#: templates/web/bromley/report/display.html:126 templates/web/default/admin/council_contacts.html:36 templates/web/default/admin/council_edit.html:42 templates/web/default/admin/list_flagged.html:12 templates/web/default/admin/list_flagged.html:35 templates/web/default/admin/list_updates.html:8 templates/web/default/admin/search_abuse.html:11 templates/web/default/admin/search_reports.html:15 templates/web/default/admin/search_users.html:13 templates/web/fixmystreet/auth/general.html:20 templates/web/fixmystreet/report/display.html:120 +#: templates/web/bromley/report/display.html:126 templates/web/default/admin/council_contacts.html:38 templates/web/default/admin/council_edit.html:70 templates/web/default/admin/list_flagged.html:12 templates/web/default/admin/list_flagged.html:35 templates/web/default/admin/list_updates.html:8 templates/web/default/admin/search_abuse.html:11 templates/web/default/admin/search_reports.html:15 templates/web/default/admin/search_users.html:13 templates/web/fixmystreet/auth/general.html:20 templates/web/fixmystreet/report/display.html:136 msgid "Email" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1126 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1140 msgid "Email added to abuse list" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1123 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1137 msgid "Email already in abuse list" msgstr "" -#: templates/web/default/around/display_location.html:85 +#: templates/web/default/around/_updates.html:5 msgid "Email me new local problems" msgstr "" @@ -621,19 +617,19 @@ msgstr "" msgid "Email me updates" msgstr "" -#: templates/web/default/admin/council_contacts.html:77 templates/web/default/admin/council_edit.html:26 templates/web/default/admin/report_edit.html:31 templates/web/default/admin/update_edit.html:24 templates/web/default/admin/user_edit.html:11 templates/web/default/alert/updates.html:13 templates/web/default/report/display.html:34 +#: templates/web/default/admin/council_contacts.html:83 templates/web/default/admin/council_edit.html:26 templates/web/default/admin/report_edit.html:31 templates/web/default/admin/update_edit.html:24 templates/web/default/admin/user_edit.html:11 templates/web/default/alert/updates.html:13 templates/web/default/report/display.html:34 msgid "Email:" msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:611 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:612 msgid "Empty flat or maisonette" msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:610 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:611 msgid "Empty house or bungalow" msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:613 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:614 msgid "Empty office or other commercial" msgstr "" @@ -641,11 +637,11 @@ msgstr "" msgid "Empty property details form" msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:614 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:615 msgid "Empty pub or bar" msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:615 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:616 msgid "Empty public building - school, hospital, etc." msgstr "" @@ -673,7 +669,7 @@ msgstr "" msgid "Enter a nearby postcode, or street name and area" msgstr "" -#: templates/web/default/around/postcode_form.html:1 templates/web/default/around/postcode_form.html:2 templates/web/fixmystreet/around/postcode_form.html:10 templates/web/fixmystreet/around/postcode_form.html:11 +#: templates/web/default/around/postcode_form.html:1 templates/web/default/around/postcode_form.html:2 templates/web/fixmystreet/around/postcode_form.html:13 templates/web/fixmystreet/around/postcode_form.html:14 msgid "Enter a nearby street name and area" msgstr "" @@ -681,11 +677,11 @@ msgstr "" msgid "Enter a new password:" msgstr "" -#: templates/web/bromley/report/display.html:148 templates/web/bromley/report/new/fill_in_details_form.html:189 templates/web/fixmystreet/auth/general.html:57 templates/web/fixmystreet/report/display.html:160 templates/web/fixmystreet/report/new/fill_in_details_form.html:200 +#: templates/web/bromley/report/display.html:148 templates/web/bromley/report/new/fill_in_details_form.html:189 templates/web/fixmystreet/auth/general.html:61 templates/web/fixmystreet/report/display.html:182 templates/web/fixmystreet/report/new/fill_in_details_form.html:210 msgid "Enter a password" msgstr "" -#: templates/web/default/index.html:33 templates/web/emptyhomes/index.html:58 templates/web/fixmystreet/index.html:41 +#: templates/web/default/index.html:33 templates/web/emptyhomes/index.html:58 templates/web/fixmystreet/index.html:46 msgid "Enter details of the problem" msgstr "" @@ -693,7 +689,7 @@ msgstr "" msgid "Error" msgstr "" -#: templates/web/default/admin/council_contacts.html:11 templates/web/default/admin/council_edit.html:18 +#: templates/web/default/admin/council_contacts.html:13 templates/web/default/admin/council_edit.html:18 msgid "Example postcode %s" msgstr "" @@ -750,7 +746,7 @@ msgid "" "for the county council." msgstr "" -#: templates/web/bromley/report/display.html:80 templates/web/bromley/report/display.html:82 templates/web/default/admin/index.html:36 templates/web/default/admin/report_edit.html:18 templates/web/default/admin/report_edit.html:20 templates/web/default/dashboard/index.html:136 templates/web/default/dashboard/index.html:138 templates/web/default/report/display.html:79 templates/web/default/report/display.html:81 templates/web/fixmystreet/report/banner.html:12 templates/web/fixmystreet/report/display.html:74 templates/web/fixmystreet/report/display.html:76 +#: templates/web/bromley/report/display.html:80 templates/web/bromley/report/display.html:82 templates/web/default/admin/index.html:36 templates/web/default/admin/report_edit.html:18 templates/web/default/admin/report_edit.html:20 templates/web/default/dashboard/index.html:138 templates/web/default/dashboard/index.html:140 templates/web/default/report/display.html:79 templates/web/default/report/display.html:81 templates/web/fixmystreet/report/banner.html:12 templates/web/fixmystreet/report/display.html:90 templates/web/fixmystreet/report/display.html:92 msgid "Fixed" msgstr "" @@ -762,7 +758,7 @@ msgstr "" msgid "Fixed - User" msgstr "" -#: templates/web/default/my/my.html:27 templates/web/fixmystreet/my/my.html:27 +#: templates/web/default/my/my.html:27 templates/web/fixmystreet/my/my.html:31 msgid "Fixed reports" msgstr "" @@ -790,7 +786,11 @@ msgstr "" msgid "For council(s):" msgstr "" -#: templates/web/default/faq/faq-en-gb.html:1 templates/web/emptyhomes/faq/faq-cy.html:1 templates/web/emptyhomes/faq/faq-en-gb.html:1 templates/web/fiksgatami/faq/faq-nb.html:1 templates/web/fiksgatami/nn/faq/faq-nn.html:1 templates/web/fixmystreet/faq/faq-en-gb.html:1 templates/web/fixmystreet/static/privacy.html:1 templates/web/zurich/faq/faq-de.html:1 +#: templates/web/fixmystreet/report/display.html:164 templates/web/fixmystreet/report/new/fill_in_details_form.html:175 +msgid "Forgotten your password?" +msgstr "" + +#: templates/web/default/faq/faq-en-gb.html:1 templates/web/emptyhomes/faq/faq-cy.html:1 templates/web/emptyhomes/faq/faq-en-gb.html:1 templates/web/fiksgatami/faq/faq-nb.html:1 templates/web/fiksgatami/nn/faq/faq-nn.html:1 templates/web/fixmybarangay/faq/faq-en-gb.html:1 templates/web/fixmystreet/faq/faq-en-gb.html:1 templates/web/fixmystreet/static/privacy.html:1 templates/web/zurich/faq/faq-de.html:1 msgid "Frequently Asked Questions" msgstr "" @@ -802,7 +802,7 @@ msgstr "" msgid "GeoRSS on Google Maps" msgstr "" -#: templates/web/bromley/report/display.html:30 templates/web/fixmystreet/report/display.html:23 +#: templates/web/bromley/report/display.html:30 templates/web/fixmystreet/report/display.html:27 msgid "Get updates" msgstr "" @@ -814,11 +814,11 @@ msgstr "" msgid "Get updates of problems in this %s" msgstr "" -#: templates/web/default/alert/_list.html:83 templates/web/fixmystreet/alert/_list.html:82 +#: templates/web/default/alert/_list.html:83 templates/web/fixmybarangay/alert/_list.html:28 templates/web/fixmystreet/alert/_list.html:82 msgid "Give me an RSS feed" msgstr "" -#: templates/web/default/alert/index.html:34 templates/web/default/around/postcode_form.html:8 templates/web/emptyhomes/index.html:47 templates/web/fixmystreet/around/postcode_form.html:18 +#: templates/web/default/alert/index.html:34 templates/web/default/around/postcode_form.html:8 templates/web/emptyhomes/index.html:47 templates/web/fixmystreet/around/postcode_form.html:24 msgid "Go" msgstr "" @@ -842,7 +842,7 @@ msgstr "" msgid "Have you ever reported a problem to a council before, or is this your first time?" msgstr "" -#: templates/web/barnet/footer.html:24 templates/web/bromley/footer.html:25 templates/web/bromley/header.html:81 templates/web/default/footer.html:15 templates/web/emptyhomes/header.html:28 templates/web/fiksgatami/footer.html:9 templates/web/fiksgatami/nn/footer.html:9 templates/web/fixmystreet/footer.html:53 templates/web/reading/footer.html:10 +#: templates/web/barnet/footer.html:24 templates/web/bromley/footer.html:25 templates/web/bromley/header.html:81 templates/web/default/footer.html:15 templates/web/emptyhomes/header.html:28 templates/web/fiksgatami/footer.html:9 templates/web/fiksgatami/nn/footer.html:9 templates/web/fixmybarangay/footer.html:24 templates/web/fixmystreet/footer.html:53 templates/web/reading/footer.html:10 msgid "Help" msgstr "" @@ -850,7 +850,7 @@ msgstr "" msgid "Here are the types of local problem alerts for ‘%s’." msgstr "" -#: templates/web/barnet/header.html:70 templates/web/bromley/header.html:64 templates/web/bromley/header.html:99 templates/web/fixmybarangay/header.html.orig:42 templates/web/fixmystreet/header.html:47 templates/web/zurich/header.html:47 +#: templates/web/barnet/header.html:70 templates/web/bromley/header.html:64 templates/web/bromley/header.html:99 templates/web/fixmybarangay/header.html:66 templates/web/fixmystreet/header.html:47 templates/web/zurich/header.html:47 msgid "Hi %s" msgstr "" @@ -858,15 +858,15 @@ msgstr "" msgid "Hidden" msgstr "" -#: templates/web/default/around/display_location.html:58 templates/web/fixmystreet/around/display_location.html:58 +#: templates/web/default/around/display_location.html:63 msgid "Hide old" msgstr "" -#: templates/web/default/around/display_location.html:53 templates/web/fixmystreet/around/display_location.html:54 +#: templates/web/default/around/display_location.html:58 msgid "Hide pins" msgstr "" -#: templates/web/default/admin/council_edit.html:38 +#: templates/web/default/admin/council_edit.html:66 msgid "History" msgstr "" @@ -874,7 +874,7 @@ msgstr "" msgid "How to report a problem" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:637 +#: perllib/FixMyStreet/App/Controller/Admin.pm:648 msgid "I am afraid you cannot confirm unconfirmed reports." msgstr "" @@ -921,7 +921,7 @@ msgstr "" msgid "Illegal feed selection" msgstr "" -#: templates/web/bromley/report/display.html:80 templates/web/bromley/report/display.html:82 templates/web/default/admin/report_edit.html:18 templates/web/default/admin/report_edit.html:20 templates/web/default/dashboard/index.html:136 templates/web/default/dashboard/index.html:138 templates/web/default/report/display.html:79 templates/web/default/report/display.html:81 templates/web/fixmystreet/report/display.html:74 templates/web/fixmystreet/report/display.html:76 +#: templates/web/bromley/report/display.html:80 templates/web/bromley/report/display.html:82 templates/web/default/admin/report_edit.html:18 templates/web/default/admin/report_edit.html:20 templates/web/default/dashboard/index.html:138 templates/web/default/dashboard/index.html:140 templates/web/default/report/display.html:79 templates/web/default/report/display.html:81 templates/web/fixmystreet/report/display.html:90 templates/web/fixmystreet/report/display.html:92 msgid "In Progress" msgstr "" @@ -945,7 +945,7 @@ msgstr "" msgid "Invalid agency_responsible value %s" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:942 +#: perllib/FixMyStreet/App/Controller/Admin.pm:956 msgid "Invalid end date" msgstr "" @@ -953,11 +953,11 @@ msgstr "" msgid "Invalid format %s specified." msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:932 +#: perllib/FixMyStreet/App/Controller/Admin.pm:946 msgid "Invalid start date" msgstr "" -#: templates/web/bromley/report/display.html:80 templates/web/bromley/report/display.html:81 templates/web/default/admin/report_edit.html:18 templates/web/default/admin/report_edit.html:19 templates/web/default/dashboard/index.html:136 templates/web/default/dashboard/index.html:137 templates/web/default/report/display.html:79 templates/web/default/report/display.html:80 templates/web/fixmystreet/report/display.html:74 templates/web/fixmystreet/report/display.html:75 +#: templates/web/bromley/report/display.html:80 templates/web/bromley/report/display.html:81 templates/web/default/admin/report_edit.html:18 templates/web/default/admin/report_edit.html:19 templates/web/default/dashboard/index.html:138 templates/web/default/dashboard/index.html:139 templates/web/default/report/display.html:79 templates/web/default/report/display.html:80 templates/web/fixmystreet/report/display.html:90 templates/web/fixmystreet/report/display.html:91 msgid "Investigating" msgstr "" @@ -965,7 +965,7 @@ msgstr "" msgid "It is worth noting however that the process can sometimes be slow, especially if the property is in very poor repair or the owner is unwilling to act. In most cases it can take six months or more before you can expect to see anything change and sometimes there may be considerable barries to a property being brought back into use. This doesn’t mean the council isn’t doing anything. We encourage councils to update the website so you can see what is happening. It may be a long process, but you reporting your concerns about this property to the council is a valuable first step." msgstr "" -#: templates/web/bromley/report/display.html:166 templates/web/bromley/report/new/fill_in_details_form.html:209 templates/web/default/auth/general.html:44 templates/web/default/report/display.html:151 templates/web/default/report/new/fill_in_details_form.html:149 templates/web/fixmystreet/auth/general.html:42 templates/web/fixmystreet/report/display.html:144 templates/web/fixmystreet/report/new/fill_in_details_form.html:167 +#: templates/web/bromley/report/display.html:166 templates/web/bromley/report/new/fill_in_details_form.html:209 templates/web/default/auth/general.html:44 templates/web/default/report/display.html:151 templates/web/default/report/new/fill_in_details_form.html:149 templates/web/fixmystreet/auth/general.html:46 templates/web/fixmystreet/report/display.html:160 templates/web/fixmystreet/report/new/fill_in_details_form.html:171 msgid "Keep me signed in on this computer" msgstr "" @@ -973,7 +973,7 @@ msgstr "" msgid "Last Name" msgstr "" -#: templates/web/default/admin/council_contacts.html:39 +#: templates/web/default/admin/council_contacts.html:42 msgid "Last editor" msgstr "" @@ -985,19 +985,19 @@ msgstr "" msgid "Last update:" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1028 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1042 msgid "List Flagged" msgstr "" -#: templates/web/default/admin/council_contacts.html:14 templates/web/default/admin/council_contacts.html:16 +#: templates/web/default/admin/council_contacts.html:16 templates/web/default/admin/council_contacts.html:18 msgid "List all reported problems" msgstr "" -#: templates/web/bromley/report/new/fill_in_details_form.html:69 templates/web/default/report/new/fill_in_details_form.html:68 templates/web/fixmystreet/report/new/fill_in_details_form.html:73 +#: templates/web/bromley/report/new/fill_in_details_form.html:69 templates/web/default/report/new/fill_in_details_form.html:68 templates/web/fixmystreet/report/new/fill_in_details_form.html:75 msgid "Loading..." msgstr "" -#: templates/web/default/alert/choose.html:1 templates/web/default/alert/choose.html:3 templates/web/default/alert/index.html:1 templates/web/default/alert/index.html:3 templates/web/default/alert/list.html:1 templates/web/default/alert/list.html:5 templates/web/default/alert/updates.html:1 templates/web/default/tokens/confirm_alert.html:1 templates/web/default/tokens/confirm_alert.html:3 templates/web/emptyhomes/alert/index.html:1 templates/web/emptyhomes/alert/index.html:3 templates/web/fixmystreet/alert/updates.html:1 +#: templates/web/default/alert/choose.html:1 templates/web/default/alert/choose.html:3 templates/web/default/alert/index.html:1 templates/web/default/alert/index.html:3 templates/web/default/alert/list.html:1 templates/web/default/alert/list.html:5 templates/web/default/alert/updates.html:1 templates/web/default/tokens/confirm_alert.html:1 templates/web/default/tokens/confirm_alert.html:3 templates/web/emptyhomes/alert/index.html:1 templates/web/emptyhomes/alert/index.html:3 templates/web/fixmybarangay/alert/index.html:1 templates/web/fixmybarangay/alert/index.html:3 templates/web/fixmystreet/alert/updates.html:1 msgid "Local RSS feeds and email alerts" msgstr "" @@ -1005,11 +1005,11 @@ msgstr "" msgid "Local RSS feeds and email alerts for ‘%s’" msgstr "" -#: templates/web/barnet/footer.html:22 templates/web/bromley/footer.html:23 templates/web/bromley/header.html:79 templates/web/default/footer.html:13 templates/web/fiksgatami/footer.html:8 templates/web/fiksgatami/nn/footer.html:8 templates/web/fixmystreet/footer.html:51 templates/web/reading/footer.html:9 +#: templates/web/barnet/footer.html:22 templates/web/bromley/footer.html:23 templates/web/bromley/header.html:79 templates/web/default/footer.html:13 templates/web/fiksgatami/footer.html:8 templates/web/fiksgatami/nn/footer.html:8 templates/web/fixmybarangay/footer.html:22 templates/web/fixmystreet/footer.html:51 templates/web/reading/footer.html:9 msgid "Local alerts" msgstr "" -#: templates/web/default/index.html:32 templates/web/emptyhomes/index.html:57 templates/web/fixmystreet/index.html:40 +#: templates/web/default/index.html:32 templates/web/emptyhomes/index.html:57 templates/web/fixmystreet/index.html:45 msgid "Locate the problem on a map of the area" msgstr "" @@ -1037,7 +1037,7 @@ msgstr "" msgid "More problems nearby" msgstr "" -#: templates/web/default/admin/list_flagged.html:11 templates/web/default/admin/list_flagged.html:34 templates/web/default/admin/list_updates.html:7 templates/web/default/admin/search_reports.html:14 templates/web/default/admin/search_users.html:12 templates/web/default/reports/index.html:15 templates/web/emptyhomes/reports/index.html:10 templates/web/fiksgatami/nn/reports/index.html:9 templates/web/fiksgatami/reports/index.html:9 templates/web/fixmystreet/auth/general.html:52 templates/web/fixmystreet/report/display.html:177 templates/web/fixmystreet/report/new/fill_in_details_form.html:117 templates/web/fixmystreet/report/new/fill_in_details_form.html:176 +#: templates/web/default/admin/list_flagged.html:11 templates/web/default/admin/list_flagged.html:34 templates/web/default/admin/list_updates.html:7 templates/web/default/admin/search_reports.html:14 templates/web/default/admin/search_users.html:12 templates/web/default/reports/index.html:15 templates/web/emptyhomes/reports/index.html:10 templates/web/fiksgatami/nn/reports/index.html:9 templates/web/fiksgatami/reports/index.html:9 templates/web/fixmystreet/auth/general.html:56 templates/web/fixmystreet/report/display.html:199 templates/web/fixmystreet/report/new/fill_in_details_form.html:119 templates/web/fixmystreet/report/new/fill_in_details_form.html:186 msgid "Name" msgstr "" @@ -1049,19 +1049,19 @@ msgstr "" msgid "Navigation" msgstr "" -#: perllib/FixMyStreet/Geocode/OSM.pm:159 +#: perllib/FixMyStreet/Geocode/OSM.pm:161 msgid "Nearest named road to the pin placed on the map (automatically generated using OpenStreetMap): %s%s" msgstr "" -#: perllib/FixMyStreet/Cobrand/UK.pm:161 +#: perllib/FixMyStreet/Cobrand/UK.pm:152 msgid "Nearest postcode to the pin placed on the map (automatically generated): %s (%sm away)" msgstr "" -#: perllib/FixMyStreet/Cobrand/Default.pm:404 perllib/FixMyStreet/Cobrand/Default.pm:444 +#: perllib/FixMyStreet/Cobrand/Default.pm:406 perllib/FixMyStreet/Cobrand/Default.pm:446 msgid "Nearest road to the pin placed on the map (automatically generated by Bing Maps): %s" msgstr "" -#: perllib/FixMyStreet/DB/ResultSet/AlertType.pm:245 +#: perllib/FixMyStreet/DB/ResultSet/AlertType.pm:265 msgid "" "Nearest road to the pin placed on the map (automatically generated by Bing Maps): %s\n" "\n" @@ -1075,7 +1075,7 @@ msgstr "" msgid "New <br>problems" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:314 +#: perllib/FixMyStreet/App/Controller/Admin.pm:320 msgid "New category contact added" msgstr "" @@ -1139,7 +1139,7 @@ msgstr "" msgid "New!" msgstr "" -#: templates/web/default/admin/council_contacts.html:48 templates/web/default/admin/council_contacts.html:49 templates/web/default/admin/council_edit.html:4 templates/web/default/admin/list_updates.html:30 templates/web/default/admin/list_updates.html:31 templates/web/default/admin/list_updates.html:32 templates/web/default/admin/problem_row.html:19 templates/web/default/admin/report_edit.html:28 templates/web/default/admin/report_edit.html:41 templates/web/default/admin/update_edit.html:16 templates/web/default/questionnaire/creator_fixed.html:16 templates/web/default/questionnaire/index.html:107 templates/web/default/questionnaire/index.html:68 templates/web/fixmystreet/questionnaire/index.html:101 templates/web/fixmystreet/questionnaire/index.html:62 +#: templates/web/default/admin/council_contacts.html:52 templates/web/default/admin/council_contacts.html:53 templates/web/default/admin/council_contacts.html:54 templates/web/default/admin/council_edit.html:4 templates/web/default/admin/list_updates.html:30 templates/web/default/admin/list_updates.html:31 templates/web/default/admin/list_updates.html:32 templates/web/default/admin/problem_row.html:19 templates/web/default/admin/report_edit.html:28 templates/web/default/admin/report_edit.html:41 templates/web/default/admin/update_edit.html:16 templates/web/default/questionnaire/creator_fixed.html:16 templates/web/default/questionnaire/index.html:107 templates/web/default/questionnaire/index.html:68 templates/web/fixmystreet/questionnaire/index.html:101 templates/web/fixmystreet/questionnaire/index.html:62 msgid "No" msgstr "" @@ -1147,7 +1147,7 @@ msgstr "" msgid "No council" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:328 +#: perllib/FixMyStreet/DB/Result/Problem.pm:336 msgid "No council selected" msgstr "" @@ -1175,6 +1175,14 @@ msgstr "" msgid "No problems have been reported yet." msgstr "" +#: templates/web/fixmystreet/report/_support.html:3 +msgid "No supporters" +msgstr "" + +#: templates/web/default/admin/council_contacts.html:57 +msgid "Non Public" +msgstr "" + #: templates/web/default/admin/council_list.html:5 templates/web/default/admin/report_edit.html:16 msgid "None" msgstr "" @@ -1187,7 +1195,7 @@ msgstr "" msgid "Not reported to council" msgstr "" -#: templates/web/default/admin/council_contacts.html:40 templates/web/default/admin/council_edit.html:46 +#: templates/web/default/admin/council_contacts.html:43 templates/web/default/admin/council_edit.html:74 msgid "Note" msgstr "" @@ -1195,7 +1203,7 @@ msgstr "" msgid "Note that when including unconfirmed reports we use the date the report was created which may not be in the same month the report was confirmed so the numbers may jump about a little" msgstr "" -#: templates/web/default/admin/council_contacts.html:89 templates/web/default/admin/council_edit.html:31 +#: templates/web/default/admin/council_contacts.html:95 templates/web/default/admin/council_edit.html:32 msgid "Note:" msgstr "" @@ -1203,7 +1211,7 @@ msgstr "" msgid "Note: <strong>%s</strong>" msgstr "" -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:149 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:153 msgid "Now to submit your report…" msgstr "" @@ -1211,7 +1219,7 @@ msgstr "" msgid "Now to submit your report… do you have a FixMyStreet password?" msgstr "" -#: templates/web/fixmystreet/report/display.html:127 +#: templates/web/fixmystreet/report/display.html:143 msgid "Now to submit your update…" msgstr "" @@ -1251,11 +1259,11 @@ msgstr "" msgid "Older problems" msgstr "" -#: templates/web/bromley/report/display.html:80 templates/web/default/admin/report_edit.html:18 templates/web/default/admin/update_edit.html:19 templates/web/default/dashboard/index.html:136 templates/web/default/report/display.html:79 templates/web/fixmystreet/report/display.html:74 +#: templates/web/bromley/report/display.html:80 templates/web/default/admin/report_edit.html:18 templates/web/default/admin/update_edit.html:19 templates/web/default/dashboard/index.html:138 templates/web/default/report/display.html:79 templates/web/fixmystreet/report/display.html:90 msgid "Open" msgstr "" -#: templates/web/default/my/my.html:22 templates/web/fixmystreet/my/my.html:22 +#: templates/web/default/my/my.html:22 templates/web/fixmystreet/my/my.html:26 msgid "Open reports" msgstr "" @@ -1279,7 +1287,7 @@ msgstr "" msgid "Or you can subscribe to an alert based upon what ward or council you’re in:" msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:655 perllib/FixMyStreet/App/Controller/Report/New.pm:656 perllib/FixMyStreet/App/Controller/Report/New.pm:999 perllib/FixMyStreet/DB/Result/Problem.pm:497 perllib/FixMyStreet/DB/Result/Problem.pm:507 perllib/FixMyStreet/DB/Result/Problem.pm:517 perllib/FixMyStreet/DB/Result/Problem.pm:529 perllib/FixMyStreet/DB/ResultSet/Problem.pm:329 perllib/FixMyStreet/DB/ResultSet/Problem.pm:338 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:1008 perllib/FixMyStreet/App/Controller/Report/New.pm:658 perllib/FixMyStreet/App/Controller/Report/New.pm:659 perllib/FixMyStreet/DB/Result/Problem.pm:505 perllib/FixMyStreet/DB/Result/Problem.pm:515 perllib/FixMyStreet/DB/Result/Problem.pm:525 perllib/FixMyStreet/DB/Result/Problem.pm:537 perllib/FixMyStreet/DB/ResultSet/Problem.pm:331 perllib/FixMyStreet/DB/ResultSet/Problem.pm:340 msgid "Other" msgstr "" @@ -1299,7 +1307,7 @@ msgstr "" msgid "Partial" msgstr "" -#: templates/web/bromley/report/display.html:145 templates/web/bromley/report/new/fill_in_details_form.html:186 templates/web/fixmystreet/auth/general.html:55 templates/web/fixmystreet/report/display.html:157 templates/web/fixmystreet/report/new/fill_in_details_form.html:197 +#: templates/web/bromley/report/display.html:145 templates/web/bromley/report/new/fill_in_details_form.html:186 templates/web/fixmystreet/auth/general.html:59 templates/web/fixmystreet/report/display.html:179 templates/web/fixmystreet/report/new/fill_in_details_form.html:207 msgid "Password (optional)" msgstr "" @@ -1307,15 +1315,15 @@ msgstr "" msgid "Password:" msgstr "" -#: templates/web/bromley/report/new/fill_in_details_form.html:136 templates/web/bromley/report/new/fill_in_details_form.html:183 templates/web/fixmystreet/report/new/fill_in_details_form.html:133 templates/web/fixmystreet/report/new/fill_in_details_form.html:194 +#: templates/web/bromley/report/new/fill_in_details_form.html:136 templates/web/bromley/report/new/fill_in_details_form.html:183 templates/web/fixmystreet/report/new/fill_in_details_form.html:137 templates/web/fixmystreet/report/new/fill_in_details_form.html:204 msgid "Phone number (optional)" msgstr "" -#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:260 templates/web/default/admin/report_edit.html:32 templates/web/default/report/new/fill_in_details_form.html:215 +#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:262 templates/web/default/admin/report_edit.html:32 templates/web/default/report/new/fill_in_details_form.html:215 msgid "Phone:" msgstr "" -#: templates/web/bromley/report/display.html:109 templates/web/bromley/report/new/fill_in_details_form.html:104 templates/web/fixmystreet/report/display.html:103 templates/web/fixmystreet/report/new/fill_in_details_form.html:108 +#: templates/web/bromley/report/display.html:109 templates/web/bromley/report/new/fill_in_details_form.html:104 templates/web/fixmystreet/report/display.html:119 templates/web/fixmystreet/report/new/fill_in_details_form.html:110 msgid "Photo" msgstr "" @@ -1327,7 +1335,7 @@ msgstr "" msgid "Photos of recent nearby reports" msgstr "" -#: templates/web/bromley/report/display.html:80 templates/web/bromley/report/display.html:81 templates/web/default/admin/report_edit.html:18 templates/web/default/admin/report_edit.html:19 templates/web/default/dashboard/index.html:136 templates/web/default/dashboard/index.html:137 templates/web/default/report/display.html:79 templates/web/default/report/display.html:80 templates/web/fixmystreet/report/display.html:74 templates/web/fixmystreet/report/display.html:75 +#: templates/web/bromley/report/display.html:80 templates/web/bromley/report/display.html:81 templates/web/default/admin/report_edit.html:18 templates/web/default/admin/report_edit.html:19 templates/web/default/dashboard/index.html:138 templates/web/default/dashboard/index.html:139 templates/web/default/report/display.html:79 templates/web/default/report/display.html:80 templates/web/fixmystreet/report/display.html:90 templates/web/fixmystreet/report/display.html:91 msgid "Planned" msgstr "" @@ -1351,11 +1359,11 @@ msgstr "" msgid "Please check your email address is correct" msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:819 perllib/FixMyStreet/App/Controller/Report/New.pm:826 perllib/FixMyStreet/App/Controller/Report/New.pm:845 perllib/FixMyStreet/App/Controller/Report/New.pm:884 perllib/FixMyStreet/DB/Result/Problem.pm:347 templates/web/default/js/validation_strings.html:9 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:824 perllib/FixMyStreet/App/Controller/Report/New.pm:831 perllib/FixMyStreet/App/Controller/Report/New.pm:850 perllib/FixMyStreet/App/Controller/Report/New.pm:893 perllib/FixMyStreet/DB/Result/Problem.pm:355 templates/web/default/js/validation_strings.html:9 msgid "Please choose a category" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:353 +#: perllib/FixMyStreet/DB/Result/Problem.pm:361 msgid "Please choose a property type" msgstr "" @@ -1382,7 +1390,7 @@ msgstr "" msgid "Please enter a password" msgstr "" -#: perllib/FixMyStreet/App/Controller/Contact.pm:97 perllib/FixMyStreet/DB/Result/Problem.pm:322 templates/web/default/js/validation_strings.html:3 +#: perllib/FixMyStreet/App/Controller/Contact.pm:97 perllib/FixMyStreet/DB/Result/Problem.pm:330 templates/web/default/js/validation_strings.html:3 msgid "Please enter a subject" msgstr "" @@ -1394,7 +1402,7 @@ msgstr "" msgid "Please enter a valid email address" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:325 templates/web/default/js/validation_strings.html:4 +#: perllib/FixMyStreet/DB/Result/Problem.pm:333 templates/web/default/js/validation_strings.html:4 msgid "Please enter some details" msgstr "" @@ -1402,7 +1410,7 @@ msgstr "" msgid "Please enter your email" msgstr "" -#: templates/web/bromley/report/new/fill_in_details_form.html:149 templates/web/fixmystreet/report/new/fill_in_details_form.html:146 +#: templates/web/bromley/report/new/fill_in_details_form.html:149 templates/web/fixmystreet/report/new/fill_in_details_form.html:150 msgid "Please enter your email address" msgstr "" @@ -1410,11 +1418,11 @@ msgstr "" msgid "Please enter your first name" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:340 templates/web/default/js/validation_strings.html:7 +#: perllib/FixMyStreet/DB/Result/Problem.pm:348 templates/web/default/js/validation_strings.html:7 msgid "Please enter your full name, councils need this information – if you do not wish your name to be shown on the site, untick the box below" msgstr "" -#: perllib/FixMyStreet/App/Controller/Contact.pm:95 perllib/FixMyStreet/DB/Result/Comment.pm:143 perllib/FixMyStreet/DB/Result/Problem.pm:333 perllib/FixMyStreet/DB/Result/User.pm:97 templates/web/default/js/validation_strings.html:6 +#: perllib/FixMyStreet/App/Controller/Contact.pm:95 perllib/FixMyStreet/DB/Result/Comment.pm:143 perllib/FixMyStreet/DB/Result/Problem.pm:341 perllib/FixMyStreet/DB/Result/User.pm:97 templates/web/default/js/validation_strings.html:6 msgid "Please enter your name" msgstr "" @@ -1436,10 +1444,17 @@ msgid "" "to read, as does a lack of punctuation." msgstr "" -#: templates/web/default/report/new/fill_in_details_text.html:1 templates/web/default/report/new/fill_in_details_text.html:11 templates/web/fixmystreet/report/new/fill_in_details_text.html:1 templates/web/fixmystreet/report/new/fill_in_details_text.html:11 +#: templates/web/default/report/new/fill_in_details_text.html:1 templates/web/default/report/new/fill_in_details_text.html:11 templates/web/fixmybarangay/report/new/fill_in_details_text.html:1 templates/web/fixmybarangay/report/new/fill_in_details_text.html:10 templates/web/fixmystreet/report/new/fill_in_details_text.html:1 templates/web/fixmystreet/report/new/fill_in_details_text.html:11 msgid "Please fill in details of the problem below." msgstr "" +#: templates/web/fixmybarangay/report/new/fill_in_details_text.html:1 templates/web/fixmybarangay/report/new/fill_in_details_text.html:3 +msgid "" +"Please fill in details of the problem below. Leave as much detail as you can, \n" +"and if possible describe the exact location of\n" +"the problem (e.g. if there is a streetlight number or road name)." +msgstr "" + #: templates/web/default/report/new/fill_in_details_text.html:1 templates/web/default/report/new/fill_in_details_text.html:3 msgid "" "Please fill in details of the problem below. The council won't be able\n" @@ -1448,15 +1463,15 @@ msgid "" "photo of the problem if you have one), etc." msgstr "" -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:68 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:70 msgid "Please fill in details of the problem." msgstr "" -#: templates/web/bromley/report/new/fill_in_details_form.html:28 templates/web/default/report/new/fill_in_details_form.html:27 templates/web/fixmystreet/report/new/fill_in_details_form.html:34 +#: templates/web/bromley/report/new/fill_in_details_form.html:28 templates/web/default/report/new/fill_in_details_form.html:27 templates/web/fixmystreet/report/new/fill_in_details_form.html:35 msgid "Please fill in the form below with details of the problem, and describe the location as precisely as possible in the details box." msgstr "" -#: perllib/FixMyStreet/App/Controller/Questionnaire.pm:241 +#: perllib/FixMyStreet/App/Controller/Questionnaire.pm:243 msgid "Please indicate whether you'd like to receive another questionnaire" msgstr "" @@ -1472,23 +1487,23 @@ msgstr "" msgid "Please note that updates are not sent to the relevant department. If you leave your name it will be public. Your information will only be used in accordance with our <a href=\"/faq#privacy\">privacy policy</a>" msgstr "" -#: templates/web/bromley/report/new/fill_in_details_form.html:23 templates/web/default/report/new/fill_in_details_form.html:5 templates/web/fixmystreet/report/new/fill_in_details_form.html:25 +#: templates/web/bromley/report/new/fill_in_details_form.html:23 templates/web/default/report/new/fill_in_details_form.html:5 templates/web/fixmystreet/report/new/fill_in_details_form.html:26 msgid "Please note your report has <strong>not yet been sent</strong>. Choose a category and add further information below, then submit." msgstr "" -#: templates/web/default/report/new/notes.html:1 templates/web/fixmystreet/report/new/notes.html:1 +#: templates/web/default/report/new/notes.html:1 templates/web/fixmybarangay/report/new/notes.html:1 templates/web/fixmystreet/report/new/notes.html:1 msgid "Please note:" msgstr "" -#: perllib/FixMyStreet/App/Controller/Questionnaire.pm:244 +#: perllib/FixMyStreet/App/Controller/Questionnaire.pm:246 msgid "Please provide some explanation as to why you're reopening this report" msgstr "" -#: perllib/FixMyStreet/App/Controller/Questionnaire.pm:251 +#: perllib/FixMyStreet/App/Controller/Questionnaire.pm:253 msgid "Please provide some text as well as a photo" msgstr "" -#: perllib/FixMyStreet/App/Controller/Questionnaire.pm:116 perllib/FixMyStreet/App/Controller/Questionnaire.pm:237 +#: perllib/FixMyStreet/App/Controller/Questionnaire.pm:116 perllib/FixMyStreet/App/Controller/Questionnaire.pm:239 msgid "Please say whether you've ever reported a problem to your council before" msgstr "" @@ -1500,7 +1515,7 @@ msgstr "" msgid "Please select the type of alert you want" msgstr "" -#: perllib/FixMyStreet/App/Controller/Questionnaire.pm:233 +#: perllib/FixMyStreet/App/Controller/Questionnaire.pm:235 msgid "Please state whether or not the problem has been fixed" msgstr "" @@ -1508,11 +1523,11 @@ msgstr "" msgid "Please take a look at the updates that have been left." msgstr "" -#: perllib/FixMyStreet/App/Controller/Photo.pm:176 +#: perllib/FixMyStreet/App/Controller/Photo.pm:175 msgid "Please upload a JPEG image only" msgstr "" -#: perllib/FixMyStreet/App/Controller/Photo.pm:183 +#: perllib/FixMyStreet/App/Controller/Photo.pm:182 msgid "Please upload a JPEG image only\n" msgstr "" @@ -1520,11 +1535,11 @@ msgstr "" msgid "Please write a message" msgstr "" -#: templates/web/bromley/report/display.html:70 templates/web/fixmystreet/report/display.html:69 +#: templates/web/bromley/report/display.html:70 templates/web/fixmystreet/report/display.html:85 msgid "Please write your update here" msgstr "" -#: templates/web/bromley/report/display.html:121 templates/web/bromley/report/display.html:149 templates/web/bromley/report/display.html:161 templates/web/default/contact/index.html:93 templates/web/default/report/display.html:119 templates/web/default/report/display.html:156 templates/web/default/report/display.html:178 templates/web/fixmystreet/contact/index.html:93 templates/web/fixmystreet/report/display.html:115 templates/web/fixmystreet/report/display.html:139 templates/web/fixmystreet/report/display.html:161 +#: templates/web/bromley/report/display.html:121 templates/web/bromley/report/display.html:149 templates/web/bromley/report/display.html:161 templates/web/default/contact/index.html:93 templates/web/default/report/display.html:119 templates/web/default/report/display.html:156 templates/web/default/report/display.html:178 templates/web/fixmystreet/contact/index.html:93 templates/web/fixmystreet/report/display.html:131 templates/web/fixmystreet/report/display.html:155 templates/web/fixmystreet/report/display.html:183 msgid "Post" msgstr "" @@ -1540,6 +1555,10 @@ msgstr "" msgid "Posted by %s at %s" msgstr "" +#: templates/web/default/admin/council_contacts.html:100 templates/web/default/admin/council_edit.html:30 templates/web/default/admin/report_edit.html:43 +msgid "Private" +msgstr "" + #: templates/web/default/maps/openlayers.html:85 msgid "Problem" msgstr "" @@ -1560,7 +1579,7 @@ msgstr "" msgid "Problem breakdown by state" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:819 +#: perllib/FixMyStreet/App/Controller/Admin.pm:833 msgid "Problem marked as open." msgstr "" @@ -1572,15 +1591,15 @@ msgstr "" msgid "Problems" msgstr "" -#: templates/web/default/around/display_location.html:81 +#: templates/web/default/around/_updates.html:1 msgid "Problems in this area" msgstr "" -#: templates/web/bromley/report/display.html:31 templates/web/fixmystreet/around/display_location.html:98 templates/web/fixmystreet/report/display.html:24 +#: templates/web/bromley/report/display.html:31 templates/web/fixmystreet/around/tabbed_lists.html:4 templates/web/fixmystreet/report/display.html:31 msgid "Problems nearby" msgstr "" -#: templates/web/fixmystreet/around/display_location.html:97 +#: templates/web/fixmystreet/around/tabbed_lists.html:3 msgid "Problems on the map" msgstr "" @@ -1592,11 +1611,11 @@ msgstr "" msgid "Problems within %.1fkm of this location" msgstr "" -#: perllib/FixMyStreet/Cobrand/Default.pm:609 perllib/FixMyStreet/Cobrand/EmptyHomes.pm:95 perllib/FixMyStreet/Cobrand/FiksGataMi.pm:162 perllib/FixMyStreet/Cobrand/UK.pm:240 +#: perllib/FixMyStreet/Cobrand/Default.pm:611 perllib/FixMyStreet/Cobrand/EmptyHomes.pm:95 perllib/FixMyStreet/Cobrand/FiksGataMi.pm:162 perllib/FixMyStreet/Cobrand/UK.pm:231 msgid "Problems within %s" msgstr "" -#: perllib/FixMyStreet/Cobrand/EmptyHomes.pm:103 perllib/FixMyStreet/Cobrand/UK.pm:254 +#: perllib/FixMyStreet/Cobrand/EmptyHomes.pm:103 perllib/FixMyStreet/Cobrand/UK.pm:245 msgid "Problems within %s ward" msgstr "" @@ -1604,7 +1623,7 @@ msgstr "" msgid "Problems within %s, FixMyStreet" msgstr "" -#: templates/web/default/alert/_list.html:40 templates/web/fixmystreet/alert/_list.html:42 +#: templates/web/default/alert/_list.html:40 templates/web/fixmybarangay/alert/_list.html:13 templates/web/fixmystreet/alert/_list.html:42 msgid "Problems within the boundary of:" msgstr "" @@ -1612,15 +1631,15 @@ msgstr "" msgid "Properties recently reported as put back to use on reportemptyhomes.com" msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:617 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:618 msgid "Property type:" msgstr "" -#: templates/web/bromley/report/new/fill_in_details_form.html:52 templates/web/fixmystreet/report/new/fill_in_details_form.html:62 +#: templates/web/bromley/report/new/fill_in_details_form.html:52 templates/web/fixmystreet/report/new/fill_in_details_form.html:64 msgid "Provide a title" msgstr "" -#: templates/web/bromley/report/display.html:57 templates/web/default/report/display.html:51 templates/web/fixmystreet/report/display.html:50 +#: templates/web/bromley/report/display.html:57 templates/web/default/report/display.html:51 templates/web/fixmystreet/report/display.html:66 msgid "Provide an update" msgstr "" @@ -1628,10 +1647,14 @@ msgstr "" msgid "Providing a password is optional, but doing so will allow you to more easily report future problems, leave updates and manage your reports." msgstr "" -#: templates/web/bromley/report/display.html:142 templates/web/default/report/display.html:175 templates/web/default/report/new/fill_in_details_form.html:173 templates/web/fixmystreet/report/display.html:154 templates/web/fixmystreet/report/new/fill_in_details_form.html:191 +#: templates/web/bromley/report/display.html:142 templates/web/default/report/display.html:175 templates/web/default/report/new/fill_in_details_form.html:173 templates/web/fixmystreet/report/display.html:176 templates/web/fixmystreet/report/new/fill_in_details_form.html:201 msgid "Providing a password is optional, but doing so will allow you to more easily report problems, leave updates and manage your reports." msgstr "" +#: templates/web/default/admin/council_contacts.html:44 templates/web/default/admin/council_contacts.html:57 +msgid "Public" +msgstr "" + #: templates/web/default/questionnaire/completed.html:1 templates/web/default/questionnaire/completed.html:2 templates/web/default/questionnaire/index.html:0 templates/web/default/questionnaire/index.html:14 templates/web/default/questionnaire/index.html:4 templates/web/fixmystreet/questionnaire/index.html:0 templates/web/fixmystreet/questionnaire/index.html:14 templates/web/fixmystreet/questionnaire/index.html:32 templates/web/fixmystreet/questionnaire/index.html:4 msgid "Questionnaire" msgstr "" @@ -1644,27 +1667,27 @@ msgstr "" msgid "Questionnaire %d sent for problem %d" msgstr "" -#: perllib/FixMyStreet/App/Controller/Questionnaire.pm:190 +#: perllib/FixMyStreet/App/Controller/Questionnaire.pm:192 msgid "Questionnaire filled in by problem reporter" msgstr "" -#: templates/web/bromley/report/display.html:37 templates/web/default/alert/_list.html:21 templates/web/default/around/display_location.html:1 templates/web/default/around/display_location.html:3 templates/web/default/report/display.html:42 templates/web/default/reports/_rss.html:1 templates/web/fixmystreet/alert/_list.html:22 templates/web/fixmystreet/alert/updates.html:9 templates/web/fixmystreet/around/display_location.html:1 templates/web/fixmystreet/around/display_location.html:3 templates/web/fixmystreet/report/display.html:30 +#: templates/web/bromley/report/display.html:37 templates/web/default/alert/_list.html:21 templates/web/default/around/display_location.html:1 templates/web/default/around/display_location.html:3 templates/web/default/report/display.html:42 templates/web/default/reports/_rss.html:1 templates/web/fixmystreet/alert/_list.html:22 templates/web/fixmystreet/alert/updates.html:9 templates/web/fixmystreet/report/display.html:45 msgid "RSS feed" msgstr "" -#: perllib/FixMyStreet/Cobrand/UK.pm:283 perllib/FixMyStreet/Cobrand/UK.pm:295 +#: perllib/FixMyStreet/Cobrand/UK.pm:274 perllib/FixMyStreet/Cobrand/UK.pm:286 msgid "RSS feed for %s" msgstr "" -#: perllib/FixMyStreet/Cobrand/UK.pm:289 perllib/FixMyStreet/Cobrand/UK.pm:301 +#: perllib/FixMyStreet/Cobrand/UK.pm:280 perllib/FixMyStreet/Cobrand/UK.pm:292 msgid "RSS feed for %s ward, %s" msgstr "" -#: perllib/FixMyStreet/Cobrand/FiksGataMi.pm:178 perllib/FixMyStreet/Cobrand/FiksGataMi.pm:186 perllib/FixMyStreet/Cobrand/FiksGataMi.pm:196 perllib/FixMyStreet/Cobrand/FiksGataMi.pm:204 perllib/FixMyStreet/Cobrand/UK.pm:309 perllib/FixMyStreet/Cobrand/UK.pm:321 +#: perllib/FixMyStreet/Cobrand/FiksGataMi.pm:178 perllib/FixMyStreet/Cobrand/FiksGataMi.pm:186 perllib/FixMyStreet/Cobrand/FiksGataMi.pm:196 perllib/FixMyStreet/Cobrand/FiksGataMi.pm:204 perllib/FixMyStreet/Cobrand/UK.pm:300 perllib/FixMyStreet/Cobrand/UK.pm:312 msgid "RSS feed of %s" msgstr "" -#: perllib/FixMyStreet/Cobrand/UK.pm:314 perllib/FixMyStreet/Cobrand/UK.pm:326 +#: perllib/FixMyStreet/Cobrand/UK.pm:305 perllib/FixMyStreet/Cobrand/UK.pm:317 msgid "RSS feed of %s, within %s ward" msgstr "" @@ -1676,27 +1699,27 @@ msgstr "" msgid "RSS feed of problems in this %s" msgstr "" -#: perllib/FixMyStreet/Cobrand/Default.pm:610 perllib/FixMyStreet/Cobrand/EmptyHomes.pm:96 perllib/FixMyStreet/Cobrand/FiksGataMi.pm:161 perllib/FixMyStreet/Cobrand/UK.pm:247 +#: perllib/FixMyStreet/Cobrand/Default.pm:612 perllib/FixMyStreet/Cobrand/EmptyHomes.pm:96 perllib/FixMyStreet/Cobrand/FiksGataMi.pm:161 perllib/FixMyStreet/Cobrand/UK.pm:238 msgid "RSS feed of problems within %s" msgstr "" -#: perllib/FixMyStreet/Cobrand/EmptyHomes.pm:102 perllib/FixMyStreet/Cobrand/UK.pm:253 +#: perllib/FixMyStreet/Cobrand/EmptyHomes.pm:102 perllib/FixMyStreet/Cobrand/UK.pm:244 msgid "RSS feed of problems within %s ward" msgstr "" -#: templates/web/default/around/display_location.html:1 templates/web/default/around/display_location.html:4 templates/web/fixmystreet/around/display_location.html:1 templates/web/fixmystreet/around/display_location.html:4 +#: templates/web/default/around/display_location.html:1 templates/web/default/around/display_location.html:4 msgid "RSS feed of recent local problems" msgstr "" -#: templates/web/bromley/report/display.html:37 templates/web/default/report/display.html:42 templates/web/fixmystreet/alert/updates.html:9 templates/web/fixmystreet/report/display.html:30 +#: templates/web/bromley/report/display.html:37 templates/web/default/report/display.html:42 templates/web/fixmystreet/alert/updates.html:9 templates/web/fixmystreet/report/display.html:45 msgid "RSS feed of updates to this problem" msgstr "" -#: templates/web/bromley/report/display.html:39 templates/web/default/alert/updates.html:9 templates/web/default/report/display.html:33 templates/web/fixmystreet/alert/updates.html:14 templates/web/fixmystreet/report/display.html:32 +#: templates/web/bromley/report/display.html:39 templates/web/default/alert/updates.html:9 templates/web/default/report/display.html:33 templates/web/fixmystreet/alert/updates.html:14 templates/web/fixmystreet/report/display.html:47 msgid "Receive email when updates are left on this problem." msgstr "" -#: templates/web/default/around/display_location.html:0 templates/web/default/around/display_location.html:34 templates/web/fixmystreet/around/display_location.html:0 templates/web/fixmystreet/around/display_location.html:34 +#: templates/web/default/around/display_location.html:0 templates/web/default/around/display_location.html:34 msgid "Recent local problems, FixMyStreet" msgstr "" @@ -1708,7 +1731,7 @@ msgstr "" msgid "Recently fixed" msgstr "" -#: templates/web/default/index.html:50 templates/web/fixmystreet/index.html:62 +#: templates/web/default/index.html:50 templates/web/fixmystreet/index.html:68 msgid "Recently reported problems" msgstr "" @@ -1716,11 +1739,15 @@ msgstr "" msgid "Remember that FixMyStreet is primarily for reporting physical problems that can be fixed. If your problem is not appropriate for submission via this site remember that you can contact your council directly using their own website." msgstr "" +#: templates/web/fixmybarangay/report/new/notes.html:9 +msgid "Remember that, for the pilot project, FixMyBarangay is only for reporting potholes and streetlights in bgy. Luz or Basak San Nicolas." +msgstr "" + #: templates/web/default/admin/report_blocks.html:16 msgid "Remove flag" msgstr "" -#: templates/web/default/admin/report_edit.html:53 templates/web/default/admin/update_edit.html:48 +#: templates/web/default/admin/report_edit.html:54 templates/web/default/admin/update_edit.html:48 msgid "Remove photo (can't be undone!)" msgstr "" @@ -1732,7 +1759,7 @@ msgstr "" msgid "Report a problem" msgstr "" -#: templates/web/bromley/report/display.html:28 templates/web/fixmystreet/report/display.html:22 +#: templates/web/bromley/report/display.html:28 templates/web/fixmystreet/report/display.html:26 msgid "Report abuse" msgstr "" @@ -1744,7 +1771,7 @@ msgstr "" msgid "Report on %s" msgstr "" -#: templates/web/default/index.html:15 templates/web/fixmystreet/around/postcode_form.html:6 +#: templates/web/default/index.html:15 templates/web/fixmystreet/around/postcode_form.html:9 msgid "Report, view, or discuss local problems" msgstr "" @@ -1756,7 +1783,7 @@ msgstr "" msgid "Reported %s, to %s" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:512 templates/web/default/contact/index.html:45 templates/web/fixmystreet/contact/index.html:46 +#: perllib/FixMyStreet/DB/Result/Problem.pm:520 templates/web/default/contact/index.html:45 templates/web/fixmystreet/contact/index.html:46 msgid "Reported anonymously at %s" msgstr "" @@ -1764,31 +1791,31 @@ msgstr "" msgid "Reported before" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:504 +#: perllib/FixMyStreet/DB/Result/Problem.pm:512 msgid "Reported by %s anonymously at %s" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:535 templates/web/default/contact/index.html:47 templates/web/fixmystreet/contact/index.html:48 +#: perllib/FixMyStreet/DB/Result/Problem.pm:543 templates/web/default/contact/index.html:47 templates/web/fixmystreet/contact/index.html:48 msgid "Reported by %s at %s" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:526 +#: perllib/FixMyStreet/DB/Result/Problem.pm:534 msgid "Reported by %s by %s at %s" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:500 +#: perllib/FixMyStreet/DB/Result/Problem.pm:508 msgid "Reported by %s in the %s category anonymously at %s" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:520 +#: perllib/FixMyStreet/DB/Result/Problem.pm:528 msgid "Reported by %s in the %s category by %s at %s" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:508 +#: perllib/FixMyStreet/DB/Result/Problem.pm:516 msgid "Reported in the %s category anonymously at %s" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:530 +#: perllib/FixMyStreet/DB/Result/Problem.pm:538 msgid "Reported in the %s category by %s at %s" msgstr "" @@ -1796,7 +1823,7 @@ msgstr "" msgid "Reporting a problem" msgstr "" -#: templates/web/default/around/display_location.html:95 +#: templates/web/default/around/tabbed_lists.html:3 msgid "Reports on and around the map" msgstr "" @@ -1804,19 +1831,19 @@ msgstr "" msgid "Resend report" msgstr "" -#: perllib/FixMyStreet/Geocode/OSM.pm:166 +#: perllib/FixMyStreet/Geocode/OSM.pm:168 msgid "Road operator for this named road (derived from road reference number and type): %s" msgstr "" -#: perllib/FixMyStreet/Geocode/OSM.pm:163 +#: perllib/FixMyStreet/Geocode/OSM.pm:165 msgid "Road operator for this named road (from OpenStreetMap): %s" msgstr "" -#: templates/web/default/admin/council_edit.html:35 +#: templates/web/default/admin/council_edit.html:63 msgid "Save changes" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1027 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1041 msgid "Search Abuse" msgstr "" @@ -1824,11 +1851,11 @@ msgstr "" msgid "Search Abuse Table" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1023 templates/web/default/admin/list_flagged.html:1 templates/web/default/admin/search_reports.html:1 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1037 templates/web/default/admin/list_flagged.html:1 templates/web/default/admin/search_reports.html:1 msgid "Search Reports" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1026 templates/web/default/admin/search_users.html:1 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1040 templates/web/default/admin/search_users.html:1 msgid "Search Users" msgstr "" @@ -1840,7 +1867,7 @@ msgstr "" msgid "Select which type of alert you'd like and click the button for an RSS feed, or enter your email address to subscribe to an email alert." msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:618 +#: perllib/FixMyStreet/DB/Result/Problem.pm:626 msgid "Sent to %s %s later" msgstr "" @@ -1852,6 +1879,10 @@ msgstr "" msgid "Service:" msgstr "" +#: templates/web/fixmystreet/report/display.html:29 +msgid "Share" +msgstr "" + #: templates/web/emptyhomes/static/about.html:21 msgid "Shelter Cymru" msgstr "" @@ -1869,19 +1900,19 @@ msgid "" " significant contribution to the supply of affordable homes in Wales." msgstr "" -#: templates/web/bromley/report/display.html:203 templates/web/bromley/report/new/fill_in_details_form.html:129 templates/web/bromley/report/new/fill_in_details_form.html:175 templates/web/default/report/display.html:208 templates/web/default/report/new/fill_in_details_form.html:210 templates/web/fixmystreet/report/display.html:185 templates/web/fixmystreet/report/new/fill_in_details_form.html:126 templates/web/fixmystreet/report/new/fill_in_details_form.html:186 +#: templates/web/bromley/report/display.html:203 templates/web/bromley/report/new/fill_in_details_form.html:129 templates/web/bromley/report/new/fill_in_details_form.html:175 templates/web/default/report/display.html:208 templates/web/default/report/new/fill_in_details_form.html:210 templates/web/fixmystreet/report/display.html:207 templates/web/fixmystreet/report/new/fill_in_details_form.html:128 templates/web/fixmystreet/report/new/fill_in_details_form.html:196 msgid "Show my name publicly" msgstr "" -#: templates/web/default/around/display_location.html:60 templates/web/fixmystreet/around/display_location.html:60 +#: templates/web/default/around/display_location.html:65 msgid "Show old" msgstr "" -#: templates/web/default/around/display_location.html:51 templates/web/fixmystreet/around/display_location.html:52 +#: templates/web/default/around/display_location.html:56 msgid "Show pins" msgstr "" -#: templates/web/default/auth/general.html:3 templates/web/default/auth/general.html:49 templates/web/fixmybarangay/header.html.orig:46 templates/web/fixmystreet/auth/general.html:3 templates/web/fixmystreet/auth/general.html:38 templates/web/fixmystreet/auth/general.html:58 templates/web/fixmystreet/header.html:51 templates/web/zurich/header.html:51 +#: templates/web/default/auth/general.html:3 templates/web/default/auth/general.html:49 templates/web/fixmybarangay/header.html:70 templates/web/fixmystreet/auth/general.html:3 templates/web/fixmystreet/auth/general.html:42 templates/web/fixmystreet/auth/general.html:62 templates/web/fixmystreet/header.html:51 templates/web/zurich/header.html:51 msgid "Sign in" msgstr "" @@ -1901,11 +1932,11 @@ msgstr "" msgid "Signed in as %s" msgstr "" -#: templates/web/default/report/new/fill_in_details_text.html:1 templates/web/fixmystreet/report/new/fill_in_details_text.html:1 +#: templates/web/default/report/new/fill_in_details_text.html:1 templates/web/fixmybarangay/report/new/fill_in_details_text.html:1 templates/web/fixmystreet/report/new/fill_in_details_text.html:1 msgid "Some categories may require additional information." msgstr "" -#: templates/web/default/alert/index.html:42 +#: templates/web/default/alert/index.html:42 templates/web/fixmybarangay/alert/index.html:32 msgid "Some photos of recent reports" msgstr "" @@ -1917,7 +1948,7 @@ msgstr "" msgid "Some unconfirmeds" msgstr "" -#: perllib/FixMyStreet/Cobrand/UK.pm:97 +#: perllib/FixMyStreet/Cobrand/UK.pm:89 msgid "Sorry, that appears to be a Crown dependency postcode, which we don't cover." msgstr "" @@ -1925,11 +1956,11 @@ msgstr "" msgid "Sorry, there has been an error confirming your problem." msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:214 perllib/FixMyStreet/Geocode.pm:27 perllib/FixMyStreet/Geocode/Bing.pm:51 perllib/FixMyStreet/Geocode/Google.pm:69 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:213 perllib/FixMyStreet/Geocode.pm:27 perllib/FixMyStreet/Geocode/Bing.pm:51 perllib/FixMyStreet/Geocode/Google.pm:69 perllib/FixMyStreet/Geocode/OSM.pm:61 msgid "Sorry, we could not find that location." msgstr "" -#: perllib/FixMyStreet/Geocode/Bing.pm:46 perllib/FixMyStreet/Geocode/Google.pm:64 perllib/FixMyStreet/Geocode/OSM.pm:59 +#: perllib/FixMyStreet/Geocode/Bing.pm:46 perllib/FixMyStreet/Geocode/Google.pm:64 msgid "Sorry, we could not parse that location. Please try again." msgstr "" @@ -1949,7 +1980,7 @@ msgstr "" msgid "Start month:" msgstr "" -#: templates/web/bromley/report/display.html:78 templates/web/default/admin/list_flagged.html:18 templates/web/default/admin/list_updates.html:6 templates/web/default/admin/search_reports.html:21 templates/web/fixmystreet/report/display.html:72 +#: templates/web/bromley/report/display.html:78 templates/web/default/admin/list_flagged.html:18 templates/web/default/admin/list_updates.html:6 templates/web/default/admin/search_reports.html:21 templates/web/fixmystreet/report/display.html:88 msgid "State" msgstr "" @@ -1957,7 +1988,7 @@ msgstr "" msgid "State:" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1029 templates/web/default/admin/stats.html:1 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1043 templates/web/default/admin/stats.html:1 msgid "Stats" msgstr "" @@ -1965,7 +1996,7 @@ msgstr "" msgid "Still open, via questionnaire, %s" msgstr "" -#: templates/web/bromley/report/new/fill_in_details_form.html:48 templates/web/fixmystreet/contact/index.html:79 templates/web/fixmystreet/report/new/fill_in_details_form.html:58 +#: templates/web/bromley/report/new/fill_in_details_form.html:48 templates/web/fixmystreet/contact/index.html:79 templates/web/fixmystreet/report/new/fill_in_details_form.html:60 msgid "Subject" msgstr "" @@ -1973,11 +2004,11 @@ msgstr "" msgid "Subject:" msgstr "" -#: templates/web/bromley/report/new/fill_in_details_form.html:140 templates/web/bromley/report/new/fill_in_details_form.html:190 templates/web/bromley/report/new/fill_in_details_form.html:204 templates/web/default/questionnaire/creator_fixed.html:19 templates/web/default/report/new/fill_in_details_form.html:114 templates/web/default/report/new/fill_in_details_form.html:154 templates/web/default/report/new/fill_in_details_form.html:176 templates/web/fixmystreet/report/new/fill_in_details_form.html:137 templates/web/fixmystreet/report/new/fill_in_details_form.html:162 templates/web/fixmystreet/report/new/fill_in_details_form.html:201 +#: templates/web/bromley/report/new/fill_in_details_form.html:140 templates/web/bromley/report/new/fill_in_details_form.html:190 templates/web/bromley/report/new/fill_in_details_form.html:204 templates/web/default/questionnaire/creator_fixed.html:19 templates/web/default/report/new/fill_in_details_form.html:114 templates/web/default/report/new/fill_in_details_form.html:154 templates/web/default/report/new/fill_in_details_form.html:176 templates/web/fixmystreet/report/new/fill_in_details_form.html:141 templates/web/fixmystreet/report/new/fill_in_details_form.html:166 templates/web/fixmystreet/report/new/fill_in_details_form.html:211 msgid "Submit" msgstr "" -#: templates/web/default/admin/report_edit.html:56 templates/web/default/admin/update_edit.html:51 templates/web/default/admin/user_edit.html:20 +#: templates/web/default/admin/report_edit.html:57 templates/web/default/admin/update_edit.html:51 templates/web/default/admin/user_edit.html:20 msgid "Submit changes" msgstr "" @@ -1985,15 +2016,19 @@ msgstr "" msgid "Submit questionnaire" msgstr "" -#: templates/web/bromley/report/display.html:44 templates/web/default/alert/updates.html:17 templates/web/default/report/display.html:38 templates/web/fixmystreet/alert/updates.html:23 templates/web/fixmystreet/report/display.html:37 +#: templates/web/bromley/report/display.html:44 templates/web/default/alert/updates.html:17 templates/web/default/report/display.html:38 templates/web/fixmystreet/alert/updates.html:23 templates/web/fixmystreet/report/display.html:52 msgid "Subscribe" msgstr "" -#: templates/web/default/alert/_list.html:97 templates/web/fixmystreet/alert/_list.html:92 +#: templates/web/default/alert/_list.html:97 templates/web/fixmybarangay/alert/_list.html:42 templates/web/fixmystreet/alert/_list.html:92 msgid "Subscribe me to an email alert" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1021 templates/web/default/admin/index.html:1 +#: templates/web/fixmybarangay/alert/_list.html:6 +msgid "Subscribe to an alert based upon what baranagay you’re in:" +msgstr "" + +#: perllib/FixMyStreet/App/Controller/Admin.pm:1035 templates/web/default/admin/index.html:1 msgid "Summary" msgstr "" @@ -2001,7 +2036,7 @@ msgstr "" msgid "Summary reports" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1025 templates/web/default/admin/questionnaire.html:1 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1039 templates/web/default/admin/questionnaire.html:1 msgid "Survey Results" msgstr "" @@ -2009,7 +2044,7 @@ msgstr "" msgid "Text" msgstr "" -#: templates/web/default/admin/council_contacts.html:18 +#: templates/web/default/admin/council_contacts.html:20 msgid "Text only version" msgstr "" @@ -2057,7 +2092,7 @@ msgstr "" msgid "Thanks, glad to hear it's been fixed! Could we just ask if you have ever reported a problem to a council before?" msgstr "" -#: perllib/FixMyStreet/App/Controller/Photo.pm:190 +#: perllib/FixMyStreet/App/Controller/Photo.pm:189 msgid "That image doesn't appear to have uploaded correctly (%s), please try again." msgstr "" @@ -2065,19 +2100,23 @@ msgstr "" msgid "That location does not appear to be covered by a council; perhaps it is offshore or outside the country. Please try again." msgstr "" -#: perllib/FixMyStreet/App/Controller/Location.pm:107 +#: perllib/FixMyStreet/App/Controller/Location.pm:120 msgid "That location does not appear to be in the UK; please try again." msgstr "" -#: perllib/FixMyStreet/Cobrand/FiksGataMi.pm:63 perllib/FixMyStreet/Cobrand/UK.pm:90 +#: perllib/FixMyStreet/Cobrand/FiksGataMi.pm:63 perllib/FixMyStreet/Cobrand/UK.pm:82 msgid "That postcode was not recognised, sorry." msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:605 +#: perllib/FixMyStreet/App/Controller/Admin.pm:616 msgid "That problem will now be resent." msgstr "" -#: perllib/FixMyStreet/App/Controller/Report.pm:75 +#: perllib/FixMyStreet/App/Controller/Report.pm:98 +msgid "That report cannot be viewed on FixMyStreet." +msgstr "" + +#: perllib/FixMyStreet/App/Controller/Report.pm:92 msgid "That report has been removed from FixMyStreet." msgstr "" @@ -2120,7 +2159,7 @@ msgstr "" msgid "The details of your problem are available on the right hand side of this page." msgstr "" -#: perllib/FixMyStreet/App/Controller/Dashboard.pm:60 perllib/FixMyStreet/App/Controller/Reports.pm:44 perllib/FixMyStreet/App/Controller/Reports.pm:75 +#: perllib/FixMyStreet/App/Controller/Dashboard.pm:60 perllib/FixMyStreet/App/Controller/Reports.pm:43 perllib/FixMyStreet/App/Controller/Reports.pm:74 msgid "The error was: %s" msgstr "" @@ -2128,7 +2167,7 @@ msgstr "" msgid "The following Open311 v2 attributes are returned for each request: service_request_id, description, lat, long, media_url, status, requested_datetime, updated_datetime, service_code and service_name." msgstr "" -#: perllib/FixMyStreet/Geocode/OSM.pm:158 +#: perllib/FixMyStreet/Geocode/OSM.pm:160 msgid "The following information about the nearest road might be inaccurate or irrelevant, if the problem is close to several roads or close to a road without a name registered in OpenStreetMap." msgstr "" @@ -2192,11 +2231,11 @@ msgstr "" msgid "The subject and details of the problem will be public, plus your name if you give us permission." msgstr "" -#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:269 +#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:271 msgid "The user could not locate the problem on a map, but to see the area around the location they entered" msgstr "" -#: perllib/FixMyStreet/App/Controller/Reports.pm:72 +#: perllib/FixMyStreet/App/Controller/Reports.pm:71 msgid "There was a problem showing the All Reports page. Please try again later." msgstr "" @@ -2204,7 +2243,7 @@ msgstr "" msgid "There was a problem showing this page. Please try again later." msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:733 perllib/FixMyStreet/App/Controller/Report/Update.pm:130 templates/web/default/auth/general.html:23 templates/web/fixmystreet/auth/general.html:24 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:738 perllib/FixMyStreet/App/Controller/Report/Update.pm:134 templates/web/default/auth/general.html:23 templates/web/fixmystreet/auth/general.html:24 msgid "There was a problem with your email/password combination. If you cannot remember your password, or do not have one, please fill in the ‘sign in by email’ section of the form." msgstr "" @@ -2212,7 +2251,7 @@ msgstr "" msgid "There was a problem with your email/password combination. Please try again." msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/Update.pm:252 +#: perllib/FixMyStreet/App/Controller/Report/Update.pm:256 msgid "There was a problem with your update. Please try again." msgstr "" @@ -2220,7 +2259,7 @@ msgstr "" msgid "There were problems with your report. Please see below." msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/Update.pm:279 +#: perllib/FixMyStreet/App/Controller/Report/Update.pm:283 msgid "There were problems with your update. Please see below." msgstr "" @@ -2228,15 +2267,15 @@ msgstr "" msgid "This API implementation is work in progress and not yet stabilized. It will change without warnings in the future." msgstr "" -#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:339 +#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:341 msgid "This email has been sent to both councils covering the location of the problem, as the user did not categorise it; please ignore it if you're not the correct council to deal with the issue, or let us know what category of problem this is so we can add it to our system." msgstr "" -#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:342 +#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:344 msgid "This email has been sent to several councils covering the location of the problem, as the category selected is provided for all of them; please ignore it if you're not the correct council to deal with the issue." msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:865 perllib/FixMyStreet/Cobrand/UK.pm:62 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:870 perllib/FixMyStreet/Cobrand/UK.pm:54 msgid "This information is required" msgstr "" @@ -2260,11 +2299,11 @@ msgstr "" msgid "This problem has been closed" msgstr "" -#: templates/web/bromley/report/display.html:96 templates/web/default/report/banner.html:12 templates/web/default/report/display.html:95 templates/web/emptyhomes/report/display.html:12 templates/web/fixmystreet/report/display.html:90 +#: templates/web/bromley/report/display.html:96 templates/web/default/report/banner.html:12 templates/web/default/report/display.html:95 templates/web/emptyhomes/report/display.html:12 templates/web/fixmystreet/report/display.html:106 msgid "This problem has been fixed" msgstr "" -#: templates/web/bromley/report/display.html:90 templates/web/default/report/display.html:90 templates/web/fixmystreet/report/display.html:84 +#: templates/web/bromley/report/display.html:90 templates/web/default/report/display.html:90 templates/web/fixmystreet/report/display.html:100 msgid "This problem has not been fixed" msgstr "" @@ -2276,23 +2315,23 @@ msgstr "" msgid "This problem is old and of unknown status." msgstr "" -#: perllib/FixMyStreet/DB/ResultSet/AlertType.pm:83 +#: perllib/FixMyStreet/DB/ResultSet/AlertType.pm:86 msgid "This report is currently marked as closed." msgstr "" -#: perllib/FixMyStreet/DB/ResultSet/AlertType.pm:81 +#: perllib/FixMyStreet/DB/ResultSet/AlertType.pm:84 msgid "This report is currently marked as fixed." msgstr "" -#: perllib/FixMyStreet/DB/ResultSet/AlertType.pm:85 +#: perllib/FixMyStreet/DB/ResultSet/AlertType.pm:88 msgid "This report is currently marked as open." msgstr "" -#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:262 +#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:264 msgid "This web page also contains a photo of the problem, provided by the user." msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1024 templates/web/default/admin/timeline.html:1 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1038 templates/web/default/admin/timeline.html:1 msgid "Timeline" msgstr "" @@ -2300,7 +2339,7 @@ msgstr "" msgid "Title" msgstr "" -#: templates/web/default/around/display_location.html:69 +#: templates/web/default/around/_report_banner.html:2 msgid "To <strong>report a problem</strong>, click on the map at the correct location." msgstr "" @@ -2312,7 +2351,7 @@ msgstr "" msgid "To find out what local alerts we have for you, please enter your postcode or street name and area" msgstr "" -#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:268 +#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:270 msgid "To view a map of the precise location of this issue" msgstr "" @@ -2320,7 +2359,7 @@ msgstr "" msgid "Total" msgstr "" -#: perllib/FixMyStreet/App/Controller/Reports.pm:43 +#: perllib/FixMyStreet/App/Controller/Reports.pm:42 msgid "Unable to look up areas in MaPit. Please try again later." msgstr "" @@ -2336,11 +2375,11 @@ msgstr "" msgid "Unknown alert type" msgstr "" -#: perllib/FixMyStreet/App/Controller/Report.pm:70 +#: perllib/FixMyStreet/App/Controller/Report.pm:87 msgid "Unknown problem ID" msgstr "" -#: templates/web/bromley/report/display.html:66 templates/web/fixmystreet/report/display.html:65 +#: templates/web/bromley/report/display.html:66 templates/web/fixmystreet/report/display.html:81 msgid "Update" msgstr "" @@ -2376,7 +2415,7 @@ msgstr "" msgid "Update reopened problem" msgstr "" -#: templates/web/default/admin/council_contacts.html:62 +#: templates/web/default/admin/council_contacts.html:68 msgid "Update statuses" msgstr "" @@ -2384,7 +2423,7 @@ msgstr "" msgid "Update:" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:694 perllib/FixMyStreet/App/Controller/Admin.pm:809 perllib/FixMyStreet/App/Controller/Admin.pm:889 +#: perllib/FixMyStreet/App/Controller/Admin.pm:708 perllib/FixMyStreet/App/Controller/Admin.pm:823 perllib/FixMyStreet/App/Controller/Admin.pm:903 msgid "Updated!" msgstr "" @@ -2400,11 +2439,11 @@ msgstr "" msgid "Updates to this problem, FixMyStreet" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1182 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1196 msgid "User flag removed" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1154 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1168 msgid "User flagged" msgstr "" @@ -2412,7 +2451,7 @@ msgstr "" msgid "Users" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:309 perllib/FixMyStreet/App/Controller/Admin.pm:339 +#: perllib/FixMyStreet/App/Controller/Admin.pm:315 perllib/FixMyStreet/App/Controller/Admin.pm:345 msgid "Values updated" msgstr "" @@ -2428,11 +2467,11 @@ msgstr "" msgid "View your report" msgstr "" -#: templates/web/default/around/display_location.html:0 templates/web/default/around/display_location.html:33 templates/web/emptyhomes/around/display_location.html:0 templates/web/emptyhomes/around/display_location.html:16 templates/web/fixmystreet/around/display_location.html:0 templates/web/fixmystreet/around/display_location.html:33 +#: templates/web/default/around/display_location.html:0 templates/web/default/around/display_location.html:33 templates/web/emptyhomes/around/display_location.html:0 templates/web/emptyhomes/around/display_location.html:16 msgid "Viewing a location" msgstr "" -#: templates/web/bromley/report/display.html:0 templates/web/default/report/display.html:0 templates/web/emptyhomes/report/display.html:2 templates/web/fixmystreet/report/display.html:0 +#: templates/web/bromley/report/display.html:0 templates/web/default/report/display.html:0 templates/web/emptyhomes/report/display.html:1 templates/web/emptyhomes/report/display.html:2 templates/web/fixmystreet/report/display.html:0 msgid "Viewing a problem" msgstr "" @@ -2452,23 +2491,23 @@ msgstr "" msgid "We may contact you periodically to ask if anything has changed with the property you reported." msgstr "" -#: templates/web/bromley/report/display.html:141 templates/web/fixmystreet/report/display.html:153 +#: templates/web/bromley/report/display.html:141 templates/web/fixmystreet/report/display.html:175 msgid "We never show your email" msgstr "" -#: templates/web/bromley/report/new/fill_in_details_form.html:133 templates/web/bromley/report/new/fill_in_details_form.html:179 templates/web/fixmystreet/report/new/fill_in_details_form.html:130 templates/web/fixmystreet/report/new/fill_in_details_form.html:190 +#: templates/web/bromley/report/new/fill_in_details_form.html:133 templates/web/bromley/report/new/fill_in_details_form.html:179 templates/web/fixmystreet/report/new/fill_in_details_form.html:133 templates/web/fixmystreet/report/new/fill_in_details_form.html:200 msgid "We never show your email address or phone number." msgstr "" -#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:349 +#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:351 msgid "We realise this problem might be the responsibility of %s; however, we don't currently have any contact details for them. If you know of an appropriate contact address, please do get in touch." msgstr "" -#: templates/web/default/index.html:34 templates/web/emptyhomes/index.html:59 templates/web/fixmystreet/index.html:45 +#: templates/web/default/index.html:34 templates/web/emptyhomes/index.html:59 templates/web/fixmystreet/index.html:50 msgid "We send it to the council on your behalf" msgstr "" -#: templates/web/bromley/report/new/fill_in_details_form.html:217 templates/web/default/report/new/notes.html:5 +#: templates/web/bromley/report/new/fill_in_details_form.html:217 templates/web/default/report/new/notes.html:5 templates/web/fixmybarangay/report/new/notes.html:5 msgid "We will only use your personal information in accordance with our <a href=\"/faq#privacy\">privacy policy.</a>" msgstr "" @@ -2484,7 +2523,7 @@ msgstr "" msgid "We'd love to hear what you think about this site. Just fill in the form, or send an email to <a href='mailto:%s'>%s</a>:" msgstr "" -#: templates/web/default/admin/council_contacts.html:41 templates/web/default/admin/council_edit.html:41 +#: templates/web/default/admin/council_contacts.html:45 templates/web/default/admin/council_edit.html:69 msgid "When edited" msgstr "" @@ -2492,7 +2531,7 @@ msgstr "" msgid "When sent" msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:612 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:613 msgid "Whole block of empty flats" msgstr "" @@ -2512,7 +2551,7 @@ msgstr "" msgid "Would you like to receive another questionnaire in 4 weeks, reminding you to check the status?" msgstr "" -#: templates/web/default/report/new/notes.html:8 templates/web/fixmystreet/report/new/notes.html:7 +#: templates/web/default/report/new/notes.html:8 templates/web/fixmybarangay/report/new/notes.html:8 templates/web/fixmystreet/report/new/notes.html:7 msgid "Writing your message entirely in block capitals makes it hard to read, as does a lack of punctuation." msgstr "" @@ -2520,11 +2559,11 @@ msgstr "" msgid "Year" msgstr "" -#: templates/web/default/admin/council_contacts.html:48 templates/web/default/admin/council_contacts.html:49 templates/web/default/admin/council_edit.html:5 templates/web/default/admin/list_updates.html:30 templates/web/default/admin/list_updates.html:31 templates/web/default/admin/list_updates.html:32 templates/web/default/admin/problem_row.html:19 templates/web/default/admin/report_edit.html:27 templates/web/default/admin/report_edit.html:41 templates/web/default/admin/search_users.html:23 templates/web/default/admin/update_edit.html:15 templates/web/default/questionnaire/creator_fixed.html:14 templates/web/default/questionnaire/index.html:105 templates/web/default/questionnaire/index.html:66 templates/web/fixmystreet/questionnaire/index.html:60 templates/web/fixmystreet/questionnaire/index.html:99 +#: templates/web/default/admin/council_contacts.html:52 templates/web/default/admin/council_contacts.html:53 templates/web/default/admin/council_contacts.html:54 templates/web/default/admin/council_edit.html:5 templates/web/default/admin/list_updates.html:30 templates/web/default/admin/list_updates.html:31 templates/web/default/admin/list_updates.html:32 templates/web/default/admin/problem_row.html:19 templates/web/default/admin/report_edit.html:27 templates/web/default/admin/report_edit.html:41 templates/web/default/admin/search_users.html:23 templates/web/default/admin/update_edit.html:15 templates/web/default/questionnaire/creator_fixed.html:14 templates/web/default/questionnaire/index.html:105 templates/web/default/questionnaire/index.html:66 templates/web/fixmystreet/questionnaire/index.html:60 templates/web/fixmystreet/questionnaire/index.html:99 msgid "Yes" msgstr "" -#: templates/web/bromley/report/display.html:155 templates/web/bromley/report/new/fill_in_details_form.html:198 templates/web/fixmystreet/report/display.html:133 templates/web/fixmystreet/report/new/fill_in_details_form.html:156 +#: templates/web/bromley/report/display.html:155 templates/web/bromley/report/new/fill_in_details_form.html:198 templates/web/fixmystreet/report/display.html:149 templates/web/fixmystreet/report/new/fill_in_details_form.html:160 msgid "Yes I have a password" msgstr "" @@ -2552,11 +2591,11 @@ msgstr "" msgid "You have already answered this questionnaire. If you have a question, please <a href='%s'>get in touch</a>, or <a href='%s'>view your problem</a>.\n" msgstr "" -#: templates/web/bromley/report/new/fill_in_details_form.html:97 templates/web/default/questionnaire/index.html:92 templates/web/default/report/new/fill_in_details_form.html:93 templates/web/fixmystreet/questionnaire/index.html:87 templates/web/fixmystreet/report/new/fill_in_details_form.html:101 +#: templates/web/bromley/report/new/fill_in_details_form.html:97 templates/web/default/questionnaire/index.html:92 templates/web/default/report/new/fill_in_details_form.html:93 templates/web/fixmystreet/questionnaire/index.html:87 templates/web/fixmystreet/report/new/fill_in_details_form.html:103 msgid "You have already attached a photo to this report, attaching another one will replace it." msgstr "" -#: templates/web/bromley/report/display.html:106 templates/web/default/report/display.html:106 templates/web/fixmystreet/report/display.html:100 +#: templates/web/bromley/report/display.html:106 templates/web/default/report/display.html:106 templates/web/fixmystreet/report/display.html:116 msgid "You have already attached a photo to this update, attaching another one will replace it." msgstr "" @@ -2564,7 +2603,7 @@ msgstr "" msgid "You have been signed out" msgstr "" -#: templates/web/bromley/report/new/fill_in_details_form.html:25 templates/web/default/report/new/fill_in_details_form.html:7 templates/web/fixmystreet/report/new/fill_in_details_form.html:27 +#: templates/web/bromley/report/new/fill_in_details_form.html:25 templates/web/default/report/new/fill_in_details_form.html:7 templates/web/fixmystreet/report/new/fill_in_details_form.html:28 msgid "You have located the problem at the point marked with a green pin on the map. If this is not the correct location, simply click on the map again. " msgstr "" @@ -2588,7 +2627,7 @@ msgstr "" msgid "You have successfully deleted your alert." msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:740 perllib/FixMyStreet/App/Controller/Report/Update.pm:136 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:745 perllib/FixMyStreet/App/Controller/Report/Update.pm:140 msgid "You have successfully signed in; please check and confirm your details are accurate:" msgstr "" @@ -2604,11 +2643,11 @@ msgstr "" msgid "Your Reports" msgstr "" -#: templates/web/bromley/report/display.html:41 templates/web/bromley/report/display.html:43 templates/web/bromley/report/new/fill_in_details_form.html:145 templates/web/fixmystreet/alert/_list.html:89 templates/web/fixmystreet/alert/updates.html:19 templates/web/fixmystreet/alert/updates.html:22 templates/web/fixmystreet/contact/index.html:72 templates/web/fixmystreet/report/display.html:34 templates/web/fixmystreet/report/display.html:36 templates/web/fixmystreet/report/new/fill_in_details_form.html:142 +#: templates/web/bromley/report/display.html:41 templates/web/bromley/report/display.html:43 templates/web/bromley/report/new/fill_in_details_form.html:145 templates/web/fixmystreet/alert/_list.html:89 templates/web/fixmystreet/alert/updates.html:19 templates/web/fixmystreet/alert/updates.html:22 templates/web/fixmystreet/contact/index.html:72 templates/web/fixmystreet/report/display.html:49 templates/web/fixmystreet/report/display.html:51 templates/web/fixmystreet/report/new/fill_in_details_form.html:146 msgid "Your email" msgstr "" -#: templates/web/bromley/report/display.html:130 templates/web/fixmystreet/auth/general.html:26 templates/web/fixmystreet/report/display.html:124 +#: templates/web/bromley/report/display.html:130 templates/web/fixmystreet/auth/general.html:26 templates/web/fixmystreet/report/display.html:140 msgid "Your email address" msgstr "" @@ -2616,7 +2655,7 @@ msgstr "" msgid "Your email address:" msgstr "" -#: templates/web/default/alert/_list.html:92 templates/web/default/report/display.html:128 templates/web/default/report/new/fill_in_details_form.html:124 +#: templates/web/default/alert/_list.html:92 templates/web/default/report/display.html:128 templates/web/default/report/new/fill_in_details_form.html:124 templates/web/fixmybarangay/alert/_list.html:37 msgid "Your email:" msgstr "" @@ -2632,7 +2671,7 @@ msgstr "" msgid "Your last name" msgstr "" -#: templates/web/fixmystreet/auth/general.html:53 templates/web/fixmystreet/contact/index.html:65 templates/web/fixmystreet/report/display.html:181 templates/web/fixmystreet/report/new/fill_in_details_form.html:121 templates/web/fixmystreet/report/new/fill_in_details_form.html:181 +#: templates/web/fixmystreet/auth/general.html:57 templates/web/fixmystreet/contact/index.html:65 templates/web/fixmystreet/report/display.html:203 templates/web/fixmystreet/report/new/fill_in_details_form.html:123 templates/web/fixmystreet/report/new/fill_in_details_form.html:191 msgid "Your name" msgstr "" @@ -2640,7 +2679,7 @@ msgstr "" msgid "Your name:" msgstr "" -#: templates/web/bromley/report/display.html:160 templates/web/bromley/report/new/fill_in_details_form.html:203 templates/web/fixmystreet/auth/general.html:37 templates/web/fixmystreet/report/display.html:138 templates/web/fixmystreet/report/new/fill_in_details_form.html:161 +#: templates/web/bromley/report/display.html:160 templates/web/bromley/report/new/fill_in_details_form.html:203 templates/web/fixmystreet/auth/general.html:41 templates/web/fixmystreet/report/display.html:154 templates/web/fixmystreet/report/new/fill_in_details_form.html:165 msgid "Your password" msgstr "" @@ -2648,7 +2687,7 @@ msgstr "" msgid "Your password has been changed" msgstr "" -#: templates/web/bromley/report/new/fill_in_details_form.html:137 templates/web/bromley/report/new/fill_in_details_form.html:184 templates/web/fixmystreet/report/new/fill_in_details_form.html:134 templates/web/fixmystreet/report/new/fill_in_details_form.html:195 +#: templates/web/bromley/report/new/fill_in_details_form.html:137 templates/web/bromley/report/new/fill_in_details_form.html:184 templates/web/fixmystreet/report/new/fill_in_details_form.html:138 templates/web/fixmystreet/report/new/fill_in_details_form.html:205 msgid "Your phone number" msgstr "" @@ -2660,7 +2699,7 @@ msgstr "" msgid "Your reports" msgstr "" -#: templates/web/default/my/my.html:45 templates/web/fixmystreet/my/my.html:45 +#: templates/web/default/my/my.html:45 templates/web/fixmystreet/my/my.html:49 msgid "Your updates" msgstr "" @@ -2676,11 +2715,15 @@ msgstr "" msgid "council" msgstr "" +#: perllib/FixMyStreet/DB/Result/Problem.pm:611 +msgid "council ref: %s" +msgstr "" + #: templates/web/default/admin/report_edit.html:15 msgid "didn't use map" msgstr "" -#: templates/web/default/alert/index.html:33 templates/web/fixmystreet/around/postcode_form.html:17 +#: templates/web/default/alert/index.html:33 templates/web/fixmystreet/around/postcode_form.html:23 msgid "e.g. ‘%s’ or ‘%s’" msgstr "" @@ -2688,7 +2731,7 @@ msgstr "" msgid "from %d different users" msgstr "" -#: perllib/Utils.pm:289 +#: perllib/Utils.pm:295 msgid "less than a minute" msgstr "" @@ -2700,11 +2743,11 @@ msgstr "" msgid "marked as fixed" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:112 templates/web/default/admin/questionnaire.html:15 templates/web/default/admin/questionnaire.html:16 +#: perllib/FixMyStreet/App/Controller/Admin.pm:113 templates/web/default/admin/questionnaire.html:15 templates/web/default/admin/questionnaire.html:16 msgid "n/a" msgstr "" -#: templates/web/default/alert/_list.html:87 templates/web/fixmystreet/alert/_list.html:85 +#: templates/web/default/alert/_list.html:87 templates/web/fixmybarangay/alert/_list.html:32 templates/web/fixmystreet/alert/_list.html:85 msgid "or" msgstr "" @@ -2720,7 +2763,7 @@ msgstr "" msgid "reopened" msgstr "" -#: templates/web/barnet/header.html:71 templates/web/bromley/header.html:100 templates/web/bromley/header.html:65 templates/web/fixmybarangay/header.html.orig:43 templates/web/fixmystreet/header.html:48 templates/web/zurich/header.html:48 +#: templates/web/barnet/header.html:71 templates/web/bromley/header.html:100 templates/web/bromley/header.html:65 templates/web/fixmybarangay/header.html:67 templates/web/fixmystreet/header.html:48 templates/web/zurich/header.html:48 msgid "sign out" msgstr "" @@ -2728,19 +2771,15 @@ msgstr "" msgid "the local council" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:541 -msgid "the map was not used so pin location may be inaccurate" +#: perllib/FixMyStreet/DB/Result/Problem.pm:549 +msgid "there is no pin shown as the user did not use the map" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:603 -msgid "their ref: %s" -msgstr "" - -#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:330 +#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:332 msgid "this type of local problem" msgstr "" -#: perllib/Utils.pm:263 +#: perllib/Utils.pm:269 msgid "today" msgstr "" @@ -2784,21 +2823,49 @@ msgstr "" msgid "your update will not be posted" msgstr "" -#: templates/web/emptyhomes/report/new/councils_text_none.html:3 +#: templates/web/default/front/stats.html:17 +#, perl-format +msgid "<big>%s</big> report recently" +msgid_plural "<big>%s</big> reports recently" +msgstr[0] "" +msgstr[1] "" + +#: perllib/Utils.pm:314 +#, perl-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "" +msgstr[1] "" + +#: perllib/Utils.pm:316 +#, perl-format +msgid "%d minute" +msgid_plural "%d minutes" +msgstr[0] "" +msgstr[1] "" + +#: templates/web/default/front/stats.html:29 +#, perl-format +msgid "<big>%s</big> update on reports" +msgid_plural "<big>%s</big> updates on reports" +msgstr[0] "" +msgstr[1] "" + +#: templates/web/default/report/new/councils_text_none.html:5 #, perl-format msgid "We do not yet have details for the council that covers this location." msgid_plural "We do not yet have details for the councils that cover this location." msgstr[0] "" msgstr[1] "" -#: templates/web/emptyhomes/front/stats.html:17 +#: perllib/Utils.pm:310 #, perl-format -msgid "<big>%s</big> report recently" -msgid_plural "<big>%s</big> reports recently" +msgid "%d week" +msgid_plural "%d weeks" msgstr[0] "" msgstr[1] "" -#: templates/web/emptyhomes/front/stats.html:12 +#: templates/web/default/front/stats.html:12 #, perl-format msgid "<big>%s</big> report in past week" msgid_plural "<big>%s</big> reports in past week" @@ -2819,9 +2886,9 @@ msgid_plural "We do <strong>not</strong> yet have details for the other councils msgstr[0] "" msgstr[1] "" -#: templates/web/default/front/stats.html:29 +#: perllib/Utils.pm:312 #, perl-format -msgid "<big>%s</big> update on reports" -msgid_plural "<big>%s</big> updates on reports" +msgid "%d day" +msgid_plural "%d days" msgstr[0] "" msgstr[1] "" diff --git a/locale/de_DE.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/de_DE.UTF-8/LC_MESSAGES/FixMyStreet.po index dd68c3694..32ee690a6 100644 --- a/locale/de_DE.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/de_DE.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -1,23 +1,23 @@ # Copyright (C) 2011 UK Citizens Online Democracy # This file is distributed under the same license as the main FixMyStreet code. -# Matthew Somerville <matthew@mysociety.org>, 2011-06-03. +# Matthew Somerville <matthew@mysociety.org>, 2011-06-03. # msgid "" msgstr "" "Project-Id-Version: 1.0\n" "Report-Msgid-Bugs-To: matthew@mysociety.org\n" -"POT-Creation-Date: 2012-08-21 09:54+0100\n" -"PO-Revision-Date: 2012-08-21 09:08+0100\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" -"Language-Team: LANGUAGE <team@fixmystreet.com>\n" +"POT-Creation-Date: 2012-10-24 11:20+0100\n" +"PO-Revision-Date: 2012-08-21 14:03+0100\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <team@fixmystreet.com>\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -#: perllib/FixMyStreet/DB/Result/Problem.pm:555 -#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:337 +#: perllib/FixMyStreet/DB/Result/Problem.pm:563 +#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:339 msgid " and " msgstr "und" @@ -50,49 +50,21 @@ msgstr "" msgid "%d council contacts – %d confirmed, %d unconfirmed" msgstr "" -#: perllib/Utils.pm:293 -msgid "%d day" -msgstr "%d Tag" - -#: perllib/Utils.pm:293 -msgid "%d days" -msgstr "%d Tage" - #: templates/web/default/admin/council_list.html:27 msgid "%d edits by %s" msgstr "" -#: perllib/Utils.pm:294 -msgid "%d hour" -msgstr "%d Stunde" - -#: perllib/Utils.pm:294 -msgid "%d hours" -msgstr "%d Stunden" - #: templates/web/default/admin/index.html:16 msgid "%d live updates" msgstr "" -#: perllib/Utils.pm:295 -msgid "%d minute" -msgstr "%d Minute" - -#: perllib/Utils.pm:295 -msgid "%d minutes" -msgstr "%d Minuten" - #: templates/web/default/admin/index.html:18 msgid "%d questionnaires sent – %d answered (%s%%)" msgstr "" -#: perllib/Utils.pm:292 -msgid "%d week" -msgstr "%d Woche" - -#: perllib/Utils.pm:292 -msgid "%d weeks" -msgstr "%d Wochen" +#: templates/web/fixmystreet/report/_support.html:3 +msgid "%d supporters" +msgstr "" #: templates/web/default/reports/council.html:0 #: templates/web/default/reports/council.html:26 @@ -101,30 +73,26 @@ msgstr "%d Wochen" msgid "%s - Summary reports" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:605 +#: perllib/FixMyStreet/DB/Result/Problem.pm:613 msgid "%s ref: %s" msgstr "" -#: perllib/FixMyStreet/Cobrand/UK.pm:288 perllib/FixMyStreet/Cobrand/UK.pm:300 +#: perllib/FixMyStreet/Cobrand/UK.pm:279 perllib/FixMyStreet/Cobrand/UK.pm:291 msgid "%s ward, %s" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:488 +#: perllib/FixMyStreet/DB/Result/Problem.pm:496 msgid "%s, reported anonymously at %s" msgstr "%s anonym gemeldet um %s" -#: perllib/FixMyStreet/DB/Result/Problem.pm:490 +#: perllib/FixMyStreet/DB/Result/Problem.pm:498 msgid "%s, reported by %s at %s" msgstr "" -#: perllib/FixMyStreet/Cobrand/UK.pm:315 perllib/FixMyStreet/Cobrand/UK.pm:327 +#: perllib/FixMyStreet/Cobrand/UK.pm:306 perllib/FixMyStreet/Cobrand/UK.pm:318 msgid "%s, within %s ward" msgstr "" -#: templates/web/default/admin/stats.html:5 -msgid "%sreports between %s and %s" -msgstr "" - #: templates/web/default/email_sent.html:28 msgid "(Don't worry — %s)" msgstr "" @@ -157,7 +125,7 @@ msgid "(fixed)" msgstr "(gelöst)" #: templates/web/default/index.html:12 templates/web/default/index.html:8 -#: templates/web/fixmystreet/around/postcode_form.html:7 +#: templates/web/fixmystreet/around/postcode_form.html:10 msgid "(like graffiti, fly tipping, broken paving slabs, or street lighting)" msgstr "(z.B. illegale Deponien, Strassenschäden, Graffitis usw.)" @@ -183,25 +151,32 @@ msgstr "(ihre eMail-Adresse oder Telefonnummer werden nie angezeigt)" msgid "(we never show your email)" msgstr "(ihre eMail-Adresse wird nie angezeigt)" -#: perllib/FixMyStreet/App/Controller/Admin.pm:284 +#: perllib/FixMyStreet/App/Controller/Admin.pm:285 msgid "*unknown*" msgstr "*unbekannt*" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:629 -#: perllib/FixMyStreet/App/Controller/Report/New.pm:655 -#: perllib/FixMyStreet/DB/Result/Problem.pm:345 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:630 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:658 +#: perllib/FixMyStreet/DB/Result/Problem.pm:353 msgid "-- Pick a category --" msgstr "-- Wählen Sie eine Kategorie --" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:609 -#: perllib/FixMyStreet/DB/Result/Problem.pm:351 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:610 +#: perllib/FixMyStreet/DB/Result/Problem.pm:359 msgid "-- Pick a property type --" msgstr "" #: templates/web/default/tokens/confirm_problem.html:14 #: templates/web/default/tokens/confirm_problem.html:22 +#, fuzzy msgid ". You can <a href=\"%s%s\">view the problem on this site</a>." msgstr "" +"Danke &mdash; Sie können Ihre aktualisierte Meldung <a href=\"%s" +"\">auf der Webseite anschauen</a>" + +#: templates/web/fixmystreet/report/_support.html:3 +msgid "1 supporter" +msgstr "" #: templates/web/default/questionnaire/completed.html:20 msgid "" @@ -285,58 +260,52 @@ msgid "" "site and leave an update.</p>" msgstr "" -#: templates/web/default/around/display_location.html:70 -#: templates/web/default/around/display_location.html:72 +#: templates/web/default/around/_report_banner.html:3 +#: templates/web/default/around/_report_banner.html:5 #: templates/web/emptyhomes/around/display_location.html:36 #: templates/web/emptyhomes/around/display_location.html:38 -#, fuzzy msgid "" "<small>If you cannot see the map, <a href='%s' rel='nofollow'>skip this " "step</a>.</small>" msgstr "" -"Karte nicht sichtbar? <a href='%s' rel='nofollow'>Überspringen " -"Sie diesen Schritt</a>.</small>" +"Karte nicht sichtbar? <a href='%s' rel='nofollow'>Überspringen Sie " +"diesen Schritt</a>.</small>" #: templates/web/default/admin/index.html:14 msgid "<strong>%d</strong> live problems" msgstr "" -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:172 -#, fuzzy +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:182 msgid "<strong>No</strong> Let me confirm my report by email" msgstr "Meldung per eMail bestätigen" -#: templates/web/fixmystreet/report/display.html:148 -#, fuzzy +#: templates/web/fixmystreet/report/display.html:170 msgid "<strong>No</strong> Let me confirm my update by email" -msgstr "Meldung per eMail bestätigen" +msgstr "" -#: templates/web/fixmystreet/auth/general.html:46 -#, fuzzy +#: templates/web/fixmystreet/auth/general.html:50 msgid "<strong>No</strong> let me sign in by email" -msgstr "Meldung per eMail bestätigen" +msgstr "" #: templates/web/default/auth/general.html:55 msgid "<strong>No</strong>, I do not, let me sign in by email:" msgstr "" #: templates/web/default/report/new/fill_in_details_form.html:162 -#, fuzzy msgid "<strong>No</strong>, let me confirm my report by email:" -msgstr "Meldung per eMail bestätigen" +msgstr "" #: templates/web/default/report/display.html:164 -#, fuzzy msgid "<strong>No</strong>, let me confirm my update by email:" -msgstr "Meldung per eMail bestätigen" +msgstr "" #: templates/web/default/auth/general.html:37 #: templates/web/default/report/display.html:142 #: templates/web/default/report/new/fill_in_details_form.html:140 -#: templates/web/fixmystreet/auth/general.html:32 -#: templates/web/fixmystreet/auth/general.html:34 -#: templates/web/fixmystreet/report/display.html:131 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:154 +#: templates/web/fixmystreet/auth/general.html:36 +#: templates/web/fixmystreet/auth/general.html:38 +#: templates/web/fixmystreet/report/display.html:147 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:158 msgid "<strong>Yes</strong> I have a password" msgstr "" @@ -348,11 +317,11 @@ msgstr "" msgid "About us" msgstr "Über uns" -#: templates/web/default/admin/council_contacts.html:66 +#: templates/web/default/admin/council_contacts.html:72 msgid "Add new category" msgstr "Füge neue Kategorie hinzu" -#: templates/web/default/my/my.html:56 templates/web/fixmystreet/my/my.html:56 +#: templates/web/default/my/my.html:56 templates/web/fixmystreet/my/my.html:60 msgid "Added %s" msgstr "" @@ -370,14 +339,10 @@ msgstr "" #: templates/web/bromley/report/display.html:207 #: templates/web/default/report/display.html:214 -#: templates/web/fixmystreet/report/display.html:189 +#: templates/web/fixmystreet/report/display.html:211 msgid "Alert me to future updates" msgstr "" -#: templates/web/default/admin/stats.html:5 -msgid "All" -msgstr "Alle" - #: templates/web/default/reports/index.html:3 msgid "All Reports" msgstr "Alle Meldungen" @@ -390,11 +355,17 @@ msgstr "Alle bestätigten" #: templates/web/bromley/header.html:77 templates/web/default/footer.html:11 #: templates/web/fiksgatami/footer.html:7 #: templates/web/fiksgatami/nn/footer.html:7 +#: templates/web/fixmybarangay/footer.html:20 #: templates/web/fixmystreet/footer.html:49 #: templates/web/reading/footer.html:8 msgid "All reports" msgstr "Alle Meldungen" +#: templates/web/default/admin/stats.html:5 +#, fuzzy +msgid "All reports between %s and %s" +msgstr "Gemeldet von %s um %s" + #: templates/web/default/report/new/councils_text_some.html:2 msgid "All the information you provide here will be sent to" msgstr "" @@ -479,6 +450,12 @@ msgstr "" msgid "Ban email address" msgstr "" +#: templates/web/fixmybarangay/report/new/notes.html:7 +msgid "" +"Be sure to choose the right category, because we use that to determine to " +"whom the report is sent." +msgstr "" + #: templates/web/fiksgatami/footer.html:16 #: templates/web/fiksgatami/nn/footer.html:16 msgid "" @@ -490,22 +467,21 @@ msgstr "" msgid "By Date" msgstr "" -#: templates/web/fixmystreet/around/display_location.html:80 -#: templates/web/fixmystreet/around/display_location.html:82 -#, fuzzy +#: templates/web/fixmystreet/around/_report_banner.html:10 +#: templates/web/fixmystreet/around/_report_banner.html:8 msgid "Can't see the map? <a href='%s' rel='nofollow'>Skip this step</a>" msgstr "" -"Karte nicht sichtbar? <a href='%s' rel='nofollow'>Überspringen " -"Sie diesen Schritt</a>" +"Karte nicht sichtbar? <a href='%s' rel='nofollow'>Überspringen Sie " +"diesen Schritt</a>" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:632 -#: perllib/FixMyStreet/App/Controller/Report/New.pm:657 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:633 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:660 #: templates/web/bromley/report/new/fill_in_details_form.html:68 -#: templates/web/default/admin/council_contacts.html:35 +#: templates/web/default/admin/council_contacts.html:37 #: templates/web/default/admin/index.html:36 #: templates/web/default/admin/list_flagged.html:14 #: templates/web/default/admin/search_reports.html:17 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:72 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:74 msgid "Category" msgstr "Kategorie" @@ -513,14 +489,14 @@ msgstr "Kategorie" msgid "Category fix rate for problems > 4 weeks old" msgstr "" -#: templates/web/default/admin/council_contacts.html:72 +#: templates/web/default/admin/council_contacts.html:78 #: templates/web/default/admin/council_edit.html:23 #: templates/web/default/admin/report_edit.html:25 #: templates/web/default/report/new/fill_in_details_form.html:67 msgid "Category:" msgstr "Kategorie:" -#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:334 +#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:336 msgid "Category: %s" msgstr "Kategorie: %s" @@ -530,8 +506,7 @@ msgstr "Kategorie: %s" msgid "Change Password" msgstr "Passwort ändern" -#: templates/web/fixmystreet/around/display_location.html:72 -#: templates/web/fixmystreet/around/display_location.html:73 +#: templates/web/fixmystreet/around/_report_banner.html:2 msgid "Click map to report a problem" msgstr "Klicken Sie in die Karte um eine Meldung zu erfassen" @@ -539,21 +514,21 @@ msgstr "Klicken Sie in die Karte um eine Meldung zu erfassen" #: templates/web/bromley/report/display.html:82 #: templates/web/default/admin/report_edit.html:18 #: templates/web/default/admin/report_edit.html:20 -#: templates/web/default/dashboard/index.html:136 #: templates/web/default/dashboard/index.html:138 +#: templates/web/default/dashboard/index.html:140 #: templates/web/default/report/display.html:79 #: templates/web/default/report/display.html:81 #: templates/web/fixmystreet/report/banner.html:15 -#: templates/web/fixmystreet/report/display.html:74 -#: templates/web/fixmystreet/report/display.html:76 +#: templates/web/fixmystreet/report/display.html:90 +#: templates/web/fixmystreet/report/display.html:92 msgid "Closed" msgstr "Geschlossen" -#: perllib/FixMyStreet/DB/Result/Problem.pm:690 +#: perllib/FixMyStreet/DB/Result/Problem.pm:698 msgid "Closed by council" msgstr "" -#: templates/web/default/my/my.html:32 templates/web/fixmystreet/my/my.html:32 +#: templates/web/default/my/my.html:32 templates/web/fixmystreet/my/my.html:36 msgid "Closed reports" msgstr "" @@ -561,8 +536,8 @@ msgstr "" msgid "Closed:" msgstr "Geschlossen:" -#: templates/web/default/around/display_location.html:103 -#: templates/web/default/around/display_location.html:105 +#: templates/web/default/around/tabbed_lists.html:10 +#: templates/web/default/around/tabbed_lists.html:12 msgid "Closest nearby problems <small>(within %skm)</small>" msgstr "" @@ -586,23 +561,27 @@ msgstr "" msgid "Cobrand:" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:358 +#: perllib/FixMyStreet/App/Controller/Admin.pm:365 msgid "Configuration updated" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:372 +#: perllib/FixMyStreet/App/Controller/Admin.pm:380 msgid "Configuration updated - contacts will be generated automatically later" msgstr "" -#: templates/web/default/admin/council_contacts.html:153 +#: templates/web/default/admin/council_edit.html:34 +msgid "Configure Endpoint" +msgstr "" + +#: templates/web/default/admin/council_contacts.html:168 msgid "Configure Open311" msgstr "" -#: templates/web/default/admin/council_contacts.html:105 +#: templates/web/default/admin/council_contacts.html:116 msgid "Configure Open311 integration" msgstr "" -#: templates/web/default/admin/council_contacts.html:42 +#: templates/web/default/admin/council_contacts.html:46 msgid "Confirm" msgstr "Bestätigen" @@ -610,6 +589,13 @@ msgstr "Bestätigen" msgid "Confirm account" msgstr "" +#: templates/web/fixmystreet/report/display.html:165 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:176 +msgid "" +"Confirm by email below, providing a new password at that point. When you " +"confirm, your password will be updated." +msgstr "" + #: templates/web/default/questionnaire/creator_fixed.html:1 #: templates/web/default/tokens/confirm_problem.html:1 #: templates/web/default/tokens/confirm_problem.html:3 @@ -620,14 +606,17 @@ msgstr "" msgid "Confirmation" msgstr "Bestätigung" -#: templates/web/default/admin/council_contacts.html:37 -#: templates/web/default/admin/council_contacts.html:82 +#: templates/web/default/admin/council_contacts.html:39 +#: templates/web/default/admin/council_contacts.html:88 #: templates/web/default/admin/council_edit.html:28 -#: templates/web/default/admin/council_edit.html:43 -#: templates/web/default/admin/stats.html:5 +#: templates/web/default/admin/council_edit.html:71 msgid "Confirmed" msgstr "Bestätigt" +#: templates/web/default/admin/stats.html:5 +msgid "Confirmed reports between %s and %s" +msgstr "" + #: templates/web/default/admin/problem_row.html:23 #: templates/web/default/admin/report_edit.html:34 msgid "Confirmed:" @@ -658,8 +647,8 @@ msgstr "" msgid "Contact the team" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1150 -#: perllib/FixMyStreet/App/Controller/Admin.pm:1178 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1164 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1192 msgid "Could not find user" msgstr "" @@ -670,7 +659,7 @@ msgstr "" msgid "Council" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1022 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1036 #: templates/web/default/admin/council_list.html:1 msgid "Council contacts" msgstr "" @@ -698,7 +687,7 @@ msgstr "" msgid "Create a report" msgstr "Erfasse eine Meldung" -#: templates/web/default/admin/council_contacts.html:96 +#: templates/web/default/admin/council_contacts.html:107 msgid "Create category" msgstr "" @@ -726,15 +715,15 @@ msgstr "" msgid "Dashboard" msgstr "" -#: templates/web/default/admin/council_contacts.html:38 -#: templates/web/default/admin/council_contacts.html:85 +#: templates/web/default/admin/council_contacts.html:40 +#: templates/web/default/admin/council_contacts.html:91 #: templates/web/default/admin/council_edit.html:29 -#: templates/web/default/admin/council_edit.html:44 +#: templates/web/default/admin/council_edit.html:72 msgid "Deleted" msgstr "Gelöscht" #: templates/web/bromley/report/new/fill_in_details_form.html:54 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:64 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:66 msgid "Details" msgstr "Beschreibung" @@ -743,14 +732,22 @@ msgstr "Beschreibung" msgid "Details:" msgstr "Beschreibung:" +#: templates/web/default/admin/council_contacts.html:41 +msgid "Devolved" +msgstr "" + #: templates/web/default/admin/council_list.html:23 msgid "Diligency prize league table" msgstr "Weiss ich nicht" +#: templates/web/fixmystreet/auth/general.html:30 +msgid "Do you have a FixMyBarangay password?" +msgstr "" + #: templates/web/default/auth/general.html:32 -#: templates/web/fixmystreet/auth/general.html:29 -#: templates/web/fixmystreet/report/display.html:128 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:150 +#: templates/web/fixmystreet/auth/general.html:32 +#: templates/web/fixmystreet/report/display.html:144 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:154 msgid "Do you have a FixMyStreet password?" msgstr "" @@ -777,13 +774,13 @@ msgstr "" msgid "Editing user %d" msgstr "" -#: templates/web/default/admin/council_edit.html:45 +#: templates/web/default/admin/council_edit.html:73 msgid "Editor" msgstr "" #: templates/web/bromley/report/display.html:126 -#: templates/web/default/admin/council_contacts.html:36 -#: templates/web/default/admin/council_edit.html:42 +#: templates/web/default/admin/council_contacts.html:38 +#: templates/web/default/admin/council_edit.html:70 #: templates/web/default/admin/list_flagged.html:12 #: templates/web/default/admin/list_flagged.html:35 #: templates/web/default/admin/list_updates.html:8 @@ -791,19 +788,19 @@ msgstr "" #: templates/web/default/admin/search_reports.html:15 #: templates/web/default/admin/search_users.html:13 #: templates/web/fixmystreet/auth/general.html:20 -#: templates/web/fixmystreet/report/display.html:120 +#: templates/web/fixmystreet/report/display.html:136 msgid "Email" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1126 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1140 msgid "Email added to abuse list" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1123 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1137 msgid "Email already in abuse list" msgstr "" -#: templates/web/default/around/display_location.html:85 +#: templates/web/default/around/_updates.html:5 msgid "Email me new local problems" msgstr "" @@ -811,7 +808,7 @@ msgstr "" msgid "Email me updates" msgstr "Schicken sie mir Aktualisierungen" -#: templates/web/default/admin/council_contacts.html:77 +#: templates/web/default/admin/council_contacts.html:83 #: templates/web/default/admin/council_edit.html:26 #: templates/web/default/admin/report_edit.html:31 #: templates/web/default/admin/update_edit.html:24 @@ -821,15 +818,15 @@ msgstr "Schicken sie mir Aktualisierungen" msgid "Email:" msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:611 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:612 msgid "Empty flat or maisonette" msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:610 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:611 msgid "Empty house or bungalow" msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:613 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:614 msgid "Empty office or other commercial" msgstr "" @@ -837,11 +834,11 @@ msgstr "" msgid "Empty property details form" msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:614 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:615 msgid "Empty pub or bar" msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:615 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:616 msgid "Empty public building - school, hospital, etc." msgstr "" @@ -873,8 +870,9 @@ msgstr "Geben Sie eine Adresse an" #: templates/web/default/around/postcode_form.html:1 #: templates/web/default/around/postcode_form.html:2 -#: templates/web/fixmystreet/around/postcode_form.html:10 -#: templates/web/fixmystreet/around/postcode_form.html:11 +#: templates/web/fixmystreet/around/postcode_form.html:13 +#: templates/web/fixmystreet/around/postcode_form.html:14 +#, fuzzy msgid "Enter a nearby street name and area" msgstr "Geben Sie eine Adresse an" @@ -886,14 +884,14 @@ msgstr "" #: templates/web/bromley/report/display.html:148 #: templates/web/bromley/report/new/fill_in_details_form.html:189 -#: templates/web/fixmystreet/auth/general.html:57 -#: templates/web/fixmystreet/report/display.html:160 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:200 +#: templates/web/fixmystreet/auth/general.html:61 +#: templates/web/fixmystreet/report/display.html:182 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:210 msgid "Enter a password" msgstr "" #: templates/web/default/index.html:33 templates/web/emptyhomes/index.html:58 -#: templates/web/fixmystreet/index.html:41 +#: templates/web/fixmystreet/index.html:46 msgid "Enter details of the problem" msgstr "Beschreiben sie den Mangel" @@ -907,7 +905,7 @@ msgstr "Beschreiben sie den Mangel" msgid "Error" msgstr "Fehler" -#: templates/web/default/admin/council_contacts.html:11 +#: templates/web/default/admin/council_contacts.html:13 #: templates/web/default/admin/council_edit.html:18 msgid "Example postcode %s" msgstr "Beispieladresse" @@ -984,13 +982,13 @@ msgstr "" #: templates/web/default/admin/index.html:36 #: templates/web/default/admin/report_edit.html:18 #: templates/web/default/admin/report_edit.html:20 -#: templates/web/default/dashboard/index.html:136 #: templates/web/default/dashboard/index.html:138 +#: templates/web/default/dashboard/index.html:140 #: templates/web/default/report/display.html:79 #: templates/web/default/report/display.html:81 #: templates/web/fixmystreet/report/banner.html:12 -#: templates/web/fixmystreet/report/display.html:74 -#: templates/web/fixmystreet/report/display.html:76 +#: templates/web/fixmystreet/report/display.html:90 +#: templates/web/fixmystreet/report/display.html:92 msgid "Fixed" msgstr "Gelöst" @@ -1004,7 +1002,7 @@ msgstr "" msgid "Fixed - User" msgstr "" -#: templates/web/default/my/my.html:27 templates/web/fixmystreet/my/my.html:27 +#: templates/web/default/my/my.html:27 templates/web/fixmystreet/my/my.html:31 msgid "Fixed reports" msgstr "" @@ -1035,11 +1033,18 @@ msgstr "" msgid "For council(s):" msgstr "" +#: templates/web/fixmystreet/report/display.html:164 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:175 +#, fuzzy +msgid "Forgotten your password?" +msgstr "Ihr Passwort" + #: templates/web/default/faq/faq-en-gb.html:1 #: templates/web/emptyhomes/faq/faq-cy.html:1 #: templates/web/emptyhomes/faq/faq-en-gb.html:1 #: templates/web/fiksgatami/faq/faq-nb.html:1 #: templates/web/fiksgatami/nn/faq/faq-nn.html:1 +#: templates/web/fixmybarangay/faq/faq-en-gb.html:1 #: templates/web/fixmystreet/faq/faq-en-gb.html:1 #: templates/web/fixmystreet/static/privacy.html:1 #: templates/web/zurich/faq/faq-de.html:1 @@ -1055,7 +1060,7 @@ msgid "GeoRSS on Google Maps" msgstr "" #: templates/web/bromley/report/display.html:30 -#: templates/web/fixmystreet/report/display.html:23 +#: templates/web/fixmystreet/report/display.html:27 msgid "Get updates" msgstr "" @@ -1071,6 +1076,7 @@ msgid "Get updates of problems in this %s" msgstr "" #: templates/web/default/alert/_list.html:83 +#: templates/web/fixmybarangay/alert/_list.html:28 #: templates/web/fixmystreet/alert/_list.html:82 msgid "Give me an RSS feed" msgstr "" @@ -1078,7 +1084,7 @@ msgstr "" #: templates/web/default/alert/index.html:34 #: templates/web/default/around/postcode_form.html:8 #: templates/web/emptyhomes/index.html:47 -#: templates/web/fixmystreet/around/postcode_form.html:18 +#: templates/web/fixmystreet/around/postcode_form.html:24 msgid "Go" msgstr "Los" @@ -1112,6 +1118,7 @@ msgstr "" #: templates/web/emptyhomes/header.html:28 #: templates/web/fiksgatami/footer.html:9 #: templates/web/fiksgatami/nn/footer.html:9 +#: templates/web/fixmybarangay/footer.html:24 #: templates/web/fixmystreet/footer.html:53 #: templates/web/reading/footer.html:10 msgid "Help" @@ -1124,7 +1131,7 @@ msgstr "" #: templates/web/barnet/header.html:70 templates/web/bromley/header.html:64 #: templates/web/bromley/header.html:99 -#: templates/web/fixmybarangay/header.html.orig:42 +#: templates/web/fixmybarangay/header.html:66 #: templates/web/fixmystreet/header.html:47 #: templates/web/zurich/header.html:47 msgid "Hi %s" @@ -1136,17 +1143,15 @@ msgstr "Hallo %s" msgid "Hidden" msgstr "Unsichtbar" -#: templates/web/default/around/display_location.html:58 -#: templates/web/fixmystreet/around/display_location.html:58 +#: templates/web/default/around/display_location.html:63 msgid "Hide old" msgstr "Alte ausblenden" -#: templates/web/default/around/display_location.html:53 -#: templates/web/fixmystreet/around/display_location.html:54 +#: templates/web/default/around/display_location.html:58 msgid "Hide pins" msgstr "Stecknadeln ausblenden" -#: templates/web/default/admin/council_edit.html:38 +#: templates/web/default/admin/council_edit.html:66 msgid "History" msgstr "History" @@ -1155,7 +1160,7 @@ msgstr "History" msgid "How to report a problem" msgstr "Erfasse eine neue Meldung:" -#: perllib/FixMyStreet/App/Controller/Admin.pm:637 +#: perllib/FixMyStreet/App/Controller/Admin.pm:648 msgid "I am afraid you cannot confirm unconfirmed reports." msgstr "" @@ -1226,12 +1231,12 @@ msgstr "" #: templates/web/bromley/report/display.html:82 #: templates/web/default/admin/report_edit.html:18 #: templates/web/default/admin/report_edit.html:20 -#: templates/web/default/dashboard/index.html:136 #: templates/web/default/dashboard/index.html:138 +#: templates/web/default/dashboard/index.html:140 #: templates/web/default/report/display.html:79 #: templates/web/default/report/display.html:81 -#: templates/web/fixmystreet/report/display.html:74 -#: templates/web/fixmystreet/report/display.html:76 +#: templates/web/fixmystreet/report/display.html:90 +#: templates/web/fixmystreet/report/display.html:92 msgid "In Progress" msgstr "In Bearbeitung" @@ -1259,7 +1264,7 @@ msgstr "" msgid "Invalid agency_responsible value %s" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:942 +#: perllib/FixMyStreet/App/Controller/Admin.pm:956 msgid "Invalid end date" msgstr "Ung&ultiges Enddatum" @@ -1267,7 +1272,7 @@ msgstr "Ung&ultiges Enddatum" msgid "Invalid format %s specified." msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:932 +#: perllib/FixMyStreet/App/Controller/Admin.pm:946 msgid "Invalid start date" msgstr "Ung&ultiges Startdatum" @@ -1275,12 +1280,12 @@ msgstr "Ung&ultiges Startdatum" #: templates/web/bromley/report/display.html:81 #: templates/web/default/admin/report_edit.html:18 #: templates/web/default/admin/report_edit.html:19 -#: templates/web/default/dashboard/index.html:136 -#: templates/web/default/dashboard/index.html:137 +#: templates/web/default/dashboard/index.html:138 +#: templates/web/default/dashboard/index.html:139 #: templates/web/default/report/display.html:79 #: templates/web/default/report/display.html:80 -#: templates/web/fixmystreet/report/display.html:74 -#: templates/web/fixmystreet/report/display.html:75 +#: templates/web/fixmystreet/report/display.html:90 +#: templates/web/fixmystreet/report/display.html:91 msgid "Investigating" msgstr "" @@ -1302,9 +1307,9 @@ msgstr "" #: templates/web/default/auth/general.html:44 #: templates/web/default/report/display.html:151 #: templates/web/default/report/new/fill_in_details_form.html:149 -#: templates/web/fixmystreet/auth/general.html:42 -#: templates/web/fixmystreet/report/display.html:144 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:167 +#: templates/web/fixmystreet/auth/general.html:46 +#: templates/web/fixmystreet/report/display.html:160 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:171 msgid "Keep me signed in on this computer" msgstr "" @@ -1315,7 +1320,7 @@ msgstr "" msgid "Last Name" msgstr "Letzte Bearbeitung" -#: templates/web/default/admin/council_contacts.html:39 +#: templates/web/default/admin/council_contacts.html:42 msgid "Last editor" msgstr "Letzter Bearbeiter" @@ -1328,18 +1333,18 @@ msgstr "Letzte Bearbeitung" msgid "Last update:" msgstr "Letzte Bearbeitung" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1028 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1042 msgid "List Flagged" msgstr "" -#: templates/web/default/admin/council_contacts.html:14 #: templates/web/default/admin/council_contacts.html:16 +#: templates/web/default/admin/council_contacts.html:18 msgid "List all reported problems" msgstr "Liste aller Meldungen" #: templates/web/bromley/report/new/fill_in_details_form.html:69 #: templates/web/default/report/new/fill_in_details_form.html:68 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:73 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:75 msgid "Loading..." msgstr "" @@ -1354,6 +1359,8 @@ msgstr "" #: templates/web/default/tokens/confirm_alert.html:3 #: templates/web/emptyhomes/alert/index.html:1 #: templates/web/emptyhomes/alert/index.html:3 +#: templates/web/fixmybarangay/alert/index.html:1 +#: templates/web/fixmybarangay/alert/index.html:3 #: templates/web/fixmystreet/alert/updates.html:1 msgid "Local RSS feeds and email alerts" msgstr "" @@ -1369,13 +1376,14 @@ msgstr "" #: templates/web/bromley/header.html:79 templates/web/default/footer.html:13 #: templates/web/fiksgatami/footer.html:8 #: templates/web/fiksgatami/nn/footer.html:8 +#: templates/web/fixmybarangay/footer.html:22 #: templates/web/fixmystreet/footer.html:51 #: templates/web/reading/footer.html:9 msgid "Local alerts" msgstr "RSS" #: templates/web/default/index.html:32 templates/web/emptyhomes/index.html:57 -#: templates/web/fixmystreet/index.html:40 +#: templates/web/fixmystreet/index.html:45 msgid "Locate the problem on a map of the area" msgstr "Identifizieren Sie den Mangel auf der Karte" @@ -1415,10 +1423,10 @@ msgstr "Meldungen in der Nähe" #: templates/web/emptyhomes/reports/index.html:10 #: templates/web/fiksgatami/nn/reports/index.html:9 #: templates/web/fiksgatami/reports/index.html:9 -#: templates/web/fixmystreet/auth/general.html:52 -#: templates/web/fixmystreet/report/display.html:177 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:117 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:176 +#: templates/web/fixmystreet/auth/general.html:56 +#: templates/web/fixmystreet/report/display.html:199 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:119 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:186 msgid "Name" msgstr "Name" @@ -1434,26 +1442,26 @@ msgstr "Name:" msgid "Navigation" msgstr "Navigation" -#: perllib/FixMyStreet/Geocode/OSM.pm:159 +#: perllib/FixMyStreet/Geocode/OSM.pm:161 msgid "" "Nearest named road to the pin placed on the map (automatically generated " "using OpenStreetMap): %s%s" msgstr "" -#: perllib/FixMyStreet/Cobrand/UK.pm:161 +#: perllib/FixMyStreet/Cobrand/UK.pm:152 msgid "" "Nearest postcode to the pin placed on the map (automatically generated): %s " "(%sm away)" msgstr "" -#: perllib/FixMyStreet/Cobrand/Default.pm:404 -#: perllib/FixMyStreet/Cobrand/Default.pm:444 +#: perllib/FixMyStreet/Cobrand/Default.pm:406 +#: perllib/FixMyStreet/Cobrand/Default.pm:446 msgid "" "Nearest road to the pin placed on the map (automatically generated by Bing " "Maps): %s" msgstr "" -#: perllib/FixMyStreet/DB/ResultSet/AlertType.pm:245 +#: perllib/FixMyStreet/DB/ResultSet/AlertType.pm:265 msgid "" "Nearest road to the pin placed on the map (automatically generated by Bing " "Maps): %s\n" @@ -1465,11 +1473,10 @@ msgid "Nearly Done! Now check your email..." msgstr "Fast Fertig! Bitte checken Sie ihre Mailbox..." #: templates/web/default/reports/index.html:16 -#, fuzzy msgid "New <br>problems" -msgstr "Neue Meldungen" +msgstr "Neue <br>Meldungen" -#: perllib/FixMyStreet/App/Controller/Admin.pm:314 +#: perllib/FixMyStreet/App/Controller/Admin.pm:320 msgid "New category contact added" msgstr "" @@ -1538,8 +1545,9 @@ msgstr "" msgid "New!" msgstr "Neu!" -#: templates/web/default/admin/council_contacts.html:48 -#: templates/web/default/admin/council_contacts.html:49 +#: templates/web/default/admin/council_contacts.html:52 +#: templates/web/default/admin/council_contacts.html:53 +#: templates/web/default/admin/council_contacts.html:54 #: templates/web/default/admin/council_edit.html:4 #: templates/web/default/admin/list_updates.html:30 #: templates/web/default/admin/list_updates.html:31 @@ -1561,7 +1569,7 @@ msgstr "Nein" msgid "No council" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:328 +#: perllib/FixMyStreet/DB/Result/Problem.pm:336 msgid "No council selected" msgstr "" @@ -1591,6 +1599,14 @@ msgstr "Keine Meldungen gefunden." msgid "No problems have been reported yet." msgstr "Bisher wurden noch keine Meldungen erfasst." +#: templates/web/fixmystreet/report/_support.html:3 +msgid "No supporters" +msgstr "" + +#: templates/web/default/admin/council_contacts.html:57 +msgid "Non Public" +msgstr "" + #: templates/web/default/admin/council_list.html:5 #: templates/web/default/admin/report_edit.html:16 msgid "None" @@ -1606,8 +1622,8 @@ msgstr "" msgid "Not reported to council" msgstr "" -#: templates/web/default/admin/council_contacts.html:40 -#: templates/web/default/admin/council_edit.html:46 +#: templates/web/default/admin/council_contacts.html:43 +#: templates/web/default/admin/council_edit.html:74 msgid "Note" msgstr "" @@ -1618,8 +1634,8 @@ msgid "" "numbers may jump about a little" msgstr "" -#: templates/web/default/admin/council_contacts.html:89 -#: templates/web/default/admin/council_edit.html:31 +#: templates/web/default/admin/council_contacts.html:95 +#: templates/web/default/admin/council_edit.html:32 msgid "Note:" msgstr "" @@ -1627,7 +1643,7 @@ msgstr "" msgid "Note: <strong>%s</strong>" msgstr "" -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:149 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:153 msgid "Now to submit your report…" msgstr "" @@ -1635,7 +1651,7 @@ msgstr "" msgid "Now to submit your report… do you have a FixMyStreet password?" msgstr "" -#: templates/web/fixmystreet/report/display.html:127 +#: templates/web/fixmystreet/report/display.html:143 msgid "Now to submit your update…" msgstr "" @@ -1666,9 +1682,8 @@ msgid "Older <br>fixed" msgstr "" #: templates/web/default/reports/index.html:17 -#, fuzzy msgid "Older <br>problems" -msgstr "Neue Meldungen" +msgstr "" #: templates/web/emptyhomes/reports/index.html:14 #: templates/web/fiksgatami/nn/reports/index.html:14 @@ -1685,13 +1700,13 @@ msgstr "" #: templates/web/bromley/report/display.html:80 #: templates/web/default/admin/report_edit.html:18 #: templates/web/default/admin/update_edit.html:19 -#: templates/web/default/dashboard/index.html:136 +#: templates/web/default/dashboard/index.html:138 #: templates/web/default/report/display.html:79 -#: templates/web/fixmystreet/report/display.html:74 +#: templates/web/fixmystreet/report/display.html:90 msgid "Open" msgstr "Öffnen" -#: templates/web/default/my/my.html:22 templates/web/fixmystreet/my/my.html:22 +#: templates/web/default/my/my.html:22 templates/web/fixmystreet/my/my.html:26 msgid "Open reports" msgstr "" @@ -1719,15 +1734,15 @@ msgid "" "re in:" msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:655 -#: perllib/FixMyStreet/App/Controller/Report/New.pm:656 -#: perllib/FixMyStreet/App/Controller/Report/New.pm:999 -#: perllib/FixMyStreet/DB/Result/Problem.pm:497 -#: perllib/FixMyStreet/DB/Result/Problem.pm:507 -#: perllib/FixMyStreet/DB/Result/Problem.pm:517 -#: perllib/FixMyStreet/DB/Result/Problem.pm:529 -#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:329 -#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:338 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:1008 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:658 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:659 +#: perllib/FixMyStreet/DB/Result/Problem.pm:505 +#: perllib/FixMyStreet/DB/Result/Problem.pm:515 +#: perllib/FixMyStreet/DB/Result/Problem.pm:525 +#: perllib/FixMyStreet/DB/Result/Problem.pm:537 +#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:331 +#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:340 msgid "Other" msgstr "" @@ -1753,9 +1768,9 @@ msgstr "" #: templates/web/bromley/report/display.html:145 #: templates/web/bromley/report/new/fill_in_details_form.html:186 -#: templates/web/fixmystreet/auth/general.html:55 -#: templates/web/fixmystreet/report/display.html:157 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:197 +#: templates/web/fixmystreet/auth/general.html:59 +#: templates/web/fixmystreet/report/display.html:179 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:207 msgid "Password (optional)" msgstr "" @@ -1765,12 +1780,12 @@ msgstr "" #: templates/web/bromley/report/new/fill_in_details_form.html:136 #: templates/web/bromley/report/new/fill_in_details_form.html:183 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:133 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:194 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:137 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:204 msgid "Phone number (optional)" msgstr "Telefonnummer (optional)" -#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:260 +#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:262 #: templates/web/default/admin/report_edit.html:32 #: templates/web/default/report/new/fill_in_details_form.html:215 msgid "Phone:" @@ -1778,8 +1793,8 @@ msgstr "Telefonnummer:" #: templates/web/bromley/report/display.html:109 #: templates/web/bromley/report/new/fill_in_details_form.html:104 -#: templates/web/fixmystreet/report/display.html:103 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:108 +#: templates/web/fixmystreet/report/display.html:119 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:110 msgid "Photo" msgstr "Foto" @@ -1798,12 +1813,12 @@ msgstr "Fotos von neuen Meldungen in der Nähe" #: templates/web/bromley/report/display.html:81 #: templates/web/default/admin/report_edit.html:18 #: templates/web/default/admin/report_edit.html:19 -#: templates/web/default/dashboard/index.html:136 -#: templates/web/default/dashboard/index.html:137 +#: templates/web/default/dashboard/index.html:138 +#: templates/web/default/dashboard/index.html:139 #: templates/web/default/report/display.html:79 #: templates/web/default/report/display.html:80 -#: templates/web/fixmystreet/report/display.html:74 -#: templates/web/fixmystreet/report/display.html:75 +#: templates/web/fixmystreet/report/display.html:90 +#: templates/web/fixmystreet/report/display.html:91 msgid "Planned" msgstr "Geplant" @@ -1834,16 +1849,16 @@ msgstr "Bitte überprüfen sie ihre eMail" msgid "Please check your email address is correct" msgstr "Bitte überprüfen Sie ob Ihre eMail-Adresse korrekt ist" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:819 -#: perllib/FixMyStreet/App/Controller/Report/New.pm:826 -#: perllib/FixMyStreet/App/Controller/Report/New.pm:845 -#: perllib/FixMyStreet/App/Controller/Report/New.pm:884 -#: perllib/FixMyStreet/DB/Result/Problem.pm:347 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:824 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:831 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:850 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:893 +#: perllib/FixMyStreet/DB/Result/Problem.pm:355 #: templates/web/default/js/validation_strings.html:9 msgid "Please choose a category" msgstr "Bitte wählen Sie eine Kategorie" -#: perllib/FixMyStreet/DB/Result/Problem.pm:353 +#: perllib/FixMyStreet/DB/Result/Problem.pm:361 msgid "Please choose a property type" msgstr "" @@ -1882,7 +1897,7 @@ msgid "Please enter a password" msgstr "" #: perllib/FixMyStreet/App/Controller/Contact.pm:97 -#: perllib/FixMyStreet/DB/Result/Problem.pm:322 +#: perllib/FixMyStreet/DB/Result/Problem.pm:330 #: templates/web/default/js/validation_strings.html:3 msgid "Please enter a subject" msgstr "" @@ -1898,7 +1913,7 @@ msgstr "Bitte geben Sie eine gültige eMail-Adresse an" msgid "Please enter a valid email address" msgstr "Bitte geben Sie eine gültige eMail-Adresse an" -#: perllib/FixMyStreet/DB/Result/Problem.pm:325 +#: perllib/FixMyStreet/DB/Result/Problem.pm:333 #: templates/web/default/js/validation_strings.html:4 msgid "Please enter some details" msgstr "Bitte geben Sie einiges Details an" @@ -1915,7 +1930,7 @@ msgid "Please enter your email" msgstr "Bitte geben Sie Ihre eMail-Adresse an" #: templates/web/bromley/report/new/fill_in_details_form.html:149 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:146 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:150 msgid "Please enter your email address" msgstr "Bitte geben Sie eine Ihre eMail-Adresse an" @@ -1924,7 +1939,7 @@ msgstr "Bitte geben Sie eine Ihre eMail-Adresse an" msgid "Please enter your first name" msgstr "Bitte geben Sie Ihren Namen an" -#: perllib/FixMyStreet/DB/Result/Problem.pm:340 +#: perllib/FixMyStreet/DB/Result/Problem.pm:348 #: templates/web/default/js/validation_strings.html:7 msgid "" "Please enter your full name, councils need this information – if you do not " @@ -1933,7 +1948,7 @@ msgstr "" #: perllib/FixMyStreet/App/Controller/Contact.pm:95 #: perllib/FixMyStreet/DB/Result/Comment.pm:143 -#: perllib/FixMyStreet/DB/Result/Problem.pm:333 +#: perllib/FixMyStreet/DB/Result/Problem.pm:341 #: perllib/FixMyStreet/DB/Result/User.pm:97 #: templates/web/default/js/validation_strings.html:6 msgid "Please enter your name" @@ -1964,11 +1979,28 @@ msgstr "" #: templates/web/default/report/new/fill_in_details_text.html:1 #: templates/web/default/report/new/fill_in_details_text.html:11 +#: templates/web/fixmybarangay/report/new/fill_in_details_text.html:1 +#: templates/web/fixmybarangay/report/new/fill_in_details_text.html:10 #: templates/web/fixmystreet/report/new/fill_in_details_text.html:1 #: templates/web/fixmystreet/report/new/fill_in_details_text.html:11 msgid "Please fill in details of the problem below." msgstr "" +#: templates/web/fixmybarangay/report/new/fill_in_details_text.html:1 +#: templates/web/fixmybarangay/report/new/fill_in_details_text.html:3 +#, fuzzy +msgid "" +"Please fill in details of the problem below. Leave as much detail as you " +"can, \n" +"and if possible describe the exact location of\n" +"the problem (e.g. if there is a streetlight number or road name)." +msgstr "" +"Bitte beschreiben sie Ihre Meldung weiter unten. Wir können den Mangel " +"nur beheben, wenn Sie soviel Details wie möglich angeben: Beschreiben " +"sie die exakte Lage (z.B. An der Wand Richtung Strasse), was genau der " +"Mangel ist, wie lange dieser schon da ist und laden sie wenn möglich " +"ein Photo des Mangels hoch." + #: templates/web/default/report/new/fill_in_details_text.html:1 #: templates/web/default/report/new/fill_in_details_text.html:3 msgid "" @@ -1985,19 +2017,19 @@ msgstr "" "Mangel ist, wie lange dieser schon da ist und laden sie wenn möglich " "ein Photo des Mangels hoch." -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:68 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:70 msgid "Please fill in details of the problem." msgstr "" #: templates/web/bromley/report/new/fill_in_details_form.html:28 #: templates/web/default/report/new/fill_in_details_form.html:27 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:34 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:35 msgid "" "Please fill in the form below with details of the problem, and describe the " "location as precisely as possible in the details box." msgstr "" -#: perllib/FixMyStreet/App/Controller/Questionnaire.pm:241 +#: perllib/FixMyStreet/App/Controller/Questionnaire.pm:243 msgid "Please indicate whether you'd like to receive another questionnaire" msgstr "" @@ -2013,35 +2045,39 @@ msgid "" msgstr "" #: templates/web/barnet/report/updates-sidebar-notes.html:1 +#, fuzzy msgid "" "Please note that updates are not sent to the relevant department. If you " "leave your name it will be public. Your information will only be used in " "accordance with our <a href=\"/faq#privacy\">privacy policy</a>" msgstr "" +"Wir verwenden Ihre persönlichen Daten nur entsprechend unserer <a href=" +"\"/faq#privacy\">Datenschutzrichtlinien.</a>" #: templates/web/bromley/report/new/fill_in_details_form.html:23 #: templates/web/default/report/new/fill_in_details_form.html:5 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:25 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:26 msgid "" "Please note your report has <strong>not yet been sent</strong>. Choose a " "category and add further information below, then submit." msgstr "" #: templates/web/default/report/new/notes.html:1 +#: templates/web/fixmybarangay/report/new/notes.html:1 #: templates/web/fixmystreet/report/new/notes.html:1 msgid "Please note:" msgstr "Hinweise:" -#: perllib/FixMyStreet/App/Controller/Questionnaire.pm:244 +#: perllib/FixMyStreet/App/Controller/Questionnaire.pm:246 msgid "Please provide some explanation as to why you're reopening this report" msgstr "" -#: perllib/FixMyStreet/App/Controller/Questionnaire.pm:251 +#: perllib/FixMyStreet/App/Controller/Questionnaire.pm:253 msgid "Please provide some text as well as a photo" msgstr "" #: perllib/FixMyStreet/App/Controller/Questionnaire.pm:116 -#: perllib/FixMyStreet/App/Controller/Questionnaire.pm:237 +#: perllib/FixMyStreet/App/Controller/Questionnaire.pm:239 msgid "" "Please say whether you've ever reported a problem to your council before" msgstr "" @@ -2054,7 +2090,7 @@ msgstr "" msgid "Please select the type of alert you want" msgstr "" -#: perllib/FixMyStreet/App/Controller/Questionnaire.pm:233 +#: perllib/FixMyStreet/App/Controller/Questionnaire.pm:235 msgid "Please state whether or not the problem has been fixed" msgstr "" @@ -2062,11 +2098,11 @@ msgstr "" msgid "Please take a look at the updates that have been left." msgstr "" -#: perllib/FixMyStreet/App/Controller/Photo.pm:176 +#: perllib/FixMyStreet/App/Controller/Photo.pm:175 msgid "Please upload a JPEG image only" msgstr "" -#: perllib/FixMyStreet/App/Controller/Photo.pm:183 +#: perllib/FixMyStreet/App/Controller/Photo.pm:182 msgid "Please upload a JPEG image only\n" msgstr "" @@ -2075,7 +2111,7 @@ msgid "Please write a message" msgstr "" #: templates/web/bromley/report/display.html:70 -#: templates/web/fixmystreet/report/display.html:69 +#: templates/web/fixmystreet/report/display.html:85 msgid "Please write your update here" msgstr "" @@ -2087,9 +2123,9 @@ msgstr "" #: templates/web/default/report/display.html:156 #: templates/web/default/report/display.html:178 #: templates/web/fixmystreet/contact/index.html:93 -#: templates/web/fixmystreet/report/display.html:115 -#: templates/web/fixmystreet/report/display.html:139 -#: templates/web/fixmystreet/report/display.html:161 +#: templates/web/fixmystreet/report/display.html:131 +#: templates/web/fixmystreet/report/display.html:155 +#: templates/web/fixmystreet/report/display.html:183 msgid "Post" msgstr "" @@ -2105,6 +2141,12 @@ msgstr "" msgid "Posted by %s at %s" msgstr "" +#: templates/web/default/admin/council_contacts.html:100 +#: templates/web/default/admin/council_edit.html:30 +#: templates/web/default/admin/report_edit.html:43 +msgid "Private" +msgstr "" + #: templates/web/default/maps/openlayers.html:85 msgid "Problem" msgstr "Meldung" @@ -2125,7 +2167,7 @@ msgstr "" msgid "Problem breakdown by state" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:819 +#: perllib/FixMyStreet/App/Controller/Admin.pm:833 msgid "Problem marked as open." msgstr "" @@ -2137,17 +2179,17 @@ msgstr "" msgid "Problems" msgstr "Meldungen" -#: templates/web/default/around/display_location.html:81 +#: templates/web/default/around/_updates.html:1 msgid "Problems in this area" msgstr "Meldungen in dieser Gegend" #: templates/web/bromley/report/display.html:31 -#: templates/web/fixmystreet/around/display_location.html:98 -#: templates/web/fixmystreet/report/display.html:24 +#: templates/web/fixmystreet/around/tabbed_lists.html:4 +#: templates/web/fixmystreet/report/display.html:31 msgid "Problems nearby" msgstr "Meldungen in der Nähe" -#: templates/web/fixmystreet/around/display_location.html:97 +#: templates/web/fixmystreet/around/tabbed_lists.html:3 msgid "Problems on the map" msgstr "Meldungen auf der Karte" @@ -2160,15 +2202,15 @@ msgstr "Meldungen, welche kürzlich gelöst wurden" msgid "Problems within %.1fkm of this location" msgstr "" -#: perllib/FixMyStreet/Cobrand/Default.pm:609 +#: perllib/FixMyStreet/Cobrand/Default.pm:611 #: perllib/FixMyStreet/Cobrand/EmptyHomes.pm:95 #: perllib/FixMyStreet/Cobrand/FiksGataMi.pm:162 -#: perllib/FixMyStreet/Cobrand/UK.pm:240 +#: perllib/FixMyStreet/Cobrand/UK.pm:231 msgid "Problems within %s" msgstr "Meldungen innerhalb %s" #: perllib/FixMyStreet/Cobrand/EmptyHomes.pm:103 -#: perllib/FixMyStreet/Cobrand/UK.pm:254 +#: perllib/FixMyStreet/Cobrand/UK.pm:245 msgid "Problems within %s ward" msgstr "" @@ -2178,6 +2220,7 @@ msgid "Problems within %s, FixMyStreet" msgstr "" #: templates/web/default/alert/_list.html:40 +#: templates/web/fixmybarangay/alert/_list.html:13 #: templates/web/fixmystreet/alert/_list.html:42 msgid "Problems within the boundary of:" msgstr "" @@ -2186,18 +2229,18 @@ msgstr "" msgid "Properties recently reported as put back to use on reportemptyhomes.com" msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:617 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:618 msgid "Property type:" msgstr "" #: templates/web/bromley/report/new/fill_in_details_form.html:52 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:62 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:64 msgid "Provide a title" msgstr "" #: templates/web/bromley/report/display.html:57 #: templates/web/default/report/display.html:51 -#: templates/web/fixmystreet/report/display.html:50 +#: templates/web/fixmystreet/report/display.html:66 msgid "Provide an update" msgstr "Meldung aktualisieren" @@ -2210,13 +2253,18 @@ msgstr "" #: templates/web/bromley/report/display.html:142 #: templates/web/default/report/display.html:175 #: templates/web/default/report/new/fill_in_details_form.html:173 -#: templates/web/fixmystreet/report/display.html:154 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:191 +#: templates/web/fixmystreet/report/display.html:176 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:201 msgid "" "Providing a password is optional, but doing so will allow you to more easily " "report problems, leave updates and manage your reports." msgstr "" +#: templates/web/default/admin/council_contacts.html:44 +#: templates/web/default/admin/council_contacts.html:57 +msgid "Public" +msgstr "" + #: templates/web/default/questionnaire/completed.html:1 #: templates/web/default/questionnaire/completed.html:2 #: templates/web/default/questionnaire/index.html:0 @@ -2237,7 +2285,7 @@ msgstr "" msgid "Questionnaire %d sent for problem %d" msgstr "" -#: perllib/FixMyStreet/App/Controller/Questionnaire.pm:190 +#: perllib/FixMyStreet/App/Controller/Questionnaire.pm:192 msgid "Questionnaire filled in by problem reporter" msgstr "" @@ -2249,17 +2297,15 @@ msgstr "" #: templates/web/default/reports/_rss.html:1 #: templates/web/fixmystreet/alert/_list.html:22 #: templates/web/fixmystreet/alert/updates.html:9 -#: templates/web/fixmystreet/around/display_location.html:1 -#: templates/web/fixmystreet/around/display_location.html:3 -#: templates/web/fixmystreet/report/display.html:30 +#: templates/web/fixmystreet/report/display.html:45 msgid "RSS feed" msgstr "" -#: perllib/FixMyStreet/Cobrand/UK.pm:283 perllib/FixMyStreet/Cobrand/UK.pm:295 +#: perllib/FixMyStreet/Cobrand/UK.pm:274 perllib/FixMyStreet/Cobrand/UK.pm:286 msgid "RSS feed for %s" msgstr "" -#: perllib/FixMyStreet/Cobrand/UK.pm:289 perllib/FixMyStreet/Cobrand/UK.pm:301 +#: perllib/FixMyStreet/Cobrand/UK.pm:280 perllib/FixMyStreet/Cobrand/UK.pm:292 msgid "RSS feed for %s ward, %s" msgstr "" @@ -2267,11 +2313,11 @@ msgstr "" #: perllib/FixMyStreet/Cobrand/FiksGataMi.pm:186 #: perllib/FixMyStreet/Cobrand/FiksGataMi.pm:196 #: perllib/FixMyStreet/Cobrand/FiksGataMi.pm:204 -#: perllib/FixMyStreet/Cobrand/UK.pm:309 perllib/FixMyStreet/Cobrand/UK.pm:321 +#: perllib/FixMyStreet/Cobrand/UK.pm:300 perllib/FixMyStreet/Cobrand/UK.pm:312 msgid "RSS feed of %s" msgstr "" -#: perllib/FixMyStreet/Cobrand/UK.pm:314 perllib/FixMyStreet/Cobrand/UK.pm:326 +#: perllib/FixMyStreet/Cobrand/UK.pm:305 perllib/FixMyStreet/Cobrand/UK.pm:317 msgid "RSS feed of %s, within %s ward" msgstr "" @@ -2284,29 +2330,27 @@ msgstr "" msgid "RSS feed of problems in this %s" msgstr "" -#: perllib/FixMyStreet/Cobrand/Default.pm:610 +#: perllib/FixMyStreet/Cobrand/Default.pm:612 #: perllib/FixMyStreet/Cobrand/EmptyHomes.pm:96 #: perllib/FixMyStreet/Cobrand/FiksGataMi.pm:161 -#: perllib/FixMyStreet/Cobrand/UK.pm:247 +#: perllib/FixMyStreet/Cobrand/UK.pm:238 msgid "RSS feed of problems within %s" msgstr "" #: perllib/FixMyStreet/Cobrand/EmptyHomes.pm:102 -#: perllib/FixMyStreet/Cobrand/UK.pm:253 +#: perllib/FixMyStreet/Cobrand/UK.pm:244 msgid "RSS feed of problems within %s ward" msgstr "" #: templates/web/default/around/display_location.html:1 #: templates/web/default/around/display_location.html:4 -#: templates/web/fixmystreet/around/display_location.html:1 -#: templates/web/fixmystreet/around/display_location.html:4 msgid "RSS feed of recent local problems" msgstr "" #: templates/web/bromley/report/display.html:37 #: templates/web/default/report/display.html:42 #: templates/web/fixmystreet/alert/updates.html:9 -#: templates/web/fixmystreet/report/display.html:30 +#: templates/web/fixmystreet/report/display.html:45 msgid "RSS feed of updates to this problem" msgstr "" @@ -2314,21 +2358,18 @@ msgstr "" #: templates/web/default/alert/updates.html:9 #: templates/web/default/report/display.html:33 #: templates/web/fixmystreet/alert/updates.html:14 -#: templates/web/fixmystreet/report/display.html:32 +#: templates/web/fixmystreet/report/display.html:47 msgid "Receive email when updates are left on this problem." msgstr "Erhalten Sie Aktualisierungen dieser Meldung." #: templates/web/default/around/display_location.html:0 #: templates/web/default/around/display_location.html:34 -#: templates/web/fixmystreet/around/display_location.html:0 -#: templates/web/fixmystreet/around/display_location.html:34 msgid "Recent local problems, FixMyStreet" msgstr "" #: templates/web/default/reports/index.html:19 -#, fuzzy msgid "Recently <br>fixed" -msgstr "Kürzlich gelöst" +msgstr "Kürzlich <br>gelöst" #: templates/web/emptyhomes/reports/index.html:13 #: templates/web/fiksgatami/nn/reports/index.html:13 @@ -2336,7 +2377,7 @@ msgstr "Kürzlich gelöst" msgid "Recently fixed" msgstr "Kürzlich gelöst" -#: templates/web/default/index.html:50 templates/web/fixmystreet/index.html:62 +#: templates/web/default/index.html:50 templates/web/fixmystreet/index.html:68 msgid "Recently reported problems" msgstr "Kürzlich erfasste Meldungen" @@ -2353,11 +2394,17 @@ msgstr "" "r nicht passend erscheint, können sie die entsprechende Dienststelle " "weiterhin telefonisch oder per eMail erreichen." +#: templates/web/fixmybarangay/report/new/notes.html:9 +msgid "" +"Remember that, for the pilot project, FixMyBarangay is only for reporting " +"potholes and streetlights in bgy. Luz or Basak San Nicolas." +msgstr "" + #: templates/web/default/admin/report_blocks.html:16 msgid "Remove flag" msgstr "" -#: templates/web/default/admin/report_edit.html:53 +#: templates/web/default/admin/report_edit.html:54 #: templates/web/default/admin/update_edit.html:48 msgid "Remove photo (can't be undone!)" msgstr "" @@ -2376,7 +2423,7 @@ msgid "Report a problem" msgstr "Eine Meldung erfassen" #: templates/web/bromley/report/display.html:28 -#: templates/web/fixmystreet/report/display.html:22 +#: templates/web/fixmystreet/report/display.html:26 msgid "Report abuse" msgstr "Missbrauch melden" @@ -2389,7 +2436,7 @@ msgid "Report on %s" msgstr "" #: templates/web/default/index.html:15 -#: templates/web/fixmystreet/around/postcode_form.html:6 +#: templates/web/fixmystreet/around/postcode_form.html:9 msgid "Report, view, or discuss local problems" msgstr "Melden sie Mängel an der Infrastruktur von Zürich" @@ -2401,7 +2448,7 @@ msgstr "" msgid "Reported %s, to %s" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:512 +#: perllib/FixMyStreet/DB/Result/Problem.pm:520 #: templates/web/default/contact/index.html:45 #: templates/web/fixmystreet/contact/index.html:46 msgid "Reported anonymously at %s" @@ -2413,33 +2460,33 @@ msgstr "Anonym gemeldet um" msgid "Reported before" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:504 +#: perllib/FixMyStreet/DB/Result/Problem.pm:512 msgid "Reported by %s anonymously at %s" msgstr "Anonym gemeldet von %s um %s " -#: perllib/FixMyStreet/DB/Result/Problem.pm:535 +#: perllib/FixMyStreet/DB/Result/Problem.pm:543 #: templates/web/default/contact/index.html:47 #: templates/web/fixmystreet/contact/index.html:48 msgid "Reported by %s at %s" msgstr "Gemeldet von %s um %s" -#: perllib/FixMyStreet/DB/Result/Problem.pm:526 +#: perllib/FixMyStreet/DB/Result/Problem.pm:534 msgid "Reported by %s by %s at %s" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:500 +#: perllib/FixMyStreet/DB/Result/Problem.pm:508 msgid "Reported by %s in the %s category anonymously at %s" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:520 +#: perllib/FixMyStreet/DB/Result/Problem.pm:528 msgid "Reported by %s in the %s category by %s at %s" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:508 +#: perllib/FixMyStreet/DB/Result/Problem.pm:516 msgid "Reported in the %s category anonymously at %s" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:530 +#: perllib/FixMyStreet/DB/Result/Problem.pm:538 msgid "Reported in the %s category by %s at %s" msgstr "" @@ -2454,7 +2501,7 @@ msgstr "" msgid "Reporting a problem" msgstr "Verfassen Sie eine Meldung" -#: templates/web/default/around/display_location.html:95 +#: templates/web/default/around/tabbed_lists.html:3 msgid "Reports on and around the map" msgstr "" @@ -2462,21 +2509,21 @@ msgstr "" msgid "Resend report" msgstr "" -#: perllib/FixMyStreet/Geocode/OSM.pm:166 +#: perllib/FixMyStreet/Geocode/OSM.pm:168 msgid "" "Road operator for this named road (derived from road reference number and " "type): %s" msgstr "" -#: perllib/FixMyStreet/Geocode/OSM.pm:163 +#: perllib/FixMyStreet/Geocode/OSM.pm:165 msgid "Road operator for this named road (from OpenStreetMap): %s" msgstr "" -#: templates/web/default/admin/council_edit.html:35 +#: templates/web/default/admin/council_edit.html:63 msgid "Save changes" msgstr "Änderungen speichern" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1027 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1041 msgid "Search Abuse" msgstr "" @@ -2484,13 +2531,13 @@ msgstr "" msgid "Search Abuse Table" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1023 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1037 #: templates/web/default/admin/list_flagged.html:1 #: templates/web/default/admin/search_reports.html:1 msgid "Search Reports" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1026 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1040 #: templates/web/default/admin/search_users.html:1 msgid "Search Users" msgstr "" @@ -2508,7 +2555,7 @@ msgid "" "or enter your email address to subscribe to an email alert." msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:618 +#: perllib/FixMyStreet/DB/Result/Problem.pm:626 msgid "Sent to %s %s later" msgstr "" @@ -2520,6 +2567,10 @@ msgstr "Gesendet:" msgid "Service:" msgstr "" +#: templates/web/fixmystreet/report/display.html:29 +msgid "Share" +msgstr "" + #: templates/web/emptyhomes/static/about.html:21 msgid "Shelter Cymru" msgstr "" @@ -2546,28 +2597,26 @@ msgstr "" #: templates/web/bromley/report/new/fill_in_details_form.html:175 #: templates/web/default/report/display.html:208 #: templates/web/default/report/new/fill_in_details_form.html:210 -#: templates/web/fixmystreet/report/display.html:185 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:126 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:186 +#: templates/web/fixmystreet/report/display.html:207 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:128 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:196 msgid "Show my name publicly" msgstr "" -#: templates/web/default/around/display_location.html:60 -#: templates/web/fixmystreet/around/display_location.html:60 +#: templates/web/default/around/display_location.html:65 msgid "Show old" msgstr "" -#: templates/web/default/around/display_location.html:51 -#: templates/web/fixmystreet/around/display_location.html:52 +#: templates/web/default/around/display_location.html:56 msgid "Show pins" msgstr "Zeige Stecknadeln" #: templates/web/default/auth/general.html:3 #: templates/web/default/auth/general.html:49 -#: templates/web/fixmybarangay/header.html.orig:46 +#: templates/web/fixmybarangay/header.html:70 #: templates/web/fixmystreet/auth/general.html:3 -#: templates/web/fixmystreet/auth/general.html:38 -#: templates/web/fixmystreet/auth/general.html:58 +#: templates/web/fixmystreet/auth/general.html:42 +#: templates/web/fixmystreet/auth/general.html:62 #: templates/web/fixmystreet/header.html:51 #: templates/web/zurich/header.html:51 msgid "Sign in" @@ -2603,11 +2652,13 @@ msgid "Signed in as %s" msgstr "" #: templates/web/default/report/new/fill_in_details_text.html:1 +#: templates/web/fixmybarangay/report/new/fill_in_details_text.html:1 #: templates/web/fixmystreet/report/new/fill_in_details_text.html:1 msgid "Some categories may require additional information." msgstr "" #: templates/web/default/alert/index.html:42 +#: templates/web/fixmybarangay/alert/index.html:32 msgid "Some photos of recent reports" msgstr "" @@ -2620,7 +2671,7 @@ msgstr "" msgid "Some unconfirmeds" msgstr "" -#: perllib/FixMyStreet/Cobrand/UK.pm:97 +#: perllib/FixMyStreet/Cobrand/UK.pm:89 msgid "" "Sorry, that appears to be a Crown dependency postcode, which we don't cover." msgstr "" @@ -2629,15 +2680,15 @@ msgstr "" msgid "Sorry, there has been an error confirming your problem." msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:214 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:213 #: perllib/FixMyStreet/Geocode.pm:27 perllib/FixMyStreet/Geocode/Bing.pm:51 #: perllib/FixMyStreet/Geocode/Google.pm:69 +#: perllib/FixMyStreet/Geocode/OSM.pm:61 msgid "Sorry, we could not find that location." msgstr "" #: perllib/FixMyStreet/Geocode/Bing.pm:46 #: perllib/FixMyStreet/Geocode/Google.pm:64 -#: perllib/FixMyStreet/Geocode/OSM.pm:59 msgid "Sorry, we could not parse that location. Please try again." msgstr "" @@ -2662,7 +2713,7 @@ msgstr "" #: templates/web/default/admin/list_flagged.html:18 #: templates/web/default/admin/list_updates.html:6 #: templates/web/default/admin/search_reports.html:21 -#: templates/web/fixmystreet/report/display.html:72 +#: templates/web/fixmystreet/report/display.html:88 msgid "State" msgstr "" @@ -2672,7 +2723,7 @@ msgstr "" msgid "State:" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1029 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1043 #: templates/web/default/admin/stats.html:1 msgid "Stats" msgstr "" @@ -2683,7 +2734,7 @@ msgstr "" #: templates/web/bromley/report/new/fill_in_details_form.html:48 #: templates/web/fixmystreet/contact/index.html:79 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:58 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:60 msgid "Subject" msgstr "Titel" @@ -2700,13 +2751,13 @@ msgstr "Titel:" #: templates/web/default/report/new/fill_in_details_form.html:114 #: templates/web/default/report/new/fill_in_details_form.html:154 #: templates/web/default/report/new/fill_in_details_form.html:176 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:137 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:162 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:201 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:141 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:166 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:211 msgid "Submit" msgstr "Abschicken" -#: templates/web/default/admin/report_edit.html:56 +#: templates/web/default/admin/report_edit.html:57 #: templates/web/default/admin/update_edit.html:51 #: templates/web/default/admin/user_edit.html:20 msgid "Submit changes" @@ -2721,16 +2772,21 @@ msgstr "" #: templates/web/default/alert/updates.html:17 #: templates/web/default/report/display.html:38 #: templates/web/fixmystreet/alert/updates.html:23 -#: templates/web/fixmystreet/report/display.html:37 +#: templates/web/fixmystreet/report/display.html:52 msgid "Subscribe" msgstr "" #: templates/web/default/alert/_list.html:97 +#: templates/web/fixmybarangay/alert/_list.html:42 #: templates/web/fixmystreet/alert/_list.html:92 msgid "Subscribe me to an email alert" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1021 +#: templates/web/fixmybarangay/alert/_list.html:6 +msgid "Subscribe to an alert based upon what baranagay you’re in:" +msgstr "" + +#: perllib/FixMyStreet/App/Controller/Admin.pm:1035 #: templates/web/default/admin/index.html:1 msgid "Summary" msgstr "Zusammenfassung" @@ -2742,7 +2798,7 @@ msgstr "Zusammenfassung" msgid "Summary reports" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1025 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1039 #: templates/web/default/admin/questionnaire.html:1 msgid "Survey Results" msgstr "" @@ -2751,7 +2807,7 @@ msgstr "" msgid "Text" msgstr "" -#: templates/web/default/admin/council_contacts.html:18 +#: templates/web/default/admin/council_contacts.html:20 msgid "Text only version" msgstr "" @@ -2825,7 +2881,7 @@ msgid "" "reported a problem to a council before?" msgstr "" -#: perllib/FixMyStreet/App/Controller/Photo.pm:190 +#: perllib/FixMyStreet/App/Controller/Photo.pm:189 msgid "" "That image doesn't appear to have uploaded correctly (%s), please try again." msgstr "" @@ -2836,20 +2892,25 @@ msgid "" "offshore or outside the country. Please try again." msgstr "" -#: perllib/FixMyStreet/App/Controller/Location.pm:107 +#: perllib/FixMyStreet/App/Controller/Location.pm:120 msgid "That location does not appear to be in the UK; please try again." msgstr "" #: perllib/FixMyStreet/Cobrand/FiksGataMi.pm:63 -#: perllib/FixMyStreet/Cobrand/UK.pm:90 +#: perllib/FixMyStreet/Cobrand/UK.pm:82 msgid "That postcode was not recognised, sorry." msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:605 +#: perllib/FixMyStreet/App/Controller/Admin.pm:616 msgid "That problem will now be resent." msgstr "" -#: perllib/FixMyStreet/App/Controller/Report.pm:75 +#: perllib/FixMyStreet/App/Controller/Report.pm:98 +#, fuzzy +msgid "That report cannot be viewed on FixMyStreet." +msgstr "Diese Meldung wurde von Fix My Zürich entfernt." + +#: perllib/FixMyStreet/App/Controller/Report.pm:92 msgid "That report has been removed from FixMyStreet." msgstr "Diese Meldung wurde von Fix My Zürich entfernt." @@ -2915,8 +2976,8 @@ msgid "" msgstr "" #: perllib/FixMyStreet/App/Controller/Dashboard.pm:60 -#: perllib/FixMyStreet/App/Controller/Reports.pm:44 -#: perllib/FixMyStreet/App/Controller/Reports.pm:75 +#: perllib/FixMyStreet/App/Controller/Reports.pm:43 +#: perllib/FixMyStreet/App/Controller/Reports.pm:74 msgid "The error was: %s" msgstr "" @@ -2927,7 +2988,7 @@ msgid "" "requested_datetime, updated_datetime, service_code and service_name." msgstr "" -#: perllib/FixMyStreet/Geocode/OSM.pm:158 +#: perllib/FixMyStreet/Geocode/OSM.pm:160 msgid "" "The following information about the nearest road might be inaccurate or " "irrelevant, if the problem is close to several roads or close to a road " @@ -3007,13 +3068,13 @@ msgid "" "give us permission." msgstr "" -#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:269 +#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:271 msgid "" "The user could not locate the problem on a map, but to see the area around " "the location they entered" msgstr "" -#: perllib/FixMyStreet/App/Controller/Reports.pm:72 +#: perllib/FixMyStreet/App/Controller/Reports.pm:71 msgid "" "There was a problem showing the All Reports page. Please try again later." msgstr "" @@ -3022,8 +3083,8 @@ msgstr "" msgid "There was a problem showing this page. Please try again later." msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:733 -#: perllib/FixMyStreet/App/Controller/Report/Update.pm:130 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:738 +#: perllib/FixMyStreet/App/Controller/Report/Update.pm:134 #: templates/web/default/auth/general.html:23 #: templates/web/fixmystreet/auth/general.html:24 msgid "" @@ -3037,7 +3098,7 @@ msgid "" "There was a problem with your email/password combination. Please try again." msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/Update.pm:252 +#: perllib/FixMyStreet/App/Controller/Report/Update.pm:256 msgid "There was a problem with your update. Please try again." msgstr "" @@ -3045,7 +3106,7 @@ msgstr "" msgid "There were problems with your report. Please see below." msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/Update.pm:279 +#: perllib/FixMyStreet/App/Controller/Report/Update.pm:283 msgid "There were problems with your update. Please see below." msgstr "" @@ -3055,7 +3116,7 @@ msgid "" "change without warnings in the future." msgstr "" -#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:339 +#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:341 msgid "" "This email has been sent to both councils covering the location of the " "problem, as the user did not categorise it; please ignore it if you're not " @@ -3063,15 +3124,15 @@ msgid "" "problem this is so we can add it to our system." msgstr "" -#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:342 +#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:344 msgid "" "This email has been sent to several councils covering the location of the " "problem, as the category selected is provided for all of them; please ignore " "it if you're not the correct council to deal with the issue." msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:865 -#: perllib/FixMyStreet/Cobrand/UK.pm:62 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:870 +#: perllib/FixMyStreet/Cobrand/UK.pm:54 msgid "This information is required" msgstr "Diese Information wird benötigt" @@ -3106,13 +3167,13 @@ msgstr "" #: templates/web/default/report/banner.html:12 #: templates/web/default/report/display.html:95 #: templates/web/emptyhomes/report/display.html:12 -#: templates/web/fixmystreet/report/display.html:90 +#: templates/web/fixmystreet/report/display.html:106 msgid "This problem has been fixed" msgstr "Dieser Mangel wurde behoben" #: templates/web/bromley/report/display.html:90 #: templates/web/default/report/display.html:90 -#: templates/web/fixmystreet/report/display.html:84 +#: templates/web/fixmystreet/report/display.html:100 msgid "This problem has not been fixed" msgstr "Dieser Mangel wurde nicht behoben" @@ -3124,24 +3185,24 @@ msgstr "Dieser Mangel ist in Bearbeitung" msgid "This problem is old and of unknown status." msgstr "Dieses Problem ist alt und hat einen unbekannten Status" -#: perllib/FixMyStreet/DB/ResultSet/AlertType.pm:83 +#: perllib/FixMyStreet/DB/ResultSet/AlertType.pm:86 msgid "This report is currently marked as closed." msgstr "" -#: perllib/FixMyStreet/DB/ResultSet/AlertType.pm:81 +#: perllib/FixMyStreet/DB/ResultSet/AlertType.pm:84 msgid "This report is currently marked as fixed." msgstr "" -#: perllib/FixMyStreet/DB/ResultSet/AlertType.pm:85 +#: perllib/FixMyStreet/DB/ResultSet/AlertType.pm:88 msgid "This report is currently marked as open." msgstr "" -#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:262 +#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:264 msgid "" "This web page also contains a photo of the problem, provided by the user." msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1024 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1038 #: templates/web/default/admin/timeline.html:1 msgid "Timeline" msgstr "" @@ -3151,7 +3212,7 @@ msgstr "" msgid "Title" msgstr "Titel" -#: templates/web/default/around/display_location.html:69 +#: templates/web/default/around/_report_banner.html:2 msgid "" "To <strong>report a problem</strong>, click on the map at the correct " "location." @@ -3170,7 +3231,7 @@ msgid "" "street name and area" msgstr "Geben Sie eine Adresse an" -#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:268 +#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:270 msgid "To view a map of the precise location of this issue" msgstr "" @@ -3181,7 +3242,7 @@ msgstr "" msgid "Total" msgstr "Total" -#: perllib/FixMyStreet/App/Controller/Reports.pm:43 +#: perllib/FixMyStreet/App/Controller/Reports.pm:42 msgid "Unable to look up areas in MaPit. Please try again later." msgstr "" @@ -3199,12 +3260,12 @@ msgstr "Unbekannt" msgid "Unknown alert type" msgstr "" -#: perllib/FixMyStreet/App/Controller/Report.pm:70 +#: perllib/FixMyStreet/App/Controller/Report.pm:87 msgid "Unknown problem ID" msgstr "" #: templates/web/bromley/report/display.html:66 -#: templates/web/fixmystreet/report/display.html:65 +#: templates/web/fixmystreet/report/display.html:81 msgid "Update" msgstr "Beschreibung" @@ -3242,7 +3303,7 @@ msgstr "" msgid "Update reopened problem" msgstr "" -#: templates/web/default/admin/council_contacts.html:62 +#: templates/web/default/admin/council_contacts.html:68 msgid "Update statuses" msgstr "" @@ -3250,9 +3311,9 @@ msgstr "" msgid "Update:" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:694 -#: perllib/FixMyStreet/App/Controller/Admin.pm:809 -#: perllib/FixMyStreet/App/Controller/Admin.pm:889 +#: perllib/FixMyStreet/App/Controller/Admin.pm:708 +#: perllib/FixMyStreet/App/Controller/Admin.pm:823 +#: perllib/FixMyStreet/App/Controller/Admin.pm:903 msgid "Updated!" msgstr "" @@ -3275,11 +3336,11 @@ msgstr "" msgid "Updates to this problem, FixMyStreet" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1182 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1196 msgid "User flag removed" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:1154 +#: perllib/FixMyStreet/App/Controller/Admin.pm:1168 msgid "User flagged" msgstr "" @@ -3287,8 +3348,8 @@ msgstr "" msgid "Users" msgstr "" -#: perllib/FixMyStreet/App/Controller/Admin.pm:309 -#: perllib/FixMyStreet/App/Controller/Admin.pm:339 +#: perllib/FixMyStreet/App/Controller/Admin.pm:315 +#: perllib/FixMyStreet/App/Controller/Admin.pm:345 msgid "Values updated" msgstr "" @@ -3309,13 +3370,12 @@ msgstr "" #: templates/web/default/around/display_location.html:33 #: templates/web/emptyhomes/around/display_location.html:0 #: templates/web/emptyhomes/around/display_location.html:16 -#: templates/web/fixmystreet/around/display_location.html:0 -#: templates/web/fixmystreet/around/display_location.html:33 msgid "Viewing a location" msgstr "" #: templates/web/bromley/report/display.html:0 #: templates/web/default/report/display.html:0 +#: templates/web/emptyhomes/report/display.html:1 #: templates/web/emptyhomes/report/display.html:2 #: templates/web/fixmystreet/report/display.html:0 msgid "Viewing a problem" @@ -3346,18 +3406,18 @@ msgid "" msgstr "" #: templates/web/bromley/report/display.html:141 -#: templates/web/fixmystreet/report/display.html:153 +#: templates/web/fixmystreet/report/display.html:175 msgid "We never show your email" msgstr "Ihre eMail wird nie angezeigt" #: templates/web/bromley/report/new/fill_in_details_form.html:133 #: templates/web/bromley/report/new/fill_in_details_form.html:179 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:130 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:190 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:133 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:200 msgid "We never show your email address or phone number." msgstr "Ihre eMail-Adresse oder Telefonnummer werden nie angezeigt" -#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:349 +#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:351 msgid "" "We realise this problem might be the responsibility of %s; however, we don't " "currently have any contact details for them. If you know of an appropriate " @@ -3365,19 +3425,19 @@ msgid "" msgstr "" #: templates/web/default/index.html:34 templates/web/emptyhomes/index.html:59 -#: templates/web/fixmystreet/index.html:45 +#: templates/web/fixmystreet/index.html:50 msgid "We send it to the council on your behalf" msgstr "" #: templates/web/bromley/report/new/fill_in_details_form.html:217 #: templates/web/default/report/new/notes.html:5 -#, fuzzy +#: templates/web/fixmybarangay/report/new/notes.html:5 msgid "" "We will only use your personal information in accordance with our <a href=\"/" "faq#privacy\">privacy policy.</a>" msgstr "" -"Wir verwenden Ihre persönlichen Daten nur entsprechend unserer <a " -"href=\"/faq#privacy\">Datenschutzrichtlinien.</a>" +"Wir verwenden Ihre persönlichen Daten nur entsprechend unserer <a href=" +"\"/faq#privacy\">Datenschutzrichtlinien.</a>" #: templates/web/fixmystreet/report/new/notes.html:4 #, fuzzy @@ -3385,8 +3445,8 @@ msgid "" "We will only use your personal information in accordance with our <a href=\"/" "privacy\">privacy policy.</a>" msgstr "" -"Wir verwenden Ihre persönlichen Daten nur entsprechend unserer <a " -"href=\"/faq#privacy\">Datenschutzrichtlinien.</a>" +"Wir verwenden Ihre persönlichen Daten nur entsprechend unserer <a href=" +"\"/faq#privacy\">Datenschutzrichtlinien.</a>" #: templates/web/emptyhomes/contact/blurb.html:2 msgid "" @@ -3401,8 +3461,8 @@ msgid "" "send an email to <a href='mailto:%s'>%s</a>:" msgstr "" -#: templates/web/default/admin/council_contacts.html:41 -#: templates/web/default/admin/council_edit.html:41 +#: templates/web/default/admin/council_contacts.html:45 +#: templates/web/default/admin/council_edit.html:69 msgid "When edited" msgstr "Wann editiert" @@ -3411,7 +3471,7 @@ msgstr "Wann editiert" msgid "When sent" msgstr "Wann gesendet" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:612 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:613 msgid "Whole block of empty flats" msgstr "" @@ -3443,6 +3503,7 @@ msgid "" msgstr "" #: templates/web/default/report/new/notes.html:8 +#: templates/web/fixmybarangay/report/new/notes.html:8 #: templates/web/fixmystreet/report/new/notes.html:7 msgid "" "Writing your message entirely in block capitals makes it hard to read, as " @@ -3455,8 +3516,9 @@ msgstr "" msgid "Year" msgstr "Jahr" -#: templates/web/default/admin/council_contacts.html:48 -#: templates/web/default/admin/council_contacts.html:49 +#: templates/web/default/admin/council_contacts.html:52 +#: templates/web/default/admin/council_contacts.html:53 +#: templates/web/default/admin/council_contacts.html:54 #: templates/web/default/admin/council_edit.html:5 #: templates/web/default/admin/list_updates.html:30 #: templates/web/default/admin/list_updates.html:31 @@ -3476,8 +3538,8 @@ msgstr "Ja" #: templates/web/bromley/report/display.html:155 #: templates/web/bromley/report/new/fill_in_details_form.html:198 -#: templates/web/fixmystreet/report/display.html:133 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:156 +#: templates/web/fixmystreet/report/display.html:149 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:160 msgid "Yes I have a password" msgstr "" @@ -3524,7 +3586,7 @@ msgstr "" #: templates/web/default/questionnaire/index.html:92 #: templates/web/default/report/new/fill_in_details_form.html:93 #: templates/web/fixmystreet/questionnaire/index.html:87 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:101 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:103 msgid "" "You have already attached a photo to this report, attaching another one will " "replace it." @@ -3532,7 +3594,7 @@ msgstr "" #: templates/web/bromley/report/display.html:106 #: templates/web/default/report/display.html:106 -#: templates/web/fixmystreet/report/display.html:100 +#: templates/web/fixmystreet/report/display.html:116 msgid "" "You have already attached a photo to this update, attaching another one will " "replace it." @@ -3544,12 +3606,12 @@ msgstr "" #: templates/web/bromley/report/new/fill_in_details_form.html:25 #: templates/web/default/report/new/fill_in_details_form.html:7 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:27 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:28 msgid "" "You have located the problem at the point marked with a green pin on the " "map. If this is not the correct location, simply click on the map again. " msgstr "" -"Der gr¨ne Pin auf der Karte repräsentiert ihre Meldung. Falls " +"Der grüne Pin auf der Karte repräsentiert ihre Meldung. Falls " "dieser Ort nicht der Richtige ist, klicken Sie einfach nochmals am richtigen " "Ort auf die Karte." @@ -3577,8 +3639,8 @@ msgstr "" msgid "You have successfully deleted your alert." msgstr "" -#: perllib/FixMyStreet/App/Controller/Report/New.pm:740 -#: perllib/FixMyStreet/App/Controller/Report/Update.pm:136 +#: perllib/FixMyStreet/App/Controller/Report/New.pm:745 +#: perllib/FixMyStreet/App/Controller/Report/Update.pm:140 msgid "" "You have successfully signed in; please check and confirm your details are " "accurate:" @@ -3608,15 +3670,15 @@ msgstr "" #: templates/web/fixmystreet/alert/updates.html:19 #: templates/web/fixmystreet/alert/updates.html:22 #: templates/web/fixmystreet/contact/index.html:72 -#: templates/web/fixmystreet/report/display.html:34 -#: templates/web/fixmystreet/report/display.html:36 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:142 +#: templates/web/fixmystreet/report/display.html:49 +#: templates/web/fixmystreet/report/display.html:51 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:146 msgid "Your email" msgstr "Ihre eMail" #: templates/web/bromley/report/display.html:130 #: templates/web/fixmystreet/auth/general.html:26 -#: templates/web/fixmystreet/report/display.html:124 +#: templates/web/fixmystreet/report/display.html:140 msgid "Your email address" msgstr "Ihre eMail-Adresse" @@ -3627,6 +3689,7 @@ msgstr "Ihre eMail-Adresse:" #: templates/web/default/alert/_list.html:92 #: templates/web/default/report/display.html:128 #: templates/web/default/report/new/fill_in_details_form.html:124 +#: templates/web/fixmybarangay/alert/_list.html:37 msgid "Your email:" msgstr "Ihre eMail:" @@ -3643,8 +3706,8 @@ msgid "" "Your information will only be used in accordance with our <a href=\"/privacy" "\">privacy policy</a>" msgstr "" -"Wir verwenden Ihre persönlichen Daten nur entsprechend unserer <a " -"href=\"/faq#privacy\">Datenschutzrichtlinien.</a>" +"Wir verwenden Ihre persönlichen Daten nur entsprechend unserer <a href=" +"\"/faq#privacy\">Datenschutzrichtlinien.</a>" #: templates/web/bromley/report/display.html:199 #: templates/web/bromley/report/new/fill_in_details_form.html:123 @@ -3653,11 +3716,11 @@ msgstr "" msgid "Your last name" msgstr "Ihr Name" -#: templates/web/fixmystreet/auth/general.html:53 +#: templates/web/fixmystreet/auth/general.html:57 #: templates/web/fixmystreet/contact/index.html:65 -#: templates/web/fixmystreet/report/display.html:181 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:121 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:181 +#: templates/web/fixmystreet/report/display.html:203 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:123 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:191 msgid "Your name" msgstr "Ihr Name" @@ -3670,9 +3733,9 @@ msgstr "Ihr Name:" #: templates/web/bromley/report/display.html:160 #: templates/web/bromley/report/new/fill_in_details_form.html:203 -#: templates/web/fixmystreet/auth/general.html:37 -#: templates/web/fixmystreet/report/display.html:138 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:161 +#: templates/web/fixmystreet/auth/general.html:41 +#: templates/web/fixmystreet/report/display.html:154 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:165 msgid "Your password" msgstr "Ihr Passwort" @@ -3682,8 +3745,8 @@ msgstr "Ihr Passwort wurde geändert" #: templates/web/bromley/report/new/fill_in_details_form.html:137 #: templates/web/bromley/report/new/fill_in_details_form.html:184 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:134 -#: templates/web/fixmystreet/report/new/fill_in_details_form.html:195 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:138 +#: templates/web/fixmystreet/report/new/fill_in_details_form.html:205 msgid "Your phone number" msgstr "Ihre Telefonnummer" @@ -3700,7 +3763,7 @@ msgstr "Ihre Meldung" msgid "Your reports" msgstr "Ihre Meldungen" -#: templates/web/default/my/my.html:45 templates/web/fixmystreet/my/my.html:45 +#: templates/web/default/my/my.html:45 templates/web/fixmystreet/my/my.html:49 msgid "Your updates" msgstr "" @@ -3720,12 +3783,16 @@ msgstr "" msgid "council" msgstr "" +#: perllib/FixMyStreet/DB/Result/Problem.pm:611 +msgid "council ref: %s" +msgstr "" + #: templates/web/default/admin/report_edit.html:15 msgid "didn't use map" msgstr "hat Karte nicht verwendet" #: templates/web/default/alert/index.html:33 -#: templates/web/fixmystreet/around/postcode_form.html:17 +#: templates/web/fixmystreet/around/postcode_form.html:23 msgid "e.g. ‘%s’ or ‘%s’" msgstr "" @@ -3733,7 +3800,7 @@ msgstr "" msgid "from %d different users" msgstr "" -#: perllib/Utils.pm:289 +#: perllib/Utils.pm:295 msgid "less than a minute" msgstr "weniger als einer Minute" @@ -3745,13 +3812,14 @@ msgstr "" msgid "marked as fixed" msgstr "als gelöst markiert" -#: perllib/FixMyStreet/App/Controller/Admin.pm:112 +#: perllib/FixMyStreet/App/Controller/Admin.pm:113 #: templates/web/default/admin/questionnaire.html:15 #: templates/web/default/admin/questionnaire.html:16 msgid "n/a" msgstr "" #: templates/web/default/alert/_list.html:87 +#: templates/web/fixmybarangay/alert/_list.html:32 #: templates/web/fixmystreet/alert/_list.html:85 msgid "or" msgstr "oder" @@ -3770,7 +3838,7 @@ msgstr "" #: templates/web/barnet/header.html:71 templates/web/bromley/header.html:100 #: templates/web/bromley/header.html:65 -#: templates/web/fixmybarangay/header.html.orig:43 +#: templates/web/fixmybarangay/header.html:67 #: templates/web/fixmystreet/header.html:48 #: templates/web/zurich/header.html:48 msgid "sign out" @@ -3785,21 +3853,15 @@ msgstr "ausloggen" msgid "the local council" msgstr "" -#: perllib/FixMyStreet/DB/Result/Problem.pm:541 -msgid "the map was not used so pin location may be inaccurate" -msgstr "" -"Die Karte wurde nicht verwendet und die Stecknadel könnte demnach " -"ungenau sein" - -#: perllib/FixMyStreet/DB/Result/Problem.pm:603 -msgid "their ref: %s" +#: perllib/FixMyStreet/DB/Result/Problem.pm:549 +msgid "there is no pin shown as the user did not use the map" msgstr "" -#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:330 +#: perllib/FixMyStreet/DB/ResultSet/Problem.pm:332 msgid "this type of local problem" msgstr "" -#: perllib/Utils.pm:263 +#: perllib/Utils.pm:269 msgid "today" msgstr "heute" @@ -3852,21 +3914,49 @@ msgstr "" msgid "your update will not be posted" msgstr "" -#: templates/web/emptyhomes/report/new/councils_text_none.html:3 +#: templates/web/default/front/stats.html:17 +#, perl-format +msgid "<big>%s</big> report recently" +msgid_plural "<big>%s</big> reports recently" +msgstr[0] "" +msgstr[1] "" + +#: perllib/Utils.pm:314 +#, perl-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d Stunde" +msgstr[1] "%d Stunden" + +#: perllib/Utils.pm:316 +#, perl-format +msgid "%d minute" +msgid_plural "%d minutes" +msgstr[0] "%d Minute" +msgstr[1] "%d Minuten" + +#: templates/web/default/front/stats.html:29 +#, perl-format +msgid "<big>%s</big> update on reports" +msgid_plural "<big>%s</big> updates on reports" +msgstr[0] "<big>%s</big> Meldung bearbeitet" +msgstr[1] "<big>%s</big> Meldungen bearbeitet" + +#: templates/web/default/report/new/councils_text_none.html:5 #, perl-format msgid "We do not yet have details for the council that covers this location." msgid_plural "" "We do not yet have details for the councils that cover this location." msgstr[0] "" -#: templates/web/emptyhomes/front/stats.html:17 +#: perllib/Utils.pm:310 #, perl-format -msgid "<big>%s</big> report recently" -msgid_plural "<big>%s</big> reports recently" -msgstr[0] "" -msgstr[1] "" +msgid "%d week" +msgid_plural "%d weeks" +msgstr[0] "%d Woche" +msgstr[1] "%d Wochen" -#: templates/web/emptyhomes/front/stats.html:12 +#: templates/web/default/front/stats.html:12 #, perl-format msgid "<big>%s</big> report in past week" msgid_plural "<big>%s</big> reports in past week" @@ -3891,9 +3981,17 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: templates/web/default/front/stats.html:29 +#: perllib/Utils.pm:312 #, perl-format -msgid "<big>%s</big> update on reports" -msgid_plural "<big>%s</big> updates on reports" -msgstr[0] "<big>%s</big> Meldung bearbeitet" -msgstr[1] "<big>%s</big> Meldungen bearbeitet" +msgid "%d day" +msgid_plural "%d days" +msgstr[0] "%d Tag" +msgstr[1] "%d Tage" + +#~ msgid "All" +#~ msgstr "Alle" + +#~ msgid "the map was not used so pin location may be inaccurate" +#~ msgstr "" +#~ "Die Karte wurde nicht verwendet und die Stecknadel könnte demnach " +#~ "ungenau sein" diff --git a/locale/nb_NO.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/nb_NO.UTF-8/LC_MESSAGES/FixMyStreet.po index 58b307d58..bcf77f56c 100644 --- a/locale/nb_NO.UTF-8/LC_MESSAGES/FixMyStreet.po +++ b/locale/nb_NO.UTF-8/LC_MESSAGES/FixMyStreet.po @@ -5,20 +5,22 @@ # # Matthew Somerville <matthew@mysociety.org>, 2008-04-15. # Petter Reinholdtsen <pere@hungry.com>, 2011. +# Anders Einar Hilden <hildenae@gmail.com>, 2012. msgid "" msgstr "" "Project-Id-Version: FixMyStreet\n" "Report-Msgid-Bugs-To: matthew@mysociety.org\n" "POT-Creation-Date: 2012-08-21 09:54+0100\n" -"PO-Revision-Date: 2012-08-07 01:09+0100\n" +"PO-Revision-Date: 2012-09-14 00:22+0100\n" "Last-Translator: Anders Einar Hilden <hildenae@gmail.com>\n" "Language-Team: Norwegian Bokmål <i18n-nb@lister.ping.uio.no>\n" -"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: KBabel 1.11.4\n" +"X-Poedit-Basepath: ../../../\n" +"Language: Norwegian Bokmål\n" #: perllib/FixMyStreet/DB/Result/Problem.pm:555 #: perllib/FixMyStreet/DB/ResultSet/Problem.pm:337 @@ -107,7 +109,7 @@ msgstr "%s - oppsummeringsrapporter" #: perllib/FixMyStreet/DB/Result/Problem.pm:605 msgid "%s ref: %s" -msgstr "" +msgstr "%s ref: %s" #: perllib/FixMyStreet/Cobrand/UK.pm:288 perllib/FixMyStreet/Cobrand/UK.pm:300 msgid "%s ward, %s" @@ -150,9 +152,8 @@ msgstr "(alternativt kan RSS-strømmen tilpasses, innenfor" #: templates/web/default/around/around_map_list_items.html:12 #: templates/web/default/around/on_map_list_items.html:9 #: templates/web/fixmystreet/report/_item.html:23 -#, fuzzy msgid "(closed)" -msgstr "Lukket" +msgstr "(lukket)" #: templates/web/default/around/around_map_list_items.html:10 #: templates/web/default/around/on_map_list_items.html:7 @@ -203,12 +204,11 @@ msgstr "-- Velg en kategori --" msgid "-- Pick a property type --" msgstr "-- Velg en eiendomsstype --" -# Bør "portalen" byttes ut med et annet ord? (trenger kontekst) +# Trenger kontekst for bedre oversettelse #: templates/web/default/tokens/confirm_problem.html:14 #: templates/web/default/tokens/confirm_problem.html:22 -#, fuzzy msgid ". You can <a href=\"%s%s\">view the problem on this site</a>." -msgstr ". Du kan <a href=\"%s\">lese om problemet på portalen </a>." +msgstr ". Du kan <a href=\"%s\">lese om problemet på denne siden</a>." #: templates/web/default/questionnaire/completed.html:20 msgid "" @@ -218,8 +218,8 @@ msgstr "" "<p style=\"font-size:150%\">Tusen takk for at du fylte ut vårt spørreskjema. " "Vi er glad for å høre at ditt problem er blitt fikset.</p>" +# Er pledgebank noe vi vil sende uvitende, norske innbyggere til? #: templates/web/fiksgatami/questionnaire/completed-open.html:1 -#, fuzzy msgid "" "<p style=\"font-size:150%\">We’re sorry to hear that. We have two\n" "suggestions: why not try <a href=\"http://www.norge.no/styresmakter/" @@ -229,15 +229,14 @@ msgid "" "<a href=\"http://www.pledgebank.com/new\">make and publicise a pledge</a>?\n" "</p>" msgstr "" -"<p style=\"font-size:150%%\">Det var trist å høre dette. Vi har to forslag: " +"<p style=\"font-size:150%\">Det var trist å høre dette. Vi har to forslag: " "hva med å forsøke\n" -"<a href=\"%s\">å skrive direkte til dine representanter</a>, eller hvis det " -"er et problem som kan fikses\n" +"<a href=\"http://www.norge.no/styresmakter/\">å skrive direkte til dine \n" +"representanter</a>, eller hvis det er et problem som kan fikses\n" "av folk i nabolaget som jobber sammen, hva med å <a href=\"http://www." "pledgebank.com/new\">publisere en utfordring om å bidra</a>?</p>" #: templates/web/fixmystreet/questionnaire/completed-open.html:1 -#, fuzzy msgid "" "<p style=\"font-size:150%\">We’re sorry to hear that. We have two\n" "suggestions: why not try <a href=\"http://www.writetothem.com/\">writing " @@ -248,7 +247,7 @@ msgid "" "<a href=\"http://www.pledgebank.com/new\">make and publicise a pledge</a>?\n" "</p>" msgstr "" -"<p style=\"font-size:150%%\">Det var trist å høre dette. Vi har to forslag: " +"<p style=\"font-size:150%\">Det var trist å høre dette. Vi har to forslag: " "hva med å forsøke\n" "<a href=\"%s\">å skrive direkte til dine representanter</a>, eller hvis det " "er et problem som kan fikses\n" @@ -256,7 +255,6 @@ msgstr "" "pledgebank.com/new\">publisere en utfordring om å bidra</a>?</p>" #: templates/web/default/questionnaire/completed-open.html:1 -#, fuzzy msgid "" "<p style=\"font-size:150%\">We’re sorry to hear that. We have two\n" "suggestions: why not try writing to your local representative or, if " @@ -267,8 +265,8 @@ msgid "" msgstr "" "<p style=\"font-size:150%%\">Det var trist å høre dette. Vi har to forslag: " "hva med å forsøke\n" -"<a href=\"%s\">å skrive direkte til dine representanter</a>, eller hvis det " -"er et problem som kan fikses\n" +"å skrive direkte til dine representanter, eller hvis det er et problem som " +"kan fikses\n" "av folk i nabolaget som jobber sammen, hva med å <a href=\"http://www." "pledgebank.com/new\">publisere en utfordring om å bidra</a>?</p>" @@ -429,12 +427,11 @@ msgstr "All informasjonen du har lagt inn her vil bli sendt til" #: templates/web/default/report/new/councils_text_all.html:10 #: templates/web/default/report/new/councils_text_all.html:12 -#, fuzzy msgid "" "All the information you provide here will be sent to <strong>%s</strong> or " "<strong>Roads Service</strong>." msgstr "" -"All informasjonen du har lagt inn her vil bli sendt til <strong>%s</strong>." +"All informasjon du legger inn her vil bli sendt til <strong>%s</strong>." #: templates/web/default/report/new/councils_text_all.html:3 #: templates/web/default/report/new/councils_text_all.html:5 @@ -768,7 +765,7 @@ msgstr "For tiden har 1+ slettet" #: templates/web/default/dashboard/index.html:5 #: templates/web/default/dashboard/index.html:7 msgid "Dashboard" -msgstr "" +msgstr "Oversikt" #: templates/web/default/admin/council_contacts.html:38 #: templates/web/default/admin/council_contacts.html:85 @@ -906,22 +903,22 @@ msgstr "Sluttmåned:" msgid "Enter a nearby GB postcode, or street name and area" msgstr "Skriv inn GB-postnummer i nærheten, eller veinavn og sted" +# Fra UK cobrand #: perllib/FixMyStreet/Cobrand/UK.pm:18 -#, fuzzy msgid "Enter a nearby UK postcode, or street name and area" -msgstr "Skriv inn postnummer i nærheten, eller veinavn og sted" +msgstr "Skriv inn et britisk postnummer i nærheten, eller veinavn og sted" #: perllib/FixMyStreet/Cobrand/FiksGataMi.pm:25 msgid "Enter a nearby postcode, or street name and area" msgstr "Skriv inn postnummer i nærheten, eller veinavn og sted" +# Kan "Oppgi" være bedre? #: templates/web/default/around/postcode_form.html:1 #: templates/web/default/around/postcode_form.html:2 #: templates/web/fixmystreet/around/postcode_form.html:10 #: templates/web/fixmystreet/around/postcode_form.html:11 -#, fuzzy msgid "Enter a nearby street name and area" -msgstr "Skriv inn postnummer i nærheten, eller veinavn og sted" +msgstr "Skriv inn et veinavn og sted" #: templates/web/default/auth/general.html:64 #: templates/web/default/report/display.html:171 @@ -962,9 +959,8 @@ msgid "Examples:" msgstr "Eksempler:" #: templates/web/default/admin/report_edit.html:40 -#, fuzzy msgid "Extra data:" -msgstr "Merkevaresamarbeidsdata:" +msgstr "Ekstra data:" #: templates/web/bromley/contact/submit.html:14 #: templates/web/default/contact/submit.html:15 @@ -978,9 +974,8 @@ msgstr "" #: templates/web/bromley/report/display.html:189 #: templates/web/bromley/report/new/fill_in_details_form.html:113 #: templates/web/bromley/report/new/fill_in_details_form.html:160 -#, fuzzy msgid "First Name" -msgstr "Første gang" +msgstr "Fornavn" #: templates/web/default/questionnaire/index.html:79 #: templates/web/fixmystreet/questionnaire/index.html:73 @@ -1117,7 +1112,6 @@ msgstr "Få oppdateringer" #: templates/web/fixmystreet/reports/_rss.html:3 #: templates/web/fixmystreet/reports/_rss.html:9 -#, fuzzy msgid "Get updates of %s problems" msgstr "Få oppdateringer for problemer i denne %s" @@ -1389,9 +1383,8 @@ msgstr "Husk min innlogging på denne datamaskinen" #: templates/web/bromley/report/display.html:195 #: templates/web/bromley/report/new/fill_in_details_form.html:119 #: templates/web/bromley/report/new/fill_in_details_form.html:166 -#, fuzzy msgid "Last Name" -msgstr "Siste oppdatering:" +msgstr "Etternavn" #: templates/web/default/admin/council_contacts.html:39 msgid "Last editor" @@ -1950,6 +1943,8 @@ msgid "" "Please describe the exact location of the report. Example: “2 dumped " "mattresses outside Number 19 Stockwell Close”" msgstr "" +"Vennligst beskriv den nøyaktige posisjonen til problemet. For eksempel: «2 " +"madrasser dumpet utenfor Jernbanegata 19»" #: templates/web/default/contact/blurb.html:2 msgid "" @@ -2022,9 +2017,8 @@ msgid "Please enter your email address" msgstr "Vennligst tast inn din e-postadresse" #: templates/web/default/js/validation_strings.html:19 -#, fuzzy msgid "Please enter your first name" -msgstr "Legg inn ditt navn" +msgstr "Vennligst tast inn ditt fornavn" #: perllib/FixMyStreet/DB/Result/Problem.pm:340 #: templates/web/default/js/validation_strings.html:7 @@ -2045,14 +2039,12 @@ msgid "Please enter your name" msgstr "Legg inn ditt navn" #: templates/web/default/js/validation_strings.html:20 -#, fuzzy msgid "Please enter your second name" -msgstr "Legg inn ditt navn" +msgstr "Vennligst tast inn ditt mellomnavn" #: templates/web/default/js/validation_strings.html:18 -#, fuzzy msgid "Please enter your title" -msgstr "Legg inn din e-post" +msgstr "Vennligst legg inn din tittel" #: templates/web/emptyhomes/report/new/fill_in_details_text.html:1 msgid "" @@ -2112,6 +2104,8 @@ msgstr "Vennligst indiker om du ønsker å motta et nytt spørreskjema" #: templates/web/fixmystreet/report/updates-sidebar-notes.html:3 msgid "Please note that updates are not sent to the council." msgstr "" +"Vær oppmerksom på at oppdaterginger ikke blir videresendt til " +"administrasjonen." #: templates/web/default/report/display.html:56 msgid "" @@ -2125,16 +2119,15 @@ msgstr "" "\">personvernpolicy</a>" #: templates/web/barnet/report/updates-sidebar-notes.html:1 -#, fuzzy msgid "" "Please note that updates are not sent to the relevant department. If you " "leave your name it will be public. Your information will only be used in " "accordance with our <a href=\"/faq#privacy\">privacy policy</a>" msgstr "" -"Vennligst merk at oppdateringer ikke blir sendt til administrasjonen. Hvis " -"du legger igjen navnet ditt så vil det være offentlig tilgjengelig. Din " +"Vennligst merk at oppdateringer ikke vil bli sendt til administrasjonen. " +"Dersom du legger igjen navnet ditt vil det være synlig for alle. Din " "informasjon vil kun bli brukt i henhold til våre <a href=\"/faq#privacy" -"\">personvernpolicy</a>" +"\">personvernsregler</a>" #: templates/web/bromley/report/new/fill_in_details_form.html:23 #: templates/web/default/report/new/fill_in_details_form.html:5 @@ -2190,9 +2183,8 @@ msgid "Please upload a JPEG image only" msgstr "Vennligst last opp kun JPEG-bilder" #: perllib/FixMyStreet/App/Controller/Photo.pm:183 -#, fuzzy msgid "Please upload a JPEG image only\n" -msgstr "Vennligst last opp kun JPEG-bilder" +msgstr "Vennligst last opp kun JPEG eller JPG-bilder\n" #: perllib/FixMyStreet/App/Controller/Contact.pm:98 msgid "Please write a message" @@ -2327,14 +2319,13 @@ msgid "Provide an update" msgstr "Bidra med en oppdatering" #: templates/web/bromley/report/new/fill_in_details_form.html:180 -#, fuzzy msgid "" "Providing a password is optional, but doing so will allow you to more easily " "report future problems, leave updates and manage your reports." msgstr "" "Det er valgfritt å oppgi et passord, men om du gjør det vil det bli enklere " "for deg å rapportere problemer, legge inn oppdateringer og holde oversikt " -"over dine rapporter" +"over dine rapporter." #: templates/web/bromley/report/display.html:142 #: templates/web/default/report/display.html:175 @@ -2947,14 +2938,13 @@ msgstr "" "å løse UKs tomme hjem-krise." #: templates/web/fixmystreet/around/around_index.html:27 -#, fuzzy msgid "" "Thanks for uploading your photo. We now need to locate your problem, so " "please enter a nearby street name or postcode in the box above :" msgstr "" -"Takk for at du lastet opp ditt bilde. Nå trenger vi å plassere ditt problem," -"så vær så snill å skriv inn navn på vei i nærheten, eller postnummer i " -"boksen under :" +"Takk for at du lastet opp ditt bilde. Vi må nå plassere ditt problem, så " +"vær så snill å skriv inn navnet på en vei eller et postnummer i området i " +"boksen ovenfor :" #: templates/web/default/around/around_index.html:28 msgid "" @@ -2983,17 +2973,15 @@ msgid "" msgstr "Bildet ser ikke ut til å blitt lastet opp riktig (%s), prøv på nytt." #: perllib/FixMyStreet/App/Controller/Council.pm:91 -#, fuzzy msgid "" "That location does not appear to be covered by a council; perhaps it is " "offshore or outside the country. Please try again." msgstr "" -"Det stedet dekkes ikke av noen administrasjon, kanskje det er til havs - " -"vennligst forsøk et mer spesifikt sted." +"Det stedet dekkes ikke av noen administrasjon, kanskje det er til havs eller " +"utenfor lander - vennligst forsøk et annet sted." # Should this be "Norge" or "Storbritannia" ? #: perllib/FixMyStreet/App/Controller/Location.pm:107 -#, fuzzy msgid "That location does not appear to be in the UK; please try again." msgstr "Det stedet virker ikke å være i Storbritannia. Vennligst prøv igjen." @@ -3199,11 +3187,8 @@ msgstr "" "senere." #: perllib/FixMyStreet/App/Controller/Dashboard.pm:59 -#, fuzzy msgid "There was a problem showing this page. Please try again later." -msgstr "" -"Det var problemer med å vise 'Alle rapporter'-siden. Vennligst prøv igjen " -"senere." +msgstr "Det var problemer med å vise denne siden. Vennligst prøv igjen senere." #: perllib/FixMyStreet/App/Controller/Report/New.pm:733 #: perllib/FixMyStreet/App/Controller/Report/Update.pm:130 @@ -3370,12 +3355,11 @@ msgstr "" "For å <strong>rapportere et problem</strong>, klikk på kartet på riktig sted." #: templates/web/default/alert/index.html:27 -#, fuzzy msgid "" "To find out what local alerts we have for you, please enter your postcode or " "street name and area" msgstr "" -"Du finner lokale problemer ved å søke på ditt postnummer, veinavn eller sted:" +"Du finner lokale problemer ved å søke på ditt postnummer, veinavn eller sted" #: perllib/FixMyStreet/DB/ResultSet/Problem.pm:268 msgid "To view a map of the precise location of this issue" @@ -3505,9 +3489,8 @@ msgid "View report on site" msgstr "Se rapport på nettstedet" #: templates/web/default/reports/council.html:18 -#, fuzzy msgid "View reports by ward" -msgstr "Se rapport på nettstedet" +msgstr "Se rapport per bydel" #: templates/web/emptyhomes/tokens/confirm_problem.html:39 msgid "View your report" @@ -3595,13 +3578,12 @@ msgstr "" "faq#privacy\">personvernpolicy.</a>" #: templates/web/fixmystreet/report/new/notes.html:4 -#, fuzzy msgid "" "We will only use your personal information in accordance with our <a href=\"/" "privacy\">privacy policy.</a>" msgstr "" -"Vi vil kun bruke personlig informasjon om deg i henhold til vår <a href=\"/" -"faq#privacy\">personvernpolicy.</a>" +"Vi vil kun bruke personlige informasjon om deg i henhold til våre <a href=\"/" +"faq#privacy\">personvernsregler.</a>" #: templates/web/emptyhomes/contact/blurb.html:2 msgid "" @@ -3648,7 +3630,6 @@ msgstr "" "href=\"%s\">MaPit</a>." #: templates/web/fixmystreet/footer.html:22 -#, fuzzy msgid "" "Would you like better integration with FixMyStreet? <a href=\"http://www." "mysociety.org/for-councils/fixmystreet/\">Find out about FixMyStreet for " @@ -3886,25 +3867,22 @@ msgstr "Din e-post" #: templates/web/bromley/report/display.html:193 #: templates/web/bromley/report/new/fill_in_details_form.html:117 #: templates/web/bromley/report/new/fill_in_details_form.html:164 -#, fuzzy msgid "Your first name" -msgstr "Ditt navn" +msgstr "Ditt fornavn" #: templates/web/fixmystreet/report/updates-sidebar-notes.html:5 -#, fuzzy msgid "" "Your information will only be used in accordance with our <a href=\"/privacy" "\">privacy policy</a>" msgstr "" -"Vi vil kun bruke personlig informasjon om deg i henhold til vår <a href=\"/" -"faq#privacy\">personvernpolicy.</a>" +"Vi vil kun bruke personlig informasjon om deg i henhold til våre <a href=\"/" +"faq#privacy\">personvernsregler.</a>" #: templates/web/bromley/report/display.html:199 #: templates/web/bromley/report/new/fill_in_details_form.html:123 #: templates/web/bromley/report/new/fill_in_details_form.html:170 -#, fuzzy msgid "Your last name" -msgstr "Ditt navn" +msgstr "Ditt etternavn" #: templates/web/fixmystreet/auth/general.html:53 #: templates/web/fixmystreet/contact/index.html:65 @@ -4043,7 +4021,7 @@ msgstr "kartet ble ikke brukt, så nåleposisjon kan være unøyaktig" #: perllib/FixMyStreet/DB/Result/Problem.pm:603 msgid "their ref: %s" -msgstr "" +msgstr "deres ref: %s" #: perllib/FixMyStreet/DB/ResultSet/Problem.pm:330 msgid "this type of local problem" diff --git a/notes/no-update-server b/notes/no-update-server index 2d149d850..da3656829 100644 --- a/notes/no-update-server +++ b/notes/no-update-server @@ -511,7 +511,7 @@ case "$1" in ;; update) fetch_git_source - fgmdbpassword=$(grep OPTION_BCI_DB_PASS $basedir/fixmystreet/conf/general | cut -d\' -f4) + fgmdbpassword=$(grep OPTION_FMS_DB_PASS $basedir/fixmystreet/conf/general | cut -d\' -f4) midbpassword=$(grep OPTION_MAPIT_DB_PASS $basedir/mapit/conf/general | cut -d\' -f4) update_fixmystreet_config www-data $fgmdbpassword fixmystreet diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm index ef299d224..b53b6ab06 100644 --- a/perllib/FixMyStreet/App/Controller/Admin.pm +++ b/perllib/FixMyStreet/App/Controller/Admin.pm @@ -7,6 +7,7 @@ BEGIN { extends 'Catalyst::Controller'; } use POSIX qw(strftime strcoll); use Digest::MD5 qw(md5_hex); use mySociety::EmailUtil qw(is_valid_email); +use if !$ENV{TRAVIS}, 'Image::Magick'; use FixMyStreet::SendReport; @@ -305,6 +306,10 @@ sub update_contacts : Private { $contact->note( $c->req->param('note') ); $contact->whenedited( \'ms_current_timestamp()' ); $contact->editor( $editor ); + $contact->endpoint( $c->req->param('endpoint') ); + $contact->jurisdiction( $c->req->param('jurisdiction') ); + $contact->api_key( $c->req->param('api_key') ); + $contact->send_method( $c->req->param('send_method') ); if ( $contact->in_storage ) { $c->stash->{updated} = _('Values updated'); @@ -341,7 +346,7 @@ sub update_contacts : Private { } elsif ( $posted eq 'open311' ) { $c->forward('check_token'); - my %params = map { $_ => $c->req->param($_) || '' } qw/open311_id endpoint jurisdiction api_key area_id send_method send_comments suppress_alerts comment_user_id/; + my %params = map { $_ => $c->req->param($_) || '' } qw/open311_id endpoint jurisdiction api_key area_id send_method send_comments suppress_alerts comment_user_id devolved/; if ( $params{open311_id} ) { my $conf = $c->model('DB::Open311Conf')->find( { id => $params{open311_id} } ); @@ -353,6 +358,7 @@ sub update_contacts : Private { $conf->send_comments( $params{send_comments} || 0); $conf->suppress_alerts( $params{suppress_alerts} || 0); $conf->comment_user_id( $params{comment_user_id} || undef ); + $conf->can_be_devolved( $params{devolved} || 0 ); $conf->update(); @@ -367,6 +373,7 @@ sub update_contacts : Private { $conf->send_comments( $params{send_comments} || 0); $conf->suppress_alerts( $params{suppress_alerts} || 0); $conf->comment_user_id( $params{comment_user_id} || undef ); + $conf->can_be_devolved( $params{devolved} || 0 ); $conf->insert(); @@ -462,6 +469,9 @@ sub council_edit : Path('council_edit') : Args(2) { $c->stash->{history} = $history; + my @methods = map { $_ =~ s/FixMyStreet::SendReport:://; $_ } keys %{ FixMyStreet::SendReport->get_senders }; + $c->stash->{send_methods} = \@methods; + return 1; } @@ -652,7 +662,6 @@ sub report_edit : Path('report_edit') : Args(1) { || $flagged != $problem->flagged || $non_public != $problem->non_public ) { - warn "edited"; $edited = 1; } @@ -1281,7 +1290,6 @@ sub trim { sub _rotate_image { my ($photo, $direction) = @_; - use Image::Magick; my $image = Image::Magick->new; $image->BlobToImage($photo); my $err = $image->Rotate($direction); diff --git a/perllib/FixMyStreet/App/Controller/Alert.pm b/perllib/FixMyStreet/App/Controller/Alert.pm index 4e5319a59..91ea61fbc 100644 --- a/perllib/FixMyStreet/App/Controller/Alert.pm +++ b/perllib/FixMyStreet/App/Controller/Alert.pm @@ -438,7 +438,7 @@ sub determine_location : Private { $c->detach('choose'); } - $c->go('index') if $c->stash->{location_error}; + $c->go('index'); } # truncate the lat,lon for nicer urls diff --git a/perllib/FixMyStreet/App/Controller/Around.pm b/perllib/FixMyStreet/App/Controller/Around.pm index 3047b195c..f2bb23350 100644 --- a/perllib/FixMyStreet/App/Controller/Around.pm +++ b/perllib/FixMyStreet/App/Controller/Around.pm @@ -45,7 +45,7 @@ sub around_index : Path : Args(0) { || $c->forward('/location/determine_location_from_pc'); # Check to see if the spot is covered by a council - if not show an error. - return unless $c->forward('check_location_is_acceptable'); + return unless $c->cobrand->moniker eq 'fixmybarangay' || $c->forward('check_location_is_acceptable'); # If we have a partial - redirect to /report/new so that it can be # completed. @@ -204,6 +204,7 @@ sub display_location : Private { longitude => $short_longitude, clickable => 1, pins => \@pins, + area => $c->cobrand->areas_on_around, ); return 1; diff --git a/perllib/FixMyStreet/App/Controller/Council.pm b/perllib/FixMyStreet/App/Controller/Council.pm index a6ce533e4..cb9e78421 100644 --- a/perllib/FixMyStreet/App/Controller/Council.pm +++ b/perllib/FixMyStreet/App/Controller/Council.pm @@ -52,7 +52,6 @@ sub load_and_check_councils : Private { my $short_latitude = Utils::truncate_coordinate($latitude); my $short_longitude = Utils::truncate_coordinate($longitude); - # TODO: I think we want in_gb_locale around the MaPit line, needs testing my $all_councils; if ( $c->stash->{fetch_all_areas} ) { my %area_types = map { $_ => 1 } @$area_types; diff --git a/perllib/FixMyStreet/App/Controller/Dashboard.pm b/perllib/FixMyStreet/App/Controller/Dashboard.pm index e4266dc64..a5ba8ff07 100644 --- a/perllib/FixMyStreet/App/Controller/Dashboard.pm +++ b/perllib/FixMyStreet/App/Controller/Dashboard.pm @@ -96,7 +96,7 @@ sub index : Path : Args(0) { $c->stash->{council} = $council_detail; my $children = mySociety::MaPit::call('area/children', $council, - type => $mySociety::VotingArea::council_child_types, + type => $c->cobrand->area_types_children, ); $c->stash->{children} = $children; diff --git a/perllib/FixMyStreet/App/Controller/Location.pm b/perllib/FixMyStreet/App/Controller/Location.pm index c3d754485..3e44cd748 100644 --- a/perllib/FixMyStreet/App/Controller/Location.pm +++ b/perllib/FixMyStreet/App/Controller/Location.pm @@ -64,6 +64,19 @@ sub determine_location_from_pc : Private { $pc ||= $c->req->param('pc') || return; $c->stash->{pc} = $pc; # for template + if ( $pc =~ /^(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)$/ ) { + $c->stash->{latitude} = $1; + $c->stash->{longitude} = $2; + return $c->forward( 'check_location' ); + } + if ( $c->cobrand->country eq 'GB' && $pc =~ /^([A-Z])([A-Z])([\d\s]+)$/i ) { + if (my $convert = gridref_to_latlon( $1, $2, $3 )) { + $c->stash->{latitude} = $convert->{latitude}; + $c->stash->{longitude} = $convert->{longitude}; + return $c->forward( 'check_location' ); + } + } + my ( $latitude, $longitude, $error ) = FixMyStreet::Geocode::lookup( $pc, $c ); @@ -114,6 +127,36 @@ sub check_location : Private { return 1; } +# Utility function for if someone (rarely) enters a grid reference +sub gridref_to_latlon { + my ( $a, $b, $num ) = @_; + $a = ord(uc $a) - 65; $a-- if $a > 7; + $b = ord(uc $b) - 65; $b-- if $b > 7; + my $e = (($a-2)%5)*5 + $b%5; + my $n = 19 - int($a/5)*5 - int($b/5); + + $num =~ s/\s+//g; + my $l = length($num); + return if $l % 2 or $l > 10; + + $l /= 2; + $e .= substr($num, 0, $l); + $n .= substr($num, $l); + + if ( $l < 5 ) { + $e .= 5; + $n .= 5; + $e .= 0 x (4-$l); + $n .= 0 x (4-$l); + } + + my ( $lat, $lon ) = Utils::convert_en_to_latlon( $e, $n ); + return { + latitude => $lat, + longitude => $lon, + }; +} + =head1 AUTHOR Struan Donald diff --git a/perllib/FixMyStreet/App/Controller/Photo.pm b/perllib/FixMyStreet/App/Controller/Photo.pm index fc4c3fde7..fa4baf045 100644 --- a/perllib/FixMyStreet/App/Controller/Photo.pm +++ b/perllib/FixMyStreet/App/Controller/Photo.pm @@ -9,6 +9,7 @@ use Digest::SHA1 qw(sha1_hex); use File::Path; use File::Slurp; use Path::Class; +use if !$ENV{TRAVIS}, 'Image::Magick'; =head1 NAME @@ -116,7 +117,6 @@ sub no_photo : Private { # Shrinks a picture to the specified size, but keeping in proportion. sub _shrink { my ($photo, $size) = @_; - use Image::Magick; my $image = Image::Magick->new; $image->BlobToImage($photo); my $err = $image->Scale(geometry => "$size>"); @@ -130,7 +130,6 @@ sub _shrink { # Shrinks a picture to 90x60, cropping so that it is exactly that. sub _crop { my ($photo) = @_; - use Image::Magick; my $image = Image::Magick->new; $image->BlobToImage($photo); my $err = $image->Resize( geometry => "90x60^" ); diff --git a/perllib/FixMyStreet/App/Controller/Questionnaire.pm b/perllib/FixMyStreet/App/Controller/Questionnaire.pm index f0cc72e07..46d6350d7 100755 --- a/perllib/FixMyStreet/App/Controller/Questionnaire.pm +++ b/perllib/FixMyStreet/App/Controller/Questionnaire.pm @@ -157,6 +157,8 @@ sub submit_standard : Private { my $new_state = ''; $new_state = 'fixed - user' if $c->stash->{been_fixed} eq 'Yes' && FixMyStreet::DB::Result::Problem->open_states()->{$old_state}; + $new_state = 'fixed - user' if $c->stash->{been_fixed} eq 'Yes' && + FixMyStreet::DB::Result::Problem->closed_states()->{$old_state}; $new_state = 'confirmed' if $c->stash->{been_fixed} eq 'No' && FixMyStreet::DB::Result::Problem->fixed_states()->{$old_state}; diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm index cda569860..a7e1e8a3a 100644 --- a/perllib/FixMyStreet/App/Controller/Report.pm +++ b/perllib/FixMyStreet/App/Controller/Report.pm @@ -56,6 +56,23 @@ sub display : Path('') : Args(1) { $c->forward( 'format_problem_for_display' ); } +sub support : Path('support') : Args(0) { + my ( $self, $c ) = @_; + + my $id = $c->req->param('id'); + + my $uri = + $id + ? $c->uri_for( '/report', $id ) + : $c->uri_for('/'); + + if ( $id && $c->cobrand->can_support_problems && $c->user && $c->user->from_council ) { + $c->forward( 'load_problem_or_display_error', [ $id ] ); + $c->stash->{problem}->update( { interest_count => \'interest_count +1' } ); + } + $c->res->redirect( $uri ); +} + sub load_problem_or_display_error : Private { my ( $self, $c, $id ) = @_; diff --git a/perllib/FixMyStreet/App/Controller/Report/New.pm b/perllib/FixMyStreet/App/Controller/Report/New.pm index 2318ee9e1..dedd447ee 100644 --- a/perllib/FixMyStreet/App/Controller/Report/New.pm +++ b/perllib/FixMyStreet/App/Controller/Report/New.pm @@ -6,7 +6,6 @@ BEGIN { extends 'Catalyst::Controller'; } use FixMyStreet::Geocode; use Encode; -use Image::Magick; use List::MoreUtils qw(uniq); use POSIX 'strcoll'; use HTML::Entities; @@ -14,7 +13,6 @@ use mySociety::MaPit; use Path::Class; use Utils; use mySociety::EmailUtil; -use mySociety::TempFiles; use JSON; =head1 NAME @@ -709,22 +707,23 @@ sub process_user : Private { my $report = $c->stash->{report}; + # Extract all the params to a hash to make them easier to work with + my %params = map { $_ => scalar $c->req->param($_) } + ( 'email', 'name', 'phone', 'password_register', 'fms_extra_title' ); + + my $user_title = Utils::trim_text( $params{fms_extra_title} ); + # The user is already signed in if ( $c->user_exists ) { my $user = $c->user->obj; - my %params = map { $_ => scalar $c->req->param($_) } ( 'name', 'phone', 'fms_extra_title' ); $user->name( Utils::trim_text( $params{name} ) ) if $params{name}; $user->phone( Utils::trim_text( $params{phone} ) ); - $user->title( Utils::trim_text( $params{fms_extra_title} ) ); + $user->title( $user_title ) if $user_title; $report->user( $user ); $report->name( $user->name ); return 1; } - # Extract all the params to a hash to make them easier to work with - my %params = map { $_ => scalar $c->req->param($_) } - ( 'email', 'name', 'phone', 'password_register', 'fms_extra_title' ); - # cleanup the email address my $email = $params{email} ? lc $params{email} : ''; $email =~ s{\s+}{}g; @@ -752,7 +751,7 @@ sub process_user : Private { $report->user->phone( Utils::trim_text( $params{phone} ) ); $report->user->password( Utils::trim_text( $params{password_register} ) ) if $params{password_register}; - $report->user->title( Utils::trim_text( $params{fms_extra_title} ) ); + $report->user->title( $user_title ) if $user_title; $report->name( Utils::trim_text( $params{name} ) ); return 1; @@ -1010,6 +1009,13 @@ sub save_user_and_report : Private { # Set unknown to DB unknown $report->council( undef ) if $report->council eq '-1'; + # if there is a Message Manager message ID, pass it back to the client view + if ($c->cobrand->moniker eq 'fixmybarangay' && $c->req->param('external_source_id')=~/^\d+$/) { + $c->stash->{external_source_id} = $c->req->param('external_source_id'); + $report->external_source_id( $c->req->param('external_source_id') ); + $report->external_source( $c->config->{MESSAGE_MANAGER_URL} ) ; + } + # save the report; $report->in_storage ? $report->update : $report->insert(); @@ -1080,7 +1086,13 @@ sub redirect_or_confirm_creation : Private { if ( $report->confirmed ) { # Subscribe problem reporter to email updates $c->forward( 'create_reporter_alert' ); - my $report_uri = $c->cobrand->base_url_for_report( $report ) . $report->url; + my $report_uri; + + if ( $c->cobrand->moniker eq 'fixmybarangay' && $c->user->from_council && $c->stash->{external_source_id}) { + $report_uri = $c->uri_for( '/report', $report->id, undef, { external_source_id => $c->stash->{external_source_id} } ); + } else { + $report_uri = $c->cobrand->base_url_for_report( $report ) . $report->url; + } $c->log->info($report->user->id . ' was logged in, redirecting to /report/' . $report->id); $c->res->redirect($report_uri); $c->detach; diff --git a/perllib/FixMyStreet/App/Controller/Report/Update.pm b/perllib/FixMyStreet/App/Controller/Report/Update.pm index c49123a90..da4cc33ca 100644 --- a/perllib/FixMyStreet/App/Controller/Report/Update.pm +++ b/perllib/FixMyStreet/App/Controller/Report/Update.pm @@ -76,6 +76,10 @@ sub update_problem : Private { $problem->state('confirmed'); } + if ( $c->cobrand->can_support_problems && $c->user && $c->user->from_council && $c->req->param('external_source_id') ) { + $problem->interest_count( \'interest_count + 1' ); + } + $problem->lastupdate( \'ms_current_timestamp()' ); $problem->update; @@ -348,6 +352,7 @@ sub redirect_or_confirm_creation : Private { if ( $update->confirmed ) { $c->forward( 'update_problem' ); $c->forward( 'signup_for_alerts' ); + my $report_uri = $c->cobrand->base_url_for_report( $update->problem ) . $update->problem->url; $c->res->redirect($report_uri); $c->detach; diff --git a/perllib/FixMyStreet/App/Controller/Reports.pm b/perllib/FixMyStreet/App/Controller/Reports.pm index dd725be19..7087e846b 100644 --- a/perllib/FixMyStreet/App/Controller/Reports.pm +++ b/perllib/FixMyStreet/App/Controller/Reports.pm @@ -6,7 +6,6 @@ use File::Slurp; use List::MoreUtils qw(zip); use POSIX qw(strcoll); use mySociety::MaPit; -use mySociety::VotingArea; BEGIN { extends 'Catalyst::Controller'; } @@ -71,7 +70,7 @@ sub index : Path : Args(0) { if ($@) { $c->stash->{message} = _("There was a problem showing the All Reports page. Please try again later."); if ($c->config->{STAGING_SITE}) { - $c->stash->{message} .= '</p><p>Perhaps the bin/update-all-reports script needs running.</p><p>' + $c->stash->{message} .= '</p><p>Perhaps the bin/update-all-reports script needs running. Use: bin/cron-wrapper bin/update-all-reports</p><p>' . sprintf(_('The error was: %s'), $@); } $c->stash->{template} = 'errors/generic.html'; @@ -135,7 +134,7 @@ sub ward : Path : Args(2) { # List of wards unless ($c->stash->{ward}) { my $children = mySociety::MaPit::call('area/children', [ $c->stash->{council}->{id} ], - type => $mySociety::VotingArea::council_child_types, + type => $c->cobrand->area_types_children, ); foreach (values %$children) { $_->{url} = $c->uri_for( $c->stash->{council_url} @@ -170,13 +169,6 @@ sub rss_ward : Regex('^rss/(reports|area)$') : Args(2) { $url .= '/' . $c->cobrand->short_name( $c->stash->{ward} ) if $c->stash->{ward}; $c->stash->{qs} = "/$url"; - my @params; - push @params, $c->stash->{council}->{id} if $rss eq 'reports'; - push @params, $c->stash->{ward} - ? $c->stash->{ward}->{id} - : $c->stash->{council}->{id}; - $c->stash->{db_params} = [ @params ]; - if ( $rss eq 'area' && $c->stash->{ward} ) { # All problems within a particular ward $c->stash->{type} = 'area_problems'; @@ -258,7 +250,6 @@ sub council_check : Private { This action checks the ward name from a URI exists and is part of the right parent, already found with council_check. It either stores the ward Area if okay, or redirects to the council page if bad. -This is currently only used in the UK, hence the use of mySociety::VotingArea. =cut @@ -272,7 +263,7 @@ sub ward_check : Private { my $council = $c->stash->{council}; my $qw = mySociety::MaPit::call('areas', $ward, - type => $mySociety::VotingArea::council_child_types, + type => $c->cobrand->area_types_children, min_generation => $c->cobrand->area_min_generation ); foreach my $area (sort { $a->{name} cmp $b->{name} } values %$qw) { diff --git a/perllib/FixMyStreet/App/Controller/Rss.pm b/perllib/FixMyStreet/App/Controller/Rss.pm index fe4b652ed..baaa3b927 100755 --- a/perllib/FixMyStreet/App/Controller/Rss.pm +++ b/perllib/FixMyStreet/App/Controller/Rss.pm @@ -106,10 +106,19 @@ sub local_problems_pc_distance : Path('pc') : Args(2) { } -sub local_problems : LocalRegex('^(n|l)/([\d.-]+)[,/]([\d.-]+)(?:/(\d+))?$') { +sub local_problems_dist : LocalRegex('^(n|l)/([\d.-]+)[,/]([\d.-]+)/(\d+)$') { my ( $self, $c ) = @_; + $c->forward( 'local_problems', $c->req->captures ); +} + +sub local_problems_no_dist : LocalRegex('^(n|l)/([\d.-]+)[,/]([\d.-]+)$') { + my ( $self, $c ) = @_; + $c->forward( 'local_problems', $c->req->captures ); +} + +sub local_problems : Private { + my ( $self, $c, $type, $a, $b, $d ) = @_; - my ( $type, $a, $b, $d) = @{ $c->req->captures }; $c->forward( 'get_query_parameters', [ $d ] ); $c->detach( 'redirect_lat_lon', [ $a, $b ] ) diff --git a/perllib/FixMyStreet/App/View/Web.pm b/perllib/FixMyStreet/App/View/Web.pm index eac194dff..42878be37 100644 --- a/perllib/FixMyStreet/App/View/Web.pm +++ b/perllib/FixMyStreet/App/View/Web.pm @@ -171,6 +171,7 @@ sub version { my $path = FixMyStreet->path_to('web', $file); $version_hash{$file} = ( stat( $path ) )[9]; } + $version_hash{$file} ||= ''; return "$file?$version_hash{$file}"; } diff --git a/perllib/FixMyStreet/Cobrand/Default.pm b/perllib/FixMyStreet/Cobrand/Default.pm index b1127833c..6324030b8 100644 --- a/perllib/FixMyStreet/Cobrand/Default.pm +++ b/perllib/FixMyStreet/Cobrand/Default.pm @@ -159,7 +159,8 @@ sub set_lang_and_domain { my $lang_override = $self->language_override || $lang; my $lang_domain = $self->language_domain || 'FixMyStreet'; - my $set_lang = mySociety::Locale::negotiate_language( $languages, $lang_override ); + my $headers = $self->{c} ? $self->{c}->req->headers : undef; + my $set_lang = mySociety::Locale::negotiate_language( $languages, $lang_override, $headers ); mySociety::Locale::gettext_domain( $lang_domain, $unicode, $dir ); mySociety::Locale::change(); return $set_lang; @@ -645,7 +646,34 @@ Get stats to display on the council reports page sub get_report_stats { return 0; } -sub get_council_sender { return 'Email' }; +sub get_council_sender { + my ( $self, $area_id, $area_info, $category ) = @_; + + my $send_method; + + my $council_config = FixMyStreet::App->model("DB::Open311conf")->search( { area_id => $area_id } )->first; + $send_method = $council_config->send_method if $council_config; + + if ( $council_config && $council_config->can_be_devolved ) { + # look up via category + my $config = FixMyStreet::App->model("DB::Contact")->search( { area_id => $area_id, category => $category } )->first; + if ( $config->send_method ) { + return { method => $config->send_method, config => $config }; + } else { + return { method => $send_method, config => $council_config }; + } + } elsif ( $send_method ) { + return { method => $send_method, config => $council_config }; + } + + return $self->_fallback_council_sender( $area_id, $area_info, $category ); +} + +sub _fallback_council_sender { + my ( $self, $area_id, $area_info, $category ) = @_; + + return { method => 'Email' }; +}; sub example_places { my $e = FixMyStreet->config('EXAMPLE_PLACES') || [ 'High Street', 'Main Street' ]; @@ -653,6 +681,24 @@ sub example_places { return $e; } +=head2 only_authed_can_create + +If true, only users with the from_council flag set are able to create reports. + +=cut + +sub only_authed_can_create { + return 0; +} + +=head2 areas_on_around + +If set to an arrayref, will plot those area ID(s) from mapit on all the /around pages. + +=cut + +sub areas_on_around { []; } + sub process_extras {} =head 2 pin_colour @@ -678,6 +724,8 @@ Used in some cobrands to improve the intial display for Internet Explorer. sub tweak_all_reports_map {} +sub can_support_problems { return 0; } + sub default_map_zoom { undef }; 1; diff --git a/perllib/FixMyStreet/Cobrand/FixMyBarangay.pm b/perllib/FixMyStreet/Cobrand/FixMyBarangay.pm new file mode 100644 index 000000000..849a53b2b --- /dev/null +++ b/perllib/FixMyStreet/Cobrand/FixMyBarangay.pm @@ -0,0 +1,45 @@ +package FixMyStreet::Cobrand::FixMyBarangay; +use base 'FixMyStreet::Cobrand::Default'; + +use strict; +use warnings; + +sub path_to_web_templates { + my $self = shift; + return [ + FixMyStreet->path_to( 'templates/web', $self->moniker )->stringify, + FixMyStreet->path_to( 'templates/web/fixmystreet' )->stringify + ]; +} + +sub country { + return 'PH'; +} + +sub language_domain { 'FixMyBarangay' } + +sub area_types { + return [ 'BGY' ]; +} + +sub disambiguate_location { + return { + country => 'ph', + bing_country => 'Philippines', + }; +} + +sub only_authed_can_create { + return 1; +} + +sub areas_on_around { + return [ 1, 2 ]; +} + +sub can_support_problems { + return 1; +} + +1; + diff --git a/perllib/FixMyStreet/Cobrand/LichfieldDC.pm b/perllib/FixMyStreet/Cobrand/LichfieldDC.pm index 5c8a04681..b3dbad089 100644 --- a/perllib/FixMyStreet/Cobrand/LichfieldDC.pm +++ b/perllib/FixMyStreet/Cobrand/LichfieldDC.pm @@ -37,5 +37,9 @@ sub base_url_for_report { } } +sub map_type { + return 'OSM'; +} + 1; diff --git a/perllib/FixMyStreet/Cobrand/UK.pm b/perllib/FixMyStreet/Cobrand/UK.pm index 0d6f98590..58da5166c 100644 --- a/perllib/FixMyStreet/Cobrand/UK.pm +++ b/perllib/FixMyStreet/Cobrand/UK.pm @@ -31,19 +31,11 @@ sub disambiguate_location { }; } -sub get_council_sender { - my ( $self, $area_id, $area_info ) = @_; - - my $send_method; - - my $council_config = FixMyStreet::App->model("DB::Open311conf")->search( { area_id => $area_id } )->first; - $send_method = $council_config->send_method if $council_config; - - return $send_method if $send_method; - - return 'London' if $area_info->{type} eq 'LBO'; - return 'NI' if $area_info->{type} eq 'LGD'; - return 'Email'; +sub _fallback_council_sender { + my ( $self, $area_id, $area_info, $category ) = @_; + return { method => 'London' } if $area_info->{type} eq 'LBO'; + return { method => 'NI' } if $area_info->{type} eq 'LGD'; + return { method => 'Email' }; } sub process_extras { @@ -53,7 +45,7 @@ sub process_extras { my $extra = shift; my $fields = shift || []; - if ( $area_id == 2482 ) { + if ( $area_id eq '2482' ) { my @fields = ( 'fms_extra_title', @$fields ); for my $field ( @fields ) { my $value = $ctx->request->param( $field ); @@ -152,7 +144,6 @@ sub find_closest { my $str = $self->SUPER::find_closest( $latitude, $longitude, $problem ); - # Get nearest postcode from Matthew's random gazetteer (put in MaPit? Or elsewhere?) my $url = "http://mapit.mysociety.org/nearest/4326/$longitude,$latitude"; my $j = LWP::Simple::get($url); if ($j) { diff --git a/perllib/FixMyStreet/DB/Result/Comment.pm b/perllib/FixMyStreet/DB/Result/Comment.pm index 91695d7d0..8c9fea282 100644 --- a/perllib/FixMyStreet/DB/Result/Comment.pm +++ b/perllib/FixMyStreet/DB/Result/Comment.pm @@ -54,10 +54,6 @@ __PACKAGE__->add_columns( { data_type => "boolean", default_value => \"false", is_nullable => 0 }, "problem_state", { data_type => "text", is_nullable => 1 }, - "external_id", - { data_type => "text", is_nullable => 1 }, - "extra", - { data_type => "text", is_nullable => 1 }, "send_fail_count", { data_type => "integer", default_value => 0, is_nullable => 0 }, "send_fail_reason", @@ -66,6 +62,10 @@ __PACKAGE__->add_columns( { data_type => "timestamp", is_nullable => 1 }, "whensent", { data_type => "timestamp", is_nullable => 1 }, + "external_id", + { data_type => "text", is_nullable => 1 }, + "extra", + { data_type => "text", is_nullable => 1 }, ); __PACKAGE__->set_primary_key("id"); __PACKAGE__->belongs_to( @@ -82,8 +82,8 @@ __PACKAGE__->belongs_to( ); -# Created by DBIx::Class::Schema::Loader v0.07017 @ 2012-03-26 15:44:18 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:nvkElEgSU6XcLd9znSqhmQ +# Created by DBIx::Class::Schema::Loader v0.07017 @ 2012-07-11 18:53:26 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:tSejJzLxHD/fMWjpa10lfA __PACKAGE__->filter_column( extra => { diff --git a/perllib/FixMyStreet/DB/Result/Contact.pm b/perllib/FixMyStreet/DB/Result/Contact.pm index cad12f1fc..993e3524b 100644 --- a/perllib/FixMyStreet/DB/Result/Contact.pm +++ b/perllib/FixMyStreet/DB/Result/Contact.pm @@ -38,6 +38,14 @@ __PACKAGE__->add_columns( { data_type => "text", is_nullable => 1 }, "non_public", { data_type => "boolean", default_value => \"false", is_nullable => 1 }, + "endpoint", + { data_type => "text", is_nullable => 1 }, + "jurisdiction", + { data_type => "text", default_value => "", is_nullable => 1 }, + "api_key", + { data_type => "text", default_value => "", is_nullable => 1 }, + "send_method", + { data_type => "text", is_nullable => 1 }, ); __PACKAGE__->set_primary_key("id"); __PACKAGE__->add_unique_constraint("contacts_area_id_category_idx", ["area_id", "category"]); diff --git a/perllib/FixMyStreet/DB/Result/Open311conf.pm b/perllib/FixMyStreet/DB/Result/Open311conf.pm index c95b0c8f2..8051e27de 100644 --- a/perllib/FixMyStreet/DB/Result/Open311conf.pm +++ b/perllib/FixMyStreet/DB/Result/Open311conf.pm @@ -34,6 +34,8 @@ __PACKAGE__->add_columns( { data_type => "integer", is_foreign_key => 1, is_nullable => 1 }, "suppress_alerts", { data_type => "boolean", default_value => \"false", is_nullable => 0 }, + "can_be_devolved", + { data_type => "boolean", default_value => \"false", is_nullable => 0 }, ); __PACKAGE__->set_primary_key("id"); __PACKAGE__->add_unique_constraint("open311conf_area_id_key", ["area_id"]); @@ -50,8 +52,8 @@ __PACKAGE__->belongs_to( ); -# Created by DBIx::Class::Schema::Loader v0.07017 @ 2012-05-11 13:30:31 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ByJbRe/Y/9Z1WHdG8kaIHg +# Created by DBIx::Class::Schema::Loader v0.07017 @ 2012-08-29 14:04:20 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:Yoult8K/ldH6DMAKURtr3Q # You can replace this text with custom code or comments, and it will be preserved on regeneration diff --git a/perllib/FixMyStreet/DB/Result/Problem.pm b/perllib/FixMyStreet/DB/Result/Problem.pm index a1cf107a9..ce197076b 100644 --- a/perllib/FixMyStreet/DB/Result/Problem.pm +++ b/perllib/FixMyStreet/DB/Result/Problem.pm @@ -94,6 +94,12 @@ __PACKAGE__->add_columns( { data_type => "text", is_nullable => 1 }, "non_public", { data_type => "boolean", default_value => \"false", is_nullable => 1 }, + "external_source", + { data_type => "text", is_nullable => 1 }, + "external_source_id", + { data_type => "text", is_nullable => 1 }, + "interest_count", + { data_type => "integer", is_nullable => 1 }, ); __PACKAGE__->set_primary_key("id"); __PACKAGE__->has_many( @@ -540,9 +546,6 @@ sub meta_line { } - $meta .= '; ' . _('the map was not used so pin location may be inaccurate') - unless $problem->used_map; - return $meta; } @@ -602,7 +605,7 @@ sub processed_summary_string { } if ($problem->can_display_external_id) { if ($duration_clause) { - $external_ref_clause = sprintf(_('their ref: %s'), $problem->external_id); + $external_ref_clause = sprintf(_('council ref: %s'), $problem->external_id); } else { $external_ref_clause = sprintf(_('%s ref: %s'), $problem->external_body, $problem->external_id); } diff --git a/perllib/FixMyStreet/DB/ResultSet/AlertType.pm b/perllib/FixMyStreet/DB/ResultSet/AlertType.pm index 2d206d84e..468df2654 100644 --- a/perllib/FixMyStreet/DB/ResultSet/AlertType.pm +++ b/perllib/FixMyStreet/DB/ResultSet/AlertType.pm @@ -94,7 +94,23 @@ sub email_alerts ($) { } # this is currently only for new_updates if ($row->{item_text}) { - $data{problem_url} = $url . "/report/" . $row->{id}; + if ( $row->{alert_user_id} == $row->{user_id} ) { + # This is an alert to the same user who made the report - make this a login link + my $user = FixMyStreet::App->model('DB::User')->find( { + id => $row->{alert_user_id} + } ); + $data{alert_email} = $user->email; + my $token_obj = FixMyStreet::App->model('DB::Token')->create( { + scope => 'email_sign_in', + data => { + email => $user->email, + r => 'report/' . $row->{id}, + } + } ); + $data{problem_url} = $url . "/M/" . $token_obj->token; + } else { + $data{problem_url} = $url . "/report/" . $row->{id}; + } $data{data} .= $row->{item_name} . ' : ' if $row->{item_name} && !$row->{item_anonymous}; $data{data} .= $row->{item_text} . "\n\n------\n\n"; # this is ward and council problems diff --git a/perllib/FixMyStreet/DB/ResultSet/Problem.pm b/perllib/FixMyStreet/DB/ResultSet/Problem.pm index 2f426e8ca..bb826a5ca 100644 --- a/perllib/FixMyStreet/DB/ResultSet/Problem.pm +++ b/perllib/FixMyStreet/DB/ResultSet/Problem.pm @@ -310,8 +310,8 @@ sub send_reports { foreach my $council (@councils) { my $name = $areas_info->{$council}->{name}; - my $sender = $cobrand->get_council_sender( $council, $areas_info->{$council} ); - $sender = "FixMyStreet::SendReport::$sender"; + my $sender_info = $cobrand->get_council_sender( $council, $areas_info->{$council}, $row->category ); + my $sender = "FixMyStreet::SendReport::" . $sender_info->{method}; if ( ! exists $senders->{ $sender } ) { warn "No such sender [ $sender ] for council $name ( $council )"; @@ -324,7 +324,7 @@ sub send_reports { $reporters{ $sender }->skipped; } else { push @dear, $name; - $reporters{ $sender }->add_council( $council, $areas_info->{$council} ); + $reporters{ $sender }->add_council( $council, $areas_info->{$council}, $sender_info->{config} ); } } @@ -422,6 +422,21 @@ sub send_reports { } printf " %-24s %4d\n", "Total:", $c; } + my $sending_errors = ''; + my $unsent = FixMyStreet::App->model("DB::Problem")->search( { + state => [ 'confirmed', 'fixed' ], + whensent => undef, + council => { '!=', undef }, + send_fail_count => { '>', 0 } + } ); + while (my $row = $unsent->next) { + $sending_errors .= "* http://www.fixmystreet.com/report/" . $row->id . ", failed " + . $row->send_fail_count . " times, last at " . $row->send_fail_timestamp + . ", reason " . $row->send_fail_reason . "\n"; + } + if ($sending_errors) { + print "The following reports had problems sending:\n$sending_errors"; + } } } diff --git a/perllib/FixMyStreet/DB/ResultSet/Questionnaire.pm b/perllib/FixMyStreet/DB/ResultSet/Questionnaire.pm index bbf0c9a9e..d6b3eb5cb 100644 --- a/perllib/FixMyStreet/DB/ResultSet/Questionnaire.pm +++ b/perllib/FixMyStreet/DB/ResultSet/Questionnaire.pm @@ -62,7 +62,9 @@ sub send_questionnaires_period { ($template = $period) =~ s/ //; $template = Utils::read_file( FixMyStreet->path_to( "templates/email/emptyhomes/" . $row->lang . "/questionnaire-$template.txt" )->stringify ); } else { - $template = FixMyStreet->path_to( "templates", "email", $cobrand->moniker, "questionnaire.txt" )->stringify; + $template = FixMyStreet->path_to( "templates", "email", $cobrand->moniker, $row->lang, "questionnaire.txt" )->stringify; + $template = FixMyStreet->path_to( "templates", "email", $cobrand->moniker, "questionnaire.txt" )->stringify + unless -e $template; $template = FixMyStreet->path_to( "templates", "email", "default", "questionnaire.txt" )->stringify unless -e $template; $template = Utils::read_file( $template ); diff --git a/perllib/FixMyStreet/Geocode/OSM.pm b/perllib/FixMyStreet/Geocode/OSM.pm index 197b2b1e7..d96338c16 100644 --- a/perllib/FixMyStreet/Geocode/OSM.pm +++ b/perllib/FixMyStreet/Geocode/OSM.pm @@ -18,6 +18,7 @@ use File::Path (); use LWP::Simple qw($ua); use Memcached; use XML::Simple; +use mySociety::Locale; my $osmapibase = "http://www.openstreetmap.org/api/"; my $nominatimbase = "http://nominatim.openstreetmap.org/"; @@ -57,7 +58,7 @@ sub string { } if (!$js) { - return { error => _('Sorry, we could not parse that location. Please try again.') }; + return { error => _('Sorry, we could not find that location.') }; } $js = JSON->new->utf8->allow_nonref->decode($js); diff --git a/perllib/FixMyStreet/Map.pm b/perllib/FixMyStreet/Map.pm index d36b91ffe..587c63d25 100644 --- a/perllib/FixMyStreet/Map.pm +++ b/perllib/FixMyStreet/Map.pm @@ -52,10 +52,6 @@ sub set_map_class { $map_class = $str; } -sub header_js { - return $map_class->header_js(@_); -} - sub display_map { return $map_class->display_map(@_); } diff --git a/perllib/FixMyStreet/SendReport.pm b/perllib/FixMyStreet/SendReport.pm index f750ef479..9ba507862 100644 --- a/perllib/FixMyStreet/SendReport.pm +++ b/perllib/FixMyStreet/SendReport.pm @@ -39,8 +39,9 @@ sub add_council { my $self = shift; my $council = shift; my $info = shift; + my $config = shift; - $self->councils->{ $council } = $info; + $self->councils->{ $council } = { info => $info, config => $config }; } diff --git a/perllib/FixMyStreet/SendReport/Email.pm b/perllib/FixMyStreet/SendReport/Email.pm index 654ed6b3a..b69436dd7 100644 --- a/perllib/FixMyStreet/SendReport/Email.pm +++ b/perllib/FixMyStreet/SendReport/Email.pm @@ -12,6 +12,7 @@ sub build_recipient_list { my $all_confirmed = 1; foreach my $council ( keys %{ $self->councils } ) { + my $contact = FixMyStreet::App->model("DB::Contact")->find( { deleted => 0, area_id => $council, @@ -32,7 +33,7 @@ sub build_recipient_list { $self->unconfirmed_notes->{$council_email}{$row->category} = $note; } - push @{ $self->to }, [ $council_email, $self->councils->{ $council }->{name} ]; + push @{ $self->to }, [ $council_email, $self->councils->{ $council }->{info}->{name} ]; $recips{$council_email} = 1; } @@ -45,7 +46,9 @@ sub get_template { my $template = 'submit.txt'; $template = 'submit-brent.txt' if $row->council eq 2488 || $row->council eq 2237; - my $template_path = FixMyStreet->path_to( "templates", "email", $row->cobrand, $template )->stringify; + my $template_path = FixMyStreet->path_to( "templates", "email", $row->cobrand, $row->lang, $template )->stringify; + $template_path = FixMyStreet->path_to( "templates", "email", $row->cobrand, $template )->stringify + unless -e $template_path; $template_path = FixMyStreet->path_to( "templates", "email", "default", $template )->stringify unless -e $template_path; $template = Utils::read_file( $template_path ); diff --git a/perllib/FixMyStreet/SendReport/EmptyHomes.pm b/perllib/FixMyStreet/SendReport/EmptyHomes.pm index e1b914523..4a6f058fe 100644 --- a/perllib/FixMyStreet/SendReport/EmptyHomes.pm +++ b/perllib/FixMyStreet/SendReport/EmptyHomes.pm @@ -28,7 +28,7 @@ sub build_recipient_list { #$note{$council_email}{$row->category} = $note; } - push @{ $self->to }, [ $council_email, $self->councils->{ $council }->{name} ]; + push @{ $self->to }, [ $council_email, $self->councils->{ $council }->{ info }->{name} ]; $recips{$council_email} = 1; my $country = $self->councils->{$council}->{country}; diff --git a/perllib/FixMyStreet/SendReport/NI.pm b/perllib/FixMyStreet/SendReport/NI.pm index 0783a385b..810ee60e2 100644 --- a/perllib/FixMyStreet/SendReport/NI.pm +++ b/perllib/FixMyStreet/SendReport/NI.pm @@ -23,7 +23,7 @@ sub build_recipient_list { $email = 'N/A' unless $email; } - my $name = $self->councils->{$council}->{name}; + my $name = $self->councils->{$council}->{info}->{name}; if ( $email =~ /^roads.([^@]*)\@drdni/ ) { $name = "Roads Service (\u$1)"; $h->{councils_name} = $name; diff --git a/perllib/FixMyStreet/SendReport/Open311.pm b/perllib/FixMyStreet/SendReport/Open311.pm index 42c103b82..70bce3d47 100644 --- a/perllib/FixMyStreet/SendReport/Open311.pm +++ b/perllib/FixMyStreet/SendReport/Open311.pm @@ -28,7 +28,7 @@ sub send { my $result = -1; foreach my $council ( keys %{ $self->councils } ) { - my $conf = FixMyStreet::App->model("DB::Open311conf")->search( { area_id => $council, endpoint => { '!=', '' } } )->first; + my $conf = $self->councils->{$council}->{config}; my $always_send_latlong = 1; my $send_notpinpointed = 0; @@ -94,10 +94,15 @@ sub send { $row->user->name( $row->user->id . ' ' . $row->user->name ); } + if ($row->cobrand eq 'fixmybarangay') { + # FixMyBarangay endpoints expect external_id as an attribute + $row->extra( [ { 'name' => 'external_id', 'value' => $row->id } ] ); + } + my $resp = $open311->send_service_request( $row, $h, $contact->email ); # make sure we don't save user changes from above - if ( $row->council =~ /2218/ || $row->council =~ /2482/ ) { + if ( $row->council =~ /2218/ || $row->council =~ /2482/ || $row->cobrand eq 'fixmybarangay') { $row->discard_changes(); } diff --git a/perllib/FixMyStreet/TestMech.pm b/perllib/FixMyStreet/TestMech.pm index 2a9c3ba7b..7f81c0fc2 100644 --- a/perllib/FixMyStreet/TestMech.pm +++ b/perllib/FixMyStreet/TestMech.pm @@ -460,6 +460,7 @@ sub visible_form_values { grep { ref($_) ne 'HTML::Form::SubmitInput' } grep { ref($_) ne 'HTML::Form::ImageInput' } grep { ref($_) ne 'HTML::Form::TextInput' || $_->type ne 'hidden' } + grep { !$_->disabled } $form->inputs; my @visible_field_names = map { $_->name } @visible_fields; @@ -534,12 +535,11 @@ sub delete_problems_for_council { sub create_problems_for_council { my ( $mech, $count, $council, $title, $params ) = @_; - my $dt = DateTime->now() || $params->{dt}; + my $dt = $params->{dt} || DateTime->now(); - my $user = + my $user = $params->{user} || FixMyStreet::App->model('DB::User') - ->find_or_create( { email => 'test@example.com', name => 'Test User' } ) - or $params->{user}; + ->find_or_create( { email => 'test@example.com', name => 'Test User' } ); delete $params->{user}; delete $params->{dt}; diff --git a/perllib/Open311.pm b/perllib/Open311.pm index 6ad93cf78..60b658dc3 100644 --- a/perllib/Open311.pm +++ b/perllib/Open311.pm @@ -79,9 +79,13 @@ sub send_service_request { } } - warn sprintf( "Failed to submit problem %s over Open311, response\n: %s\n%s", $problem->id, $response, $self->debug_details ); - return 0; + warn sprintf( "Failed to submit problem %s over Open311, response\n: %s\n%s", $problem->id, $response, $self->debug_details ) + unless $problem->send_fail_count; + } else { + warn sprintf( "Failed to submit problem %s over Open311, details:\n%s", $problem->id, $self->error) + unless $problem->send_fail_count; } + return 0; } sub _populate_service_request_params { @@ -263,9 +267,13 @@ sub post_service_request_update { } } - warn sprintf( "Failed to submit comment %s over Open311, response - %s\n%s\n", $comment->id, $response, $self->debug_details ); - return 0; + warn sprintf( "Failed to submit comment %s over Open311, response - %s\n%s\n", $comment->id, $response, $self->debug_details ) + unless $comment->send_fail_count; + } else { + warn sprintf( "Failed to submit comment %s over Open311, details\n%s\n", $comment->id, $self->error) + unless $comment->send_fail_count; } + return 0; } sub _populate_service_request_update_params { @@ -389,7 +397,6 @@ sub _post { $self->_process_error( $res->decoded_content ), $self->debug_details ) ); - warn $self->error; return 0; } } @@ -418,7 +425,7 @@ sub _get_xml_object { my $obj; eval { - $obj = $simple ->XMLin( $xml, ForceArray => [ qr/^key$/, qr/^name$/ ] ); + $obj = $simple ->parse_string( $xml, ForceArray => [ qr/^key$/, qr/^name$/ ] ); }; return $obj; diff --git a/perllib/Open311/GetServiceRequestUpdates.pm b/perllib/Open311/GetServiceRequestUpdates.pm index 1f0852c96..656fa9d68 100644 --- a/perllib/Open311/GetServiceRequestUpdates.pm +++ b/perllib/Open311/GetServiceRequestUpdates.pm @@ -10,6 +10,7 @@ has system_user => ( is => 'rw' ); has start_date => ( is => 'ro', default => undef ); has end_date => ( is => 'ro', default => undef ); has suppress_alerts => ( is => 'rw', default => 0 ); +has verbose => ( is => 'ro', default => 0 ); sub fetch { my $self = shift; @@ -67,7 +68,8 @@ sub update_comments { my $requests = $open311->get_service_request_updates( @args ); unless ( $open311->success ) { - warn "Failed to fetch ServiceRequest Updates: " . $open311->error; + warn "Failed to fetch ServiceRequest Updates: " . $open311->error + if $self->verbose; return 0; } diff --git a/perllib/Open311/PopulateServiceList.pm b/perllib/Open311/PopulateServiceList.pm index 833aa4ee5..d8730a703 100644 --- a/perllib/Open311/PopulateServiceList.pm +++ b/perllib/Open311/PopulateServiceList.pm @@ -21,6 +21,7 @@ sub process_councils { while ( my $council = $self->council_list->next ) { next unless $council->endpoint; + next unless lc($council->send_method) eq 'open311'; $self->_current_council( $council ); $self->process_council; } @@ -40,7 +41,9 @@ sub process_council { my $list = $open311->get_service_list; unless ( $list ) { - warn "ERROR: no service list found for " . $self->_current_council->area_id . "\n"; + my $id = $self->_current_council->area_id; + warn "Council $id - http://mapit.mysociety.org/area/$id.html - did not return a service list\n" + if $self->verbose >= 1; return; } $self->process_services( $list ); @@ -82,7 +85,7 @@ sub process_service { $self->_current_service->{description} : $self->_current_service->{service_name}; - print $self->_current_service->{service_code} . ': ' . $category . "\n" if $self->verbose; + print $self->_current_service->{service_code} . ': ' . $category . "\n" if $self->verbose >= 2; my $contacts = FixMyStreet::App->model( 'DB::Contact')->search( { area_id => $self->_current_council->area_id, @@ -122,7 +125,7 @@ sub _handle_existing_contact { my $service_name = $self->_normalize_service_name; - print $self->_current_council->area_id . " already has a contact for service code " . $self->_current_service->{service_code} . "\n" if $self->verbose; + print $self->_current_council->area_id . " already has a contact for service code " . $self->_current_service->{service_code} . "\n" if $self->verbose >= 2; if ( $contact->deleted || $service_name ne $contact->category || $self->_current_service->{service_code} ne $contact->email ) { eval { @@ -140,7 +143,8 @@ sub _handle_existing_contact { }; if ( $@ ) { - warn "Failed to update contact for service code " . $self->_current_service->{service_code} . " for council @{[$self->_current_council->area_id]}: $@\n"; + warn "Failed to update contact for service code " . $self->_current_service->{service_code} . " for council @{[$self->_current_council->area_id]}: $@\n" + if $self->verbose >= 1; return; } } @@ -176,7 +180,8 @@ sub _create_contact { }; if ( $@ ) { - warn "Failed to create contact for service code " . $self->_current_service->{service_code} . " for council @{[$self->_current_council->area_id]}: $@\n"; + warn "Failed to create contact for service code " . $self->_current_service->{service_code} . " for council @{[$self->_current_council->area_id]}: $@\n" + if $self->verbose >= 1; return; } @@ -186,14 +191,14 @@ sub _create_contact { if ( $contact ) { push @{ $self->found_contacts }, $self->_current_service->{service_code}; - print "created contact for service code " . $self->_current_service->{service_code} . " for council @{[$self->_current_council->area_id]}\n" if $self->verbose; + print "created contact for service code " . $self->_current_service->{service_code} . " for council @{[$self->_current_council->area_id]}\n" if $self->verbose >= 2; } } sub _add_meta_to_contact { my ( $self, $contact ) = @_; - print "Fetching meta data for $self->_current_service->{service_code}\n" if $self->verbose; + print "Fetching meta data for $self->_current_service->{service_code}\n" if $self->verbose >= 2; my $meta_data = $self->_current_open311->get_service_meta_info( $self->_current_service->{service_code} ); if ( ref $meta_data->{ attributes }->{ attribute } eq 'HASH' ) { diff --git a/perllib/PoChange.pm b/perllib/PoChange.pm index deecd3b00..06b78fa3f 100644 --- a/perllib/PoChange.pm +++ b/perllib/PoChange.pm @@ -3,6 +3,19 @@ use strict; package PoChange; +sub translate($$) { + my $file = shift; + my $s = shift; + + if ( $file eq 'FixMyStreet-EmptyHomes' ) { + return fixmystreet_to_reportemptyhomes( $s ); + } elsif ( $file eq 'FixMyBarangay' ) { + return fixmystreet_to_fixmybarangay( $s ); + } + + return $s; +} + # Takes a msgid from the main FixMyStreet .po file and # converts it to a msgid for the ReportEmptyHomes .po file sub fixmystreet_to_reportemptyhomes($) { @@ -35,4 +48,16 @@ sub fixmystreet_to_reportemptyhomes($) { return $s; } +sub fixmystreet_to_fixmybarangay($) { + my $s = shift; + + $s =~ s/FixMyStreet/FixMyBarangay/g; + $s =~ s/\bcouncil\b/barangay/g; + $s =~ s/\bCouncil\b/Barangay/g; + $s =~ s/\bcouncils\b/barangays/g; + $s =~ s/\bCouncils\b/Barangays/g; + + return $s; +} + 1; diff --git a/perllib/Utils.pm b/perllib/Utils.pm index 6a47fd17d..fa90620a0 100644 --- a/perllib/Utils.pm +++ b/perllib/Utils.pm @@ -12,31 +12,13 @@ package Utils; use strict; +use DateTime; use Encode; use File::Slurp qw(); -use POSIX qw(strftime); use mySociety::DBHandle qw(dbh); use mySociety::GeoUtil; use mySociety::Locale; -sub workaround_pg_bytea { - my ( $st, $img_idx, @elements ) = @_; - my $s = dbh()->prepare($st); - for ( my $i = 1 ; $i <= @elements ; $i++ ) { - if ( $i == $img_idx ) { - $s->bind_param( - $i, - $elements[ $i - 1 ], - { pg_type => DBD::Pg::PG_BYTEA } - ); - } - else { - $s->bind_param( $i, $elements[ $i - 1 ] ); - } - } - $s->execute(); -} - =head2 convert_latlon_to_en ( $easting, $northing ) = Utils::convert_en_to_latlon( $latitude, $longitude ); @@ -144,22 +126,10 @@ sub barnet_categories { # The values here are KBIDs from Barnet's system: see bin/send-reports for formatting if (mySociety::Config::get('STAGING_SITE')) { # note staging site must use different KBIDs return { - 'Blocked drain' => 255, # Gullies-Blocked - 'Dead animal' => 286, # Animals-Dead-Removal - 'Dog fouling' => 288, # Dog Fouling-Clear - 'Fly tipping' => 347, # Fly tipping-Clear - 'Graffiti' => 292, # Graffiti-Removal - 'Litter, accumulated' => 349, # Accumulated Litter - 'Litter, overflowing bins' => 205, # Litter Bins-Overflowing - 'Pavements' => 195, # Pavements-Damaged/Cracked - 'Pothole' => 204, # Pothole - 'Roads Signs' => 432, # Roads Signs - Maintenance - 'Street Lighting' => 251, # Street Lighting - 'Traffic Lights' => 103, # Traffic Lights + 'Street scene misc' => 14 # for test } } else { return { - 'Abandoned Vehicle' => 468, 'Accumulated Litter' => 349, 'Dog Bin' => 203, 'Dog Fouling' => 288, @@ -252,25 +222,33 @@ sub cleanup_text { } sub prettify_epoch { - my ( $s, $type ) = @_; + my ( $epoch, $type ) = @_; + $type ||= ''; $type = 'short' if $type eq '1'; - my @s = localtime($s); + my $dt = DateTime->from_epoch( epoch => $epoch, time_zone => 'local' ); + $dt->set_time_zone( FixMyStreet->config('TIME_ZONE') ) + if FixMyStreet->config('TIME_ZONE'); + + my $now = DateTime->now( time_zone => 'local' ); + $now->set_time_zone( FixMyStreet->config('TIME_ZONE') ) + if FixMyStreet->config('TIME_ZONE'); + my $tt = ''; - $tt = strftime('%H:%M', @s) unless $type eq 'date'; - my @t = localtime(); - if (strftime('%Y%m%d', @s) eq strftime('%Y%m%d', @t)) { + $tt = $dt->strftime('%H:%M') unless $type eq 'date'; + + if ($dt->strftime('%Y%m%d') eq $now->strftime('%Y%m%d')) { return "$tt " . _('today'); } $tt .= ', ' unless $type eq 'date'; - if (strftime('%Y %U', @s) eq strftime('%Y %U', @t)) { - $tt .= decode_utf8(strftime('%A', @s)); + if ($dt->strftime('%Y %U') eq $now->strftime('%Y %U')) { + $tt .= decode_utf8($dt->strftime('%A')); } elsif ($type eq 'short') { - $tt .= decode_utf8(strftime('%e %b %Y', @s)); - } elsif (strftime('%Y', @s) eq strftime('%Y', @t)) { - $tt .= decode_utf8(strftime('%A %e %B %Y', @s)); + $tt .= decode_utf8($dt->strftime('%e %b %Y')); + } elsif ($dt->strftime('%Y') eq $now->strftime('%Y')) { + $tt .= decode_utf8($dt->strftime('%A %e %B %Y')); } else { - $tt .= decode_utf8(strftime('%a %e %B %Y', @s)); + $tt .= decode_utf8($dt->strftime('%a %e %B %Y')); } return $tt; } @@ -289,17 +267,27 @@ sub prettify_duration { return _('less than a minute') if $s == 0; } my @out = (); - _part(\$s, 60*60*24*7, _('%d week'), _('%d weeks'), \@out); - _part(\$s, 60*60*24, _('%d day'), _('%d days'), \@out); - _part(\$s, 60*60, _('%d hour'), _('%d hours'), \@out); - _part(\$s, 60, _('%d minute'), _('%d minutes'), \@out); + _part(\$s, 60*60*24*7, \@out); + _part(\$s, 60*60*24, \@out); + _part(\$s, 60*60, \@out); + _part(\$s, 60, \@out); return join(', ', @out); } sub _part { - my ($s, $m, $w1, $w2, $o) = @_; + my ($s, $m, $o) = @_; if ($$s >= $m) { my $i = int($$s / $m); - push @$o, sprintf(mySociety::Locale::nget($w1, $w2, $i), $i); + my $str; + if ($m == 60*60*24*7) { + $str = mySociety::Locale::nget("%d week", "%d weeks", $i); + } elsif ($m == 60*60*24) { + $str = mySociety::Locale::nget("%d day", "%d days", $i); + } elsif ($m == 60*60) { + $str = mySociety::Locale::nget("%d hour", "%d hours", $i); + } elsif ($m == 60) { + $str = mySociety::Locale::nget("%d minute", "%d minutes", $i); + } + push @$o, sprintf($str, $i); $$s -= $i * $m; } } diff --git a/phonegap/Android/.classpath b/phonegap/Android/.classpath index 075ed1757..e088a5d5b 100644 --- a/phonegap/Android/.classpath +++ b/phonegap/Android/.classpath @@ -4,6 +4,6 @@ <classpathentry kind="src" path="gen"/> <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/> <classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/> - <classpathentry kind="lib" path="libs/cordova-1.8.0.jar"/> + <classpathentry kind="lib" path="libs/cordova-2.1.0.jar"/> <classpathentry kind="output" path="bin/classes"/> </classpath> diff --git a/phonegap/Android/AndroidManifest.xml b/phonegap/Android/AndroidManifest.xml index b9540ffbe..8e7f49994 100644 --- a/phonegap/Android/AndroidManifest.xml +++ b/phonegap/Android/AndroidManifest.xml @@ -4,7 +4,16 @@ android:versionCode="1" android:versionName="1.0" > - <uses-sdk android:minSdkVersion="10" /> + <uses-sdk + android:minSdkVersion="7" + android:targetSdkVersion="15" /> + + <supports-screens + android:largeScreens="true" + android:normalScreens="true" + android:smallScreens="true" + android:resizeable="true" + android:anyDensity="true" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/> @@ -15,10 +24,12 @@ <application android:icon="@drawable/ic_launcher" - android:label="@string/app_name"> + android:label="@string/app_name" + android:theme="@style/AppTheme" > <activity android:name=".AndroidActivity" - android:label="@string/app_name" > + android:label="@string/title_activity_main" + android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" > <intent-filter> <action android:name="android.intent.action.MAIN" /> diff --git a/phonegap/Android/gen/org/mysociety/FixMyStreet/R.java b/phonegap/Android/gen/org/mysociety/FixMyStreet/R.java index adcacc076..9dd2e6d98 100644 --- a/phonegap/Android/gen/org/mysociety/FixMyStreet/R.java +++ b/phonegap/Android/gen/org/mysociety/FixMyStreet/R.java @@ -11,17 +11,28 @@ public final class R { public static final class attr { } public static final class drawable { - public static final int ic_launcher=0x7f020000; + public static final int ic_action_search=0x7f020000; + public static final int ic_launcher=0x7f020001; + } + public static final class id { + public static final int menu_settings=0x7f080000; } public static final class layout { - public static final int main=0x7f030000; + public static final int activity_main=0x7f030000; + } + public static final class menu { + public static final int activity_main=0x7f070000; } public static final class string { - public static final int app_name=0x7f050001; - public static final int hello=0x7f050000; + public static final int app_name=0x7f050000; + public static final int hello=0x7f050001; + public static final int menu_settings=0x7f050002; + public static final int title_activity_main=0x7f050003; + } + public static final class style { + public static final int AppTheme=0x7f060000; } public static final class xml { - public static final int cordova=0x7f040000; - public static final int plugins=0x7f040001; + public static final int config=0x7f040000; } } diff --git a/phonegap/Android/libs/cordova-1.8.0.jar b/phonegap/Android/libs/cordova-1.8.0.jar Binary files differdeleted file mode 100755 index 326fa8392..000000000 --- a/phonegap/Android/libs/cordova-1.8.0.jar +++ /dev/null diff --git a/phonegap/Android/libs/cordova-2.1.0.jar b/phonegap/Android/libs/cordova-2.1.0.jar Binary files differnew file mode 100644 index 000000000..d3eecaaaf --- /dev/null +++ b/phonegap/Android/libs/cordova-2.1.0.jar diff --git a/phonegap/Android/proguard-project.txt b/phonegap/Android/proguard-project.txt new file mode 100644 index 000000000..f2fe1559a --- /dev/null +++ b/phonegap/Android/proguard-project.txt @@ -0,0 +1,20 @@ +# To enable ProGuard in your project, edit project.properties +# to define the proguard.config property as described in that file. +# +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in ${sdk.dir}/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the ProGuard +# include property in project.properties. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/phonegap/Android/proguard.cfg b/phonegap/Android/proguard.cfg deleted file mode 100644 index b1cdf17b5..000000000 --- a/phonegap/Android/proguard.cfg +++ /dev/null @@ -1,40 +0,0 @@ --optimizationpasses 5 --dontusemixedcaseclassnames --dontskipnonpubliclibraryclasses --dontpreverify --verbose --optimizations !code/simplification/arithmetic,!field/*,!class/merging/* - --keep public class * extends android.app.Activity --keep public class * extends android.app.Application --keep public class * extends android.app.Service --keep public class * extends android.content.BroadcastReceiver --keep public class * extends android.content.ContentProvider --keep public class * extends android.app.backup.BackupAgentHelper --keep public class * extends android.preference.Preference --keep public class com.android.vending.licensing.ILicensingService - --keepclasseswithmembernames class * { - native <methods>; -} - --keepclasseswithmembers class * { - public <init>(android.content.Context, android.util.AttributeSet); -} - --keepclasseswithmembers class * { - public <init>(android.content.Context, android.util.AttributeSet, int); -} - --keepclassmembers class * extends android.app.Activity { - public void *(android.view.View); -} - --keepclassmembers enum * { - public static **[] values(); - public static ** valueOf(java.lang.String); -} - --keep class * implements android.os.Parcelable { - public static final android.os.Parcelable$Creator *; -} diff --git a/phonegap/Android/project.properties b/phonegap/Android/project.properties index f049142c1..9b84a6b4b 100644 --- a/phonegap/Android/project.properties +++ b/phonegap/Android/project.properties @@ -3,9 +3,12 @@ # # This file must be checked in Version Control Systems. # -# To customize properties used by the Ant build system use, +# To customize properties used by the Ant build system edit # "ant.properties", and override values to adapt the script to your # project structure. +# +# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): +#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt # Project target. -target=android-10 +target=android-16 diff --git a/phonegap/Android/res/drawable-hdpi/ic_action_search.png b/phonegap/Android/res/drawable-hdpi/ic_action_search.png Binary files differnew file mode 100644 index 000000000..67de12dec --- /dev/null +++ b/phonegap/Android/res/drawable-hdpi/ic_action_search.png diff --git a/phonegap/Android/res/drawable-hdpi/ic_launcher.png b/phonegap/Android/res/drawable-hdpi/ic_launcher.png Binary files differindex 8074c4c57..a301d5795 100644 --- a/phonegap/Android/res/drawable-hdpi/ic_launcher.png +++ b/phonegap/Android/res/drawable-hdpi/ic_launcher.png diff --git a/phonegap/Android/res/drawable-ldpi/ic_launcher.png b/phonegap/Android/res/drawable-ldpi/ic_launcher.png Binary files differindex 1095584ec..2c2a58b2f 100644 --- a/phonegap/Android/res/drawable-ldpi/ic_launcher.png +++ b/phonegap/Android/res/drawable-ldpi/ic_launcher.png diff --git a/phonegap/Android/res/drawable-mdpi/ic_action_search.png b/phonegap/Android/res/drawable-mdpi/ic_action_search.png Binary files differnew file mode 100644 index 000000000..134d5490b --- /dev/null +++ b/phonegap/Android/res/drawable-mdpi/ic_action_search.png diff --git a/phonegap/Android/res/drawable-mdpi/ic_launcher.png b/phonegap/Android/res/drawable-mdpi/ic_launcher.png Binary files differindex a07c69fa5..f91f736fe 100644 --- a/phonegap/Android/res/drawable-mdpi/ic_launcher.png +++ b/phonegap/Android/res/drawable-mdpi/ic_launcher.png diff --git a/phonegap/Android/res/drawable-xhdpi/ic_action_search.png b/phonegap/Android/res/drawable-xhdpi/ic_action_search.png Binary files differnew file mode 100644 index 000000000..d699c6b37 --- /dev/null +++ b/phonegap/Android/res/drawable-xhdpi/ic_action_search.png diff --git a/phonegap/Android/res/drawable-xhdpi/ic_launcher.png b/phonegap/Android/res/drawable-xhdpi/ic_launcher.png Binary files differnew file mode 100644 index 000000000..96095ec84 --- /dev/null +++ b/phonegap/Android/res/drawable-xhdpi/ic_launcher.png diff --git a/phonegap/Android/res/layout/activity_main.xml b/phonegap/Android/res/layout/activity_main.xml new file mode 100644 index 000000000..0b4ffccc1 --- /dev/null +++ b/phonegap/Android/res/layout/activity_main.xml @@ -0,0 +1,14 @@ +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" > + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerHorizontal="true" + android:layout_centerVertical="true" + android:text="@string/hello" + tools:context=".MainActivity" /> + +</RelativeLayout> diff --git a/phonegap/Android/res/layout/main.xml b/phonegap/Android/res/layout/main.xml deleted file mode 100644 index bc12cd823..000000000 --- a/phonegap/Android/res/layout/main.xml +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:orientation="vertical" > - - <TextView - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:text="@string/hello" /> - -</LinearLayout>
\ No newline at end of file diff --git a/phonegap/Android/res/menu/activity_main.xml b/phonegap/Android/res/menu/activity_main.xml new file mode 100644 index 000000000..cfc10fd52 --- /dev/null +++ b/phonegap/Android/res/menu/activity_main.xml @@ -0,0 +1,6 @@ +<menu xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:id="@+id/menu_settings" + android:title="@string/menu_settings" + android:orderInCategory="100" + android:showAsAction="never" /> +</menu> diff --git a/phonegap/Android/res/values-v11/styles.xml b/phonegap/Android/res/values-v11/styles.xml new file mode 100644 index 000000000..d408cbc37 --- /dev/null +++ b/phonegap/Android/res/values-v11/styles.xml @@ -0,0 +1,5 @@ +<resources> + + <style name="AppTheme" parent="android:Theme.Holo.Light" /> + +</resources>
\ No newline at end of file diff --git a/phonegap/Android/res/values-v14/styles.xml b/phonegap/Android/res/values-v14/styles.xml new file mode 100644 index 000000000..1c089a788 --- /dev/null +++ b/phonegap/Android/res/values-v14/styles.xml @@ -0,0 +1,5 @@ +<resources> + + <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar" /> + +</resources>
\ No newline at end of file diff --git a/phonegap/Android/res/values/strings.xml b/phonegap/Android/res/values/strings.xml index a4df04a14..6e091cf98 100644 --- a/phonegap/Android/res/values/strings.xml +++ b/phonegap/Android/res/values/strings.xml @@ -3,5 +3,7 @@ <string name="hello">Hello World, AndroidActivity!</string> <string name="app_name">FixMyStreet</string> + <string name="menu_settings">Settings</string> + <string name="title_activity_main">AndroidActivity</string> </resources>
\ No newline at end of file diff --git a/phonegap/Android/res/xml/plugins.xml b/phonegap/Android/res/xml/config.xml index 76879a1ce..4a6fffccb 100644 --- a/phonegap/Android/res/xml/plugins.xml +++ b/phonegap/Android/res/xml/config.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- +<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information @@ -17,6 +17,21 @@ specific language governing permissions and limitations under the License. --> +<cordova> + <!-- + access elements control the Android whitelist. + Domains are assumed blocked unless set otherwise + --> + + <access origin="http://127.0.0.1*"/> <!-- allow local pages --> + + <!-- <access origin="https://example.com" /> allow any secure requests to example.com --> + <!-- <access origin="https://example.com" subdomains="true" /> such as above, but including subdomains, such as www --> + <access origin=".*"/> + + <log level="DEBUG"/> + <preference name="useBrowserHistory" value="false" /> + <preference name="exit-on-suspend" value="false" /> <plugins> <plugin name="App" value="org.apache.cordova.App"/> <plugin name="Geolocation" value="org.apache.cordova.GeoBroker"/> @@ -35,4 +50,7 @@ <plugin name="Capture" value="org.apache.cordova.Capture"/> <plugin name="Battery" value="org.apache.cordova.BatteryListener"/> <plugin name="SplashScreen" value="org.apache.cordova.SplashScreen"/> + <plugin name="Echo" value="org.apache.cordova.Echo" /> </plugins> +</cordova> + diff --git a/phonegap/Android/res/xml/cordova.xml b/phonegap/Android/res/xml/cordova.xml deleted file mode 100644 index c7b500003..000000000 --- a/phonegap/Android/res/xml/cordova.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<cordova> - <access origin="http://127.0.0.1*"/> - <log level="DEBUG"/> -</cordova> diff --git a/phonegap/iPhone/Default-568h@2x.png b/phonegap/iPhone/Default-568h@2x.png Binary files differnew file mode 100644 index 000000000..0891b7aab --- /dev/null +++ b/phonegap/iPhone/Default-568h@2x.png diff --git a/phonegap/iPhone/FixMyStreet.xcodeproj/project.pbxproj b/phonegap/iPhone/FixMyStreet.xcodeproj/project.pbxproj index 9dea27891..9ab180b40 100644 --- a/phonegap/iPhone/FixMyStreet.xcodeproj/project.pbxproj +++ b/phonegap/iPhone/FixMyStreet.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + 24065F8D162C7721004574A1 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 24065F8C162C7721004574A1 /* Default-568h@2x.png */; }; + 249ED5EB162D82AD000076A1 /* cordova in Resources */ = {isa = PBXBuildFile; fileRef = 249ED5EA162D82AD000076A1 /* cordova */; }; + 249ED5EC162D83BA000076A1 /* libCordova.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 240FE2F1162D6E4D00250E2D /* libCordova.a */; }; 24D3BF4C1508D60F005923FE /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 24D3BF4B1508D60F005923FE /* Foundation.framework */; }; 24D3BF4E1508D60F005923FE /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 24D3BF4D1508D60F005923FE /* UIKit.framework */; }; 24D3BF501508D60F005923FE /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 24D3BF4F1508D60F005923FE /* CoreGraphics.framework */; }; @@ -22,7 +25,6 @@ 24D3BF641508D60F005923FE /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 24D3BF631508D60F005923FE /* CoreMedia.framework */; }; 24D3BF6A1508D60F005923FE /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 24D3BF681508D60F005923FE /* InfoPlist.strings */; }; 24D3BF6C1508D60F005923FE /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 24D3BF6B1508D60F005923FE /* main.m */; }; - 24D3BF6F1508D60F005923FE /* Cordova.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 24D3BF6E1508D60F005923FE /* Cordova.framework */; }; 24D3BF741508D60F005923FE /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 24D3BF721508D60F005923FE /* Localizable.strings */; }; 24D3BF781508D60F005923FE /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 24D3BF761508D60F005923FE /* Localizable.strings */; }; 24D3BF7C1508D60F005923FE /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 24D3BF7A1508D60F005923FE /* Localizable.strings */; }; @@ -37,11 +39,30 @@ 24D3BF941508D60F005923FE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 24D3BF931508D60F005923FE /* AppDelegate.m */; }; 24D3BF971508D60F005923FE /* MainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 24D3BF961508D60F005923FE /* MainViewController.m */; }; 24D3BF991508D60F005923FE /* MainViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 24D3BF981508D60F005923FE /* MainViewController.xib */; }; - 24D3BF9D1508D60F005923FE /* verify.sh in Resources */ = {isa = PBXBuildFile; fileRef = 24D3BF9C1508D60F005923FE /* verify.sh */; }; 24E16541150E0F9600F31308 /* www in Resources */ = {isa = PBXBuildFile; fileRef = 24E16540150E0F9600F31308 /* www */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + 240FE2F0162D6E4D00250E2D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 240FE2E9162D6E4D00250E2D /* CordovaLib.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 68A32D7114102E1C006B237C; + remoteInfo = CordovaLib; + }; + 249ED5DC162D7057000076A1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 240FE2E9162D6E4D00250E2D /* CordovaLib.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = CordovaLib; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXFileReference section */ + 24065F8C162C7721004574A1 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; }; + 240FE2E9162D6E4D00250E2D /* CordovaLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = CordovaLib.xcodeproj; path = ../../../../../libs/cordova_2.1/lib/ios/CordovaLib/CordovaLib.xcodeproj; sourceTree = "<group>"; }; + 249ED5EA162D82AD000076A1 /* cordova */ = {isa = PBXFileReference; lastKnownFileType = folder; path = cordova; sourceTree = "<group>"; }; 24D3BF471508D60F005923FE /* FixMyStreet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FixMyStreet.app; sourceTree = BUILT_PRODUCTS_DIR; }; 24D3BF4B1508D60F005923FE /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 24D3BF4D1508D60F005923FE /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; @@ -60,7 +81,6 @@ 24D3BF691508D60F005923FE /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 24D3BF6B1508D60F005923FE /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; }; 24D3BF6D1508D60F005923FE /* FixMyStreet-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "FixMyStreet-Prefix.pch"; sourceTree = "<group>"; }; - 24D3BF6E1508D60F005923FE /* Cordova.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cordova.framework; path = /Users/Shared/Cordova/Frameworks/Cordova.framework; sourceTree = "<absolute>"; }; 24D3BF731508D60F005923FE /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = Resources/en.lproj/Localizable.strings; sourceTree = "<group>"; }; 24D3BF771508D60F005923FE /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = Resources/es.lproj/Localizable.strings; sourceTree = "<group>"; }; 24D3BF7B1508D60F005923FE /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = Resources/de.lproj/Localizable.strings; sourceTree = "<group>"; }; @@ -78,7 +98,6 @@ 24D3BF961508D60F005923FE /* MainViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = MainViewController.m; path = Classes/MainViewController.m; sourceTree = "<group>"; }; 24D3BF981508D60F005923FE /* MainViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = MainViewController.xib; path = Classes/MainViewController.xib; sourceTree = "<group>"; }; 24D3BF9B1508D60F005923FE /* README */ = {isa = PBXFileReference; lastKnownFileType = text; name = README; path = Plugins/README; sourceTree = "<group>"; }; - 24D3BF9C1508D60F005923FE /* verify.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = verify.sh; sourceTree = "<group>"; }; 24E16540150E0F9600F31308 /* www */ = {isa = PBXFileReference; lastKnownFileType = folder; name = www; path = ../www; sourceTree = "<group>"; }; /* End PBXFileReference section */ @@ -87,6 +106,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 249ED5EC162D83BA000076A1 /* libCordova.a in Frameworks */, 24D3BF4C1508D60F005923FE /* Foundation.framework in Frameworks */, 24D3BF4E1508D60F005923FE /* UIKit.framework in Frameworks */, 24D3BF501508D60F005923FE /* CoreGraphics.framework in Frameworks */, @@ -100,7 +120,6 @@ 24D3BF601508D60F005923FE /* SystemConfiguration.framework in Frameworks */, 24D3BF621508D60F005923FE /* MobileCoreServices.framework in Frameworks */, 24D3BF641508D60F005923FE /* CoreMedia.framework in Frameworks */, - 24D3BF6F1508D60F005923FE /* Cordova.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -114,13 +133,24 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 240FE2EA162D6E4D00250E2D /* Products */ = { + isa = PBXGroup; + children = ( + 240FE2F1162D6E4D00250E2D /* libCordova.a */, + ); + name = Products; + sourceTree = "<group>"; + }; 24D3BF391508D60E005923FE = { isa = PBXGroup; children = ( + 249ED5EA162D82AD000076A1 /* cordova */, + 24065F8C162C7721004574A1 /* Default-568h@2x.png */, 24E16540150E0F9600F31308 /* www */, 24D3BF651508D60F005923FE /* FixMyStreet */, 24D3BF4A1508D60F005923FE /* Frameworks */, 24D3BF481508D60F005923FE /* Products */, + 240FE2E9162D6E4D00250E2D /* CordovaLib.xcodeproj */, ); sourceTree = "<group>"; }; @@ -155,7 +185,6 @@ 24D3BF651508D60F005923FE /* FixMyStreet */ = { isa = PBXGroup; children = ( - 24D3BF6E1508D60F005923FE /* Cordova.framework */, 24D3BF701508D60F005923FE /* Resources */, 24D3BF911508D60F005923FE /* Classes */, 24D3BF9A1508D60F005923FE /* Plugins */, @@ -173,7 +202,6 @@ 24D3BF6D1508D60F005923FE /* FixMyStreet-Prefix.pch */, 24D3BF8F1508D60F005923FE /* Cordova.plist */, 24D3BF981508D60F005923FE /* MainViewController.xib */, - 24D3BF9C1508D60F005923FE /* verify.sh */, ); name = "Supporting Files"; sourceTree = "<group>"; @@ -274,11 +302,11 @@ 24D3BF421508D60F005923FE /* Resources */, 24D3BF431508D60F005923FE /* Sources */, 24D3BF441508D60F005923FE /* Frameworks */, - 24D3BF451508D60F005923FE /* ShellScript */, ); buildRules = ( ); dependencies = ( + 249ED5DD162D7057000076A1 /* PBXTargetDependency */, ); name = FixMyStreet; productName = FixMyStreet; @@ -291,7 +319,7 @@ 24D3BF3B1508D60E005923FE /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0420; + LastUpgradeCheck = 0450; }; buildConfigurationList = 24D3BF3E1508D60E005923FE /* Build configuration list for PBXProject "FixMyStreet" */; compatibilityVersion = "Xcode 3.2"; @@ -306,6 +334,12 @@ mainGroup = 24D3BF391508D60E005923FE; productRefGroup = 24D3BF481508D60F005923FE /* Products */; projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 240FE2EA162D6E4D00250E2D /* Products */; + ProjectRef = 240FE2E9162D6E4D00250E2D /* CordovaLib.xcodeproj */; + }, + ); projectRoot = ""; targets = ( 24D3BF461508D60F005923FE /* FixMyStreet */, @@ -313,6 +347,16 @@ }; /* End PBXProject section */ +/* Begin PBXReferenceProxy section */ + 240FE2F1162D6E4D00250E2D /* libCordova.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libCordova.a; + remoteRef = 240FE2F0162D6E4D00250E2D /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + /* Begin PBXResourcesBuildPhase section */ 24D3BF421508D60F005923FE /* Resources */ = { isa = PBXResourcesBuildPhase; @@ -331,29 +375,14 @@ 24D3BF8E1508D60F005923FE /* Capture.bundle in Resources */, 24D3BF901508D60F005923FE /* Cordova.plist in Resources */, 24D3BF991508D60F005923FE /* MainViewController.xib in Resources */, - 24D3BF9D1508D60F005923FE /* verify.sh in Resources */, 24E16541150E0F9600F31308 /* www in Resources */, + 24065F8D162C7721004574A1 /* Default-568h@2x.png in Resources */, + 249ED5EB162D82AD000076A1 /* cordova in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ -/* Begin PBXShellScriptBuildPhase section */ - 24D3BF451508D60F005923FE /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/bash; - shellScript = "\n\t\t\t\t\t\t\t\tchmod 755 $PROJECT_DIR/$PROJECT_NAME/verify.sh\n\t\t\t\t\t\t\t\t$PROJECT_DIR/$PROJECT_NAME/verify.sh\n\t\t\t\t\t"; - }; -/* End PBXShellScriptBuildPhase section */ - /* Begin PBXSourcesBuildPhase section */ 24D3BF401508D60F005923FE /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -374,6 +403,14 @@ }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + 249ED5DD162D7057000076A1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CordovaLib; + targetProxy = 249ED5DC162D7057000076A1 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin PBXVariantGroup section */ 24D3BF681508D60F005923FE /* InfoPlist.strings */ = { isa = PBXVariantGroup; @@ -422,10 +459,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = ( - armv6, - "$(ARCHS_STANDARD_32_BIT)", - ); + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CLANG_ENABLE_OBJC_ARC = NO; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; @@ -437,11 +471,13 @@ "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_THUMB_SUPPORT = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 3.0; + ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; name = Debug; @@ -450,19 +486,18 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = ( - armv6, - "$(ARCHS_STANDARD_32_BIT)", - ); + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CLANG_ENABLE_OBJC_ARC = NO; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_THUMB_SUPPORT = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 3.0; + ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; @@ -477,11 +512,15 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "FixMyStreet/FixMyStreet-Prefix.pch"; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1,", - "CORDOVA_FRAMEWORK=1", + GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1,"; + GCC_THUMB_SUPPORT = NO; + "HEADER_SEARCH_PATHS[arch=*]" = ( + "\"$(TARGET_BUILD_DIR)/usr/local/lib/include\"", + "\"$(OBJROOT)/UninstalledProducts/include\"", + "\"$(BUILT_PRODUCTS_DIR)\"", ); INFOPLIST_FILE = "FixMyStreet/FixMyStreet-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 4.3; OTHER_LDFLAGS = ( "-weak_framework", UIKit, @@ -491,6 +530,10 @@ CoreMedia, "-weak_library", /usr/lib/libSystem.B.dylib, + "-Obj-C", + "-all_load", + "-weak_framework", + CoreFoundation, ); PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = 1; @@ -512,7 +555,14 @@ "NDEBUG=1,", "CORDOVA_FRAMEWORK=1", ); + GCC_THUMB_SUPPORT = NO; + "HEADER_SEARCH_PATHS[arch=*]" = ( + "\"$(TARGET_BUILD_DIR)/usr/local/lib/include\"", + "\"$(OBJROOT)/UninstalledProducts/include\"", + "\"$(BUILT_PRODUCTS_DIR)\"", + ); INFOPLIST_FILE = "FixMyStreet/FixMyStreet-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 4.3; OTHER_LDFLAGS = ( "-weak_framework", UIKit, @@ -522,6 +572,10 @@ CoreMedia, "-weak_library", /usr/lib/libSystem.B.dylib, + "-Obj-C", + "-all_load", + "-weak_framework", + CoreFoundation, ); PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = 1; diff --git a/phonegap/iPhone/FixMyStreet.xcodeproj/xcuserdata/struan.xcuserdatad/xcschemes/FixMyStreet.xcscheme b/phonegap/iPhone/FixMyStreet.xcodeproj/xcuserdata/struan.xcuserdatad/xcschemes/FixMyStreet.xcscheme index 1bd90c562..4d631ea26 100644 --- a/phonegap/iPhone/FixMyStreet.xcodeproj/xcuserdata/struan.xcuserdatad/xcschemes/FixMyStreet.xcscheme +++ b/phonegap/iPhone/FixMyStreet.xcodeproj/xcuserdata/struan.xcuserdatad/xcschemes/FixMyStreet.xcscheme @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <Scheme + LastUpgradeVersion = "0450" version = "1.3"> <BuildAction parallelizeBuildables = "YES" @@ -22,7 +23,7 @@ </BuildActionEntries> </BuildAction> <TestAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.GDB" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB" shouldUseLaunchSchemeArgsEnv = "YES" buildConfiguration = "Debug"> @@ -39,11 +40,12 @@ </MacroExpansion> </TestAction> <LaunchAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.GDB" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB" launchStyle = "0" useCustomWorkingDirectory = "NO" buildConfiguration = "Debug" + ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" allowLocationSimulation = "YES"> <BuildableProductRunnable> diff --git a/phonegap/iPhone/FixMyStreet/Classes/AppDelegate.h b/phonegap/iPhone/FixMyStreet/Classes/AppDelegate.h index cee4240b1..5c258f148 100644 --- a/phonegap/iPhone/FixMyStreet/Classes/AppDelegate.h +++ b/phonegap/iPhone/FixMyStreet/Classes/AppDelegate.h @@ -19,32 +19,27 @@ // // AppDelegate.h -// cordova1.8.0 +// tmp_cordova // -// Created by Struan Donald on 08/06/2012. -// Copyright __MyCompanyName__ 2012. All rights reserved. +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. // #import <UIKit/UIKit.h> -#ifdef CORDOVA_FRAMEWORK - #import <Cordova/CDVViewController.h> -#else - #import "CDVViewController.h" -#endif - +#import <Cordova/CDVViewController.h> @interface AppDelegate : NSObject < UIApplicationDelegate > { } // invoke string is passed to your app on launch, this is only valid if you -// edit cordova1.8.0-Info.plist to add a protocol +// edit tmp_cordova-Info.plist to add a protocol // a simple tutorial can be found here : // http://iphonedevelopertips.com/cocoa/launching-your-own-application-via-a-custom-url-scheme.html -@property (nonatomic, retain) IBOutlet UIWindow* window; -@property (nonatomic, retain) IBOutlet CDVViewController* viewController; +@property (nonatomic, strong) IBOutlet UIWindow* window; +@property (nonatomic, strong) IBOutlet CDVViewController* viewController; @end diff --git a/phonegap/iPhone/FixMyStreet/Classes/AppDelegate.m b/phonegap/iPhone/FixMyStreet/Classes/AppDelegate.m index ad518dc80..b1c862eee 100644 --- a/phonegap/iPhone/FixMyStreet/Classes/AppDelegate.m +++ b/phonegap/iPhone/FixMyStreet/Classes/AppDelegate.m @@ -19,22 +19,16 @@ // // AppDelegate.m -// cordova1.8.0 +// tmp_cordova // -// Created by Struan Donald on 08/06/2012. -// Copyright __MyCompanyName__ 2012. All rights reserved. +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. // #import "AppDelegate.h" #import "MainViewController.h" -#ifdef CORDOVA_FRAMEWORK - #import <Cordova/CDVPlugin.h> - #import <Cordova/CDVURLProtocol.h> -#else - #import "CDVPlugin.h" - #import "CDVURLProtocol.h" -#endif +#import <Cordova/CDVPlugin.h> @implementation AppDelegate @@ -49,9 +43,8 @@ NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; [cookieStorage setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways]; - [CDVURLProtocol registerURLProtocol]; - - return [super init]; + self = [super init]; + return self; } #pragma UIApplicationDelegate implementation @@ -66,21 +59,20 @@ if (url && [url isKindOfClass:[NSURL class]]) { invokeString = [url absoluteString]; - NSLog(@"cordova1.8.0 launchOptions = %@", url); + NSLog(@"tmp_cordova launchOptions = %@", url); } CGRect screenBounds = [[UIScreen mainScreen] bounds]; - self.window = [[[UIWindow alloc] initWithFrame:screenBounds] autorelease]; + self.window = [[UIWindow alloc] initWithFrame:screenBounds]; self.window.autoresizesSubviews = YES; - CGRect viewBounds = [[UIScreen mainScreen] applicationFrame]; - - self.viewController = [[[MainViewController alloc] init] autorelease]; + self.viewController = [[MainViewController alloc] init]; self.viewController.useSplashScreen = YES; self.viewController.wwwFolderName = @"www"; self.viewController.startPage = @"index.html"; self.viewController.invokeString = invokeString; - self.viewController.view.frame = viewBounds; + + // NOTE: To control the view's frame size, override [self.viewController viewWillAppear:] in your view controller. // check whether the current orientation is supported: if it is, keep it, rather than forcing a rotation BOOL forceStartupRotation = YES; @@ -92,30 +84,34 @@ } if (UIDeviceOrientationIsValidInterfaceOrientation(curDevOrientation)) { - for (NSNumber *orient in self.viewController.supportedOrientations) { - if ([orient intValue] == curDevOrientation) { - forceStartupRotation = NO; - break; - } - } + if ([self.viewController supportsOrientation:curDevOrientation]) { + forceStartupRotation = NO; + } } if (forceStartupRotation) { - NSLog(@"supportedOrientations: %@", self.viewController.supportedOrientations); - // The first item in the supportedOrientations array is the start orientation (guaranteed to be at least Portrait) - UIInterfaceOrientation newOrient = [[self.viewController.supportedOrientations objectAtIndex:0] intValue]; + UIInterfaceOrientation newOrient; + if ([self.viewController supportsOrientation:UIInterfaceOrientationPortrait]) + newOrient = UIInterfaceOrientationPortrait; + else if ([self.viewController supportsOrientation:UIInterfaceOrientationLandscapeLeft]) + newOrient = UIInterfaceOrientationLandscapeLeft; + else if ([self.viewController supportsOrientation:UIInterfaceOrientationLandscapeRight]) + newOrient = UIInterfaceOrientationLandscapeRight; + else + newOrient = UIInterfaceOrientationPortraitUpsideDown; + NSLog(@"AppDelegate forcing status bar to: %d from: %d", newOrient, curDevOrientation); [[UIApplication sharedApplication] setStatusBarOrientation:newOrient]; } - [self.window addSubview:self.viewController.view]; + self.window.rootViewController = self.viewController; [self.window makeKeyAndVisible]; return YES; } // this happens while we are running ( in the background, or from within our own app ) -// only valid if cordova1.8.0-Info.plist specifies a protocol to handle +// only valid if tmp_cordova-Info.plist specifies a protocol to handle - (BOOL) application:(UIApplication*)application handleOpenURL:(NSURL*)url { if (!url) { @@ -132,9 +128,11 @@ return YES; } -- (void) dealloc -{ - [super dealloc]; +- (NSUInteger) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window +{ + // IPhone doesn't support upside down by default, while the IPad does. Override to allow all orientations always, and let the root view controller decide whats allowed (the supported orientations mask gets intersected). + NSUInteger supportedInterfaceOrientations = (1 << UIInterfaceOrientationPortrait) | (1 << UIInterfaceOrientationLandscapeLeft) | (1 << UIInterfaceOrientationLandscapeRight) | (1 << UIInterfaceOrientationPortraitUpsideDown); + return supportedInterfaceOrientations; } @end diff --git a/phonegap/iPhone/FixMyStreet/Classes/MainViewController.h b/phonegap/iPhone/FixMyStreet/Classes/MainViewController.h index 3f48936da..c2b68deb8 100644 --- a/phonegap/iPhone/FixMyStreet/Classes/MainViewController.h +++ b/phonegap/iPhone/FixMyStreet/Classes/MainViewController.h @@ -25,11 +25,7 @@ // Copyright __MyCompanyName__ 2012. All rights reserved. // -#ifdef CORDOVA_FRAMEWORK - #import <Cordova/CDVViewController.h> -#else - #import "CDVViewController.h" -#endif +#import <Cordova/CDVViewController.h> @interface MainViewController : CDVViewController diff --git a/phonegap/iPhone/FixMyStreet/Cordova.plist b/phonegap/iPhone/FixMyStreet/Cordova.plist index 66c06689d..cc71225d2 100644 --- a/phonegap/iPhone/FixMyStreet/Cordova.plist +++ b/phonegap/iPhone/FixMyStreet/Cordova.plist @@ -26,10 +26,12 @@ <string>mapit.mysociety.org</string> <string>*.tile.openstreetmap.org</string> <string>*.virtualearth.net</string> - <string>struan.fixmystreet.com</string> + <string>struan.fixmystreet.dev.mysociety.org</string> </array> <key>Plugins</key> <dict> + <key>Device</key> + <string>CDVDevice</string> <key>Compass</key> <string>CDVLocation</string> <key>Accelerometer</key> diff --git a/phonegap/iPhone/FixMyStreet/verify.sh b/phonegap/iPhone/FixMyStreet/verify.sh deleted file mode 100755 index 0f6f0373c..000000000 --- a/phonegap/iPhone/FixMyStreet/verify.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - - -if [ ! -d "$PROJECT_DIR/www" ] ; then - cp -R /Users/Shared/Cordova/Frameworks/Cordova.framework/www "$PROJECT_DIR" -fi -# detect www folder reference in project, if missing, print warning -grep "{isa = PBXFileReference; lastKnownFileType = folder; path = www; sourceTree = \"<group>\"; };" "$PROJECT_DIR/$PROJECT_NAME.xcodeproj/project.pbxproj" -rc=$? -if [ $rc != 0 ] ; then -echo -e "warning: Missing - Add $PROJECT_DIR/www as a folder reference in your project. Just drag and drop the folder into your project, into the Project Navigator of Xcode 4. Make sure you select the second radio-button: 'Create folder references for any added folders' (which will create a blue folder)" 1>&2 -fi
\ No newline at end of file diff --git a/phonegap/www/about.html b/phonegap/www/about.html index 03d2d389a..91e3c30b4 100644 --- a/phonegap/www/about.html +++ b/phonegap/www/about.html @@ -9,7 +9,7 @@ <link rel="stylesheet" href="css/base.css"> <link rel="stylesheet" href="css/mobile.css"> <script type="text/javascript" src="js/config.js"></script> - <script type="text/javascript" charset="utf-8" src="cordova-1.8.0.js"></script> + <script type="text/javascript" charset="utf-8" src="cordova-independent.js"></script> <script type="text/javascript" src="js/jquery-1.7.0.min.js"></script> <script type="text/javascript" src="js/json2.js"></script> <script type="text/javascript" src="js/mobile.js"></script> @@ -135,7 +135,7 @@ rights reserved, Ministry of Justice 100037819 2008), Yahoo! for their BSD-licensed JavaScript libraries, the entire free software community (this particular project was brought to you by Perl, PostgreSQL, and the number 161.290) and <a -href="http://www.m247.com/">M247</a> (who kindly host all +href="http://www.bytemark.co.uk/">Bytemark</a> (who kindly host all our servers). Let us know if we’ve missed anyone.</dd> diff --git a/phonegap/www/sign_in.html b/phonegap/www/account.html index 0a4658e5a..f483b7547 100644 --- a/phonegap/www/sign_in.html +++ b/phonegap/www/account.html @@ -11,16 +11,16 @@ <link rel="stylesheet" href="css/mobile.css"> <link rel="stylesheet" href="css/layout.css" media="(min-width:48em)"> - <script type="text/javascript" src="js/config.js"></script> + <script type="text/javascript" src="js/jquery-1.7.0.min.js"></script> + <script type="text/javascript" charset="utf-8" src="cordova-independent.js"></script> - <script type="text/javascript" charset="utf-8" src="cordova-1.8.0.js"></script> + <script type="text/javascript" src="js/config.js"></script> + <script type="text/javascript" src="js/json2.js"></script> <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <script type="text/javascript" src="js/jquery-1.7.0.min.js"></script> <script src="js/jquery.validate.min.js" type="text/javascript" charset="utf-8"></script> - <script type="text/javascript" src="js/json2.js"></script> <script type="text/javascript" src="js/geo.min.js"></script> <script type="text/javascript" src="js/fixmystreet.js"></script> <script type="text/javascript" src="js/mobile.js"></script> @@ -65,7 +65,7 @@ <div class="container"> <div class="content" role="main"> <form action="" method="post" name="signInForm" id="signInForm" enctype="multipart/form-data" class="validate"> - <div id="form_sign_in_only"> + <div id="form_sign_in_only" class="nodisplay"> <div id="form_sign_in_yes" class="form-box"> <label for="form_email" id="email_label">Email</label> <input type="email" value="" name="email" id="form_email" placeholder="Please enter your email address" required> @@ -75,16 +75,20 @@ <input type="password" name="password_sign_in" id="password_sign_in" placeholder="Your password" value=""> <input class="green-btn" type="submit" id="submit_sign_in" name="submit_sign_in" value="Sign in"> </div> + </div> </div> </form> + <div id="forget_button" class="form-txt-submit-box nodisplay"> + <input class="green-btn" type="button" id="forget" name="forget" value="Forget"> + </div> </div> </div> </div><!-- .table-cell --> <div class="big-green-banner mobile-map-banner mobile-nav-banner"> <a href="index.html">home</a> - Sign In + Account </div> </div> <!-- .wrapper --> <div class="spinner" id="loadingSpinner"> diff --git a/phonegap/www/around.html b/phonegap/www/around.html index f3a6bee06..00842e777 100644 --- a/phonegap/www/around.html +++ b/phonegap/www/around.html @@ -11,13 +11,13 @@ <link rel="stylesheet" href="css/layout.css" media="(min-width:48em)"> <link rel="stylesheet" href="css/mobile.css"> + <script type="text/javascript" src="js/jquery-1.7.0.min.js"></script> + <script type="text/javascript" src="cordova-independent.js"></script> + <script type="text/javascript" src="js/config.js"></script> <script type="text/javascript" src="js/json2.js"></script> - <script type="text/javascript" charset="utf-8" src="cordova-1.8.0.js"></script> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <script type="text/javascript" src="js/jquery-1.7.0.min.js"></script> <script src="js/jquery.validate.min.js" type="text/javascript" charset="utf-8"></script> diff --git a/phonegap/www/cordova-1.8.0.js b/phonegap/www/cordova-1.8.0.js deleted file mode 100644 index d9cced70f..000000000 --- a/phonegap/www/cordova-1.8.0.js +++ /dev/null @@ -1,5226 +0,0 @@ -// commit 109b8649b0e98597b147842a6f71999d2f7910f2 - -// File generated at :: Tue Jun 05 2012 14:10:19 GMT-0700 (PDT) - -/* - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, - software distributed under the License is distributed on an - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - KIND, either express or implied. See the License for the - specific language governing permissions and limitations - under the License. -*/ - -;(function() { - -// file: lib/scripts/require.js -var require, - define; - -(function () { - var modules = {}; - - function build(module) { - var factory = module.factory; - module.exports = {}; - delete module.factory; - factory(require, module.exports, module); - return module.exports; - } - - require = function (id) { - if (!modules[id]) { - throw "module " + id + " not found"; - } - return modules[id].factory ? build(modules[id]) : modules[id].exports; - }; - - define = function (id, factory) { - if (modules[id]) { - throw "module " + id + " already defined"; - } - - modules[id] = { - id: id, - factory: factory - }; - }; - - define.remove = function (id) { - delete modules[id]; - }; - -})(); - -//Export for use in node -if (typeof module === "object" && typeof require === "function") { - module.exports.require = require; - module.exports.define = define; -} -// file: lib/cordova.js -define("cordova", function(require, exports, module) { -var channel = require('cordova/channel'); - -/** - * Listen for DOMContentLoaded and notify our channel subscribers. - */ -document.addEventListener('DOMContentLoaded', function() { - channel.onDOMContentLoaded.fire(); -}, false); -if (document.readyState == 'complete' || document.readyState == 'interactive') { - channel.onDOMContentLoaded.fire(); -} - -/** - * Intercept calls to addEventListener + removeEventListener and handle deviceready, - * resume, and pause events. - */ -var m_document_addEventListener = document.addEventListener; -var m_document_removeEventListener = document.removeEventListener; -var m_window_addEventListener = window.addEventListener; -var m_window_removeEventListener = window.removeEventListener; - -/** - * Houses custom event handlers to intercept on document + window event listeners. - */ -var documentEventHandlers = {}, - windowEventHandlers = {}; - -document.addEventListener = function(evt, handler, capture) { - var e = evt.toLowerCase(); - if (typeof documentEventHandlers[e] != 'undefined') { - if (evt === 'deviceready') { - documentEventHandlers[e].subscribeOnce(handler); - } else { - documentEventHandlers[e].subscribe(handler); - } - } else { - m_document_addEventListener.call(document, evt, handler, capture); - } -}; - -window.addEventListener = function(evt, handler, capture) { - var e = evt.toLowerCase(); - if (typeof windowEventHandlers[e] != 'undefined') { - windowEventHandlers[e].subscribe(handler); - } else { - m_window_addEventListener.call(window, evt, handler, capture); - } -}; - -document.removeEventListener = function(evt, handler, capture) { - var e = evt.toLowerCase(); - // If unsubcribing from an event that is handled by a plugin - if (typeof documentEventHandlers[e] != "undefined") { - documentEventHandlers[e].unsubscribe(handler); - } else { - m_document_removeEventListener.call(document, evt, handler, capture); - } -}; - -window.removeEventListener = function(evt, handler, capture) { - var e = evt.toLowerCase(); - // If unsubcribing from an event that is handled by a plugin - if (typeof windowEventHandlers[e] != "undefined") { - windowEventHandlers[e].unsubscribe(handler); - } else { - m_window_removeEventListener.call(window, evt, handler, capture); - } -}; - -function createEvent(type, data) { - var event = document.createEvent('Events'); - event.initEvent(type, false, false); - if (data) { - for (var i in data) { - if (data.hasOwnProperty(i)) { - event[i] = data[i]; - } - } - } - return event; -} - -if(typeof window.console === "undefined") { - window.console = { - log:function(){} - }; -} - -var cordova = { - define:define, - require:require, - /** - * Methods to add/remove your own addEventListener hijacking on document + window. - */ - addWindowEventHandler:function(event, opts) { - return (windowEventHandlers[event] = channel.create(event, opts)); - }, - addDocumentEventHandler:function(event, opts) { - return (documentEventHandlers[event] = channel.create(event, opts)); - }, - removeWindowEventHandler:function(event) { - delete windowEventHandlers[event]; - }, - removeDocumentEventHandler:function(event) { - delete documentEventHandlers[event]; - }, - /** - * Retreive original event handlers that were replaced by Cordova - * - * @return object - */ - getOriginalHandlers: function() { - return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener}, - 'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}}; - }, - /** - * Method to fire event from native code - */ - fireDocumentEvent: function(type, data) { - var evt = createEvent(type, data); - if (typeof documentEventHandlers[type] != 'undefined') { - documentEventHandlers[type].fire(evt); - } else { - document.dispatchEvent(evt); - } - }, - fireWindowEvent: function(type, data) { - var evt = createEvent(type,data); - if (typeof windowEventHandlers[type] != 'undefined') { - windowEventHandlers[type].fire(evt); - } else { - window.dispatchEvent(evt); - } - }, - // TODO: this is Android only; think about how to do this better - shuttingDown:false, - UsePolling:false, - // END TODO - - // TODO: iOS only - // This queue holds the currently executing command and all pending - // commands executed with cordova.exec(). - commandQueue:[], - // Indicates if we're currently in the middle of flushing the command - // queue on the native side. - commandQueueFlushing:false, - // END TODO - /** - * Plugin callback mechanism. - */ - callbackId: 0, - callbacks: {}, - callbackStatus: { - NO_RESULT: 0, - OK: 1, - CLASS_NOT_FOUND_EXCEPTION: 2, - ILLEGAL_ACCESS_EXCEPTION: 3, - INSTANTIATION_EXCEPTION: 4, - MALFORMED_URL_EXCEPTION: 5, - IO_EXCEPTION: 6, - INVALID_ACTION: 7, - JSON_EXCEPTION: 8, - ERROR: 9 - }, - - /** - * Called by native code when returning successful result from an action. - * - * @param callbackId - * @param args - */ - callbackSuccess: function(callbackId, args) { - if (cordova.callbacks[callbackId]) { - - // If result is to be sent to callback - if (args.status == cordova.callbackStatus.OK) { - try { - if (cordova.callbacks[callbackId].success) { - cordova.callbacks[callbackId].success(args.message); - } - } - catch (e) { - console.log("Error in success callback: "+callbackId+" = "+e); - } - } - - // Clear callback if not expecting any more results - if (!args.keepCallback) { - delete cordova.callbacks[callbackId]; - } - } - }, - - /** - * Called by native code when returning error result from an action. - * - * @param callbackId - * @param args - */ - callbackError: function(callbackId, args) { - if (cordova.callbacks[callbackId]) { - try { - if (cordova.callbacks[callbackId].fail) { - cordova.callbacks[callbackId].fail(args.message); - } - } - catch (e) { - console.log("Error in error callback: "+callbackId+" = "+e); - } - - // Clear callback if not expecting any more results - if (!args.keepCallback) { - delete cordova.callbacks[callbackId]; - } - } - }, - // TODO: remove in 2.0. - addPlugin: function(name, obj) { - console.log("[DEPRECATION NOTICE] window.addPlugin and window.plugins will be removed in version 2.0."); - if (!window.plugins[name]) { - window.plugins[name] = obj; - } - else { - console.log("Error: Plugin "+name+" already exists."); - } - }, - - addConstructor: function(func) { - channel.onCordovaReady.subscribeOnce(function() { - try { - func(); - } catch(e) { - console.log("Failed to run constructor: " + e); - } - }); - } -}; - -// Register pause, resume and deviceready channels as events on document. -channel.onPause = cordova.addDocumentEventHandler('pause'); -channel.onResume = cordova.addDocumentEventHandler('resume'); -channel.onDeviceReady = cordova.addDocumentEventHandler('deviceready'); - -// Adds deprecation warnings to functions of an object (but only logs a message once) -function deprecateFunctions(obj, objLabel) { - var newObj = {}; - var logHash = {}; - for (var i in obj) { - if (obj.hasOwnProperty(i)) { - if (typeof obj[i] == 'function') { - newObj[i] = (function(prop){ - var oldFunk = obj[prop]; - var funkId = objLabel + '_' + prop; - return function() { - if (!logHash[funkId]) { - console.log('[DEPRECATION NOTICE] The "' + objLabel + '" global will be removed in version 2.0, please use lowercase "cordova".'); - logHash[funkId] = true; - } - oldFunk.apply(obj, arguments); - }; - })(i); - } else { - newObj[i] = (function(prop) { return obj[prop]; })(i); - } - } - } - return newObj; -} - -/** - * Legacy variable for plugin support - * TODO: remove in 2.0. - */ -if (!window.PhoneGap) { - window.PhoneGap = deprecateFunctions(cordova, 'PhoneGap'); -} -if (!window.Cordova) { - window.Cordova = deprecateFunctions(cordova, 'Cordova'); -} - -/** - * Plugins object - * TODO: remove in 2.0. - */ -if (!window.plugins) { - window.plugins = {}; -} - -module.exports = cordova; - -}); - -// file: lib/common/builder.js -define("cordova/builder", function(require, exports, module) { -var utils = require('cordova/utils'); - -function each(objects, func, context) { - for (var prop in objects) { - if (objects.hasOwnProperty(prop)) { - func.apply(context, [objects[prop], prop]); - } - } -} - -function include(parent, objects, clobber, merge) { - each(objects, function (obj, key) { - try { - var result = obj.path ? require(obj.path) : {}; - - if (clobber) { - // Clobber if it doesn't exist. - if (typeof parent[key] === 'undefined') { - parent[key] = result; - } else if (typeof obj.path !== 'undefined') { - // If merging, merge properties onto parent, otherwise, clobber. - if (merge) { - recursiveMerge(parent[key], result); - } else { - parent[key] = result; - } - } - result = parent[key]; - } else { - // Overwrite if not currently defined. - if (typeof parent[key] == 'undefined') { - parent[key] = result; - } else if (merge && typeof obj.path !== 'undefined') { - // If merging, merge parent onto result - recursiveMerge(result, parent[key]); - parent[key] = result; - } else { - // Set result to what already exists, so we can build children into it if they exist. - result = parent[key]; - } - } - - if (obj.children) { - include(result, obj.children, clobber, merge); - } - } catch(e) { - utils.alert('Exception building cordova JS globals: ' + e + ' for key "' + key + '"'); - } - }); -} - -/** - * Merge properties from one object onto another recursively. Properties from - * the src object will overwrite existing target property. - * - * @param target Object to merge properties into. - * @param src Object to merge properties from. - */ -function recursiveMerge(target, src) { - for (var prop in src) { - if (src.hasOwnProperty(prop)) { - if (typeof target.prototype !== 'undefined' && target.prototype.constructor === target) { - // If the target object is a constructor override off prototype. - target.prototype[prop] = src[prop]; - } else { - target[prop] = typeof src[prop] === 'object' ? recursiveMerge( - target[prop], src[prop]) : src[prop]; - } - } - } - return target; -} - -module.exports = { - build: function (objects) { - return { - intoButDontClobber: function (target) { - include(target, objects, false, false); - }, - intoAndClobber: function(target) { - include(target, objects, true, false); - }, - intoAndMerge: function(target) { - include(target, objects, true, true); - } - }; - } -}; - -}); - -// file: lib/common/channel.js -define("cordova/channel", function(require, exports, module) { -var utils = require('cordova/utils'); - -/** - * Custom pub-sub "channel" that can have functions subscribed to it - * This object is used to define and control firing of events for - * cordova initialization. - * - * The order of events during page load and Cordova startup is as follows: - * - * onDOMContentLoaded Internal event that is received when the web page is loaded and parsed. - * onNativeReady Internal event that indicates the Cordova native side is ready. - * onCordovaReady Internal event fired when all Cordova JavaScript objects have been created. - * onCordovaInfoReady Internal event fired when device properties are available. - * onCordovaConnectionReady Internal event fired when the connection property has been set. - * onDeviceReady User event fired to indicate that Cordova is ready - * onResume User event fired to indicate a start/resume lifecycle event - * onPause User event fired to indicate a pause lifecycle event - * onDestroy Internal event fired when app is being destroyed (User should use window.onunload event, not this one). - * - * The only Cordova events that user code should register for are: - * deviceready Cordova native code is initialized and Cordova APIs can be called from JavaScript - * pause App has moved to background - * resume App has returned to foreground - * - * Listeners can be registered as: - * document.addEventListener("deviceready", myDeviceReadyListener, false); - * document.addEventListener("resume", myResumeListener, false); - * document.addEventListener("pause", myPauseListener, false); - * - * The DOM lifecycle events should be used for saving and restoring state - * window.onload - * window.onunload - * - */ - -/** - * Channel - * @constructor - * @param type String the channel name - * @param opts Object options to pass into the channel, currently - * supports: - * onSubscribe: callback that fires when - * something subscribes to the Channel. Sets - * context to the Channel. - * onUnsubscribe: callback that fires when - * something unsubscribes to the Channel. Sets - * context to the Channel. - */ -var Channel = function(type, opts) { - this.type = type; - this.handlers = {}; - this.numHandlers = 0; - this.guid = 1; - this.fired = false; - this.enabled = true; - this.events = { - onSubscribe:null, - onUnsubscribe:null - }; - if (opts) { - if (opts.onSubscribe) this.events.onSubscribe = opts.onSubscribe; - if (opts.onUnsubscribe) this.events.onUnsubscribe = opts.onUnsubscribe; - } -}, - channel = { - /** - * Calls the provided function only after all of the channels specified - * have been fired. - */ - join: function (h, c) { - var i = c.length; - var len = i; - var f = function() { - if (!(--i)) h(); - }; - for (var j=0; j<len; j++) { - !c[j].fired?c[j].subscribeOnce(f):i--; - } - if (!i) h(); - }, - create: function (type, opts) { - channel[type] = new Channel(type, opts); - return channel[type]; - }, - - /** - * cordova Channels that must fire before "deviceready" is fired. - */ - deviceReadyChannelsArray: [], - deviceReadyChannelsMap: {}, - - /** - * Indicate that a feature needs to be initialized before it is ready to be used. - * This holds up Cordova's "deviceready" event until the feature has been initialized - * and Cordova.initComplete(feature) is called. - * - * @param feature {String} The unique feature name - */ - waitForInitialization: function(feature) { - if (feature) { - var c = null; - if (this[feature]) { - c = this[feature]; - } - else { - c = this.create(feature); - } - this.deviceReadyChannelsMap[feature] = c; - this.deviceReadyChannelsArray.push(c); - } - }, - - /** - * Indicate that initialization code has completed and the feature is ready to be used. - * - * @param feature {String} The unique feature name - */ - initializationComplete: function(feature) { - var c = this.deviceReadyChannelsMap[feature]; - if (c) { - c.fire(); - } - } - }; - -function forceFunction(f) { - if (f === null || f === undefined || typeof f != 'function') throw "Function required as first argument!"; -} - -/** - * Subscribes the given function to the channel. Any time that - * Channel.fire is called so too will the function. - * Optionally specify an execution context for the function - * and a guid that can be used to stop subscribing to the channel. - * Returns the guid. - */ -Channel.prototype.subscribe = function(f, c, g) { - // need a function to call - forceFunction(f); - - var func = f; - if (typeof c == "object") { func = utils.close(c, f); } - - g = g || func.observer_guid || f.observer_guid; - if (!g) { - // first time we've seen this subscriber - g = this.guid++; - } - else { - // subscriber already handled; dont set it twice - return g; - } - func.observer_guid = g; - f.observer_guid = g; - this.handlers[g] = func; - this.numHandlers++; - if (this.events.onSubscribe) this.events.onSubscribe.call(this); - if (this.fired) func.call(this); - return g; -}; - -/** - * Like subscribe but the function is only called once and then it - * auto-unsubscribes itself. - */ -Channel.prototype.subscribeOnce = function(f, c) { - // need a function to call - forceFunction(f); - - var g = null; - var _this = this; - var m = function() { - f.apply(c || null, arguments); - _this.unsubscribe(g); - }; - if (this.fired) { - if (typeof c == "object") { f = utils.close(c, f); } - f.apply(this, this.fireArgs); - } else { - g = this.subscribe(m); - } - return g; -}; - -/** - * Unsubscribes the function with the given guid from the channel. - */ -Channel.prototype.unsubscribe = function(g) { - // need a function to unsubscribe - if (g === null || g === undefined) { throw "You must pass _something_ into Channel.unsubscribe"; } - - if (typeof g == 'function') { g = g.observer_guid; } - var handler = this.handlers[g]; - if (handler) { - if (handler.observer_guid) handler.observer_guid=null; - this.handlers[g] = null; - delete this.handlers[g]; - this.numHandlers--; - if (this.events.onUnsubscribe) this.events.onUnsubscribe.call(this); - } -}; - -/** - * Calls all functions subscribed to this channel. - */ -Channel.prototype.fire = function(e) { - if (this.enabled) { - var fail = false; - this.fired = true; - for (var item in this.handlers) { - var handler = this.handlers[item]; - if (typeof handler == 'function') { - var rv = (handler.apply(this, arguments)===false); - fail = fail || rv; - } - } - this.fireArgs = arguments; - return !fail; - } - return true; -}; - -// defining them here so they are ready super fast! -// DOM event that is received when the web page is loaded and parsed. -channel.create('onDOMContentLoaded'); - -// Event to indicate the Cordova native side is ready. -channel.create('onNativeReady'); - -// Event to indicate that all Cordova JavaScript objects have been created -// and it's time to run plugin constructors. -channel.create('onCordovaReady'); - -// Event to indicate that device properties are available -channel.create('onCordovaInfoReady'); - -// Event to indicate that the connection property has been set. -channel.create('onCordovaConnectionReady'); - -// Event to indicate that Cordova is ready -channel.create('onDeviceReady'); - -// Event to indicate a resume lifecycle event -channel.create('onResume'); - -// Event to indicate a pause lifecycle event -channel.create('onPause'); - -// Event to indicate a destroy lifecycle event -channel.create('onDestroy'); - -// Channels that must fire before "deviceready" is fired. -channel.waitForInitialization('onCordovaReady'); -channel.waitForInitialization('onCordovaInfoReady'); -channel.waitForInitialization('onCordovaConnectionReady'); - -module.exports = channel; - -}); - -// file: lib/common/common.js -define("cordova/common", function(require, exports, module) { -module.exports = { - objects: { - cordova: { - path: 'cordova', - children: { - exec: { - path: 'cordova/exec' - }, - logger: { - path: 'cordova/plugin/logger' - } - } - }, - Cordova: { - children: { - exec: { - path: 'cordova/exec' - } - } - }, - PhoneGap:{ - children: { - exec: { - path: 'cordova/exec' - } - } - }, - navigator: { - children: { - notification: { - path: 'cordova/plugin/notification' - }, - accelerometer: { - path: 'cordova/plugin/accelerometer' - }, - battery: { - path: 'cordova/plugin/battery' - }, - camera:{ - path: 'cordova/plugin/Camera' - }, - compass:{ - path: 'cordova/plugin/compass' - }, - contacts: { - path: 'cordova/plugin/contacts' - }, - device:{ - children:{ - capture: { - path: 'cordova/plugin/capture' - } - } - }, - geolocation: { - path: 'cordova/plugin/geolocation' - }, - network: { - children: { - connection: { - path: 'cordova/plugin/network' - } - } - }, - splashscreen: { - path: 'cordova/plugin/splashscreen' - } - } - }, - Acceleration: { - path: 'cordova/plugin/Acceleration' - }, - Camera:{ - path: 'cordova/plugin/CameraConstants' - }, - CameraPopoverOptions: { - path: 'cordova/plugin/CameraPopoverOptions' - }, - CaptureError: { - path: 'cordova/plugin/CaptureError' - }, - CaptureAudioOptions:{ - path: 'cordova/plugin/CaptureAudioOptions' - }, - CaptureImageOptions: { - path: 'cordova/plugin/CaptureImageOptions' - }, - CaptureVideoOptions: { - path: 'cordova/plugin/CaptureVideoOptions' - }, - CompassHeading:{ - path: 'cordova/plugin/CompassHeading' - }, - CompassError:{ - path: 'cordova/plugin/CompassError' - }, - ConfigurationData: { - path: 'cordova/plugin/ConfigurationData' - }, - Connection: { - path: 'cordova/plugin/Connection' - }, - Contact: { - path: 'cordova/plugin/Contact' - }, - ContactAddress: { - path: 'cordova/plugin/ContactAddress' - }, - ContactError: { - path: 'cordova/plugin/ContactError' - }, - ContactField: { - path: 'cordova/plugin/ContactField' - }, - ContactFindOptions: { - path: 'cordova/plugin/ContactFindOptions' - }, - ContactName: { - path: 'cordova/plugin/ContactName' - }, - ContactOrganization: { - path: 'cordova/plugin/ContactOrganization' - }, - Coordinates: { - path: 'cordova/plugin/Coordinates' - }, - DirectoryEntry: { - path: 'cordova/plugin/DirectoryEntry' - }, - DirectoryReader: { - path: 'cordova/plugin/DirectoryReader' - }, - Entry: { - path: 'cordova/plugin/Entry' - }, - File: { - path: 'cordova/plugin/File' - }, - FileEntry: { - path: 'cordova/plugin/FileEntry' - }, - FileError: { - path: 'cordova/plugin/FileError' - }, - FileReader: { - path: 'cordova/plugin/FileReader' - }, - FileSystem: { - path: 'cordova/plugin/FileSystem' - }, - FileTransfer: { - path: 'cordova/plugin/FileTransfer' - }, - FileTransferError: { - path: 'cordova/plugin/FileTransferError' - }, - FileUploadOptions: { - path: 'cordova/plugin/FileUploadOptions' - }, - FileUploadResult: { - path: 'cordova/plugin/FileUploadResult' - }, - FileWriter: { - path: 'cordova/plugin/FileWriter' - }, - Flags: { - path: 'cordova/plugin/Flags' - }, - LocalFileSystem: { - path: 'cordova/plugin/LocalFileSystem' - }, - Media: { - path: 'cordova/plugin/Media' - }, - MediaError: { - path: 'cordova/plugin/MediaError' - }, - MediaFile: { - path: 'cordova/plugin/MediaFile' - }, - MediaFileData:{ - path: 'cordova/plugin/MediaFileData' - }, - Metadata:{ - path: 'cordova/plugin/Metadata' - }, - Position: { - path: 'cordova/plugin/Position' - }, - PositionError: { - path: 'cordova/plugin/PositionError' - }, - ProgressEvent: { - path: 'cordova/plugin/ProgressEvent' - }, - requestFileSystem:{ - path: 'cordova/plugin/requestFileSystem' - }, - resolveLocalFileSystemURI:{ - path: 'cordova/plugin/resolveLocalFileSystemURI' - } - } -}; - -}); - -// file: lib/ios/exec.js -define("cordova/exec", function(require, exports, module) { - /** - * Creates a gap bridge iframe used to notify the native code about queued - * commands. - * - * @private - */ -var cordova = require('cordova'), - utils = require('cordova/utils'), - gapBridge, - createGapBridge = function() { - gapBridge = document.createElement("iframe"); - gapBridge.setAttribute("style", "display:none;"); - gapBridge.setAttribute("height","0px"); - gapBridge.setAttribute("width","0px"); - gapBridge.setAttribute("frameborder","0"); - document.documentElement.appendChild(gapBridge); - }, - channel = require('cordova/channel'); - -module.exports = function() { - if (!channel.onCordovaInfoReady.fired) { - utils.alert("ERROR: Attempting to call cordova.exec()" + - " before 'deviceready'. Ignoring."); - return; - } - - var successCallback, failCallback, service, action, actionArgs, splitCommand; - var callbackId = null; - if (typeof arguments[0] !== "string") { - // FORMAT ONE - successCallback = arguments[0]; - failCallback = arguments[1]; - service = arguments[2]; - action = arguments[3]; - actionArgs = arguments[4]; - - // Since we need to maintain backwards compatibility, we have to pass - // an invalid callbackId even if no callback was provided since plugins - // will be expecting it. The Cordova.exec() implementation allocates - // an invalid callbackId and passes it even if no callbacks were given. - callbackId = 'INVALID'; - } else { - // FORMAT TWO - splitCommand = arguments[0].split("."); - action = splitCommand.pop(); - service = splitCommand.join("."); - actionArgs = Array.prototype.splice.call(arguments, 1); - } - - // Start building the command object. - var command = { - className: service, - methodName: action, - "arguments": [] - }; - - // Register the callbacks and add the callbackId to the positional - // arguments if given. - if (successCallback || failCallback) { - callbackId = service + cordova.callbackId++; - cordova.callbacks[callbackId] = - {success:successCallback, fail:failCallback}; - } - if (callbackId !== null) { - command["arguments"].push(callbackId); - } - - for (var i = 0; i < actionArgs.length; ++i) { - var arg = actionArgs[i]; - if (arg === undefined || arg === null) { // nulls are pushed to the args now (becomes NSNull) - command["arguments"].push(arg); - } else if (typeof(arg) == 'object' && !(utils.isArray(arg))) { - command.options = arg; - } else { - command["arguments"].push(arg); - } - } - - // Stringify and queue the command. We stringify to command now to - // effectively clone the command arguments in case they are mutated before - // the command is executed. - cordova.commandQueue.push(JSON.stringify(command)); - - // If the queue length is 1, then that means it was empty before we queued - // the given command, so let the native side know that we have some - // commands to execute, unless the queue is currently being flushed, in - // which case the command will be picked up without notification. - if (cordova.commandQueue.length == 1 && !cordova.commandQueueFlushing) { - if (!gapBridge) { - createGapBridge(); - } - gapBridge.src = "gap://ready"; - } -}; - -}); - -// file: lib/ios/platform.js -define("cordova/platform", function(require, exports, module) { -module.exports = { - id: "ios", - initialize:function() { - // iOS doesn't allow reassigning / overriding navigator.geolocation object. - // So clobber its methods here instead :) - var geo = require('cordova/plugin/geolocation'); - - navigator.geolocation.getCurrentPosition = geo.getCurrentPosition; - navigator.geolocation.watchPosition = geo.watchPosition; - navigator.geolocation.clearWatch = geo.clearWatch; - }, - objects: { - File: { // exists natively, override - path: "cordova/plugin/File" - }, - MediaError: { // exists natively, override - path: "cordova/plugin/MediaError" - }, - device: { - path: 'cordova/plugin/ios/device' - }, - console: { - path: 'cordova/plugin/ios/console' - } - }, - merges:{ - Contact:{ - path: "cordova/plugin/ios/Contact" - }, - Entry:{ - path: "cordova/plugin/ios/Entry" - }, - FileReader:{ - path: "cordova/plugin/ios/FileReader" - }, - navigator:{ - children:{ - notification:{ - path:"cordova/plugin/ios/notification" - }, - contacts:{ - path:"cordova/plugin/ios/contacts" - } - } - } - } -}; - -// use the native logger -var logger = require("cordova/plugin/logger"); -logger.useConsole(false); - -}); - -// file: lib/common/plugin/Acceleration.js -define("cordova/plugin/Acceleration", function(require, exports, module) { -var Acceleration = function(x, y, z, timestamp) { - this.x = x; - this.y = y; - this.z = z; - this.timestamp = timestamp || (new Date()).getTime(); -}; - -module.exports = Acceleration; - -}); - -// file: lib/common/plugin/Camera.js -define("cordova/plugin/Camera", function(require, exports, module) { -var exec = require('cordova/exec'), - Camera = require('cordova/plugin/CameraConstants'); - -var cameraExport = {}; - -// Tack on the Camera Constants to the base camera plugin. -for (var key in Camera) { - cameraExport[key] = Camera[key]; -} - -/** - * Gets a picture from source defined by "options.sourceType", and returns the - * image as defined by the "options.destinationType" option. - - * The defaults are sourceType=CAMERA and destinationType=FILE_URI. - * - * @param {Function} successCallback - * @param {Function} errorCallback - * @param {Object} options - */ -cameraExport.getPicture = function(successCallback, errorCallback, options) { - // successCallback required - if (typeof successCallback != "function") { - console.log("Camera Error: successCallback is not a function"); - return; - } - - // errorCallback optional - if (errorCallback && (typeof errorCallback != "function")) { - console.log("Camera Error: errorCallback is not a function"); - return; - } - - var quality = 50; - if (options && typeof options.quality == "number") { - quality = options.quality; - } else if (options && typeof options.quality == "string") { - var qlity = parseInt(options.quality, 10); - if (isNaN(qlity) === false) { - quality = qlity.valueOf(); - } - } - - var destinationType = Camera.DestinationType.FILE_URI; - if (typeof options.destinationType == "number") { - destinationType = options.destinationType; - } - - var sourceType = Camera.PictureSourceType.CAMERA; - if (typeof options.sourceType == "number") { - sourceType = options.sourceType; - } - - var targetWidth = -1; - if (typeof options.targetWidth == "number") { - targetWidth = options.targetWidth; - } else if (typeof options.targetWidth == "string") { - var width = parseInt(options.targetWidth, 10); - if (isNaN(width) === false) { - targetWidth = width.valueOf(); - } - } - - var targetHeight = -1; - if (typeof options.targetHeight == "number") { - targetHeight = options.targetHeight; - } else if (typeof options.targetHeight == "string") { - var height = parseInt(options.targetHeight, 10); - if (isNaN(height) === false) { - targetHeight = height.valueOf(); - } - } - - var encodingType = Camera.EncodingType.JPEG; - if (typeof options.encodingType == "number") { - encodingType = options.encodingType; - } - - var mediaType = Camera.MediaType.PICTURE; - if (typeof options.mediaType == "number") { - mediaType = options.mediaType; - } - var allowEdit = false; - if (typeof options.allowEdit == "boolean") { - allowEdit = options.allowEdit; - } else if (typeof options.allowEdit == "number") { - allowEdit = options.allowEdit <= 0 ? false : true; - } - var correctOrientation = false; - if (typeof options.correctOrientation == "boolean") { - correctOrientation = options.correctOrientation; - } else if (typeof options.correctOrientation == "number") { - correctOrientation = options.correctOrientation <=0 ? false : true; - } - var saveToPhotoAlbum = false; - if (typeof options.saveToPhotoAlbum == "boolean") { - saveToPhotoAlbum = options.saveToPhotoAlbum; - } else if (typeof options.saveToPhotoAlbum == "number") { - saveToPhotoAlbum = options.saveToPhotoAlbum <=0 ? false : true; - } - var popoverOptions = null; - if (typeof options.popoverOptions == "object") { - popoverOptions = options.popoverOptions; - } - - exec(successCallback, errorCallback, "Camera", "takePicture", [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType, mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions]); -}; - -module.exports = cameraExport; -}); - -// file: lib/common/plugin/CameraConstants.js -define("cordova/plugin/CameraConstants", function(require, exports, module) { -module.exports = { - DestinationType:{ - DATA_URL: 0, // Return base64 encoded string - FILE_URI: 1 // Return file uri (content://media/external/images/media/2 for Android) - }, - EncodingType:{ - JPEG: 0, // Return JPEG encoded image - PNG: 1 // Return PNG encoded image - }, - MediaType:{ - PICTURE: 0, // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType - VIDEO: 1, // allow selection of video only, ONLY RETURNS URL - ALLMEDIA : 2 // allow selection from all media types - }, - PictureSourceType:{ - PHOTOLIBRARY : 0, // Choose image from picture library (same as SAVEDPHOTOALBUM for Android) - CAMERA : 1, // Take picture from camera - SAVEDPHOTOALBUM : 2 // Choose image from picture library (same as PHOTOLIBRARY for Android) - }, - PopoverArrowDirection:{ - ARROW_UP : 1, // matches iOS UIPopoverArrowDirection constants to specify arrow location on popover - ARROW_DOWN : 2, - ARROW_LEFT : 4, - ARROW_RIGHT : 8, - ARROW_ANY : 15 - } -}; -}); - -// file: lib/common/plugin/CameraPopoverOptions.js -define("cordova/plugin/CameraPopoverOptions", function(require, exports, module) { -var Camera = require('cordova/plugin/CameraConstants'); - -/** - * Encapsulates options for iOS Popover image picker - */ -var CameraPopoverOptions = function(x,y,width,height,arrowDir){ - // information of rectangle that popover should be anchored to - this.x = x || 0; - this.y = y || 32; - this.width = width || 320; - this.height = height || 480; - // The direction of the popover arrow - this.arrowDir = arrowDir || Camera.PopoverArrowDirection.ARROW_ANY; -}; - -module.exports = CameraPopoverOptions; -}); - -// file: lib/common/plugin/CaptureAudioOptions.js -define("cordova/plugin/CaptureAudioOptions", function(require, exports, module) { -/** - * Encapsulates all audio capture operation configuration options. - */ -var CaptureAudioOptions = function(){ - // Upper limit of sound clips user can record. Value must be equal or greater than 1. - this.limit = 1; - // Maximum duration of a single sound clip in seconds. - this.duration = 0; - // The selected audio mode. Must match with one of the elements in supportedAudioModes array. - this.mode = null; -}; - -module.exports = CaptureAudioOptions; -}); - -// file: lib/common/plugin/CaptureError.js -define("cordova/plugin/CaptureError", function(require, exports, module) { -/** - * The CaptureError interface encapsulates all errors in the Capture API. - */ -var CaptureError = function(c) { - this.code = c || null; -}; - -// Camera or microphone failed to capture image or sound. -CaptureError.CAPTURE_INTERNAL_ERR = 0; -// Camera application or audio capture application is currently serving other capture request. -CaptureError.CAPTURE_APPLICATION_BUSY = 1; -// Invalid use of the API (e.g. limit parameter has value less than one). -CaptureError.CAPTURE_INVALID_ARGUMENT = 2; -// User exited camera application or audio capture application before capturing anything. -CaptureError.CAPTURE_NO_MEDIA_FILES = 3; -// The requested capture operation is not supported. -CaptureError.CAPTURE_NOT_SUPPORTED = 20; - -module.exports = CaptureError; -}); - -// file: lib/common/plugin/CaptureImageOptions.js -define("cordova/plugin/CaptureImageOptions", function(require, exports, module) { -/** - * Encapsulates all image capture operation configuration options. - */ -var CaptureImageOptions = function(){ - // Upper limit of images user can take. Value must be equal or greater than 1. - this.limit = 1; - // The selected image mode. Must match with one of the elements in supportedImageModes array. - this.mode = null; -}; - -module.exports = CaptureImageOptions; -}); - -// file: lib/common/plugin/CaptureVideoOptions.js -define("cordova/plugin/CaptureVideoOptions", function(require, exports, module) { -/** - * Encapsulates all video capture operation configuration options. - */ -var CaptureVideoOptions = function(){ - // Upper limit of videos user can record. Value must be equal or greater than 1. - this.limit = 1; - // Maximum duration of a single video clip in seconds. - this.duration = 0; - // The selected video mode. Must match with one of the elements in supportedVideoModes array. - this.mode = null; -}; - -module.exports = CaptureVideoOptions; -}); - -// file: lib/common/plugin/CompassError.js -define("cordova/plugin/CompassError", function(require, exports, module) { -/** - * CompassError. - * An error code assigned by an implementation when an error has occured - * @constructor - */ -var CompassError = function(err) { - this.code = (err !== undefined ? err : null); -}; - -CompassError.COMPASS_INTERNAL_ERR = 0; -CompassError.COMPASS_NOT_SUPPORTED = 20; - -module.exports = CompassError; -}); - -// file: lib/common/plugin/CompassHeading.js -define("cordova/plugin/CompassHeading", function(require, exports, module) { -var CompassHeading = function(magneticHeading, trueHeading, headingAccuracy, timestamp) { - this.magneticHeading = (magneticHeading !== undefined ? magneticHeading : null); - this.trueHeading = (trueHeading !== undefined ? trueHeading : null); - this.headingAccuracy = (headingAccuracy !== undefined ? headingAccuracy : null); - this.timestamp = (timestamp !== undefined ? timestamp : new Date().getTime()); -}; - -module.exports = CompassHeading; -}); - -// file: lib/common/plugin/ConfigurationData.js -define("cordova/plugin/ConfigurationData", function(require, exports, module) { -/** - * Encapsulates a set of parameters that the capture device supports. - */ -function ConfigurationData() { - // The ASCII-encoded string in lower case representing the media type. - this.type = null; - // The height attribute represents height of the image or video in pixels. - // In the case of a sound clip this attribute has value 0. - this.height = 0; - // The width attribute represents width of the image or video in pixels. - // In the case of a sound clip this attribute has value 0 - this.width = 0; -} - -module.exports = ConfigurationData; -}); - -// file: lib/common/plugin/Connection.js -define("cordova/plugin/Connection", function(require, exports, module) { -/** - * Network status - */ -module.exports = { - UNKNOWN: "unknown", - ETHERNET: "ethernet", - WIFI: "wifi", - CELL_2G: "2g", - CELL_3G: "3g", - CELL_4G: "4g", - NONE: "none" -}; -}); - -// file: lib/common/plugin/Contact.js -define("cordova/plugin/Contact", function(require, exports, module) { -var exec = require('cordova/exec'), - ContactError = require('cordova/plugin/ContactError'), - utils = require('cordova/utils'); - -/** -* Converts primitives into Complex Object -* Currently only used for Date fields -*/ -function convertIn(contact) { - var value = contact.birthday; - try { - contact.birthday = new Date(parseFloat(value)); - } catch (exception){ - console.log("Cordova Contact convertIn error: exception creating date."); - } - return contact; -} - -/** -* Converts Complex objects into primitives -* Only conversion at present is for Dates. -**/ - -function convertOut(contact) { - var value = contact.birthday; - if (value !== null) { - // try to make it a Date object if it is not already - if (!utils.isDate(value)){ - try { - value = new Date(value); - } catch(exception){ - value = null; - } - } - if (utils.isDate(value)){ - value = value.valueOf(); // convert to milliseconds - } - contact.birthday = value; - } - return contact; -} - -/** -* Contains information about a single contact. -* @constructor -* @param {DOMString} id unique identifier -* @param {DOMString} displayName -* @param {ContactName} name -* @param {DOMString} nickname -* @param {Array.<ContactField>} phoneNumbers array of phone numbers -* @param {Array.<ContactField>} emails array of email addresses -* @param {Array.<ContactAddress>} addresses array of addresses -* @param {Array.<ContactField>} ims instant messaging user ids -* @param {Array.<ContactOrganization>} organizations -* @param {DOMString} birthday contact's birthday -* @param {DOMString} note user notes about contact -* @param {Array.<ContactField>} photos -* @param {Array.<ContactField>} categories -* @param {Array.<ContactField>} urls contact's web sites -*/ -var Contact = function (id, displayName, name, nickname, phoneNumbers, emails, addresses, - ims, organizations, birthday, note, photos, categories, urls) { - this.id = id || null; - this.rawId = null; - this.displayName = displayName || null; - this.name = name || null; // ContactName - this.nickname = nickname || null; - this.phoneNumbers = phoneNumbers || null; // ContactField[] - this.emails = emails || null; // ContactField[] - this.addresses = addresses || null; // ContactAddress[] - this.ims = ims || null; // ContactField[] - this.organizations = organizations || null; // ContactOrganization[] - this.birthday = birthday || null; - this.note = note || null; - this.photos = photos || null; // ContactField[] - this.categories = categories || null; // ContactField[] - this.urls = urls || null; // ContactField[] -}; - -/** -* Removes contact from device storage. -* @param successCB success callback -* @param errorCB error callback -*/ -Contact.prototype.remove = function(successCB, errorCB) { - var fail = function(code) { - errorCB(new ContactError(code)); - }; - if (this.id === null) { - fail(ContactError.UNKNOWN_ERROR); - } - else { - exec(successCB, fail, "Contacts", "remove", [this.id]); - } -}; - -/** -* Creates a deep copy of this Contact. -* With the contact ID set to null. -* @return copy of this Contact -*/ -Contact.prototype.clone = function() { - var clonedContact = utils.clone(this); - var i; - clonedContact.id = null; - clonedContact.rawId = null; - // Loop through and clear out any id's in phones, emails, etc. - if (clonedContact.phoneNumbers) { - for (i = 0; i < clonedContact.phoneNumbers.length; i++) { - clonedContact.phoneNumbers[i].id = null; - } - } - if (clonedContact.emails) { - for (i = 0; i < clonedContact.emails.length; i++) { - clonedContact.emails[i].id = null; - } - } - if (clonedContact.addresses) { - for (i = 0; i < clonedContact.addresses.length; i++) { - clonedContact.addresses[i].id = null; - } - } - if (clonedContact.ims) { - for (i = 0; i < clonedContact.ims.length; i++) { - clonedContact.ims[i].id = null; - } - } - if (clonedContact.organizations) { - for (i = 0; i < clonedContact.organizations.length; i++) { - clonedContact.organizations[i].id = null; - } - } - if (clonedContact.categories) { - for (i = 0; i < clonedContact.categories.length; i++) { - clonedContact.categories[i].id = null; - } - } - if (clonedContact.photos) { - for (i = 0; i < clonedContact.photos.length; i++) { - clonedContact.photos[i].id = null; - } - } - if (clonedContact.urls) { - for (i = 0; i < clonedContact.urls.length; i++) { - clonedContact.urls[i].id = null; - } - } - return clonedContact; -}; - -/** -* Persists contact to device storage. -* @param successCB success callback -* @param errorCB error callback -*/ -Contact.prototype.save = function(successCB, errorCB) { - var fail = function(code) { - errorCB(new ContactError(code)); - }; - var success = function(result) { - if (result) { - if (typeof successCB === 'function') { - var fullContact = require('cordova/plugin/contacts').create(result); - successCB(convertIn(fullContact)); - } - } - else { - // no Entry object returned - fail(ContactError.UNKNOWN_ERROR); - } - }; - var dupContact = convertOut(utils.clone(this)); - exec(success, fail, "Contacts", "save", [dupContact]); -}; - - -module.exports = Contact; - -}); - -// file: lib/common/plugin/ContactAddress.js -define("cordova/plugin/ContactAddress", function(require, exports, module) { -/** -* Contact address. -* @constructor -* @param {DOMString} id unique identifier, should only be set by native code -* @param formatted // NOTE: not a W3C standard -* @param streetAddress -* @param locality -* @param region -* @param postalCode -* @param country -*/ - -var ContactAddress = function(pref, type, formatted, streetAddress, locality, region, postalCode, country) { - this.id = null; - this.pref = (typeof pref != 'undefined' ? pref : false); - this.type = type || null; - this.formatted = formatted || null; - this.streetAddress = streetAddress || null; - this.locality = locality || null; - this.region = region || null; - this.postalCode = postalCode || null; - this.country = country || null; -}; - -module.exports = ContactAddress; -}); - -// file: lib/common/plugin/ContactError.js -define("cordova/plugin/ContactError", function(require, exports, module) { -/** - * ContactError. - * An error code assigned by an implementation when an error has occured - * @constructor - */ -var ContactError = function(err) { - this.code = (typeof err != 'undefined' ? err : null); -}; - -/** - * Error codes - */ -ContactError.UNKNOWN_ERROR = 0; -ContactError.INVALID_ARGUMENT_ERROR = 1; -ContactError.TIMEOUT_ERROR = 2; -ContactError.PENDING_OPERATION_ERROR = 3; -ContactError.IO_ERROR = 4; -ContactError.NOT_SUPPORTED_ERROR = 5; -ContactError.PERMISSION_DENIED_ERROR = 20; - -module.exports = ContactError; -}); - -// file: lib/common/plugin/ContactField.js -define("cordova/plugin/ContactField", function(require, exports, module) { -/** -* Generic contact field. -* @constructor -* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard -* @param type -* @param value -* @param pref -*/ -var ContactField = function(type, value, pref) { - this.id = null; - this.type = (type && type.toString()) || null; - this.value = (value && value.toString()) || null; - this.pref = (typeof pref != 'undefined' ? pref : false); -}; - -module.exports = ContactField; -}); - -// file: lib/common/plugin/ContactFindOptions.js -define("cordova/plugin/ContactFindOptions", function(require, exports, module) { -/** - * ContactFindOptions. - * @constructor - * @param filter used to match contacts against - * @param multiple boolean used to determine if more than one contact should be returned - */ - -var ContactFindOptions = function(filter, multiple) { - this.filter = filter || ''; - this.multiple = (typeof multiple != 'undefined' ? multiple : false); -}; - -module.exports = ContactFindOptions; -}); - -// file: lib/common/plugin/ContactName.js -define("cordova/plugin/ContactName", function(require, exports, module) { -/** -* Contact name. -* @constructor -* @param formatted // NOTE: not part of W3C standard -* @param familyName -* @param givenName -* @param middle -* @param prefix -* @param suffix -*/ -var ContactName = function(formatted, familyName, givenName, middle, prefix, suffix) { - this.formatted = formatted || null; - this.familyName = familyName || null; - this.givenName = givenName || null; - this.middleName = middle || null; - this.honorificPrefix = prefix || null; - this.honorificSuffix = suffix || null; -}; - -module.exports = ContactName; -}); - -// file: lib/common/plugin/ContactOrganization.js -define("cordova/plugin/ContactOrganization", function(require, exports, module) { -/** -* Contact organization. -* @constructor -* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard -* @param name -* @param dept -* @param title -* @param startDate -* @param endDate -* @param location -* @param desc -*/ - -var ContactOrganization = function(pref, type, name, dept, title) { - this.id = null; - this.pref = (typeof pref != 'undefined' ? pref : false); - this.type = type || null; - this.name = name || null; - this.department = dept || null; - this.title = title || null; -}; - -module.exports = ContactOrganization; -}); - -// file: lib/common/plugin/Coordinates.js -define("cordova/plugin/Coordinates", function(require, exports, module) { -/** - * This class contains position information. - * @param {Object} lat - * @param {Object} lng - * @param {Object} alt - * @param {Object} acc - * @param {Object} head - * @param {Object} vel - * @param {Object} altacc - * @constructor - */ -var Coordinates = function(lat, lng, alt, acc, head, vel, altacc) { - /** - * The latitude of the position. - */ - this.latitude = lat; - /** - * The longitude of the position, - */ - this.longitude = lng; - /** - * The accuracy of the position. - */ - this.accuracy = acc; - /** - * The altitude of the position. - */ - this.altitude = (alt !== undefined ? alt : null); - /** - * The direction the device is moving at the position. - */ - this.heading = (head !== undefined ? head : null); - /** - * The velocity with which the device is moving at the position. - */ - this.speed = (vel !== undefined ? vel : null); - - if (this.speed === 0 || this.speed === null) { - this.heading = NaN; - } - - /** - * The altitude accuracy of the position. - */ - this.altitudeAccuracy = (altacc !== undefined) ? altacc : null; -}; - -module.exports = Coordinates; - -}); - -// file: lib/common/plugin/DirectoryEntry.js -define("cordova/plugin/DirectoryEntry", function(require, exports, module) { -var utils = require('cordova/utils'), - exec = require('cordova/exec'), - Entry = require('cordova/plugin/Entry'), - FileError = require('cordova/plugin/FileError'), - DirectoryReader = require('cordova/plugin/DirectoryReader'); - -/** - * An interface representing a directory on the file system. - * - * {boolean} isFile always false (readonly) - * {boolean} isDirectory always true (readonly) - * {DOMString} name of the directory, excluding the path leading to it (readonly) - * {DOMString} fullPath the absolute full path to the directory (readonly) - * {FileSystem} filesystem on which the directory resides (readonly) - */ -var DirectoryEntry = function(name, fullPath) { - DirectoryEntry.__super__.constructor.apply(this, [false, true, name, fullPath]); -}; - -utils.extend(DirectoryEntry, Entry); - -/** - * Creates a new DirectoryReader to read entries from this directory - */ -DirectoryEntry.prototype.createReader = function() { - return new DirectoryReader(this.fullPath); -}; - -/** - * Creates or looks up a directory - * - * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a directory - * @param {Flags} options to create or excluively create the directory - * @param {Function} successCallback is called with the new entry - * @param {Function} errorCallback is called with a FileError - */ -DirectoryEntry.prototype.getDirectory = function(path, options, successCallback, errorCallback) { - var win = typeof successCallback !== 'function' ? null : function(result) { - var entry = new DirectoryEntry(result.name, result.fullPath); - successCallback(entry); - }; - var fail = typeof errorCallback !== 'function' ? null : function(code) { - errorCallback(new FileError(code)); - }; - exec(win, fail, "File", "getDirectory", [this.fullPath, path, options]); -}; - -/** - * Deletes a directory and all of it's contents - * - * @param {Function} successCallback is called with no parameters - * @param {Function} errorCallback is called with a FileError - */ -DirectoryEntry.prototype.removeRecursively = function(successCallback, errorCallback) { - var fail = typeof errorCallback !== 'function' ? null : function(code) { - errorCallback(new FileError(code)); - }; - exec(successCallback, fail, "File", "removeRecursively", [this.fullPath]); -}; - -/** - * Creates or looks up a file - * - * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a file - * @param {Flags} options to create or excluively create the file - * @param {Function} successCallback is called with the new entry - * @param {Function} errorCallback is called with a FileError - */ -DirectoryEntry.prototype.getFile = function(path, options, successCallback, errorCallback) { - var win = typeof successCallback !== 'function' ? null : function(result) { - var FileEntry = require('cordova/plugin/FileEntry'); - var entry = new FileEntry(result.name, result.fullPath); - successCallback(entry); - }; - var fail = typeof errorCallback !== 'function' ? null : function(code) { - errorCallback(new FileError(code)); - }; - exec(win, fail, "File", "getFile", [this.fullPath, path, options]); -}; - -module.exports = DirectoryEntry; - -}); - -// file: lib/common/plugin/DirectoryReader.js -define("cordova/plugin/DirectoryReader", function(require, exports, module) { -var exec = require('cordova/exec'), - FileError = require('cordova/plugin/FileError') ; - -/** - * An interface that lists the files and directories in a directory. - */ -function DirectoryReader(path) { - this.path = path || null; -} - -/** - * Returns a list of entries from a directory. - * - * @param {Function} successCallback is called with a list of entries - * @param {Function} errorCallback is called with a FileError - */ -DirectoryReader.prototype.readEntries = function(successCallback, errorCallback) { - var win = typeof successCallback !== 'function' ? null : function(result) { - var retVal = []; - for (var i=0; i<result.length; i++) { - var entry = null; - if (result[i].isDirectory) { - entry = new (require('cordova/plugin/DirectoryEntry'))(); - } - else if (result[i].isFile) { - entry = new (require('cordova/plugin/FileEntry'))(); - } - entry.isDirectory = result[i].isDirectory; - entry.isFile = result[i].isFile; - entry.name = result[i].name; - entry.fullPath = result[i].fullPath; - retVal.push(entry); - } - successCallback(retVal); - }; - var fail = typeof errorCallback !== 'function' ? null : function(code) { - errorCallback(new FileError(code)); - }; - exec(win, fail, "File", "readEntries", [this.path]); -}; - -module.exports = DirectoryReader; - -}); - -// file: lib/common/plugin/Entry.js -define("cordova/plugin/Entry", function(require, exports, module) { -var exec = require('cordova/exec'), - FileError = require('cordova/plugin/FileError'), - Metadata = require('cordova/plugin/Metadata'); - -/** - * Represents a file or directory on the local file system. - * - * @param isFile - * {boolean} true if Entry is a file (readonly) - * @param isDirectory - * {boolean} true if Entry is a directory (readonly) - * @param name - * {DOMString} name of the file or directory, excluding the path - * leading to it (readonly) - * @param fullPath - * {DOMString} the absolute full path to the file or directory - * (readonly) - */ -function Entry(isFile, isDirectory, name, fullPath, fileSystem) { - this.isFile = (typeof isFile != 'undefined'?isFile:false); - this.isDirectory = (typeof isDirectory != 'undefined'?isDirectory:false); - this.name = name || ''; - this.fullPath = fullPath || ''; - this.filesystem = fileSystem || null; -} - -/** - * Look up the metadata of the entry. - * - * @param successCallback - * {Function} is called with a Metadata object - * @param errorCallback - * {Function} is called with a FileError - */ -Entry.prototype.getMetadata = function(successCallback, errorCallback) { - var success = typeof successCallback !== 'function' ? null : function(lastModified) { - var metadata = new Metadata(lastModified); - successCallback(metadata); - }; - var fail = typeof errorCallback !== 'function' ? null : function(code) { - errorCallback(new FileError(code)); - }; - - exec(success, fail, "File", "getMetadata", [this.fullPath]); -}; - -/** - * Set the metadata of the entry. - * - * @param successCallback - * {Function} is called with a Metadata object - * @param errorCallback - * {Function} is called with a FileError - * @param metadataObject - * {Object} keys and values to set - */ -Entry.prototype.setMetadata = function(successCallback, errorCallback, metadataObject) { - - exec(successCallback, errorCallback, "File", "setMetadata", [this.fullPath, metadataObject]); -}; - -/** - * Move a file or directory to a new location. - * - * @param parent - * {DirectoryEntry} the directory to which to move this entry - * @param newName - * {DOMString} new name of the entry, defaults to the current name - * @param successCallback - * {Function} called with the new DirectoryEntry object - * @param errorCallback - * {Function} called with a FileError - */ -Entry.prototype.moveTo = function(parent, newName, successCallback, errorCallback) { - var fail = function(code) { - if (typeof errorCallback === 'function') { - errorCallback(new FileError(code)); - } - }; - // user must specify parent Entry - if (!parent) { - fail(FileError.NOT_FOUND_ERR); - return; - } - // source path - var srcPath = this.fullPath, - // entry name - name = newName || this.name, - success = function(entry) { - if (entry) { - if (typeof successCallback === 'function') { - // create appropriate Entry object - var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath); - try { - successCallback(result); - } - catch (e) { - console.log('Error invoking callback: ' + e); - } - } - } - else { - // no Entry object returned - fail(FileError.NOT_FOUND_ERR); - } - }; - - // copy - exec(success, fail, "File", "moveTo", [srcPath, parent.fullPath, name]); -}; - -/** - * Copy a directory to a different location. - * - * @param parent - * {DirectoryEntry} the directory to which to copy the entry - * @param newName - * {DOMString} new name of the entry, defaults to the current name - * @param successCallback - * {Function} called with the new Entry object - * @param errorCallback - * {Function} called with a FileError - */ -Entry.prototype.copyTo = function(parent, newName, successCallback, errorCallback) { - var fail = function(code) { - if (typeof errorCallback === 'function') { - errorCallback(new FileError(code)); - } - }; - - // user must specify parent Entry - if (!parent) { - fail(FileError.NOT_FOUND_ERR); - return; - } - - // source path - var srcPath = this.fullPath, - // entry name - name = newName || this.name, - // success callback - success = function(entry) { - if (entry) { - if (typeof successCallback === 'function') { - // create appropriate Entry object - var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath); - try { - successCallback(result); - } - catch (e) { - console.log('Error invoking callback: ' + e); - } - } - } - else { - // no Entry object returned - fail(FileError.NOT_FOUND_ERR); - } - }; - - // copy - exec(success, fail, "File", "copyTo", [srcPath, parent.fullPath, name]); -}; - -/** - * Return a URL that can be used to identify this entry. - */ -Entry.prototype.toURL = function() { - // fullPath attribute contains the full URL - return this.fullPath; -}; - -/** - * Returns a URI that can be used to identify this entry. - * - * @param {DOMString} mimeType for a FileEntry, the mime type to be used to interpret the file, when loaded through this URI. - * @return uri - */ -Entry.prototype.toURI = function(mimeType) { - console.log("DEPRECATED: Update your code to use 'toURL'"); - // fullPath attribute contains the full URI - return this.toURL(); -}; - -/** - * Remove a file or directory. It is an error to attempt to delete a - * directory that is not empty. It is an error to attempt to delete a - * root directory of a file system. - * - * @param successCallback {Function} called with no parameters - * @param errorCallback {Function} called with a FileError - */ -Entry.prototype.remove = function(successCallback, errorCallback) { - var fail = typeof errorCallback !== 'function' ? null : function(code) { - errorCallback(new FileError(code)); - }; - exec(successCallback, fail, "File", "remove", [this.fullPath]); -}; - -/** - * Look up the parent DirectoryEntry of this entry. - * - * @param successCallback {Function} called with the parent DirectoryEntry object - * @param errorCallback {Function} called with a FileError - */ -Entry.prototype.getParent = function(successCallback, errorCallback) { - var win = typeof successCallback !== 'function' ? null : function(result) { - var DirectoryEntry = require('cordova/plugin/DirectoryEntry'); - var entry = new DirectoryEntry(result.name, result.fullPath); - successCallback(entry); - }; - var fail = typeof errorCallback !== 'function' ? null : function(code) { - errorCallback(new FileError(code)); - }; - exec(win, fail, "File", "getParent", [this.fullPath]); -}; - -module.exports = Entry; -}); - -// file: lib/common/plugin/File.js -define("cordova/plugin/File", function(require, exports, module) { -/** - * Constructor. - * name {DOMString} name of the file, without path information - * fullPath {DOMString} the full path of the file, including the name - * type {DOMString} mime type - * lastModifiedDate {Date} last modified date - * size {Number} size of the file in bytes - */ - -var File = function(name, fullPath, type, lastModifiedDate, size){ - this.name = name || ''; - this.fullPath = fullPath || null; - this.type = type || null; - this.lastModifiedDate = lastModifiedDate || null; - this.size = size || 0; -}; - -module.exports = File; -}); - -// file: lib/common/plugin/FileEntry.js -define("cordova/plugin/FileEntry", function(require, exports, module) { -var utils = require('cordova/utils'), - exec = require('cordova/exec'), - Entry = require('cordova/plugin/Entry'), - FileWriter = require('cordova/plugin/FileWriter'), - File = require('cordova/plugin/File'), - FileError = require('cordova/plugin/FileError'); - -/** - * An interface representing a file on the file system. - * - * {boolean} isFile always true (readonly) - * {boolean} isDirectory always false (readonly) - * {DOMString} name of the file, excluding the path leading to it (readonly) - * {DOMString} fullPath the absolute full path to the file (readonly) - * {FileSystem} filesystem on which the file resides (readonly) - */ -var FileEntry = function(name, fullPath) { - FileEntry.__super__.constructor.apply(this, [true, false, name, fullPath]); -}; - -utils.extend(FileEntry, Entry); - -/** - * Creates a new FileWriter associated with the file that this FileEntry represents. - * - * @param {Function} successCallback is called with the new FileWriter - * @param {Function} errorCallback is called with a FileError - */ -FileEntry.prototype.createWriter = function(successCallback, errorCallback) { - this.file(function(filePointer) { - var writer = new FileWriter(filePointer); - - if (writer.fileName === null || writer.fileName === "") { - if (typeof errorCallback === "function") { - errorCallback(new FileError(FileError.INVALID_STATE_ERR)); - } - } else { - if (typeof successCallback === "function") { - successCallback(writer); - } - } - }, errorCallback); -}; - -/** - * Returns a File that represents the current state of the file that this FileEntry represents. - * - * @param {Function} successCallback is called with the new File object - * @param {Function} errorCallback is called with a FileError - */ -FileEntry.prototype.file = function(successCallback, errorCallback) { - var win = typeof successCallback !== 'function' ? null : function(f) { - var file = new File(f.name, f.fullPath, f.type, f.lastModifiedDate, f.size); - successCallback(file); - }; - var fail = typeof errorCallback !== 'function' ? null : function(code) { - errorCallback(new FileError(code)); - }; - exec(win, fail, "File", "getFileMetadata", [this.fullPath]); -}; - - -module.exports = FileEntry; -}); - -// file: lib/common/plugin/FileError.js -define("cordova/plugin/FileError", function(require, exports, module) { -/** - * FileError - */ -function FileError(error) { - this.code = error || null; -} - -// File error codes -// Found in DOMException -FileError.NOT_FOUND_ERR = 1; -FileError.SECURITY_ERR = 2; -FileError.ABORT_ERR = 3; - -// Added by File API specification -FileError.NOT_READABLE_ERR = 4; -FileError.ENCODING_ERR = 5; -FileError.NO_MODIFICATION_ALLOWED_ERR = 6; -FileError.INVALID_STATE_ERR = 7; -FileError.SYNTAX_ERR = 8; -FileError.INVALID_MODIFICATION_ERR = 9; -FileError.QUOTA_EXCEEDED_ERR = 10; -FileError.TYPE_MISMATCH_ERR = 11; -FileError.PATH_EXISTS_ERR = 12; - -module.exports = FileError; -}); - -// file: lib/common/plugin/FileReader.js -define("cordova/plugin/FileReader", function(require, exports, module) { -var exec = require('cordova/exec'), - FileError = require('cordova/plugin/FileError'), - ProgressEvent = require('cordova/plugin/ProgressEvent'); - -/** - * This class reads the mobile device file system. - * - * For Android: - * The root directory is the root of the file system. - * To read from the SD card, the file name is "sdcard/my_file.txt" - * @constructor - */ -var FileReader = function() { - this.fileName = ""; - - this.readyState = 0; // FileReader.EMPTY - - // File data - this.result = null; - - // Error - this.error = null; - - // Event handlers - this.onloadstart = null; // When the read starts. - this.onprogress = null; // While reading (and decoding) file or fileBlob data, and reporting partial file data (progess.loaded/progress.total) - this.onload = null; // When the read has successfully completed. - this.onerror = null; // When the read has failed (see errors). - this.onloadend = null; // When the request has completed (either in success or failure). - this.onabort = null; // When the read has been aborted. For instance, by invoking the abort() method. -}; - -// States -FileReader.EMPTY = 0; -FileReader.LOADING = 1; -FileReader.DONE = 2; - -/** - * Abort reading file. - */ -FileReader.prototype.abort = function() { - this.result = null; - - if (this.readyState == FileReader.DONE || this.readyState == FileReader.EMPTY) { - return; - } - - this.readyState = FileReader.DONE; - - // If abort callback - if (typeof this.onabort === 'function') { - this.onabort(new ProgressEvent('abort', {target:this})); - } - // If load end callback - if (typeof this.onloadend === 'function') { - this.onloadend(new ProgressEvent('loadend', {target:this})); - } -}; - -/** - * Read text file. - * - * @param file {File} File object containing file properties - * @param encoding [Optional] (see http://www.iana.org/assignments/character-sets) - */ -FileReader.prototype.readAsText = function(file, encoding) { - // Figure out pathing - this.fileName = ''; - if (typeof file.fullPath === 'undefined') { - this.fileName = file; - } else { - this.fileName = file.fullPath; - } - - // Already loading something - if (this.readyState == FileReader.LOADING) { - throw new FileError(FileError.INVALID_STATE_ERR); - } - - // LOADING state - this.readyState = FileReader.LOADING; - - // If loadstart callback - if (typeof this.onloadstart === "function") { - this.onloadstart(new ProgressEvent("loadstart", {target:this})); - } - - // Default encoding is UTF-8 - var enc = encoding ? encoding : "UTF-8"; - - var me = this; - - // Read file - exec( - // Success callback - function(r) { - // If DONE (cancelled), then don't do anything - if (me.readyState === FileReader.DONE) { - return; - } - - // Save result - me.result = r; - - // If onload callback - if (typeof me.onload === "function") { - me.onload(new ProgressEvent("load", {target:me})); - } - - // DONE state - me.readyState = FileReader.DONE; - - // If onloadend callback - if (typeof me.onloadend === "function") { - me.onloadend(new ProgressEvent("loadend", {target:me})); - } - }, - // Error callback - function(e) { - // If DONE (cancelled), then don't do anything - if (me.readyState === FileReader.DONE) { - return; - } - - // DONE state - me.readyState = FileReader.DONE; - - // null result - me.result = null; - - // Save error - me.error = new FileError(e); - - // If onerror callback - if (typeof me.onerror === "function") { - me.onerror(new ProgressEvent("error", {target:me})); - } - - // If onloadend callback - if (typeof me.onloadend === "function") { - me.onloadend(new ProgressEvent("loadend", {target:me})); - } - }, "File", "readAsText", [this.fileName, enc]); -}; - - -/** - * Read file and return data as a base64 encoded data url. - * A data url is of the form: - * data:[<mediatype>][;base64],<data> - * - * @param file {File} File object containing file properties - */ -FileReader.prototype.readAsDataURL = function(file) { - this.fileName = ""; - if (typeof file.fullPath === "undefined") { - this.fileName = file; - } else { - this.fileName = file.fullPath; - } - - // Already loading something - if (this.readyState == FileReader.LOADING) { - throw new FileError(FileError.INVALID_STATE_ERR); - } - - // LOADING state - this.readyState = FileReader.LOADING; - - // If loadstart callback - if (typeof this.onloadstart === "function") { - this.onloadstart(new ProgressEvent("loadstart", {target:this})); - } - - var me = this; - - // Read file - exec( - // Success callback - function(r) { - // If DONE (cancelled), then don't do anything - if (me.readyState === FileReader.DONE) { - return; - } - - // DONE state - me.readyState = FileReader.DONE; - - // Save result - me.result = r; - - // If onload callback - if (typeof me.onload === "function") { - me.onload(new ProgressEvent("load", {target:me})); - } - - // If onloadend callback - if (typeof me.onloadend === "function") { - me.onloadend(new ProgressEvent("loadend", {target:me})); - } - }, - // Error callback - function(e) { - // If DONE (cancelled), then don't do anything - if (me.readyState === FileReader.DONE) { - return; - } - - // DONE state - me.readyState = FileReader.DONE; - - me.result = null; - - // Save error - me.error = new FileError(e); - - // If onerror callback - if (typeof me.onerror === "function") { - me.onerror(new ProgressEvent("error", {target:me})); - } - - // If onloadend callback - if (typeof me.onloadend === "function") { - me.onloadend(new ProgressEvent("loadend", {target:me})); - } - }, "File", "readAsDataURL", [this.fileName]); -}; - -/** - * Read file and return data as a binary data. - * - * @param file {File} File object containing file properties - */ -FileReader.prototype.readAsBinaryString = function(file) { - // TODO - Can't return binary data to browser. - console.log('method "readAsBinaryString" is not supported at this time.'); -}; - -/** - * Read file and return data as a binary data. - * - * @param file {File} File object containing file properties - */ -FileReader.prototype.readAsArrayBuffer = function(file) { - // TODO - Can't return binary data to browser. - console.log('This method is not supported at this time.'); -}; - -module.exports = FileReader; -}); - -// file: lib/common/plugin/FileSystem.js -define("cordova/plugin/FileSystem", function(require, exports, module) { -var DirectoryEntry = require('cordova/plugin/DirectoryEntry'); - -/** - * An interface representing a file system - * - * @constructor - * {DOMString} name the unique name of the file system (readonly) - * {DirectoryEntry} root directory of the file system (readonly) - */ -var FileSystem = function(name, root) { - this.name = name || null; - if (root) { - this.root = new DirectoryEntry(root.name, root.fullPath); - } -}; - -module.exports = FileSystem; -}); - -// file: lib/common/plugin/FileTransfer.js -define("cordova/plugin/FileTransfer", function(require, exports, module) { -var exec = require('cordova/exec'); - -/** - * FileTransfer uploads a file to a remote server. - * @constructor - */ -var FileTransfer = function() {}; - -/** -* Given an absolute file path, uploads a file on the device to a remote server -* using a multipart HTTP request. -* @param filePath {String} Full path of the file on the device -* @param server {String} URL of the server to receive the file -* @param successCallback (Function} Callback to be invoked when upload has completed -* @param errorCallback {Function} Callback to be invoked upon error -* @param options {FileUploadOptions} Optional parameters such as file name and mimetype -* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false -*/ -FileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) { - // check for options - var fileKey = null; - var fileName = null; - var mimeType = null; - var params = null; - var chunkedMode = true; - if (options) { - fileKey = options.fileKey; - fileName = options.fileName; - mimeType = options.mimeType; - if (options.chunkedMode !== null || typeof options.chunkedMode != "undefined") { - chunkedMode = options.chunkedMode; - } - if (options.params) { - params = options.params; - } - else { - params = {}; - } - } - - exec(successCallback, errorCallback, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode]); -}; - -/** - * Downloads a file form a given URL and saves it to the specified directory. - * @param source {String} URL of the server to receive the file - * @param target {String} Full path of the file on the device - * @param successCallback (Function} Callback to be invoked when upload has completed - * @param errorCallback {Function} Callback to be invoked upon error - */ -FileTransfer.prototype.download = function(source, target, successCallback, errorCallback) { - var win = function(result) { - var entry = null; - if (result.isDirectory) { - entry = new (require('cordova/plugin/DirectoryEntry'))(); - } - else if (result.isFile) { - entry = new (require('cordova/plugin/FileEntry'))(); - } - entry.isDirectory = result.isDirectory; - entry.isFile = result.isFile; - entry.name = result.name; - entry.fullPath = result.fullPath; - successCallback(entry); - }; - exec(win, errorCallback, 'FileTransfer', 'download', [source, target]); -}; - -module.exports = FileTransfer; - -}); - -// file: lib/common/plugin/FileTransferError.js -define("cordova/plugin/FileTransferError", function(require, exports, module) { -/** - * FileTransferError - * @constructor - */ -var FileTransferError = function(code) { - this.code = code || null; -}; - -FileTransferError.FILE_NOT_FOUND_ERR = 1; -FileTransferError.INVALID_URL_ERR = 2; -FileTransferError.CONNECTION_ERR = 3; - -module.exports = FileTransferError; -}); - -// file: lib/common/plugin/FileUploadOptions.js -define("cordova/plugin/FileUploadOptions", function(require, exports, module) { -/** - * Options to customize the HTTP request used to upload files. - * @constructor - * @param fileKey {String} Name of file request parameter. - * @param fileName {String} Filename to be used by the server. Defaults to image.jpg. - * @param mimeType {String} Mimetype of the uploaded file. Defaults to image/jpeg. - * @param params {Object} Object with key: value params to send to the server. - */ -var FileUploadOptions = function(fileKey, fileName, mimeType, params) { - this.fileKey = fileKey || null; - this.fileName = fileName || null; - this.mimeType = mimeType || null; - this.params = params || null; -}; - -module.exports = FileUploadOptions; -}); - -// file: lib/common/plugin/FileUploadResult.js -define("cordova/plugin/FileUploadResult", function(require, exports, module) { -/** - * FileUploadResult - * @constructor - */ -var FileUploadResult = function() { - this.bytesSent = 0; - this.responseCode = null; - this.response = null; -}; - -module.exports = FileUploadResult; -}); - -// file: lib/common/plugin/FileWriter.js -define("cordova/plugin/FileWriter", function(require, exports, module) { -var exec = require('cordova/exec'), - FileError = require('cordova/plugin/FileError'), - ProgressEvent = require('cordova/plugin/ProgressEvent'); - -/** - * This class writes to the mobile device file system. - * - * For Android: - * The root directory is the root of the file system. - * To write to the SD card, the file name is "sdcard/my_file.txt" - * - * @constructor - * @param file {File} File object containing file properties - * @param append if true write to the end of the file, otherwise overwrite the file - */ -var FileWriter = function(file) { - this.fileName = ""; - this.length = 0; - if (file) { - this.fileName = file.fullPath || file; - this.length = file.size || 0; - } - // default is to write at the beginning of the file - this.position = 0; - - this.readyState = 0; // EMPTY - - this.result = null; - - // Error - this.error = null; - - // Event handlers - this.onwritestart = null; // When writing starts - this.onprogress = null; // While writing the file, and reporting partial file data - this.onwrite = null; // When the write has successfully completed. - this.onwriteend = null; // When the request has completed (either in success or failure). - this.onabort = null; // When the write has been aborted. For instance, by invoking the abort() method. - this.onerror = null; // When the write has failed (see errors). -}; - -// States -FileWriter.INIT = 0; -FileWriter.WRITING = 1; -FileWriter.DONE = 2; - -/** - * Abort writing file. - */ -FileWriter.prototype.abort = function() { - // check for invalid state - if (this.readyState === FileWriter.DONE || this.readyState === FileWriter.INIT) { - throw new FileError(FileError.INVALID_STATE_ERR); - } - - // set error - this.error = new FileError(FileError.ABORT_ERR); - - this.readyState = FileWriter.DONE; - - // If abort callback - if (typeof this.onabort === "function") { - this.onabort(new ProgressEvent("abort", {"target":this})); - } - - // If write end callback - if (typeof this.onwriteend === "function") { - this.onwriteend(new ProgressEvent("writeend", {"target":this})); - } -}; - -/** - * Writes data to the file - * - * @param text to be written - */ -FileWriter.prototype.write = function(text) { - // Throw an exception if we are already writing a file - if (this.readyState === FileWriter.WRITING) { - throw new FileError(FileError.INVALID_STATE_ERR); - } - - // WRITING state - this.readyState = FileWriter.WRITING; - - var me = this; - - // If onwritestart callback - if (typeof me.onwritestart === "function") { - me.onwritestart(new ProgressEvent("writestart", {"target":me})); - } - - // Write file - exec( - // Success callback - function(r) { - // If DONE (cancelled), then don't do anything - if (me.readyState === FileWriter.DONE) { - return; - } - - // position always increases by bytes written because file would be extended - me.position += r; - // The length of the file is now where we are done writing. - - me.length = me.position; - - // DONE state - me.readyState = FileWriter.DONE; - - // If onwrite callback - if (typeof me.onwrite === "function") { - me.onwrite(new ProgressEvent("write", {"target":me})); - } - - // If onwriteend callback - if (typeof me.onwriteend === "function") { - me.onwriteend(new ProgressEvent("writeend", {"target":me})); - } - }, - // Error callback - function(e) { - // If DONE (cancelled), then don't do anything - if (me.readyState === FileWriter.DONE) { - return; - } - - // DONE state - me.readyState = FileWriter.DONE; - - // Save error - me.error = new FileError(e); - - // If onerror callback - if (typeof me.onerror === "function") { - me.onerror(new ProgressEvent("error", {"target":me})); - } - - // If onwriteend callback - if (typeof me.onwriteend === "function") { - me.onwriteend(new ProgressEvent("writeend", {"target":me})); - } - }, "File", "write", [this.fileName, text, this.position]); -}; - -/** - * Moves the file pointer to the location specified. - * - * If the offset is a negative number the position of the file - * pointer is rewound. If the offset is greater than the file - * size the position is set to the end of the file. - * - * @param offset is the location to move the file pointer to. - */ -FileWriter.prototype.seek = function(offset) { - // Throw an exception if we are already writing a file - if (this.readyState === FileWriter.WRITING) { - throw new FileError(FileError.INVALID_STATE_ERR); - } - - if (!offset && offset !== 0) { - return; - } - - // See back from end of file. - if (offset < 0) { - this.position = Math.max(offset + this.length, 0); - } - // Offset is bigger then file size so set position - // to the end of the file. - else if (offset > this.length) { - this.position = this.length; - } - // Offset is between 0 and file size so set the position - // to start writing. - else { - this.position = offset; - } -}; - -/** - * Truncates the file to the size specified. - * - * @param size to chop the file at. - */ -FileWriter.prototype.truncate = function(size) { - // Throw an exception if we are already writing a file - if (this.readyState === FileWriter.WRITING) { - throw new FileError(FileError.INVALID_STATE_ERR); - } - - // WRITING state - this.readyState = FileWriter.WRITING; - - var me = this; - - // If onwritestart callback - if (typeof me.onwritestart === "function") { - me.onwritestart(new ProgressEvent("writestart", {"target":this})); - } - - // Write file - exec( - // Success callback - function(r) { - // If DONE (cancelled), then don't do anything - if (me.readyState === FileWriter.DONE) { - return; - } - - // DONE state - me.readyState = FileWriter.DONE; - - // Update the length of the file - me.length = r; - me.position = Math.min(me.position, r); - - // If onwrite callback - if (typeof me.onwrite === "function") { - me.onwrite(new ProgressEvent("write", {"target":me})); - } - - // If onwriteend callback - if (typeof me.onwriteend === "function") { - me.onwriteend(new ProgressEvent("writeend", {"target":me})); - } - }, - // Error callback - function(e) { - // If DONE (cancelled), then don't do anything - if (me.readyState === FileWriter.DONE) { - return; - } - - // DONE state - me.readyState = FileWriter.DONE; - - // Save error - me.error = new FileError(e); - - // If onerror callback - if (typeof me.onerror === "function") { - me.onerror(new ProgressEvent("error", {"target":me})); - } - - // If onwriteend callback - if (typeof me.onwriteend === "function") { - me.onwriteend(new ProgressEvent("writeend", {"target":me})); - } - }, "File", "truncate", [this.fileName, size]); -}; - -module.exports = FileWriter; - -}); - -// file: lib/common/plugin/Flags.js -define("cordova/plugin/Flags", function(require, exports, module) { -/** - * Supplies arguments to methods that lookup or create files and directories. - * - * @param create - * {boolean} file or directory if it doesn't exist - * @param exclusive - * {boolean} used with create; if true the command will fail if - * target path exists - */ -function Flags(create, exclusive) { - this.create = create || false; - this.exclusive = exclusive || false; -} - -module.exports = Flags; -}); - -// file: lib/common/plugin/LocalFileSystem.js -define("cordova/plugin/LocalFileSystem", function(require, exports, module) { -var exec = require('cordova/exec'); - -/** - * Represents a local file system. - */ -var LocalFileSystem = function() { - -}; - -LocalFileSystem.TEMPORARY = 0; //temporary, with no guarantee of persistence -LocalFileSystem.PERSISTENT = 1; //persistent - -module.exports = LocalFileSystem; -}); - -// file: lib/common/plugin/Media.js -define("cordova/plugin/Media", function(require, exports, module) { -var utils = require('cordova/utils'), - exec = require('cordova/exec'); - -var mediaObjects = {}; - -/** - * This class provides access to the device media, interfaces to both sound and video - * - * @constructor - * @param src The file name or url to play - * @param successCallback The callback to be called when the file is done playing or recording. - * successCallback() - * @param errorCallback The callback to be called if there is an error. - * errorCallback(int errorCode) - OPTIONAL - * @param statusCallback The callback to be called when media status has changed. - * statusCallback(int statusCode) - OPTIONAL - */ -var Media = function(src, successCallback, errorCallback, statusCallback) { - - // successCallback optional - if (successCallback && (typeof successCallback !== "function")) { - console.log("Media Error: successCallback is not a function"); - return; - } - - // errorCallback optional - if (errorCallback && (typeof errorCallback !== "function")) { - console.log("Media Error: errorCallback is not a function"); - return; - } - - // statusCallback optional - if (statusCallback && (typeof statusCallback !== "function")) { - console.log("Media Error: statusCallback is not a function"); - return; - } - - this.id = utils.createUUID(); - mediaObjects[this.id] = this; - this.src = src; - this.successCallback = successCallback; - this.errorCallback = errorCallback; - this.statusCallback = statusCallback; - this._duration = -1; - this._position = -1; - exec(null, this.errorCallback, "Media", "create", [this.id, this.src]); -}; - -// Media messages -Media.MEDIA_STATE = 1; -Media.MEDIA_DURATION = 2; -Media.MEDIA_POSITION = 3; -Media.MEDIA_ERROR = 9; - -// Media states -Media.MEDIA_NONE = 0; -Media.MEDIA_STARTING = 1; -Media.MEDIA_RUNNING = 2; -Media.MEDIA_PAUSED = 3; -Media.MEDIA_STOPPED = 4; -Media.MEDIA_MSG = ["None", "Starting", "Running", "Paused", "Stopped"]; - -// "static" function to return existing objs. -Media.get = function(id) { - return mediaObjects[id]; -}; - -/** - * Start or resume playing audio file. - */ -Media.prototype.play = function(options) { - exec(null, null, "Media", "startPlayingAudio", [this.id, this.src, options]); -}; - -/** - * Stop playing audio file. - */ -Media.prototype.stop = function() { - var me = this; - exec(function() { - me._position = 0; - me.successCallback(); - }, this.errorCallback, "Media", "stopPlayingAudio", [this.id]); -}; - -/** - * Seek or jump to a new time in the track.. - */ -Media.prototype.seekTo = function(milliseconds) { - var me = this; - exec(function(p) { - me._position = p; - }, this.errorCallback, "Media", "seekToAudio", [this.id, milliseconds]); -}; - -/** - * Pause playing audio file. - */ -Media.prototype.pause = function() { - exec(null, this.errorCallback, "Media", "pausePlayingAudio", [this.id]); -}; - -/** - * Get duration of an audio file. - * The duration is only set for audio that is playing, paused or stopped. - * - * @return duration or -1 if not known. - */ -Media.prototype.getDuration = function() { - return this._duration; -}; - -/** - * Get position of audio. - */ -Media.prototype.getCurrentPosition = function(success, fail) { - var me = this; - exec(function(p) { - me._position = p; - success(p); - }, fail, "Media", "getCurrentPositionAudio", [this.id]); -}; - -/** - * Start recording audio file. - */ -Media.prototype.startRecord = function() { - exec(this.successCallback, this.errorCallback, "Media", "startRecordingAudio", [this.id, this.src]); -}; - -/** - * Stop recording audio file. - */ -Media.prototype.stopRecord = function() { - exec(this.successCallback, this.errorCallback, "Media", "stopRecordingAudio", [this.id]); -}; - -/** - * Release the resources. - */ -Media.prototype.release = function() { - exec(null, this.errorCallback, "Media", "release", [this.id]); -}; - -/** - * Adjust the volume. - */ -Media.prototype.setVolume = function(volume) { - exec(null, null, "Media", "setVolume", [this.id, volume]); -}; - -/** - * Audio has status update. - * PRIVATE - * - * @param id The media object id (string) - * @param status The status code (int) - * @param msg The status message (string) - */ -Media.onStatus = function(id, msg, value) { - var media = mediaObjects[id]; - // If state update - if (msg === Media.MEDIA_STATE) { - if (value === Media.MEDIA_STOPPED) { - if (media.successCallback) { - media.successCallback(); - } - } - if (media.statusCallback) { - media.statusCallback(value); - } - } - else if (msg === Media.MEDIA_DURATION) { - media._duration = value; - } - else if (msg === Media.MEDIA_ERROR) { - if (media.errorCallback) { - // value should be a MediaError object when msg == MEDIA_ERROR - media.errorCallback(value); - } - } - else if (msg === Media.MEDIA_POSITION) { - media._position = value; - } -}; - -module.exports = Media; -}); - -// file: lib/common/plugin/MediaError.js -define("cordova/plugin/MediaError", function(require, exports, module) { -/** - * This class contains information about any Media errors. - * @constructor - */ -var MediaError = function(code, msg) { - this.code = (code !== undefined ? code : null); - this.message = msg || ""; -}; - -MediaError.MEDIA_ERR_NONE_ACTIVE = 0; -MediaError.MEDIA_ERR_ABORTED = 1; -MediaError.MEDIA_ERR_NETWORK = 2; -MediaError.MEDIA_ERR_DECODE = 3; -MediaError.MEDIA_ERR_NONE_SUPPORTED = 4; - -module.exports = MediaError; -}); - -// file: lib/common/plugin/MediaFile.js -define("cordova/plugin/MediaFile", function(require, exports, module) { -var utils = require('cordova/utils'), - exec = require('cordova/exec'), - File = require('cordova/plugin/File'), - CaptureError = require('cordova/plugin/CaptureError'); -/** - * Represents a single file. - * - * name {DOMString} name of the file, without path information - * fullPath {DOMString} the full path of the file, including the name - * type {DOMString} mime type - * lastModifiedDate {Date} last modified date - * size {Number} size of the file in bytes - */ -var MediaFile = function(name, fullPath, type, lastModifiedDate, size){ - MediaFile.__super__.constructor.apply(this, arguments); -}; - -utils.extend(MediaFile, File); - -/** - * Request capture format data for a specific file and type - * - * @param {Function} successCB - * @param {Function} errorCB - */ -MediaFile.prototype.getFormatData = function(successCallback, errorCallback) { - if (typeof this.fullPath === "undefined" || this.fullPath === null) { - errorCallback(new CaptureError(CaptureError.CAPTURE_INVALID_ARGUMENT)); - } else { - exec(successCallback, errorCallback, "Capture", "getFormatData", [this.fullPath, this.type]); - } -}; - -// TODO: can we axe this? -/** - * Casts a PluginResult message property (array of objects) to an array of MediaFile objects - * (used in Objective-C and Android) - * - * @param {PluginResult} pluginResult - */ -MediaFile.cast = function(pluginResult) { - var mediaFiles = []; - for (var i=0; i<pluginResult.message.length; i++) { - var mediaFile = new MediaFile(); - mediaFile.name = pluginResult.message[i].name; - mediaFile.fullPath = pluginResult.message[i].fullPath; - mediaFile.type = pluginResult.message[i].type; - mediaFile.lastModifiedDate = pluginResult.message[i].lastModifiedDate; - mediaFile.size = pluginResult.message[i].size; - mediaFiles.push(mediaFile); - } - pluginResult.message = mediaFiles; - return pluginResult; -}; - -module.exports = MediaFile; - -}); - -// file: lib/common/plugin/MediaFileData.js -define("cordova/plugin/MediaFileData", function(require, exports, module) { -/** - * MediaFileData encapsulates format information of a media file. - * - * @param {DOMString} codecs - * @param {long} bitrate - * @param {long} height - * @param {long} width - * @param {float} duration - */ -var MediaFileData = function(codecs, bitrate, height, width, duration){ - this.codecs = codecs || null; - this.bitrate = bitrate || 0; - this.height = height || 0; - this.width = width || 0; - this.duration = duration || 0; -}; - -module.exports = MediaFileData; -}); - -// file: lib/common/plugin/Metadata.js -define("cordova/plugin/Metadata", function(require, exports, module) { -/** - * Information about the state of the file or directory - * - * {Date} modificationTime (readonly) - */ -var Metadata = function(time) { - this.modificationTime = (typeof time != 'undefined'?new Date(time):null); -}; - -module.exports = Metadata; -}); - -// file: lib/common/plugin/Position.js -define("cordova/plugin/Position", function(require, exports, module) { -var Coordinates = require('cordova/plugin/Coordinates'); - -var Position = function(coords, timestamp) { - if (coords) { - this.coords = new Coordinates(coords.latitude, coords.longitude, coords.altitude, coords.accuracy, coords.heading, coords.velocity, coords.altitudeAccuracy); - } else { - this.coords = new Coordinates(); - } - this.timestamp = (timestamp !== undefined) ? timestamp : new Date(); -}; - -module.exports = Position; - -}); - -// file: lib/common/plugin/PositionError.js -define("cordova/plugin/PositionError", function(require, exports, module) { -/** - * Position error object - * - * @constructor - * @param code - * @param message - */ -var PositionError = function(code, message) { - this.code = code || null; - this.message = message || ''; -}; - -PositionError.PERMISSION_DENIED = 1; -PositionError.POSITION_UNAVAILABLE = 2; -PositionError.TIMEOUT = 3; - -module.exports = PositionError; -}); - -// file: lib/common/plugin/ProgressEvent.js -define("cordova/plugin/ProgressEvent", function(require, exports, module) { -// If ProgressEvent exists in global context, use it already, otherwise use our own polyfill -// Feature test: See if we can instantiate a native ProgressEvent; -// if so, use that approach, -// otherwise fill-in with our own implementation. -// -// NOTE: right now we always fill in with our own. Down the road would be nice if we can use whatever is native in the webview. -var ProgressEvent = (function() { - /* - var createEvent = function(data) { - var event = document.createEvent('Events'); - event.initEvent('ProgressEvent', false, false); - if (data) { - for (var i in data) { - if (data.hasOwnProperty(i)) { - event[i] = data[i]; - } - } - if (data.target) { - // TODO: cannot call <some_custom_object>.dispatchEvent - // need to first figure out how to implement EventTarget - } - } - return event; - }; - try { - var ev = createEvent({type:"abort",target:document}); - return function ProgressEvent(type, data) { - data.type = type; - return createEvent(data); - }; - } catch(e){ - */ - return function ProgressEvent(type, dict) { - this.type = type; - this.bubbles = false; - this.cancelBubble = false; - this.cancelable = false; - this.lengthComputable = false; - this.loaded = dict && dict.loaded ? dict.loaded : 0; - this.total = dict && dict.total ? dict.total : 0; - this.target = dict && dict.target ? dict.target : null; - }; - //} -})(); - -module.exports = ProgressEvent; -}); - -// file: lib/common/plugin/accelerometer.js -define("cordova/plugin/accelerometer", function(require, exports, module) { -/** - * This class provides access to device accelerometer data. - * @constructor - */ -var utils = require("cordova/utils"), - exec = require("cordova/exec"), - Acceleration = require('cordova/plugin/Acceleration'); - -// Is the accel sensor running? -var running = false; - -// Keeps reference to watchAcceleration calls. -var timers = {}; - -// Array of listeners; used to keep track of when we should call start and stop. -var listeners = []; - -// Last returned acceleration object from native -var accel = null; - -// Tells native to start. -function start() { - exec(function(a) { - var tempListeners = listeners.slice(0); - accel = new Acceleration(a.x, a.y, a.z, a.timestamp); - for (var i = 0, l = tempListeners.length; i < l; i++) { - tempListeners[i].win(accel); - } - }, function(e) { - var tempListeners = listeners.slice(0); - for (var i = 0, l = tempListeners.length; i < l; i++) { - tempListeners[i].fail(e); - } - }, "Accelerometer", "start", []); - running = true; -} - -// Tells native to stop. -function stop() { - exec(null, null, "Accelerometer", "stop", []); - running = false; -} - -// Adds a callback pair to the listeners array -function createCallbackPair(win, fail) { - return {win:win, fail:fail}; -} - -// Removes a win/fail listener pair from the listeners array -function removeListeners(l) { - var idx = listeners.indexOf(l); - if (idx > -1) { - listeners.splice(idx, 1); - if (listeners.length === 0) { - stop(); - } - } -} - -var accelerometer = { - /** - * Asynchronously aquires the current acceleration. - * - * @param {Function} successCallback The function to call when the acceleration data is available - * @param {Function} errorCallback The function to call when there is an error getting the acceleration data. (OPTIONAL) - * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL) - */ - getCurrentAcceleration: function(successCallback, errorCallback, options) { - // successCallback required - if (typeof successCallback !== "function") { - throw "getCurrentAcceleration must be called with at least a success callback function as first parameter."; - } - - var p; - var win = function(a) { - successCallback(a); - removeListeners(p); - }; - var fail = function(e) { - errorCallback(e); - removeListeners(p); - }; - - p = createCallbackPair(win, fail); - listeners.push(p); - - if (!running) { - start(); - } - }, - - /** - * Asynchronously aquires the acceleration repeatedly at a given interval. - * - * @param {Function} successCallback The function to call each time the acceleration data is available - * @param {Function} errorCallback The function to call when there is an error getting the acceleration data. (OPTIONAL) - * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL) - * @return String The watch id that must be passed to #clearWatch to stop watching. - */ - watchAcceleration: function(successCallback, errorCallback, options) { - // Default interval (10 sec) - var frequency = (options && options.frequency && typeof options.frequency == 'number') ? options.frequency : 10000; - - // successCallback required - if (typeof successCallback !== "function") { - throw "watchAcceleration must be called with at least a success callback function as first parameter."; - } - - // Keep reference to watch id, and report accel readings as often as defined in frequency - var id = utils.createUUID(); - - var p = createCallbackPair(function(){}, function(e) { - errorCallback(e); - removeListeners(p); - }); - listeners.push(p); - - timers[id] = { - timer:window.setInterval(function() { - if (accel) { - successCallback(accel); - } - }, frequency), - listeners:p - }; - - if (running) { - // If we're already running then immediately invoke the success callback - successCallback(accel); - } else { - start(); - } - - return id; - }, - - /** - * Clears the specified accelerometer watch. - * - * @param {String} id The id of the watch returned from #watchAcceleration. - */ - clearWatch: function(id) { - // Stop javascript timer & remove from timer list - if (id && timers[id]) { - window.clearInterval(timers[id].timer); - removeListeners(timers[id].listeners); - delete timers[id]; - } - } -}; - -module.exports = accelerometer; - -}); - -// file: lib/common/plugin/battery.js -define("cordova/plugin/battery", function(require, exports, module) { -/** - * This class contains information about the current battery status. - * @constructor - */ -var cordova = require('cordova'), - exec = require('cordova/exec'); - -function handlers() { - return battery.channels.batterystatus.numHandlers + - battery.channels.batterylow.numHandlers + - battery.channels.batterycritical.numHandlers; -} - -var Battery = function() { - this._level = null; - this._isPlugged = null; - // Create new event handlers on the window (returns a channel instance) - var subscriptionEvents = { - onSubscribe:this.onSubscribe, - onUnsubscribe:this.onUnsubscribe - }; - this.channels = { - batterystatus:cordova.addWindowEventHandler("batterystatus", subscriptionEvents), - batterylow:cordova.addWindowEventHandler("batterylow", subscriptionEvents), - batterycritical:cordova.addWindowEventHandler("batterycritical", subscriptionEvents) - }; -}; -/** - * Event handlers for when callbacks get registered for the battery. - * Keep track of how many handlers we have so we can start and stop the native battery listener - * appropriately (and hopefully save on battery life!). - */ -Battery.prototype.onSubscribe = function() { - var me = battery; - // If we just registered the first handler, make sure native listener is started. - if (handlers() === 1) { - exec(me._status, me._error, "Battery", "start", []); - } -}; - -Battery.prototype.onUnsubscribe = function() { - var me = battery; - - // If we just unregistered the last handler, make sure native listener is stopped. - if (handlers() === 0) { - exec(null, null, "Battery", "stop", []); - } -}; - -/** - * Callback for battery status - * - * @param {Object} info keys: level, isPlugged - */ -Battery.prototype._status = function(info) { - if (info) { - var me = battery; - var level = info.level; - if (me._level !== level || me._isPlugged !== info.isPlugged) { - // Fire batterystatus event - cordova.fireWindowEvent("batterystatus", info); - - // Fire low battery event - if (level === 20 || level === 5) { - if (level === 20) { - cordova.fireWindowEvent("batterylow", info); - } - else { - cordova.fireWindowEvent("batterycritical", info); - } - } - } - me._level = level; - me._isPlugged = info.isPlugged; - } -}; - -/** - * Error callback for battery start - */ -Battery.prototype._error = function(e) { - console.log("Error initializing Battery: " + e); -}; - -var battery = new Battery(); - -module.exports = battery; -}); - -// file: lib/common/plugin/capture.js -define("cordova/plugin/capture", function(require, exports, module) { -var exec = require('cordova/exec'), - MediaFile = require('cordova/plugin/MediaFile'); - -/** - * Launches a capture of different types. - * - * @param (DOMString} type - * @param {Function} successCB - * @param {Function} errorCB - * @param {CaptureVideoOptions} options - */ -function _capture(type, successCallback, errorCallback, options) { - var win = function(pluginResult) { - var mediaFiles = []; - var i; - for (i = 0; i < pluginResult.length; i++) { - var mediaFile = new MediaFile(); - mediaFile.name = pluginResult[i].name; - mediaFile.fullPath = pluginResult[i].fullPath; - mediaFile.type = pluginResult[i].type; - mediaFile.lastModifiedDate = pluginResult[i].lastModifiedDate; - mediaFile.size = pluginResult[i].size; - mediaFiles.push(mediaFile); - } - successCallback(mediaFiles); - }; - exec(win, errorCallback, "Capture", type, [options]); -} -/** - * The Capture interface exposes an interface to the camera and microphone of the hosting device. - */ -function Capture() { - this.supportedAudioModes = []; - this.supportedImageModes = []; - this.supportedVideoModes = []; -} - -/** - * Launch audio recorder application for recording audio clip(s). - * - * @param {Function} successCB - * @param {Function} errorCB - * @param {CaptureAudioOptions} options - */ -Capture.prototype.captureAudio = function(successCallback, errorCallback, options){ - _capture("captureAudio", successCallback, errorCallback, options); -}; - -/** - * Launch camera application for taking image(s). - * - * @param {Function} successCB - * @param {Function} errorCB - * @param {CaptureImageOptions} options - */ -Capture.prototype.captureImage = function(successCallback, errorCallback, options){ - _capture("captureImage", successCallback, errorCallback, options); -}; - -/** - * Launch device camera application for recording video(s). - * - * @param {Function} successCB - * @param {Function} errorCB - * @param {CaptureVideoOptions} options - */ -Capture.prototype.captureVideo = function(successCallback, errorCallback, options){ - _capture("captureVideo", successCallback, errorCallback, options); -}; - - -module.exports = new Capture(); - -}); - -// file: lib/common/plugin/compass.js -define("cordova/plugin/compass", function(require, exports, module) { -var exec = require('cordova/exec'), - utils = require('cordova/utils'), - CompassHeading = require('cordova/plugin/CompassHeading'), - CompassError = require('cordova/plugin/CompassError'), - timers = {}, - compass = { - /** - * Asynchronously acquires the current heading. - * @param {Function} successCallback The function to call when the heading - * data is available - * @param {Function} errorCallback The function to call when there is an error - * getting the heading data. - * @param {CompassOptions} options The options for getting the heading data (not used). - */ - getCurrentHeading:function(successCallback, errorCallback, options) { - // successCallback required - if (typeof successCallback !== "function") { - console.log("Compass Error: successCallback is not a function"); - return; - } - - // errorCallback optional - if (errorCallback && (typeof errorCallback !== "function")) { - console.log("Compass Error: errorCallback is not a function"); - return; - } - - var win = function(result) { - var ch = new CompassHeading(result.magneticHeading, result.trueHeading, result.headingAccuracy, result.timestamp); - successCallback(ch); - }; - var fail = function(code) { - var ce = new CompassError(code); - errorCallback(ce); - }; - - // Get heading - exec(win, fail, "Compass", "getHeading", [options]); - }, - - /** - * Asynchronously acquires the heading repeatedly at a given interval. - * @param {Function} successCallback The function to call each time the heading - * data is available - * @param {Function} errorCallback The function to call when there is an error - * getting the heading data. - * @param {HeadingOptions} options The options for getting the heading data - * such as timeout and the frequency of the watch. For iOS, filter parameter - * specifies to watch via a distance filter rather than time. - */ - watchHeading:function(successCallback, errorCallback, options) { - // Default interval (100 msec) - var frequency = (options !== undefined && options.frequency !== undefined) ? options.frequency : 100; - var filter = (options !== undefined && options.filter !== undefined) ? options.filter : 0; - - // successCallback required - if (typeof successCallback !== "function") { - console.log("Compass Error: successCallback is not a function"); - return; - } - - // errorCallback optional - if (errorCallback && (typeof errorCallback !== "function")) { - console.log("Compass Error: errorCallback is not a function"); - return; - } - - var id = utils.createUUID(); - if (filter > 0) { - // is an iOS request for watch by filter, no timer needed - timers[id] = "iOS"; - compass.getCurrentHeading(successCallback, errorCallback, options); - } else { - // Start watch timer to get headings - timers[id] = window.setInterval(function() { - compass.getCurrentHeading(successCallback, errorCallback); - }, frequency); - } - - return id; - }, - - /** - * Clears the specified heading watch. - * @param {String} watchId The ID of the watch returned from #watchHeading. - */ - clearWatch:function(id) { - // Stop javascript timer & remove from timer list - if (id && timers[id]) { - if (timers[id] != "iOS") { - clearInterval(timers[id]); - } else { - // is iOS watch by filter so call into device to stop - exec(null, null, "Compass", "stopHeading", []); - } - delete timers[id]; - } - } - }; - -module.exports = compass; -}); - -// file: lib/common/plugin/console-via-logger.js -define("cordova/plugin/console-via-logger", function(require, exports, module) { -//------------------------------------------------------------------------------ - -var logger = require("cordova/plugin/logger"); -var utils = require("cordova/utils"); - -//------------------------------------------------------------------------------ -// object that we're exporting -//------------------------------------------------------------------------------ -var console = module.exports; - -//------------------------------------------------------------------------------ -// copy of the original console object -//------------------------------------------------------------------------------ -var WinConsole = window.console; - -//------------------------------------------------------------------------------ -// whether to use the logger -//------------------------------------------------------------------------------ -var UseLogger = false; - -//------------------------------------------------------------------------------ -// Timers -//------------------------------------------------------------------------------ -var Timers = {}; - -//------------------------------------------------------------------------------ -// used for unimplemented methods -//------------------------------------------------------------------------------ -function noop() {} - -//------------------------------------------------------------------------------ -// used for unimplemented methods -//------------------------------------------------------------------------------ -console.useLogger = function (value) { - if (arguments.length) UseLogger = !!value; - - if (UseLogger) { - if (logger.useConsole()) { - throw new Error("console and logger are too intertwingly"); - } - } - - return UseLogger; -}; - -//------------------------------------------------------------------------------ -console.log = function() { - if (logger.useConsole()) return; - logger.log.apply(logger, [].slice.call(arguments)); -}; - -//------------------------------------------------------------------------------ -console.error = function() { - if (logger.useConsole()) return; - logger.error.apply(logger, [].slice.call(arguments)); -}; - -//------------------------------------------------------------------------------ -console.warn = function() { - if (logger.useConsole()) return; - logger.warn.apply(logger, [].slice.call(arguments)); -}; - -//------------------------------------------------------------------------------ -console.info = function() { - if (logger.useConsole()) return; - logger.info.apply(logger, [].slice.call(arguments)); -}; - -//------------------------------------------------------------------------------ -console.debug = function() { - if (logger.useConsole()) return; - logger.debug.apply(logger, [].slice.call(arguments)); -}; - -//------------------------------------------------------------------------------ -console.assert = function(expression) { - if (expression) return; - - var message = utils.vformat(arguments[1], [].slice.call(arguments, 2)); - console.log("ASSERT: " + message); -}; - -//------------------------------------------------------------------------------ -console.clear = function() {}; - -//------------------------------------------------------------------------------ -console.dir = function(object) { - console.log("%o", object); -}; - -//------------------------------------------------------------------------------ -console.dirxml = function(node) { - console.log(node.innerHTML); -}; - -//------------------------------------------------------------------------------ -console.trace = noop; - -//------------------------------------------------------------------------------ -console.group = console.log; - -//------------------------------------------------------------------------------ -console.groupCollapsed = console.log; - -//------------------------------------------------------------------------------ -console.groupEnd = noop; - -//------------------------------------------------------------------------------ -console.time = function(name) { - Timers[name] = new Date().valueOf(); -}; - -//------------------------------------------------------------------------------ -console.timeEnd = function(name) { - var timeStart = Timers[name]; - if (!timeStart) { - console.warn("unknown timer: " + name); - return; - } - - var timeElapsed = new Date().valueOf() - timeStart; - console.log(name + ": " + timeElapsed + "ms"); -}; - -//------------------------------------------------------------------------------ -console.timeStamp = noop; - -//------------------------------------------------------------------------------ -console.profile = noop; - -//------------------------------------------------------------------------------ -console.profileEnd = noop; - -//------------------------------------------------------------------------------ -console.count = noop; - -//------------------------------------------------------------------------------ -console.exception = console.log; - -//------------------------------------------------------------------------------ -console.table = function(data, columns) { - console.log("%o", data); -}; - -//------------------------------------------------------------------------------ -// return a new function that calls both functions passed as args -//------------------------------------------------------------------------------ -function wrapperedOrigCall(orgFunc, newFunc) { - return function() { - var args = [].slice.call(arguments); - try { orgFunc.apply(WinConsole, args); } catch (e) {} - try { newFunc.apply(console, args); } catch (e) {} - }; -} - -//------------------------------------------------------------------------------ -// For every function that exists in the original console object, that -// also exists in the new console object, wrap the new console method -// with one that calls both -//------------------------------------------------------------------------------ -for (var key in console) { - if (typeof WinConsole[key] == "function") { - console[key] = wrapperedOrigCall(WinConsole[key], console[key]); - } -} - -}); - -// file: lib/common/plugin/contacts.js -define("cordova/plugin/contacts", function(require, exports, module) { -var exec = require('cordova/exec'), - ContactError = require('cordova/plugin/ContactError'), - utils = require('cordova/utils'), - Contact = require('cordova/plugin/Contact'); - -/** -* Represents a group of Contacts. -* @constructor -*/ -var contacts = { - /** - * Returns an array of Contacts matching the search criteria. - * @param fields that should be searched - * @param successCB success callback - * @param errorCB error callback - * @param {ContactFindOptions} options that can be applied to contact searching - * @return array of Contacts matching search criteria - */ - find:function(fields, successCB, errorCB, options) { - if (!successCB) { - throw new TypeError("You must specify a success callback for the find command."); - } - if (!fields || (utils.isArray(fields) && fields.length === 0)) { - if (typeof errorCB === "function") { - errorCB(new ContactError(ContactError.INVALID_ARGUMENT_ERROR)); - } - } else { - var win = function(result) { - var cs = []; - for (var i = 0, l = result.length; i < l; i++) { - cs.push(contacts.create(result[i])); - } - successCB(cs); - }; - exec(win, errorCB, "Contacts", "search", [fields, options]); - } - }, - - /** - * This function creates a new contact, but it does not persist the contact - * to device storage. To persist the contact to device storage, invoke - * contact.save(). - * @param properties an object who's properties will be examined to create a new Contact - * @returns new Contact object - */ - create:function(properties) { - var i; - var contact = new Contact(); - for (i in properties) { - if (typeof contact[i] !== 'undefined' && properties.hasOwnProperty(i)) { - contact[i] = properties[i]; - } - } - return contact; - } -}; - -module.exports = contacts; - -}); - -// file: lib/common/plugin/geolocation.js -define("cordova/plugin/geolocation", function(require, exports, module) { -var utils = require('cordova/utils'), - exec = require('cordova/exec'), - PositionError = require('cordova/plugin/PositionError'), - Position = require('cordova/plugin/Position'); - -var timers = {}; // list of timers in use - -// Returns default params, overrides if provided with values -function parseParameters(options) { - var opt = { - maximumAge: 0, - enableHighAccuracy: false, - timeout: Infinity - }; - - if (options) { - if (options.maximumAge !== undefined && !isNaN(options.maximumAge) && options.maximumAge > 0) { - opt.maximumAge = options.maximumAge; - } - if (options.enableHighAccuracy !== undefined) { - opt.enableHighAccuracy = options.enableHighAccuracy; - } - if (options.timeout !== undefined && !isNaN(options.timeout)) { - if (options.timeout < 0) { - opt.timeout = 0; - } else { - opt.timeout = options.timeout; - } - } - } - - return opt; -} - -// Returns a timeout failure, closed over a specified timeout value and error callback. -function createTimeout(errorCallback, timeout) { - var t = setTimeout(function() { - clearTimeout(t); - t = null; - errorCallback({ - code:PositionError.TIMEOUT, - message:"Position retrieval timed out." - }); - }, timeout); - return t; -} - -var geolocation = { - lastPosition:null, // reference to last known (cached) position returned - /** - * Asynchronously aquires the current position. - * - * @param {Function} successCallback The function to call when the position data is available - * @param {Function} errorCallback The function to call when there is an error getting the heading position. (OPTIONAL) - * @param {PositionOptions} options The options for getting the position data. (OPTIONAL) - */ - getCurrentPosition:function(successCallback, errorCallback, options) { - if (arguments.length === 0) { - throw new Error("getCurrentPosition must be called with at least one argument."); - } - options = parseParameters(options); - - // Timer var that will fire an error callback if no position is retrieved from native - // before the "timeout" param provided expires - var timeoutTimer = null; - - var win = function(p) { - clearTimeout(timeoutTimer); - if (!timeoutTimer) { - // Timeout already happened, or native fired error callback for - // this geo request. - // Don't continue with success callback. - return; - } - var pos = new Position( - { - latitude:p.latitude, - longitude:p.longitude, - altitude:p.altitude, - accuracy:p.accuracy, - heading:p.heading, - velocity:p.velocity, - altitudeAccuracy:p.altitudeAccuracy - }, - (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp))) - ); - geolocation.lastPosition = pos; - successCallback(pos); - }; - var fail = function(e) { - clearTimeout(timeoutTimer); - timeoutTimer = null; - var err = new PositionError(e.code, e.message); - if (errorCallback) { - errorCallback(err); - } - }; - - // Check our cached position, if its timestamp difference with current time is less than the maximumAge, then just - // fire the success callback with the cached position. - if (geolocation.lastPosition && options.maximumAge && (((new Date()).getTime() - geolocation.lastPosition.timestamp.getTime()) <= options.maximumAge)) { - successCallback(geolocation.lastPosition); - // If the cached position check failed and the timeout was set to 0, error out with a TIMEOUT error object. - } else if (options.timeout === 0) { - fail({ - code:PositionError.TIMEOUT, - message:"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceed's provided PositionOptions' maximumAge parameter." - }); - // Otherwise we have to call into native to retrieve a position. - } else { - if (options.timeout !== Infinity) { - // If the timeout value was not set to Infinity (default), then - // set up a timeout function that will fire the error callback - // if no successful position was retrieved before timeout expired. - timeoutTimer = createTimeout(fail, options.timeout); - } else { - // This is here so the check in the win function doesn't mess stuff up - // may seem weird but this guarantees timeoutTimer is - // always truthy before we call into native - timeoutTimer = true; - } - exec(win, fail, "Geolocation", "getLocation", [options.enableHighAccuracy, options.maximumAge]); - } - return timeoutTimer; - }, - /** - * Asynchronously watches the geolocation for changes to geolocation. When a change occurs, - * the successCallback is called with the new location. - * - * @param {Function} successCallback The function to call each time the location data is available - * @param {Function} errorCallback The function to call when there is an error getting the location data. (OPTIONAL) - * @param {PositionOptions} options The options for getting the location data such as frequency. (OPTIONAL) - * @return String The watch id that must be passed to #clearWatch to stop watching. - */ - watchPosition:function(successCallback, errorCallback, options) { - if (arguments.length === 0) { - throw new Error("watchPosition must be called with at least one argument."); - } - options = parseParameters(options); - - var id = utils.createUUID(); - - // Tell device to get a position ASAP, and also retrieve a reference to the timeout timer generated in getCurrentPosition - timers[id] = geolocation.getCurrentPosition(successCallback, errorCallback, options); - - var fail = function(e) { - clearTimeout(timers[id]); - var err = new PositionError(e.code, e.message); - if (errorCallback) { - errorCallback(err); - } - }; - - var win = function(p) { - clearTimeout(timers[id]); - if (options.timeout !== Infinity) { - timers[id] = createTimeout(fail, options.timeout); - } - var pos = new Position( - { - latitude:p.latitude, - longitude:p.longitude, - altitude:p.altitude, - accuracy:p.accuracy, - heading:p.heading, - velocity:p.velocity, - altitudeAccuracy:p.altitudeAccuracy - }, - (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp))) - ); - geolocation.lastPosition = pos; - successCallback(pos); - }; - - exec(win, fail, "Geolocation", "addWatch", [id, options.enableHighAccuracy]); - - return id; - }, - /** - * Clears the specified heading watch. - * - * @param {String} id The ID of the watch returned from #watchPosition - */ - clearWatch:function(id) { - if (id && timers[id] !== undefined) { - clearTimeout(timers[id]); - delete timers[id]; - exec(null, null, "Geolocation", "clearWatch", [id]); - } - } -}; - -module.exports = geolocation; - -}); - -// file: lib/ios/plugin/ios/Contact.js -define("cordova/plugin/ios/Contact", function(require, exports, module) { -var exec = require('cordova/exec'), - ContactError = require('cordova/plugin/ContactError'); - -/** - * Provides iOS Contact.display API. - */ -module.exports = { - display : function(errorCB, options) { - /* - * Display a contact using the iOS Contact Picker UI - * NOT part of W3C spec so no official documentation - * - * @param errorCB error callback - * @param options object - * allowsEditing: boolean AS STRING - * "true" to allow editing the contact - * "false" (default) display contact - */ - - if (this.id === null) { - if (typeof errorCB === "function") { - var errorObj = new ContactError(ContactError.UNKNOWN_ERROR); - errorCB(errorObj); - } - } - else { - exec(null, errorCB, "Contacts","displayContact", [this.id, options]); - } - } -}; -}); - -// file: lib/ios/plugin/ios/Entry.js -define("cordova/plugin/ios/Entry", function(require, exports, module) { -module.exports = { - toURL:function() { - // TODO: refactor path in a cross-platform way so we can eliminate - // these kinds of platform-specific hacks. - return "file://localhost" + this.fullPath; - }, - toURI: function() { - console.log("DEPRECATED: Update your code to use 'toURL'"); - return "file://localhost" + this.fullPath; - } -}; -}); - -// file: lib/ios/plugin/ios/FileReader.js -define("cordova/plugin/ios/FileReader", function(require, exports, module) { -var exec = require('cordova/exec'), - FileError = require('cordova/plugin/FileError'), - FileReader = require('cordova/plugin/FileReader'), - ProgressEvent = require('cordova/plugin/ProgressEvent'); - -module.exports = { - readAsText:function(file, encoding) { - // Figure out pathing - this.fileName = ''; - if (typeof file.fullPath === 'undefined') { - this.fileName = file; - } else { - this.fileName = file.fullPath; - } - - // Already loading something - if (this.readyState == FileReader.LOADING) { - throw new FileError(FileError.INVALID_STATE_ERR); - } - - // LOADING state - this.readyState = FileReader.LOADING; - - // If loadstart callback - if (typeof this.onloadstart === "function") { - this.onloadstart(new ProgressEvent("loadstart", {target:this})); - } - - // Default encoding is UTF-8 - var enc = encoding ? encoding : "UTF-8"; - - var me = this; - - // Read file - exec( - // Success callback - function(r) { - // If DONE (cancelled), then don't do anything - if (me.readyState === FileReader.DONE) { - return; - } - - // Save result - me.result = decodeURIComponent(r); - - // If onload callback - if (typeof me.onload === "function") { - me.onload(new ProgressEvent("load", {target:me})); - } - - // DONE state - me.readyState = FileReader.DONE; - - // If onloadend callback - if (typeof me.onloadend === "function") { - me.onloadend(new ProgressEvent("loadend", {target:me})); - } - }, - // Error callback - function(e) { - // If DONE (cancelled), then don't do anything - if (me.readyState === FileReader.DONE) { - return; - } - - // DONE state - me.readyState = FileReader.DONE; - - // null result - me.result = null; - - // Save error - me.error = new FileError(e); - - // If onerror callback - if (typeof me.onerror === "function") { - me.onerror(new ProgressEvent("error", {target:me})); - } - - // If onloadend callback - if (typeof me.onloadend === "function") { - me.onloadend(new ProgressEvent("loadend", {target:me})); - } - }, - "File", "readAsText", [this.fileName, enc]); - } -}; -}); - -// file: lib/ios/plugin/ios/console.js -define("cordova/plugin/ios/console", function(require, exports, module) { -var exec = require('cordova/exec'); - -/** - * This class provides access to the debugging console. - * @constructor - */ -var DebugConsole = function() { - this.winConsole = window.console; - this.logLevel = DebugConsole.INFO_LEVEL; -}; - -// from most verbose, to least verbose -DebugConsole.ALL_LEVEL = 1; // same as first level -DebugConsole.INFO_LEVEL = 1; -DebugConsole.WARN_LEVEL = 2; -DebugConsole.ERROR_LEVEL = 4; -DebugConsole.NONE_LEVEL = 8; - -DebugConsole.prototype.setLevel = function(level) { - this.logLevel = level; -}; - -var stringify = function(message) { - try { - if (typeof message === "object" && JSON && JSON.stringify) { - try { - return JSON.stringify(message); - } - catch (e) { - return "error JSON.stringify()ing argument: " + e; - } - } else { - return message.toString(); - } - } catch (e) { - return e.toString(); - } -}; - -/** - * Print a normal log message to the console - * @param {Object|String} message Message or object to print to the console - */ -DebugConsole.prototype.log = function(message) { - if (this.logLevel <= DebugConsole.INFO_LEVEL) { - exec(null, null, 'Debug Console', 'log', [ stringify(message), { logLevel: 'INFO' } ]); - } - else if (this.winConsole && this.winConsole.log) { - this.winConsole.log(message); - } -}; - -/** - * Print a warning message to the console - * @param {Object|String} message Message or object to print to the console - */ -DebugConsole.prototype.warn = function(message) { - if (this.logLevel <= DebugConsole.WARN_LEVEL) { - exec(null, null, 'Debug Console', 'log', [ stringify(message), { logLevel: 'WARN' } ]); - } - else if (this.winConsole && this.winConsole.warn) { - this.winConsole.warn(message); - } -}; - -/** - * Print an error message to the console - * @param {Object|String} message Message or object to print to the console - */ -DebugConsole.prototype.error = function(message) { - if (this.logLevel <= DebugConsole.ERROR_LEVEL) { - exec(null, null, 'Debug Console', 'log', [ stringify(message), { logLevel: 'ERROR' } ]); - } - else if (this.winConsole && this.winConsole.error){ - this.winConsole.error(message); - } -}; - -module.exports = new DebugConsole(); -}); - -// file: lib/ios/plugin/ios/contacts.js -define("cordova/plugin/ios/contacts", function(require, exports, module) { -var exec = require('cordova/exec'); - -/** - * Provides iOS enhanced contacts API. - */ -module.exports = { - newContactUI : function(successCallback) { - /* - * Create a contact using the iOS Contact Picker UI - * NOT part of W3C spec so no official documentation - * - * returns: the id of the created contact as param to successCallback - */ - exec(successCallback, null, "Contacts","newContact", []); - }, - chooseContact : function(successCallback, options) { - /* - * Select a contact using the iOS Contact Picker UI - * NOT part of W3C spec so no official documentation - * - * @param errorCB error callback - * @param options object - * allowsEditing: boolean AS STRING - * "true" to allow editing the contact - * "false" (default) display contact - * - * returns: the id of the selected contact as param to successCallback - */ - exec(successCallback, null, "Contacts","chooseContact", [options]); - } -}; -}); - -// file: lib/ios/plugin/ios/device.js -define("cordova/plugin/ios/device", function(require, exports, module) { -/** - * this represents the mobile device, and provides properties for inspecting the model, version, UUID of the - * phone, etc. - * @constructor - */ -var exec = require('cordova/exec'), - utils = require('cordova/utils'), - channel = require('cordova/channel'); - -var Device = function() { - this.platform = null; - this.version = null; - this.name = null; - this.cordova = null; - this.uuid = null; -}; - -Device.prototype.setInfo = function(info) { - try { - this.platform = info.platform; - this.version = info.version; - this.name = info.name; - this.cordova = info.cordova; - this.uuid = info.uuid; - channel.onCordovaInfoReady.fire(); - } catch(e) { - utils.alert('Error during device info setting in cordova/plugin/ios/device!'); - } -}; - -module.exports = new Device(); - -}); - -// file: lib/ios/plugin/ios/nativecomm.js -define("cordova/plugin/ios/nativecomm", function(require, exports, module) { -var cordova = require('cordova'); - -/** - * Called by native code to retrieve all queued commands and clear the queue. - */ -module.exports = function() { - var json = JSON.stringify(cordova.commandQueue); - cordova.commandQueue = []; - return json; -}; -}); - -// file: lib/ios/plugin/ios/notification.js -define("cordova/plugin/ios/notification", function(require, exports, module) { -var Media = require('cordova/plugin/Media'); - -module.exports = { - beep:function(count) { - (new Media('beep.wav')).play(); - } -}; -}); - -// file: lib/common/plugin/logger.js -define("cordova/plugin/logger", function(require, exports, module) { -//------------------------------------------------------------------------------ -// The logger module exports the following properties/functions: -// -// LOG - constant for the level LOG -// ERROR - constant for the level ERROR -// WARN - constant for the level WARN -// INFO - constant for the level INFO -// DEBUG - constant for the level DEBUG -// logLevel() - returns current log level -// logLevel(value) - sets and returns a new log level -// useConsole() - returns whether logger is using console -// useConsole(value) - sets and returns whether logger is using console -// log(message,...) - logs a message at level LOG -// error(message,...) - logs a message at level ERROR -// warn(message,...) - logs a message at level WARN -// info(message,...) - logs a message at level INFO -// debug(message,...) - logs a message at level DEBUG -// logLevel(level,message,...) - logs a message specified level -// -//------------------------------------------------------------------------------ - -var logger = exports; - -var exec = require('cordova/exec'); -var utils = require('cordova/utils'); - -var UseConsole = true; -var Queued = []; -var DeviceReady = false; -var CurrentLevel; - -/** - * Logging levels - */ - -var Levels = [ - "LOG", - "ERROR", - "WARN", - "INFO", - "DEBUG" -]; - -/* - * add the logging levels to the logger object and - * to a separate levelsMap object for testing - */ - -var LevelsMap = {}; -for (var i=0; i<Levels.length; i++) { - var level = Levels[i]; - LevelsMap[level] = i; - logger[level] = level; -} - -CurrentLevel = LevelsMap.WARN; - -/** - * Getter/Setter for the logging level - * - * Returns the current logging level. - * - * When a value is passed, sets the logging level to that value. - * The values should be one of the following constants: - * logger.LOG - * logger.ERROR - * logger.WARN - * logger.INFO - * logger.DEBUG - * - * The value used determines which messages get printed. The logging - * values above are in order, and only messages logged at the logging - * level or above will actually be displayed to the user. Eg, the - * default level is WARN, so only messages logged with LOG, ERROR, or - * WARN will be displayed; INFO and DEBUG messages will be ignored. - */ -logger.level = function (value) { - if (arguments.length) { - if (LevelsMap[value] === null) { - throw new Error("invalid logging level: " + value); - } - CurrentLevel = LevelsMap[value]; - } - - return Levels[CurrentLevel]; -}; - -/** - * Getter/Setter for the useConsole functionality - * - * When useConsole is true, the logger will log via the - * browser 'console' object. Otherwise, it will use the - * native Logger plugin. - */ -logger.useConsole = function (value) { - if (arguments.length) UseConsole = !!value; - - if (UseConsole) { - if (typeof console == "undefined") { - throw new Error("global console object is not defined"); - } - - if (typeof console.log != "function") { - throw new Error("global console object does not have a log function"); - } - - if (typeof console.useLogger == "function") { - if (console.useLogger()) { - throw new Error("console and logger are too intertwingly"); - } - } - } - - return UseConsole; -}; - -/** - * Logs a message at the LOG level. - * - * Parameters passed after message are used applied to - * the message with utils.format() - */ -logger.log = function(message) { logWithArgs("LOG", arguments); }; - -/** - * Logs a message at the ERROR level. - * - * Parameters passed after message are used applied to - * the message with utils.format() - */ -logger.error = function(message) { logWithArgs("ERROR", arguments); }; - -/** - * Logs a message at the WARN level. - * - * Parameters passed after message are used applied to - * the message with utils.format() - */ -logger.warn = function(message) { logWithArgs("WARN", arguments); }; - -/** - * Logs a message at the INFO level. - * - * Parameters passed after message are used applied to - * the message with utils.format() - */ -logger.info = function(message) { logWithArgs("INFO", arguments); }; - -/** - * Logs a message at the DEBUG level. - * - * Parameters passed after message are used applied to - * the message with utils.format() - */ -logger.debug = function(message) { logWithArgs("DEBUG", arguments); }; - -// log at the specified level with args -function logWithArgs(level, args) { - args = [level].concat([].slice.call(args)); - logger.logLevel.apply(logger, args); -} - -/** - * Logs a message at the specified level. - * - * Parameters passed after message are used applied to - * the message with utils.format() - */ -logger.logLevel = function(level, message /* , ... */) { - // format the message with the parameters - var formatArgs = [].slice.call(arguments, 2); - message = utils.vformat(message, formatArgs); - - if (LevelsMap[level] === null) { - throw new Error("invalid logging level: " + level); - } - - if (LevelsMap[level] > CurrentLevel) return; - - // queue the message if not yet at deviceready - if (!DeviceReady && !UseConsole) { - Queued.push([level, message]); - return; - } - - // if not using the console, use the native logger - if (!UseConsole) { - exec(null, null, "Logger", "logLevel", [level, message]); - return; - } - - // make sure console is not using logger - if (console.__usingCordovaLogger) { - throw new Error("console and logger are too intertwingly"); - } - - // log to the console - switch (level) { - case logger.LOG: console.log(message); break; - case logger.ERROR: console.log("ERROR: " + message); break; - case logger.WARN: console.log("WARN: " + message); break; - case logger.INFO: console.log("INFO: " + message); break; - case logger.DEBUG: console.log("DEBUG: " + message); break; - } -}; - -// when deviceready fires, log queued messages -logger.__onDeviceReady = function() { - if (DeviceReady) return; - - DeviceReady = true; - - for (var i=0; i<Queued.length; i++) { - var messageArgs = Queued[i]; - logger.logLevel(messageArgs[0], messageArgs[1]); - } - - Queued = null; -}; - -// add a deviceready event to log queued messages -document.addEventListener("deviceready", logger.__onDeviceReady, false); - -}); - -// file: lib/common/plugin/network.js -define("cordova/plugin/network", function(require, exports, module) { -var exec = require('cordova/exec'), - cordova = require('cordova'), - channel = require('cordova/channel'); - -var NetworkConnection = function () { - this.type = null; - this._firstRun = true; - this._timer = null; - this.timeout = 500; - - var me = this; - - channel.onCordovaReady.subscribeOnce(function() { - me.getInfo(function (info) { - me.type = info; - if (info === "none") { - // set a timer if still offline at the end of timer send the offline event - me._timer = setTimeout(function(){ - cordova.fireDocumentEvent("offline"); - me._timer = null; - }, me.timeout); - } else { - // If there is a current offline event pending clear it - if (me._timer !== null) { - clearTimeout(me._timer); - me._timer = null; - } - cordova.fireDocumentEvent("online"); - } - - // should only fire this once - if (me._firstRun) { - me._firstRun = false; - channel.onCordovaConnectionReady.fire(); - } - }, - function (e) { - // If we can't get the network info we should still tell Cordova - // to fire the deviceready event. - if (me._firstRun) { - me._firstRun = false; - channel.onCordovaConnectionReady.fire(); - } - console.log("Error initializing Network Connection: " + e); - }); - }); -}; - -/** - * Get connection info - * - * @param {Function} successCallback The function to call when the Connection data is available - * @param {Function} errorCallback The function to call when there is an error getting the Connection data. (OPTIONAL) - */ -NetworkConnection.prototype.getInfo = function (successCallback, errorCallback) { - // Get info - exec(successCallback, errorCallback, "NetworkStatus", "getConnectionInfo", []); -}; - -module.exports = new NetworkConnection(); -}); - -// file: lib/common/plugin/notification.js -define("cordova/plugin/notification", function(require, exports, module) { -var exec = require('cordova/exec'); - -/** - * Provides access to notifications on the device. - */ - -module.exports = { - - /** - * Open a native alert dialog, with a customizable title and button text. - * - * @param {String} message Message to print in the body of the alert - * @param {Function} completeCallback The callback that is called when user clicks on a button. - * @param {String} title Title of the alert dialog (default: Alert) - * @param {String} buttonLabel Label of the close button (default: OK) - */ - alert: function(message, completeCallback, title, buttonLabel) { - var _title = (title || "Alert"); - var _buttonLabel = (buttonLabel || "OK"); - exec(completeCallback, null, "Notification", "alert", [message, _title, _buttonLabel]); - }, - - /** - * Open a native confirm dialog, with a customizable title and button text. - * The result that the user selects is returned to the result callback. - * - * @param {String} message Message to print in the body of the alert - * @param {Function} resultCallback The callback that is called when user clicks on a button. - * @param {String} title Title of the alert dialog (default: Confirm) - * @param {String} buttonLabels Comma separated list of the labels of the buttons (default: 'OK,Cancel') - */ - confirm: function(message, resultCallback, title, buttonLabels) { - var _title = (title || "Confirm"); - var _buttonLabels = (buttonLabels || "OK,Cancel"); - exec(resultCallback, null, "Notification", "confirm", [message, _title, _buttonLabels]); - }, - - /** - * Causes the device to vibrate. - * - * @param {Integer} mills The number of milliseconds to vibrate for. - */ - vibrate: function(mills) { - exec(null, null, "Notification", "vibrate", [mills]); - }, - - /** - * Causes the device to beep. - * On Android, the default notification ringtone is played "count" times. - * - * @param {Integer} count The number of beeps. - */ - beep: function(count) { - exec(null, null, "Notification", "beep", [count]); - } -}; -}); - -// file: lib/common/plugin/requestFileSystem.js -define("cordova/plugin/requestFileSystem", function(require, exports, module) { -var FileError = require('cordova/plugin/FileError'), - FileSystem = require('cordova/plugin/FileSystem'), - exec = require('cordova/exec'); - -/** - * Request a file system in which to store application data. - * @param type local file system type - * @param size indicates how much storage space, in bytes, the application expects to need - * @param successCallback invoked with a FileSystem object - * @param errorCallback invoked if error occurs retrieving file system - */ -var requestFileSystem = function(type, size, successCallback, errorCallback) { - var fail = function(code) { - if (typeof errorCallback === 'function') { - errorCallback(new FileError(code)); - } - }; - - if (type < 0 || type > 3) { - fail(FileError.SYNTAX_ERR); - } else { - // if successful, return a FileSystem object - var success = function(file_system) { - if (file_system) { - if (typeof successCallback === 'function') { - // grab the name and root from the file system object - var result = new FileSystem(file_system.name, file_system.root); - successCallback(result); - } - } - else { - // no FileSystem object returned - fail(FileError.NOT_FOUND_ERR); - } - }; - exec(success, fail, "File", "requestFileSystem", [type, size]); - } -}; - -module.exports = requestFileSystem; -}); - -// file: lib/common/plugin/resolveLocalFileSystemURI.js -define("cordova/plugin/resolveLocalFileSystemURI", function(require, exports, module) { -var DirectoryEntry = require('cordova/plugin/DirectoryEntry'), - FileEntry = require('cordova/plugin/FileEntry'), - FileError = require('cordova/plugin/FileError'), - exec = require('cordova/exec'); - -/** - * Look up file system Entry referred to by local URI. - * @param {DOMString} uri URI referring to a local file or directory - * @param successCallback invoked with Entry object corresponding to URI - * @param errorCallback invoked if error occurs retrieving file system entry - */ -module.exports = function(uri, successCallback, errorCallback) { - // error callback - var fail = function(error) { - if (typeof errorCallback === 'function') { - errorCallback(new FileError(error)); - } - }; - // sanity check for 'not:valid:filename' - if(!uri || uri.split(":").length > 2) { - setTimeout( function() { - fail(FileError.ENCODING_ERR); - },0); - return; - } - // if successful, return either a file or directory entry - var success = function(entry) { - var result; - if (entry) { - if (typeof successCallback === 'function') { - // create appropriate Entry object - result = (entry.isDirectory) ? new DirectoryEntry(entry.name, entry.fullPath) : new FileEntry(entry.name, entry.fullPath); - try { - successCallback(result); - } - catch (e) { - console.log('Error invoking callback: ' + e); - } - } - } - else { - // no Entry object returned - fail(FileError.NOT_FOUND_ERR); - } - }; - - exec(success, fail, "File", "resolveLocalFileSystemURI", [uri]); -}; - -}); - -// file: lib/common/plugin/splashscreen.js -define("cordova/plugin/splashscreen", function(require, exports, module) { -var exec = require('cordova/exec'); - -var splashscreen = { - hide:function() { - exec(null, null, "SplashScreen", "hide", []); - } -}; - -module.exports = splashscreen; -}); - -// file: lib/common/utils.js -define("cordova/utils", function(require, exports, module) { -var utils = exports; - -/** - * Returns an indication of whether the argument is an array or not - */ -utils.isArray = function(a) { - return Object.prototype.toString.call(a) == '[object Array]'; -}; - -/** - * Returns an indication of whether the argument is a Date or not - */ -utils.isDate = function(d) { - return Object.prototype.toString.call(d) == '[object Date]'; -}; - -/** - * Does a deep clone of the object. - */ -utils.clone = function(obj) { - if(!obj || typeof obj == 'function' || utils.isDate(obj) || typeof obj != 'object') { - return obj; - } - - var retVal, i; - - if(utils.isArray(obj)){ - retVal = []; - for(i = 0; i < obj.length; ++i){ - retVal.push(utils.clone(obj[i])); - } - return retVal; - } - - retVal = {}; - for(i in obj){ - if(!(i in retVal) || retVal[i] != obj[i]) { - retVal[i] = utils.clone(obj[i]); - } - } - return retVal; -}; - -/** - * Returns a wrappered version of the function - */ -utils.close = function(context, func, params) { - if (typeof params == 'undefined') { - return function() { - return func.apply(context, arguments); - }; - } else { - return function() { - return func.apply(context, params); - }; - } -}; - -/** - * Create a UUID - */ -utils.createUUID = function() { - return UUIDcreatePart(4) + '-' + - UUIDcreatePart(2) + '-' + - UUIDcreatePart(2) + '-' + - UUIDcreatePart(2) + '-' + - UUIDcreatePart(6); -}; - -/** - * Extends a child object from a parent object using classical inheritance - * pattern. - */ -utils.extend = (function() { - // proxy used to establish prototype chain - var F = function() {}; - // extend Child from Parent - return function(Child, Parent) { - F.prototype = Parent.prototype; - Child.prototype = new F(); - Child.__super__ = Parent.prototype; - Child.prototype.constructor = Child; - }; -}()); - -/** - * Alerts a message in any available way: alert or console.log. - */ -utils.alert = function(msg) { - if (alert) { - alert(msg); - } else if (console && console.log) { - console.log(msg); - } -}; - -/** - * Formats a string and arguments following it ala sprintf() - * - * see utils.vformat() for more information - */ -utils.format = function(formatString /* ,... */) { - var args = [].slice.call(arguments, 1); - return utils.vformat(formatString, args); -}; - -/** - * Formats a string and arguments following it ala vsprintf() - * - * format chars: - * %j - format arg as JSON - * %o - format arg as JSON - * %c - format arg as '' - * %% - replace with '%' - * any other char following % will format it's - * arg via toString(). - * - * for rationale, see FireBug's Console API: - * http://getfirebug.com/wiki/index.php/Console_API - */ -utils.vformat = function(formatString, args) { - if (formatString === null || formatString === undefined) return ""; - if (arguments.length == 1) return formatString.toString(); - if (typeof formatString != "string") return formatString.toString(); - - var pattern = /(.*?)%(.)(.*)/; - var rest = formatString; - var result = []; - - while (args.length) { - var arg = args.shift(); - var match = pattern.exec(rest); - - if (!match) break; - - rest = match[3]; - - result.push(match[1]); - - if (match[2] == '%') { - result.push('%'); - args.unshift(arg); - continue; - } - - result.push(formatted(arg, match[2])); - } - - result.push(rest); - - return result.join(''); -}; - -//------------------------------------------------------------------------------ -function UUIDcreatePart(length) { - var uuidpart = ""; - for (var i=0; i<length; i++) { - var uuidchar = parseInt((Math.random() * 256), 10).toString(16); - if (uuidchar.length == 1) { - uuidchar = "0" + uuidchar; - } - uuidpart += uuidchar; - } - return uuidpart; -} - -//------------------------------------------------------------------------------ -function formatted(object, formatChar) { - - try { - switch(formatChar) { - case 'j': - case 'o': return JSON.stringify(object); - case 'c': return ''; - } - } - catch (e) { - return "error JSON.stringify()ing argument: " + e; - } - - if ((object === null) || (object === undefined)) { - return Object.prototype.toString.call(object); - } - - return object.toString(); -} - -}); - - -window.cordova = require('cordova'); - -// file: lib/scripts/bootstrap.js -(function (context) { - var channel = require("cordova/channel"), - _self = { - boot: function () { - /** - * Create all cordova objects once page has fully loaded and native side is ready. - */ - channel.join(function() { - var builder = require('cordova/builder'), - base = require('cordova/common'), - platform = require('cordova/platform'); - - // Drop the common globals into the window object, but be nice and don't overwrite anything. - builder.build(base.objects).intoButDontClobber(window); - - // Drop the platform-specific globals into the window object - // and clobber any existing object. - builder.build(platform.objects).intoAndClobber(window); - - // Merge the platform-specific overrides/enhancements into - // the window object. - if (typeof platform.merges !== 'undefined') { - builder.build(platform.merges).intoAndMerge(window); - } - - // Call the platform-specific initialization - platform.initialize(); - - // Fire event to notify that all objects are created - channel.onCordovaReady.fire(); - - // Fire onDeviceReady event once all constructors have run and - // cordova info has been received from native side. - channel.join(function() { - require('cordova').fireDocumentEvent('deviceready'); - }, channel.deviceReadyChannelsArray); - - }, [ channel.onDOMContentLoaded, channel.onNativeReady ]); - } - }; - - // boot up once native side is ready - channel.onNativeReady.subscribeOnce(_self.boot); - - // _nativeReady is global variable that the native side can set - // to signify that the native code is ready. It is a global since - // it may be called before any cordova JS is ready. - if (window._nativeReady) { - channel.onNativeReady.fire(); - } - -}(window)); - - -})();
\ No newline at end of file diff --git a/phonegap/android_cordova.js b/phonegap/www/cordova-android-2.1.0.js index 3e59432ed..9e7fa8ec2 100755 --- a/phonegap/android_cordova.js +++ b/phonegap/www/cordova-android-2.1.0.js @@ -1,6 +1,6 @@ -// commit ac0a3990438f4a89faa993316fb5614f61cf3be6 +// commit 143f5221a6251c9cbccdedc57005c61551b97f12 -// File generated at :: Tue Jun 05 2012 14:14:16 GMT-0700 (PDT) +// File generated at :: Wed Sep 12 2012 12:51:58 GMT-0700 (PDT) /* Licensed to the Apache Software Foundation (ASF) under one @@ -186,11 +186,19 @@ var cordova = { }, /** * Method to fire event from native code + * bNoDetach is required for events which cause an exception which needs to be caught in native code */ - fireDocumentEvent: function(type, data) { + fireDocumentEvent: function(type, data, bNoDetach) { var evt = createEvent(type, data); if (typeof documentEventHandlers[type] != 'undefined') { - documentEventHandlers[type].fire(evt); + if( bNoDetach ) { + documentEventHandlers[type].fire(evt); + } + else { + setTimeout(function() { + documentEventHandlers[type].fire(evt); + }, 0); + } } else { document.dispatchEvent(evt); } @@ -198,15 +206,13 @@ var cordova = { fireWindowEvent: function(type, data) { var evt = createEvent(type,data); if (typeof windowEventHandlers[type] != 'undefined') { - windowEventHandlers[type].fire(evt); + setTimeout(function() { + windowEventHandlers[type].fire(evt); + }, 0); } else { window.dispatchEvent(evt); } }, - // TODO: this is Android only; think about how to do this better - shuttingDown:false, - UsePolling:false, - // END TODO // TODO: iOS only // This queue holds the currently executing command and all pending @@ -285,17 +291,6 @@ var cordova = { } } }, - // TODO: remove in 2.0. - addPlugin: function(name, obj) { - console.log("[DEPRECATION NOTICE] window.addPlugin and window.plugins will be removed in version 2.0."); - if (!window.plugins[name]) { - window.plugins[name] = obj; - } - else { - console.log("Error: Plugin "+name+" already exists."); - } - }, - addConstructor: function(func) { channel.onCordovaReady.subscribeOnce(function() { try { @@ -312,51 +307,6 @@ channel.onPause = cordova.addDocumentEventHandler('pause'); channel.onResume = cordova.addDocumentEventHandler('resume'); channel.onDeviceReady = cordova.addDocumentEventHandler('deviceready'); -// Adds deprecation warnings to functions of an object (but only logs a message once) -function deprecateFunctions(obj, objLabel) { - var newObj = {}; - var logHash = {}; - for (var i in obj) { - if (obj.hasOwnProperty(i)) { - if (typeof obj[i] == 'function') { - newObj[i] = (function(prop){ - var oldFunk = obj[prop]; - var funkId = objLabel + '_' + prop; - return function() { - if (!logHash[funkId]) { - console.log('[DEPRECATION NOTICE] The "' + objLabel + '" global will be removed in version 2.0, please use lowercase "cordova".'); - logHash[funkId] = true; - } - oldFunk.apply(obj, arguments); - }; - })(i); - } else { - newObj[i] = (function(prop) { return obj[prop]; })(i); - } - } - } - return newObj; -} - -/** - * Legacy variable for plugin support - * TODO: remove in 2.0. - */ -if (!window.PhoneGap) { - window.PhoneGap = deprecateFunctions(cordova, 'PhoneGap'); -} -if (!window.Cordova) { - window.Cordova = deprecateFunctions(cordova, 'Cordova'); -} - -/** - * Plugins object - * TODO: remove in 2.0. - */ -if (!window.plugins) { - window.plugins = {}; -} - module.exports = cordova; }); @@ -456,7 +406,8 @@ module.exports = { // file: lib/common/channel.js define("cordova/channel", function(require, exports, module) { -var utils = require('cordova/utils'); +var utils = require('cordova/utils'), + nextGuid = 1; /** * Custom pub-sub "channel" that can have functions subscribed to it @@ -508,7 +459,6 @@ var Channel = function(type, opts) { this.type = type; this.handlers = {}; this.numHandlers = 0; - this.guid = 1; this.fired = false; this.enabled = true; this.events = { @@ -601,19 +551,19 @@ Channel.prototype.subscribe = function(f, c, g) { g = g || func.observer_guid || f.observer_guid; if (!g) { - // first time we've seen this subscriber - g = this.guid++; - } - else { - // subscriber already handled; dont set it twice - return g; + // first time any channel has seen this subscriber + g = nextGuid++; } func.observer_guid = g; f.observer_guid = g; - this.handlers[g] = func; - this.numHandlers++; - if (this.events.onSubscribe) this.events.onSubscribe.call(this); - if (this.fired) func.call(this); + + // Don't add the same handler more than once. + if (!this.handlers[g]) { + this.handlers[g] = func; + this.numHandlers++; + if (this.events.onSubscribe) this.events.onSubscribe.call(this); + if (this.fired) func.apply(this, this.fireArgs); + } return g; }; @@ -627,15 +577,14 @@ Channel.prototype.subscribeOnce = function(f, c) { var g = null; var _this = this; - var m = function() { - f.apply(c || null, arguments); - _this.unsubscribe(g); - }; if (this.fired) { - if (typeof c == "object") { f = utils.close(c, f); } - f.apply(this, this.fireArgs); + f.apply(c || null, this.fireArgs); } else { - g = this.subscribe(m); + g = this.subscribe(function() { + _this.unsubscribe(g); + f.apply(c || null, arguments); + }); + f.observer_guid = g; } return g; }; @@ -651,7 +600,6 @@ Channel.prototype.unsubscribe = function(g) { var handler = this.handlers[g]; if (handler) { if (handler.observer_guid) handler.observer_guid=null; - this.handlers[g] = null; delete this.handlers[g]; this.numHandlers--; if (this.events.onUnsubscribe) this.events.onUnsubscribe.call(this); @@ -665,14 +613,17 @@ Channel.prototype.fire = function(e) { if (this.enabled) { var fail = false; this.fired = true; + this.fireArgs = arguments; + // Copy the values first so that it is safe to modify it from within + // callbacks. + var toCall = []; for (var item in this.handlers) { - var handler = this.handlers[item]; - if (typeof handler == 'function') { - var rv = (handler.apply(this, arguments)===false); - fail = fail || rv; - } + toCall.push(this.handlers[item]); + } + for (var i = 0; i < toCall.length; ++i) { + var rv = (toCall[i].apply(this, arguments)===false); + fail = fail || rv; } - this.fireArgs = arguments; return !fail; } return true; @@ -709,7 +660,6 @@ channel.create('onDestroy'); // Channels that must fire before "deviceready" is fired. channel.waitForInitialization('onCordovaReady'); -channel.waitForInitialization('onCordovaInfoReady'); channel.waitForInitialization('onCordovaConnectionReady'); module.exports = channel; @@ -738,13 +688,6 @@ module.exports = { } } }, - PhoneGap:{ - children: { - exec: { - path: 'cordova/exec' - } - } - }, navigator: { children: { notification: { @@ -844,6 +787,9 @@ module.exports = { Coordinates: { path: 'cordova/plugin/Coordinates' }, + device: { + path: 'cordova/plugin/device' + }, DirectoryEntry: { path: 'cordova/plugin/DirectoryEntry' }, @@ -940,76 +886,170 @@ define("cordova/exec", function(require, exports, module) { * @param {String} action Action to be run in cordova * @param {String[]} [args] Zero or more arguments to pass to the method */ -var cordova = require('cordova'); +var cordova = require('cordova'), + callback = require('cordova/plugin/android/callback'), + polling = require('cordova/plugin/android/polling'), + jsToNativeBridgeMode, + nativeToJsBridgeMode, + jsToNativeModes = { + PROMPT: 0, + JS_OBJECT: 1, + // This mode is currently for benchmarking purposes only. It must be enabled + // on the native side through the ENABLE_LOCATION_CHANGE_EXEC_MODE + // constant within CordovaWebViewClient.java before it will work. + LOCATION_CHANGE: 2 + }, + nativeToJsModes = { + // Polls for messages using the prompt() bridge. + POLLING: 0, + // Does an XHR to a local server, which will send back messages. This is + // broken on ICS when a proxy server is configured. + HANGING_GET: 1, + // For LOAD_URL to be viable, it would need to have a work-around for + // the bug where the soft-keyboard gets dismissed when a message is sent. + LOAD_URL: 2, + // For the ONLINE_EVENT to be viable, it would need to intercept all event + // listeners (both through addEventListener and window.ononline) as well + // as set the navigator property itself. + ONLINE_EVENT: 3, + // Uses reflection to access private APIs of the WebView that can send JS + // to be executed. + // Requires Android 3.2.4 or above. + PRIVATE_API: 4 + }; -module.exports = function(success, fail, service, action, args) { - try { - var callbackId = service + cordova.callbackId++; - if (success || fail) { - cordova.callbacks[callbackId] = {success:success, fail:fail}; +function androidExec(success, fail, service, action, args) { + // Set default bridge modes if they have not already been set. + if (jsToNativeBridgeMode === undefined) { + androidExec.setJsToNativeBridgeMode(jsToNativeModes.PROMPT); + } + if (nativeToJsBridgeMode === undefined) { + if (callback.isAvailable()) { + androidExec.setNativeToJsBridgeMode(nativeToJsModes.HANGING_GET); + } else { + androidExec.setNativeToJsBridgeMode(nativeToJsModes.POLLING); + } } + try { + var callbackId = service + cordova.callbackId++, + argsJson = JSON.stringify(args), + result; + if (success || fail) { + cordova.callbacks[callbackId] = {success:success, fail:fail}; + } - var r = prompt(JSON.stringify(args), "gap:"+JSON.stringify([service, action, callbackId, true])); + if (jsToNativeBridgeMode == jsToNativeModes.LOCATION_CHANGE) { + window.location = 'http://cdv_exec/' + service + '#' + action + '#' + callbackId + '#' + argsJson; + } else if (jsToNativeBridgeMode == jsToNativeModes.JS_OBJECT) { + // Explicit cast to string is required on Android 2.1 to convert from + // a Java string to a JS string. + result = '' + _cordovaExec.exec(service, action, callbackId, argsJson); + } else { + result = prompt(argsJson, "gap:"+JSON.stringify([service, action, callbackId, true])); + } - // If a result was returned - if (r.length > 0) { - var v; - eval("v="+r+";"); + // If a result was returned + if (result) { + var v = JSON.parse(result); + + // If status is OK, then return value back to caller + if (v.status === cordova.callbackStatus.OK) { + + // If there is a success callback, then call it now with + // returned value + if (success) { + try { + success(v.message); + } catch (e) { + console.log("Error in success callback: " + callbackId + " = " + e); + } - // If status is OK, then return value back to caller - if (v.status === cordova.callbackStatus.OK) { + // Clear callback if not expecting any more results + if (!v.keepCallback) { + delete cordova.callbacks[callbackId]; + } + } + return v.message; + } - // If there is a success callback, then call it now with - // returned value - if (success) { - try { - success(v.message); - } catch (e) { - console.log("Error in success callback: " + callbackId + " = " + e); - } + // If no result + else if (v.status === cordova.callbackStatus.NO_RESULT) { + // Clear callback if not expecting any more results + if (!v.keepCallback) { + delete cordova.callbacks[callbackId]; + } + } - // Clear callback if not expecting any more results - if (!v.keepCallback) { - delete cordova.callbacks[callbackId]; - } - } - return v.message; - } + // If error, then display error + else { + console.log("Error: Status="+v.status+" Message="+v.message); - // If no result - else if (v.status === cordova.callbackStatus.NO_RESULT) { - // Clear callback if not expecting any more results - if (!v.keepCallback) { - delete cordova.callbacks[callbackId]; - } - } + // If there is a fail callback, then call it now with returned value + if (fail) { + try { + fail(v.message); + } + catch (e1) { + console.log("Error in error callback: "+callbackId+" = "+e1); + } - // If error, then display error - else { - console.log("Error: Status="+v.status+" Message="+v.message); + // Clear callback if not expecting any more results + if (!v.keepCallback) { + delete cordova.callbacks[callbackId]; + } + } + return null; + } + } + } catch (e2) { + console.log("Error: "+e2); + } +} - // If there is a fail callback, then call it now with returned value - if (fail) { - try { - fail(v.message); - } - catch (e1) { - console.log("Error in error callback: "+callbackId+" = "+e1); - } +function onOnLineEvent(e) { + while (polling.pollOnce()); +} - // Clear callback if not expecting any more results - if (!v.keepCallback) { - delete cordova.callbacks[callbackId]; - } - } - return null; - } +androidExec.jsToNativeModes = jsToNativeModes; +androidExec.nativeToJsModes = nativeToJsModes; + +androidExec.setJsToNativeBridgeMode = function(mode) { + if (mode == jsToNativeModes.JS_OBJECT && !window._cordovaExec) { + console.log('Falling back on PROMPT mode since _cordovaExec is missing.'); + mode = jsToNativeModes.PROMPT; } - } catch (e2) { - console.log("Error: "+e2); - } + jsToNativeBridgeMode = mode; }; +androidExec.setNativeToJsBridgeMode = function(mode) { + if (mode == nativeToJsBridgeMode) { + return; + } + if (nativeToJsBridgeMode == nativeToJsModes.POLLING) { + polling.stop(); + } else if (nativeToJsBridgeMode == nativeToJsModes.HANGING_GET) { + callback.stop(); + } else if (nativeToJsBridgeMode == nativeToJsModes.ONLINE_EVENT) { + window.removeEventListener('online', onOnLineEvent, false); + window.removeEventListener('offline', onOnLineEvent, false); + } + + nativeToJsBridgeMode = mode; + // Tell the native side to switch modes. + prompt(mode, "gap_bridge_mode:"); + + if (mode == nativeToJsModes.POLLING) { + polling.start(); + } else if (mode == nativeToJsModes.HANGING_GET) { + callback.start(); + } else if (mode == nativeToJsModes.ONLINE_EVENT) { + window.addEventListener('online', onOnLineEvent, false); + window.addEventListener('offline', onOnLineEvent, false); + } +}; + +module.exports = androidExec; + }); // file: lib/android/platform.js @@ -1019,34 +1059,8 @@ module.exports = { initialize:function() { var channel = require("cordova/channel"), cordova = require('cordova'), - callback = require('cordova/plugin/android/callback'), - polling = require('cordova/plugin/android/polling'), exec = require('cordova/exec'); - channel.onDestroy.subscribe(function() { - cordova.shuttingDown = true; - }); - - // Start listening for XHR callbacks - // Figure out which bridge approach will work on this Android - // device: polling or XHR-based callbacks - setTimeout(function() { - if (cordova.UsePolling) { - polling(); - } - else { - var isPolling = prompt("usePolling", "gap_callbackServer:"); - cordova.UsePolling = isPolling; - if (isPolling == "true") { - cordova.UsePolling = true; - polling(); - } else { - cordova.UsePolling = false; - callback(); - } - } - }, 1); - // Inject a listener for the backbutton on the document. var backButtonChannel = cordova.addDocumentEventHandler('backbutton', { onSubscribe:function() { @@ -1111,7 +1125,7 @@ module.exports = { // Let native code know we are all done on the JS side. // Native code will then un-hide the WebView. channel.join(function() { - prompt("", "gap_init:"); + exec(null, null, "App", "show", []); }, [channel.onCordovaReady]); }, objects: { @@ -1132,9 +1146,6 @@ module.exports = { } } }, - device:{ - path: "cordova/plugin/android/device" - }, File: { // exists natively on Android WebView, override path: "cordova/plugin/File" }, @@ -1149,6 +1160,9 @@ module.exports = { } }, merges: { + device: { + path: 'cordova/plugin/android/device' + }, navigator: { children: { notification: { @@ -1281,7 +1295,14 @@ cameraExport.getPicture = function(successCallback, errorCallback, options) { popoverOptions = options.popoverOptions; } - exec(successCallback, errorCallback, "Camera", "takePicture", [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType, mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions]); + var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType, + mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions]; + + exec(successCallback, errorCallback, "Camera", "takePicture", args); +}; + +cameraExport.cleanup = function(successCallback, errorCallback) { + exec(successCallback, errorCallback, "Camera", "cleanup", []); }; module.exports = cameraExport; @@ -1866,7 +1887,7 @@ var utils = require('cordova/utils'), * {boolean} isDirectory always true (readonly) * {DOMString} name of the directory, excluding the path leading to it (readonly) * {DOMString} fullPath the absolute full path to the directory (readonly) - * {FileSystem} filesystem on which the directory resides (readonly) + * TODO: implement this!!! {FileSystem} filesystem on which the directory resides (readonly) */ var DirectoryEntry = function(name, fullPath) { DirectoryEntry.__super__.constructor.apply(this, [false, true, name, fullPath]); @@ -2596,11 +2617,13 @@ var FileSystem = function(name, root) { }; module.exports = FileSystem; + }); // file: lib/common/plugin/FileTransfer.js define("cordova/plugin/FileTransfer", function(require, exports, module) { -var exec = require('cordova/exec'); +var exec = require('cordova/exec'), + FileTransferError = require('cordova/plugin/FileTransferError'); /** * FileTransfer uploads a file to a remote server. @@ -2619,16 +2642,20 @@ var FileTransfer = function() {}; * @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false */ FileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) { + // sanity parameter checking + if (!filePath || !server) throw new Error("FileTransfer.upload requires filePath and server URL parameters at the minimum."); // check for options var fileKey = null; var fileName = null; var mimeType = null; var params = null; var chunkedMode = true; + var headers = null; if (options) { fileKey = options.fileKey; fileName = options.fileName; mimeType = options.mimeType; + headers = options.headers; if (options.chunkedMode !== null || typeof options.chunkedMode != "undefined") { chunkedMode = options.chunkedMode; } @@ -2640,7 +2667,12 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro } } - exec(successCallback, errorCallback, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode]); + var fail = function(e) { + var error = new FileTransferError(e.code, e.source, e.target, e.http_status); + errorCallback(error); + }; + + exec(successCallback, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers]); }; /** @@ -2651,6 +2683,8 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro * @param errorCallback {Function} Callback to be invoked upon error */ FileTransfer.prototype.download = function(source, target, successCallback, errorCallback) { + // sanity parameter checking + if (!source || !target) throw new Error("FileTransfer.download requires source URI and target URI parameters at the minimum."); var win = function(result) { var entry = null; if (result.isDirectory) { @@ -2665,6 +2699,12 @@ FileTransfer.prototype.download = function(source, target, successCallback, erro entry.fullPath = result.fullPath; successCallback(entry); }; + + var fail = function(e) { + var error = new FileTransferError(e.code, e.source, e.target, e.http_status); + errorCallback(error); + }; + exec(win, errorCallback, 'FileTransfer', 'download', [source, target]); }; @@ -2678,8 +2718,11 @@ define("cordova/plugin/FileTransferError", function(require, exports, module) { * FileTransferError * @constructor */ -var FileTransferError = function(code) { +var FileTransferError = function(code, source, target, status) { this.code = code || null; + this.source = source || null; + this.target = target || null; + this.http_status = status || null; }; FileTransferError.FILE_NOT_FOUND_ERR = 1; @@ -2687,6 +2730,7 @@ FileTransferError.INVALID_URL_ERR = 2; FileTransferError.CONNECTION_ERR = 3; module.exports = FileTransferError; + }); // file: lib/common/plugin/FileUploadOptions.js @@ -2698,15 +2742,19 @@ define("cordova/plugin/FileUploadOptions", function(require, exports, module) { * @param fileName {String} Filename to be used by the server. Defaults to image.jpg. * @param mimeType {String} Mimetype of the uploaded file. Defaults to image/jpeg. * @param params {Object} Object with key: value params to send to the server. + * @param headers {Object} Keys are header names, values are header values. Multiple + * headers of the same name are not supported. */ -var FileUploadOptions = function(fileKey, fileName, mimeType, params) { +var FileUploadOptions = function(fileKey, fileName, mimeType, params, headers) { this.fileKey = fileKey || null; this.fileName = fileName || null; this.mimeType = mimeType || null; this.params = params || null; + this.headers = headers || null; }; module.exports = FileUploadOptions; + }); // file: lib/common/plugin/FileUploadResult.js @@ -2894,7 +2942,7 @@ FileWriter.prototype.seek = function(offset) { if (offset < 0) { this.position = Math.max(offset + this.length, 0); } - // Offset is bigger then file size so set position + // Offset is bigger than file size so set position // to the end of the file. else if (offset > this.length) { this.position = this.length; @@ -3101,7 +3149,6 @@ Media.prototype.stop = function() { var me = this; exec(function() { me._position = 0; - me.successCallback(); }, this.errorCallback, "Media", "stopPlayingAudio", [this.id]); }; @@ -3147,14 +3194,14 @@ Media.prototype.getCurrentPosition = function(success, fail) { * Start recording audio file. */ Media.prototype.startRecord = function() { - exec(this.successCallback, this.errorCallback, "Media", "startRecordingAudio", [this.id, this.src]); + exec(null, this.errorCallback, "Media", "startRecordingAudio", [this.id, this.src]); }; /** * Stop recording audio file. */ Media.prototype.stopRecord = function() { - exec(this.successCallback, this.errorCallback, "Media", "stopRecordingAudio", [this.id]); + exec(null, this.errorCallback, "Media", "stopRecordingAudio", [this.id]); }; /** @@ -3176,34 +3223,39 @@ Media.prototype.setVolume = function(volume) { * PRIVATE * * @param id The media object id (string) - * @param status The status code (int) - * @param msg The status message (string) + * @param msgType The 'type' of update this is + * @param value Use of value is determined by the msgType */ -Media.onStatus = function(id, msg, value) { +Media.onStatus = function(id, msgType, value) { + var media = mediaObjects[id]; - // If state update - if (msg === Media.MEDIA_STATE) { - if (value === Media.MEDIA_STOPPED) { - if (media.successCallback) { - media.successCallback(); - } - } - if (media.statusCallback) { - media.statusCallback(value); - } - } - else if (msg === Media.MEDIA_DURATION) { - media._duration = value; - } - else if (msg === Media.MEDIA_ERROR) { - if (media.errorCallback) { - // value should be a MediaError object when msg == MEDIA_ERROR - media.errorCallback(value); + + if(media) { + switch(msgType) { + case Media.MEDIA_STATE : + media.statusCallback && media.statusCallback(value); + if(value == Media.MEDIA_STOPPED) { + media.successCallback && media.successCallback(); + } + break; + case Media.MEDIA_DURATION : + media._duration = value; + break; + case Media.MEDIA_ERROR : + media.errorCallback && media.errorCallback(value); + break; + case Media.MEDIA_POSITION : + media._position = Number(value); + break; + default : + console && console.error && console.error("Unhandled Media.onStatus :: " + msgType); + break; } } - else if (msg === Media.MEDIA_POSITION) { - media._position = value; + else { + console && console.error && console.error("Received Media.onStatus callback for unknown media :: " + id); } + }; module.exports = Media; @@ -3213,20 +3265,36 @@ module.exports = Media; define("cordova/plugin/MediaError", function(require, exports, module) { /** * This class contains information about any Media errors. - * @constructor +*/ +/* + According to :: http://dev.w3.org/html5/spec-author-view/video.html#mediaerror + We should never be creating these objects, we should just implement the interface + which has 1 property for an instance, 'code' + + instead of doing : + errorCallbackFunction( new MediaError(3,'msg') ); +we should simply use a literal : + errorCallbackFunction( {'code':3} ); */ -var MediaError = function(code, msg) { - this.code = (code !== undefined ? code : null); - this.message = msg || ""; -}; -MediaError.MEDIA_ERR_NONE_ACTIVE = 0; -MediaError.MEDIA_ERR_ABORTED = 1; -MediaError.MEDIA_ERR_NETWORK = 2; -MediaError.MEDIA_ERR_DECODE = 3; -MediaError.MEDIA_ERR_NONE_SUPPORTED = 4; +if(!MediaError) { + var MediaError = function(code, msg) { + this.code = (typeof code != 'undefined') ? code : null; + this.message = msg || ""; // message is NON-standard! do not use! + }; +} + +MediaError.MEDIA_ERR_NONE_ACTIVE = MediaError.MEDIA_ERR_NONE_ACTIVE || 0; +MediaError.MEDIA_ERR_ABORTED = MediaError.MEDIA_ERR_ABORTED || 1; +MediaError.MEDIA_ERR_NETWORK = MediaError.MEDIA_ERR_NETWORK || 2; +MediaError.MEDIA_ERR_DECODE = MediaError.MEDIA_ERR_DECODE || 3; +MediaError.MEDIA_ERR_NONE_SUPPORTED = MediaError.MEDIA_ERR_NONE_SUPPORTED || 4; +// TODO: MediaError.MEDIA_ERR_NONE_SUPPORTED is legacy, the W3 spec now defines it as below. +// as defined by http://dev.w3.org/html5/spec-author-view/video.html#error-codes +MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED || 4; module.exports = MediaError; + }); // file: lib/common/plugin/MediaFile.js @@ -3264,28 +3332,6 @@ MediaFile.prototype.getFormatData = function(successCallback, errorCallback) { } }; -// TODO: can we axe this? -/** - * Casts a PluginResult message property (array of objects) to an array of MediaFile objects - * (used in Objective-C and Android) - * - * @param {PluginResult} pluginResult - */ -MediaFile.cast = function(pluginResult) { - var mediaFiles = []; - for (var i=0; i<pluginResult.message.length; i++) { - var mediaFile = new MediaFile(); - mediaFile.name = pluginResult.message[i].name; - mediaFile.fullPath = pluginResult.message[i].fullPath; - mediaFile.type = pluginResult.message[i].type; - mediaFile.lastModifiedDate = pluginResult.message[i].lastModifiedDate; - mediaFile.size = pluginResult.message[i].size; - mediaFiles.push(mediaFile); - } - pluginResult.message = mediaFiles; - return pluginResult; -}; - module.exports = MediaFile; }); @@ -3491,12 +3537,12 @@ var accelerometer = { var p; var win = function(a) { - successCallback(a); removeListeners(p); + successCallback(a); }; var fail = function(e) { - errorCallback(e); removeListeners(p); + errorCallback(e); }; p = createCallbackPair(win, fail); @@ -3528,8 +3574,8 @@ var accelerometer = { var id = utils.createUUID(); var p = createCallbackPair(function(){}, function(e) { - errorCallback(e); removeListeners(p); + errorCallback(e); }); listeners.push(p); @@ -3544,7 +3590,10 @@ var accelerometer = { if (running) { // If we're already running then immediately invoke the success callback - successCallback(accel); + // but only if we have retrieved a value, sample code does not check for null ... + if(accel) { + successCallback(accel); + } } else { start(); } @@ -3650,186 +3699,126 @@ module.exports = { define("cordova/plugin/android/callback", function(require, exports, module) { var port = null, token = null, - cordova = require('cordova'), - polling = require('cordova/plugin/android/polling'), - callback = function() { - // Exit if shutting down app - if (cordova.shuttingDown) { - return; - } - - // If polling flag was changed, start using polling from now on - if (cordova.UsePolling) { - polling(); - return; - } + xmlhttp; - var xmlhttp = new XMLHttpRequest(); +function startXhr() { + // cordova/exec depends on this module, so we can't require cordova/exec on the module level. + var exec = require('cordova/exec'), + xmlhttp = new XMLHttpRequest(); - // Callback function when XMLHttpRequest is ready - xmlhttp.onreadystatechange=function(){ - if(xmlhttp.readyState === 4){ - - // Exit if shutting down app - if (cordova.shuttingDown) { - return; - } + // Callback function when XMLHttpRequest is ready + xmlhttp.onreadystatechange=function(){ + if (!xmlhttp) { + return; + } + if (xmlhttp.readyState === 4){ + // If callback has JavaScript statement to execute + if (xmlhttp.status === 200) { - // If callback has JavaScript statement to execute - if (xmlhttp.status === 200) { - - // Need to url decode the response - var msg = decodeURIComponent(xmlhttp.responseText); - setTimeout(function() { - try { - var t = eval(msg); - } - catch (e) { - // If we're getting an error here, seeing the message will help in debugging - console.log("JSCallback: Message from Server: " + msg); - console.log("JSCallback Error: "+e); - } - }, 1); - setTimeout(callback, 1); - } + // Need to url decode the response + var msg = decodeURIComponent(xmlhttp.responseText); + setTimeout(function() { + try { + var t = eval(msg); + } + catch (e) { + // If we're getting an error here, seeing the message will help in debugging + console.log("JSCallback: Message from Server: " + msg); + console.log("JSCallback Error: "+e); + } + }, 1); + setTimeout(startXhr, 1); + } - // If callback ping (used to keep XHR request from timing out) - else if (xmlhttp.status === 404) { - setTimeout(callback, 10); - } + // If callback ping (used to keep XHR request from timing out) + else if (xmlhttp.status === 404) { + setTimeout(startXhr, 10); + } - // If security error - else if (xmlhttp.status === 403) { - console.log("JSCallback Error: Invalid token. Stopping callbacks."); - } + // 0 == Page is unloading. + // 400 == Bad request. + // 403 == invalid token. + // 503 == server stopped. + else { + console.log("JSCallback Error: Request failed with status " + xmlhttp.status); + exec.setNativeToJsBridgeMode(exec.nativeToJsModes.POLLING); + } + } + }; - // If server is stopping - else if (xmlhttp.status === 503) { - console.log("JSCallback Server Closed: Stopping callbacks."); - } + if (port === null) { + port = prompt("getPort", "gap_callbackServer:"); + } + if (token === null) { + token = prompt("getToken", "gap_callbackServer:"); + } + xmlhttp.open("GET", "http://127.0.0.1:"+port+"/"+token , true); + xmlhttp.send(); +} - // If request wasn't GET - else if (xmlhttp.status === 400) { - console.log("JSCallback Error: Bad request. Stopping callbacks."); - } +module.exports = { + start: function() { + startXhr(); + }, - // If error, revert to polling - else { - console.log("JSCallback Error: Request failed."); - cordova.UsePolling = true; - polling(); - } - } - }; + stop: function() { + if (xmlhttp) { + var tmp = xmlhttp; + xmlhttp = null; + tmp.abort(); + } + }, - if (port === null) { - port = prompt("getPort", "gap_callbackServer:"); - } - if (token === null) { - token = prompt("getToken", "gap_callbackServer:"); - } - xmlhttp.open("GET", "http://127.0.0.1:"+port+"/"+token , true); - xmlhttp.send(); + isAvailable: function() { + return ("true" != prompt("usePolling", "gap_callbackServer:")); + } }; -module.exports = callback; + }); // file: lib/android/plugin/android/device.js define("cordova/plugin/android/device", function(require, exports, module) { var channel = require('cordova/channel'), utils = require('cordova/utils'), - exec = require('cordova/exec'); - -/** - * This represents the mobile device, and provides properties for inspecting the model, version, UUID of the - * phone, etc. - * @constructor - */ -function Device() { - this.available = false; - this.platform = null; - this.version = null; - this.name = null; - this.uuid = null; - this.cordova = null; - - var me = this; - - channel.onCordovaReady.subscribeOnce(function() { - me.getInfo(function(info) { - me.available = true; - me.platform = info.platform; - me.version = info.version; - me.name = info.name; - me.uuid = info.uuid; - me.cordova = info.cordova; - channel.onCordovaInfoReady.fire(); - },function(e) { - me.available = false; - utils.alert("[ERROR] Error initializing Cordova: " + e); - }); - }); -} + exec = require('cordova/exec'), + app = require('cordova/plugin/android/app'); -/** - * Get device info - * - * @param {Function} successCallback The function to call when the heading data is available - * @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL) - */ -Device.prototype.getInfo = function(successCallback, errorCallback) { +module.exports = { + /* + * DEPRECATED + * This is only for Android. + * + * You must explicitly override the back button. + */ + overrideBackButton:function() { + console.log("Device.overrideBackButton() is deprecated. Use App.overrideBackbutton(true)."); + app.overrideBackbutton(true); + }, - // successCallback required - if (typeof successCallback !== "function") { - console.log("Device Error: successCallback is not a function"); - return; - } + /* + * DEPRECATED + * This is only for Android. + * + * This resets the back button to the default behaviour + */ + resetBackButton:function() { + console.log("Device.resetBackButton() is deprecated. Use App.overrideBackbutton(false)."); + app.overrideBackbutton(false); + }, - // errorCallback optional - if (errorCallback && (typeof errorCallback !== "function")) { - console.log("Device Error: errorCallback is not a function"); - return; + /* + * DEPRECATED + * This is only for Android. + * + * This terminates the activity! + */ + exitApp:function() { + console.log("Device.exitApp() is deprecated. Use App.exitApp()."); + app.exitApp(); } - - // Get info - exec(successCallback, errorCallback, "Device", "getDeviceInfo", []); }; -/* - * DEPRECATED - * This is only for Android. - * - * You must explicitly override the back button. - */ -Device.prototype.overrideBackButton = function() { - console.log("Device.overrideBackButton() is deprecated. Use App.overrideBackbutton(true)."); - navigator.app.overrideBackbutton(true); -}; - -/* - * DEPRECATED - * This is only for Android. - * - * This resets the back button to the default behaviour - */ -Device.prototype.resetBackButton = function() { - console.log("Device.resetBackButton() is deprecated. Use App.overrideBackbutton(false)."); - navigator.app.overrideBackbutton(false); -}; - -/* - * DEPRECATED - * This is only for Android. - * - * This terminates the activity! - */ -Device.prototype.exitApp = function() { - console.log("Device.exitApp() is deprecated. Use App.exitApp()."); - navigator.app.exitApp(); -}; - -module.exports = new Device(); }); // file: lib/android/plugin/android/notification.js @@ -3892,38 +3881,47 @@ module.exports = { // file: lib/android/plugin/android/polling.js define("cordova/plugin/android/polling", function(require, exports, module) { var cordova = require('cordova'), - period = 50, - polling = function() { - // Exit if shutting down app - if (cordova.shuttingDown) { - return; - } + POLL_INTERVAL = 50, + enabled = false; - // If polling flag was changed, stop using polling from now on and switch to XHR server / callback - if (!cordova.UsePolling) { - require('cordova/plugin/android/callback')(); - return; - } +function pollOnce() { + var msg = prompt("", "gap_poll:"); + if (msg) { + try { + eval(""+msg); + } + catch (e) { + console.log("JSCallbackPolling: Message from Server: " + msg); + console.log("JSCallbackPolling Error: "+e); + } + return true; + } + return false; +} - var msg = prompt("", "gap_poll:"); - if (msg) { - setTimeout(function() { - try { - var t = eval(""+msg); - } - catch (e) { - console.log("JSCallbackPolling: Message from Server: " + msg); - console.log("JSCallbackPolling Error: "+e); - } - }, 1); - setTimeout(polling, 1); - } - else { - setTimeout(polling, period); - } +function doPoll() { + if (!enabled) { + return; + } + var nextDelay = POLL_INTERVAL; + if (pollOnce()) { + nextDelay = 0; + } + setTimeout(doPoll, nextDelay); +} + +module.exports = { + start: function() { + enabled = true; + setTimeout(doPoll, 1); + }, + stop: function() { + enabled = false; + }, + pollOnce: pollOnce }; -module.exports = polling; + }); // file: lib/android/plugin/android/storage.js @@ -4796,7 +4794,7 @@ var contacts = { * This function creates a new contact, but it does not persist the contact * to device storage. To persist the contact to device storage, invoke * contact.save(). - * @param properties an object who's properties will be examined to create a new Contact + * @param properties an object whose properties will be examined to create a new Contact * @returns new Contact object */ create:function(properties) { @@ -4815,6 +4813,93 @@ module.exports = contacts; }); +// file: lib/common/plugin/device.js +define("cordova/plugin/device", function(require, exports, module) { +var channel = require('cordova/channel'), + utils = require('cordova/utils'), + exec = require('cordova/exec'); + +// Tell cordova channel to wait on the CordovaInfoReady event +channel.waitForInitialization('onCordovaInfoReady'); + +/** + * This represents the mobile device, and provides properties for inspecting the model, version, UUID of the + * phone, etc. + * @constructor + */ +function Device() { + this.available = false; + this.platform = null; + this.version = null; + this.name = null; + this.uuid = null; + this.cordova = null; + + var me = this; + + channel.onCordovaReady.subscribeOnce(function() { + me.getInfo(function(info) { + me.available = true; + me.platform = info.platform; + me.version = info.version; + me.name = info.name; + me.uuid = info.uuid; + me.cordova = info.cordova; + channel.onCordovaInfoReady.fire(); + },function(e) { + me.available = false; + utils.alert("[ERROR] Error initializing Cordova: " + e); + }); + }); +} + +/** + * Get device info + * + * @param {Function} successCallback The function to call when the heading data is available + * @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL) + */ +Device.prototype.getInfo = function(successCallback, errorCallback) { + + // successCallback required + if (typeof successCallback !== "function") { + console.log("Device Error: successCallback is not a function"); + return; + } + + // errorCallback optional + if (errorCallback && (typeof errorCallback !== "function")) { + console.log("Device Error: errorCallback is not a function"); + return; + } + + // Get info + exec(successCallback, errorCallback, "Device", "getDeviceInfo", []); +}; + +module.exports = new Device(); + +}); + +// file: lib/common/plugin/echo.js +define("cordova/plugin/echo", function(require, exports, module) { +var exec = require('cordova/exec'); + +/** + * Sends the given message through exec() to the Echo plugink, which sends it back to the successCallback. + * @param successCallback invoked with a FileSystem object + * @param errorCallback invoked if error occurs retrieving file system + * @param message The string to be echoed. + * @param forceAsync Whether to force an async return value (for testing native->js bridge). + */ +module.exports = function(successCallback, errorCallback, message, forceAsync) { + var action = forceAsync ? 'echoAsync' : 'echo'; + exec(successCallback, errorCallback, "Echo", action, [message]); +}; + + +}); + // file: lib/common/plugin/geolocation.js define("cordova/plugin/geolocation", function(require, exports, module) { var utils = require('cordova/utils'), @@ -4923,7 +5008,7 @@ var geolocation = { } else if (options.timeout === 0) { fail({ code:PositionError.TIMEOUT, - message:"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceed's provided PositionOptions' maximumAge parameter." + message:"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceeds provided PositionOptions' maximumAge parameter." }); // Otherwise we have to call into native to retrieve a position. } else { @@ -5087,7 +5172,7 @@ CurrentLevel = LevelsMap.WARN; * * The value used determines which messages get printed. The logging * values above are in order, and only messages logged at the logging - * level or above will actually be displayed to the user. Eg, the + * level or above will actually be displayed to the user. E.g., the * default level is WARN, so only messages logged with LOG, ERROR, or * WARN will be displayed; INFO and DEBUG messages will be ignored. */ @@ -5466,6 +5551,9 @@ define("cordova/plugin/splashscreen", function(require, exports, module) { var exec = require('cordova/exec'); var splashscreen = { + show:function() { + exec(null, null, "SplashScreen", "show", []); + }, hide:function() { exec(null, null, "SplashScreen", "hide", []); } @@ -5723,4 +5811,4 @@ window.cordova = require('cordova'); }(window)); -})();
\ No newline at end of file +})();var PhoneGap = cordova; diff --git a/phonegap/www/cordova-independent.js b/phonegap/www/cordova-independent.js new file mode 100644 index 000000000..f56a8f08f --- /dev/null +++ b/phonegap/www/cordova-independent.js @@ -0,0 +1,12 @@ +(function () { + var scriptElement = document.createElement("script"); + scriptElement.type = "text/javascript"; + if (navigator.userAgent.match(/(iPhone|iPod|iPad)/)) { + scriptElement.src = 'cordova-ios-2.1.0.js'; + } else if (navigator.userAgent.match(/Android/)) { + scriptElement.src = 'cordova-android-2.1.0.js'; + } else { + alert("Unknown platform - userAgent is: " + navigator.userAgent); + } + $('head').prepend(scriptElement); +})(); diff --git a/phonegap/iphone_cordova.js b/phonegap/www/cordova-ios-2.1.0.js index d9cced70f..db81edf6c 100644..100755 --- a/phonegap/iphone_cordova.js +++ b/phonegap/www/cordova-ios-2.1.0.js @@ -1,6 +1,6 @@ -// commit 109b8649b0e98597b147842a6f71999d2f7910f2 +// commit 143f5221a6251c9cbccdedc57005c61551b97f12 -// File generated at :: Tue Jun 05 2012 14:10:19 GMT-0700 (PDT) +// File generated at :: Wed Sep 12 2012 15:26:58 GMT-0700 (PDT) /* Licensed to the Apache Software Foundation (ASF) under one @@ -186,11 +186,19 @@ var cordova = { }, /** * Method to fire event from native code + * bNoDetach is required for events which cause an exception which needs to be caught in native code */ - fireDocumentEvent: function(type, data) { + fireDocumentEvent: function(type, data, bNoDetach) { var evt = createEvent(type, data); if (typeof documentEventHandlers[type] != 'undefined') { - documentEventHandlers[type].fire(evt); + if( bNoDetach ) { + documentEventHandlers[type].fire(evt); + } + else { + setTimeout(function() { + documentEventHandlers[type].fire(evt); + }, 0); + } } else { document.dispatchEvent(evt); } @@ -198,15 +206,13 @@ var cordova = { fireWindowEvent: function(type, data) { var evt = createEvent(type,data); if (typeof windowEventHandlers[type] != 'undefined') { - windowEventHandlers[type].fire(evt); + setTimeout(function() { + windowEventHandlers[type].fire(evt); + }, 0); } else { window.dispatchEvent(evt); } }, - // TODO: this is Android only; think about how to do this better - shuttingDown:false, - UsePolling:false, - // END TODO // TODO: iOS only // This queue holds the currently executing command and all pending @@ -285,17 +291,6 @@ var cordova = { } } }, - // TODO: remove in 2.0. - addPlugin: function(name, obj) { - console.log("[DEPRECATION NOTICE] window.addPlugin and window.plugins will be removed in version 2.0."); - if (!window.plugins[name]) { - window.plugins[name] = obj; - } - else { - console.log("Error: Plugin "+name+" already exists."); - } - }, - addConstructor: function(func) { channel.onCordovaReady.subscribeOnce(function() { try { @@ -312,51 +307,6 @@ channel.onPause = cordova.addDocumentEventHandler('pause'); channel.onResume = cordova.addDocumentEventHandler('resume'); channel.onDeviceReady = cordova.addDocumentEventHandler('deviceready'); -// Adds deprecation warnings to functions of an object (but only logs a message once) -function deprecateFunctions(obj, objLabel) { - var newObj = {}; - var logHash = {}; - for (var i in obj) { - if (obj.hasOwnProperty(i)) { - if (typeof obj[i] == 'function') { - newObj[i] = (function(prop){ - var oldFunk = obj[prop]; - var funkId = objLabel + '_' + prop; - return function() { - if (!logHash[funkId]) { - console.log('[DEPRECATION NOTICE] The "' + objLabel + '" global will be removed in version 2.0, please use lowercase "cordova".'); - logHash[funkId] = true; - } - oldFunk.apply(obj, arguments); - }; - })(i); - } else { - newObj[i] = (function(prop) { return obj[prop]; })(i); - } - } - } - return newObj; -} - -/** - * Legacy variable for plugin support - * TODO: remove in 2.0. - */ -if (!window.PhoneGap) { - window.PhoneGap = deprecateFunctions(cordova, 'PhoneGap'); -} -if (!window.Cordova) { - window.Cordova = deprecateFunctions(cordova, 'Cordova'); -} - -/** - * Plugins object - * TODO: remove in 2.0. - */ -if (!window.plugins) { - window.plugins = {}; -} - module.exports = cordova; }); @@ -456,7 +406,8 @@ module.exports = { // file: lib/common/channel.js define("cordova/channel", function(require, exports, module) { -var utils = require('cordova/utils'); +var utils = require('cordova/utils'), + nextGuid = 1; /** * Custom pub-sub "channel" that can have functions subscribed to it @@ -508,7 +459,6 @@ var Channel = function(type, opts) { this.type = type; this.handlers = {}; this.numHandlers = 0; - this.guid = 1; this.fired = false; this.enabled = true; this.events = { @@ -601,19 +551,19 @@ Channel.prototype.subscribe = function(f, c, g) { g = g || func.observer_guid || f.observer_guid; if (!g) { - // first time we've seen this subscriber - g = this.guid++; - } - else { - // subscriber already handled; dont set it twice - return g; + // first time any channel has seen this subscriber + g = nextGuid++; } func.observer_guid = g; f.observer_guid = g; - this.handlers[g] = func; - this.numHandlers++; - if (this.events.onSubscribe) this.events.onSubscribe.call(this); - if (this.fired) func.call(this); + + // Don't add the same handler more than once. + if (!this.handlers[g]) { + this.handlers[g] = func; + this.numHandlers++; + if (this.events.onSubscribe) this.events.onSubscribe.call(this); + if (this.fired) func.apply(this, this.fireArgs); + } return g; }; @@ -627,15 +577,14 @@ Channel.prototype.subscribeOnce = function(f, c) { var g = null; var _this = this; - var m = function() { - f.apply(c || null, arguments); - _this.unsubscribe(g); - }; if (this.fired) { - if (typeof c == "object") { f = utils.close(c, f); } - f.apply(this, this.fireArgs); + f.apply(c || null, this.fireArgs); } else { - g = this.subscribe(m); + g = this.subscribe(function() { + _this.unsubscribe(g); + f.apply(c || null, arguments); + }); + f.observer_guid = g; } return g; }; @@ -651,7 +600,6 @@ Channel.prototype.unsubscribe = function(g) { var handler = this.handlers[g]; if (handler) { if (handler.observer_guid) handler.observer_guid=null; - this.handlers[g] = null; delete this.handlers[g]; this.numHandlers--; if (this.events.onUnsubscribe) this.events.onUnsubscribe.call(this); @@ -665,14 +613,17 @@ Channel.prototype.fire = function(e) { if (this.enabled) { var fail = false; this.fired = true; + this.fireArgs = arguments; + // Copy the values first so that it is safe to modify it from within + // callbacks. + var toCall = []; for (var item in this.handlers) { - var handler = this.handlers[item]; - if (typeof handler == 'function') { - var rv = (handler.apply(this, arguments)===false); - fail = fail || rv; - } + toCall.push(this.handlers[item]); + } + for (var i = 0; i < toCall.length; ++i) { + var rv = (toCall[i].apply(this, arguments)===false); + fail = fail || rv; } - this.fireArgs = arguments; return !fail; } return true; @@ -709,7 +660,6 @@ channel.create('onDestroy'); // Channels that must fire before "deviceready" is fired. channel.waitForInitialization('onCordovaReady'); -channel.waitForInitialization('onCordovaInfoReady'); channel.waitForInitialization('onCordovaConnectionReady'); module.exports = channel; @@ -738,13 +688,6 @@ module.exports = { } } }, - PhoneGap:{ - children: { - exec: { - path: 'cordova/exec' - } - } - }, navigator: { children: { notification: { @@ -844,6 +787,9 @@ module.exports = { Coordinates: { path: 'cordova/plugin/Coordinates' }, + device: { + path: 'cordova/plugin/device' + }, DirectoryEntry: { path: 'cordova/plugin/DirectoryEntry' }, @@ -933,20 +879,46 @@ define("cordova/exec", function(require, exports, module) { * @private */ var cordova = require('cordova'), + channel = require('cordova/channel'), + nativecomm = require('cordova/plugin/ios/nativecomm'), utils = require('cordova/utils'), - gapBridge, - createGapBridge = function() { - gapBridge = document.createElement("iframe"); - gapBridge.setAttribute("style", "display:none;"); - gapBridge.setAttribute("height","0px"); - gapBridge.setAttribute("width","0px"); - gapBridge.setAttribute("frameborder","0"); - document.documentElement.appendChild(gapBridge); + jsToNativeModes = { + IFRAME_NAV: 0, + XHR_NO_PAYLOAD: 1, + XHR_WITH_PAYLOAD: 2, + XHR_OPTIONAL_PAYLOAD: 3 }, - channel = require('cordova/channel'); + // XHR mode does not work on iOS 4.2, so default to IFRAME_NAV for such devices. + // XHR mode's main advantage is working around a bug in -webkit-scroll, which + // doesn't exist in 4.X devices anyways. + bridgeMode = navigator.userAgent.indexOf(' 4_') == -1 ? jsToNativeModes.XHR_NO_PAYLOAD : jsToNativeModes.IFRAME_NAV, + execIframe, + execXhr; + +function createExecIframe() { + var iframe = document.createElement("iframe"); + iframe.style.display = 'none'; + document.body.appendChild(iframe); + return iframe; +} -module.exports = function() { - if (!channel.onCordovaInfoReady.fired) { +function shouldBundleCommandJson() { + if (bridgeMode == 2) { + return true; + } + if (bridgeMode == 3) { + var payloadLength = 0; + for (var i = 0; i < cordova.commandQueue.length; ++i) { + payloadLength += cordova.commandQueue[i].length; + } + // The value here was determined using the benchmark within CordovaLibApp on an iPad 3. + return payloadLength < 4500; + } + return false; +} + +function iOSExec() { + if (!channel.onCordovaReady.fired) { utils.alert("ERROR: Attempting to call cordova.exec()" + " before 'deviceready'. Ignoring."); return; @@ -975,13 +947,6 @@ module.exports = function() { actionArgs = Array.prototype.splice.call(arguments, 1); } - // Start building the command object. - var command = { - className: service, - methodName: action, - "arguments": [] - }; - // Register the callbacks and add the callbackId to the positional // arguments if given. if (successCallback || failCallback) { @@ -989,20 +954,8 @@ module.exports = function() { cordova.callbacks[callbackId] = {success:successCallback, fail:failCallback}; } - if (callbackId !== null) { - command["arguments"].push(callbackId); - } - for (var i = 0; i < actionArgs.length; ++i) { - var arg = actionArgs[i]; - if (arg === undefined || arg === null) { // nulls are pushed to the args now (becomes NSNull) - command["arguments"].push(arg); - } else if (typeof(arg) == 'object' && !(utils.isArray(arg))) { - command.options = arg; - } else { - command["arguments"].push(arg); - } - } + var command = [callbackId, service, action, actionArgs]; // Stringify and queue the command. We stringify to command now to // effectively clone the command arguments in case they are mutated before @@ -1014,13 +967,38 @@ module.exports = function() { // commands to execute, unless the queue is currently being flushed, in // which case the command will be picked up without notification. if (cordova.commandQueue.length == 1 && !cordova.commandQueueFlushing) { - if (!gapBridge) { - createGapBridge(); + if (bridgeMode) { + execXhr = execXhr || new XMLHttpRequest(); + // Changeing this to a GET will make the XHR reach the URIProtocol on 4.2. + // For some reason it still doesn't work though... + execXhr.open('HEAD', "file:///!gap_exec", true); + execXhr.setRequestHeader('vc', cordova.iOSVCAddr); + if (shouldBundleCommandJson()) { + execXhr.setRequestHeader('cmds', nativecomm()); + } + execXhr.send(null); + } else { + execIframe = execIframe || createExecIframe(); + execIframe.src = "gap://ready"; } - gapBridge.src = "gap://ready"; } +} + +iOSExec.jsToNativeModes = jsToNativeModes; + +iOSExec.setJsToNativeBridgeMode = function(mode) { + // Remove the iFrame since it may be no longer required, and its existence + // can trigger browser bugs. + // https://issues.apache.org/jira/browse/CB-593 + if (execIframe) { + execIframe.parentNode.removeChild(execIframe); + execIframe = null; + } + bridgeMode = mode; }; +module.exports = iOSExec; + }); // file: lib/ios/platform.js @@ -1040,12 +1018,12 @@ module.exports = { File: { // exists natively, override path: "cordova/plugin/File" }, + FileReader: { // exists natively, override + path: "cordova/plugin/FileReader" + }, MediaError: { // exists natively, override path: "cordova/plugin/MediaError" }, - device: { - path: 'cordova/plugin/ios/device' - }, console: { path: 'cordova/plugin/ios/console' } @@ -1199,7 +1177,14 @@ cameraExport.getPicture = function(successCallback, errorCallback, options) { popoverOptions = options.popoverOptions; } - exec(successCallback, errorCallback, "Camera", "takePicture", [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType, mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions]); + var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType, + mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions]; + + exec(successCallback, errorCallback, "Camera", "takePicture", args); +}; + +cameraExport.cleanup = function(successCallback, errorCallback) { + exec(successCallback, errorCallback, "Camera", "cleanup", []); }; module.exports = cameraExport; @@ -1784,7 +1769,7 @@ var utils = require('cordova/utils'), * {boolean} isDirectory always true (readonly) * {DOMString} name of the directory, excluding the path leading to it (readonly) * {DOMString} fullPath the absolute full path to the directory (readonly) - * {FileSystem} filesystem on which the directory resides (readonly) + * TODO: implement this!!! {FileSystem} filesystem on which the directory resides (readonly) */ var DirectoryEntry = function(name, fullPath) { DirectoryEntry.__super__.constructor.apply(this, [false, true, name, fullPath]); @@ -2514,11 +2499,13 @@ var FileSystem = function(name, root) { }; module.exports = FileSystem; + }); // file: lib/common/plugin/FileTransfer.js define("cordova/plugin/FileTransfer", function(require, exports, module) { -var exec = require('cordova/exec'); +var exec = require('cordova/exec'), + FileTransferError = require('cordova/plugin/FileTransferError'); /** * FileTransfer uploads a file to a remote server. @@ -2537,16 +2524,20 @@ var FileTransfer = function() {}; * @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false */ FileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) { + // sanity parameter checking + if (!filePath || !server) throw new Error("FileTransfer.upload requires filePath and server URL parameters at the minimum."); // check for options var fileKey = null; var fileName = null; var mimeType = null; var params = null; var chunkedMode = true; + var headers = null; if (options) { fileKey = options.fileKey; fileName = options.fileName; mimeType = options.mimeType; + headers = options.headers; if (options.chunkedMode !== null || typeof options.chunkedMode != "undefined") { chunkedMode = options.chunkedMode; } @@ -2558,7 +2549,12 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro } } - exec(successCallback, errorCallback, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode]); + var fail = function(e) { + var error = new FileTransferError(e.code, e.source, e.target, e.http_status); + errorCallback(error); + }; + + exec(successCallback, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers]); }; /** @@ -2569,6 +2565,8 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro * @param errorCallback {Function} Callback to be invoked upon error */ FileTransfer.prototype.download = function(source, target, successCallback, errorCallback) { + // sanity parameter checking + if (!source || !target) throw new Error("FileTransfer.download requires source URI and target URI parameters at the minimum."); var win = function(result) { var entry = null; if (result.isDirectory) { @@ -2583,6 +2581,12 @@ FileTransfer.prototype.download = function(source, target, successCallback, erro entry.fullPath = result.fullPath; successCallback(entry); }; + + var fail = function(e) { + var error = new FileTransferError(e.code, e.source, e.target, e.http_status); + errorCallback(error); + }; + exec(win, errorCallback, 'FileTransfer', 'download', [source, target]); }; @@ -2596,8 +2600,11 @@ define("cordova/plugin/FileTransferError", function(require, exports, module) { * FileTransferError * @constructor */ -var FileTransferError = function(code) { +var FileTransferError = function(code, source, target, status) { this.code = code || null; + this.source = source || null; + this.target = target || null; + this.http_status = status || null; }; FileTransferError.FILE_NOT_FOUND_ERR = 1; @@ -2605,6 +2612,7 @@ FileTransferError.INVALID_URL_ERR = 2; FileTransferError.CONNECTION_ERR = 3; module.exports = FileTransferError; + }); // file: lib/common/plugin/FileUploadOptions.js @@ -2616,15 +2624,19 @@ define("cordova/plugin/FileUploadOptions", function(require, exports, module) { * @param fileName {String} Filename to be used by the server. Defaults to image.jpg. * @param mimeType {String} Mimetype of the uploaded file. Defaults to image/jpeg. * @param params {Object} Object with key: value params to send to the server. + * @param headers {Object} Keys are header names, values are header values. Multiple + * headers of the same name are not supported. */ -var FileUploadOptions = function(fileKey, fileName, mimeType, params) { +var FileUploadOptions = function(fileKey, fileName, mimeType, params, headers) { this.fileKey = fileKey || null; this.fileName = fileName || null; this.mimeType = mimeType || null; this.params = params || null; + this.headers = headers || null; }; module.exports = FileUploadOptions; + }); // file: lib/common/plugin/FileUploadResult.js @@ -2812,7 +2824,7 @@ FileWriter.prototype.seek = function(offset) { if (offset < 0) { this.position = Math.max(offset + this.length, 0); } - // Offset is bigger then file size so set position + // Offset is bigger than file size so set position // to the end of the file. else if (offset > this.length) { this.position = this.length; @@ -3019,7 +3031,6 @@ Media.prototype.stop = function() { var me = this; exec(function() { me._position = 0; - me.successCallback(); }, this.errorCallback, "Media", "stopPlayingAudio", [this.id]); }; @@ -3065,14 +3076,14 @@ Media.prototype.getCurrentPosition = function(success, fail) { * Start recording audio file. */ Media.prototype.startRecord = function() { - exec(this.successCallback, this.errorCallback, "Media", "startRecordingAudio", [this.id, this.src]); + exec(null, this.errorCallback, "Media", "startRecordingAudio", [this.id, this.src]); }; /** * Stop recording audio file. */ Media.prototype.stopRecord = function() { - exec(this.successCallback, this.errorCallback, "Media", "stopRecordingAudio", [this.id]); + exec(null, this.errorCallback, "Media", "stopRecordingAudio", [this.id]); }; /** @@ -3094,34 +3105,39 @@ Media.prototype.setVolume = function(volume) { * PRIVATE * * @param id The media object id (string) - * @param status The status code (int) - * @param msg The status message (string) + * @param msgType The 'type' of update this is + * @param value Use of value is determined by the msgType */ -Media.onStatus = function(id, msg, value) { +Media.onStatus = function(id, msgType, value) { + var media = mediaObjects[id]; - // If state update - if (msg === Media.MEDIA_STATE) { - if (value === Media.MEDIA_STOPPED) { - if (media.successCallback) { - media.successCallback(); - } - } - if (media.statusCallback) { - media.statusCallback(value); - } - } - else if (msg === Media.MEDIA_DURATION) { - media._duration = value; - } - else if (msg === Media.MEDIA_ERROR) { - if (media.errorCallback) { - // value should be a MediaError object when msg == MEDIA_ERROR - media.errorCallback(value); + + if(media) { + switch(msgType) { + case Media.MEDIA_STATE : + media.statusCallback && media.statusCallback(value); + if(value == Media.MEDIA_STOPPED) { + media.successCallback && media.successCallback(); + } + break; + case Media.MEDIA_DURATION : + media._duration = value; + break; + case Media.MEDIA_ERROR : + media.errorCallback && media.errorCallback(value); + break; + case Media.MEDIA_POSITION : + media._position = Number(value); + break; + default : + console && console.error && console.error("Unhandled Media.onStatus :: " + msgType); + break; } } - else if (msg === Media.MEDIA_POSITION) { - media._position = value; + else { + console && console.error && console.error("Received Media.onStatus callback for unknown media :: " + id); } + }; module.exports = Media; @@ -3131,20 +3147,36 @@ module.exports = Media; define("cordova/plugin/MediaError", function(require, exports, module) { /** * This class contains information about any Media errors. - * @constructor +*/ +/* + According to :: http://dev.w3.org/html5/spec-author-view/video.html#mediaerror + We should never be creating these objects, we should just implement the interface + which has 1 property for an instance, 'code' + + instead of doing : + errorCallbackFunction( new MediaError(3,'msg') ); +we should simply use a literal : + errorCallbackFunction( {'code':3} ); */ -var MediaError = function(code, msg) { - this.code = (code !== undefined ? code : null); - this.message = msg || ""; -}; -MediaError.MEDIA_ERR_NONE_ACTIVE = 0; -MediaError.MEDIA_ERR_ABORTED = 1; -MediaError.MEDIA_ERR_NETWORK = 2; -MediaError.MEDIA_ERR_DECODE = 3; -MediaError.MEDIA_ERR_NONE_SUPPORTED = 4; +if(!MediaError) { + var MediaError = function(code, msg) { + this.code = (typeof code != 'undefined') ? code : null; + this.message = msg || ""; // message is NON-standard! do not use! + }; +} + +MediaError.MEDIA_ERR_NONE_ACTIVE = MediaError.MEDIA_ERR_NONE_ACTIVE || 0; +MediaError.MEDIA_ERR_ABORTED = MediaError.MEDIA_ERR_ABORTED || 1; +MediaError.MEDIA_ERR_NETWORK = MediaError.MEDIA_ERR_NETWORK || 2; +MediaError.MEDIA_ERR_DECODE = MediaError.MEDIA_ERR_DECODE || 3; +MediaError.MEDIA_ERR_NONE_SUPPORTED = MediaError.MEDIA_ERR_NONE_SUPPORTED || 4; +// TODO: MediaError.MEDIA_ERR_NONE_SUPPORTED is legacy, the W3 spec now defines it as below. +// as defined by http://dev.w3.org/html5/spec-author-view/video.html#error-codes +MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED || 4; module.exports = MediaError; + }); // file: lib/common/plugin/MediaFile.js @@ -3182,28 +3214,6 @@ MediaFile.prototype.getFormatData = function(successCallback, errorCallback) { } }; -// TODO: can we axe this? -/** - * Casts a PluginResult message property (array of objects) to an array of MediaFile objects - * (used in Objective-C and Android) - * - * @param {PluginResult} pluginResult - */ -MediaFile.cast = function(pluginResult) { - var mediaFiles = []; - for (var i=0; i<pluginResult.message.length; i++) { - var mediaFile = new MediaFile(); - mediaFile.name = pluginResult.message[i].name; - mediaFile.fullPath = pluginResult.message[i].fullPath; - mediaFile.type = pluginResult.message[i].type; - mediaFile.lastModifiedDate = pluginResult.message[i].lastModifiedDate; - mediaFile.size = pluginResult.message[i].size; - mediaFiles.push(mediaFile); - } - pluginResult.message = mediaFiles; - return pluginResult; -}; - module.exports = MediaFile; }); @@ -3409,12 +3419,12 @@ var accelerometer = { var p; var win = function(a) { - successCallback(a); removeListeners(p); + successCallback(a); }; var fail = function(e) { - errorCallback(e); removeListeners(p); + errorCallback(e); }; p = createCallbackPair(win, fail); @@ -3446,8 +3456,8 @@ var accelerometer = { var id = utils.createUUID(); var p = createCallbackPair(function(){}, function(e) { - errorCallback(e); removeListeners(p); + errorCallback(e); }); listeners.push(p); @@ -3462,7 +3472,10 @@ var accelerometer = { if (running) { // If we're already running then immediately invoke the success callback - successCallback(accel); + // but only if we have retrieved a value, sample code does not check for null ... + if(accel) { + successCallback(accel); + } } else { start(); } @@ -3977,7 +3990,7 @@ var contacts = { * This function creates a new contact, but it does not persist the contact * to device storage. To persist the contact to device storage, invoke * contact.save(). - * @param properties an object who's properties will be examined to create a new Contact + * @param properties an object whose properties will be examined to create a new Contact * @returns new Contact object */ create:function(properties) { @@ -3996,6 +4009,93 @@ module.exports = contacts; }); +// file: lib/common/plugin/device.js +define("cordova/plugin/device", function(require, exports, module) { +var channel = require('cordova/channel'), + utils = require('cordova/utils'), + exec = require('cordova/exec'); + +// Tell cordova channel to wait on the CordovaInfoReady event +channel.waitForInitialization('onCordovaInfoReady'); + +/** + * This represents the mobile device, and provides properties for inspecting the model, version, UUID of the + * phone, etc. + * @constructor + */ +function Device() { + this.available = false; + this.platform = null; + this.version = null; + this.name = null; + this.uuid = null; + this.cordova = null; + + var me = this; + + channel.onCordovaReady.subscribeOnce(function() { + me.getInfo(function(info) { + me.available = true; + me.platform = info.platform; + me.version = info.version; + me.name = info.name; + me.uuid = info.uuid; + me.cordova = info.cordova; + channel.onCordovaInfoReady.fire(); + },function(e) { + me.available = false; + utils.alert("[ERROR] Error initializing Cordova: " + e); + }); + }); +} + +/** + * Get device info + * + * @param {Function} successCallback The function to call when the heading data is available + * @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL) + */ +Device.prototype.getInfo = function(successCallback, errorCallback) { + + // successCallback required + if (typeof successCallback !== "function") { + console.log("Device Error: successCallback is not a function"); + return; + } + + // errorCallback optional + if (errorCallback && (typeof errorCallback !== "function")) { + console.log("Device Error: errorCallback is not a function"); + return; + } + + // Get info + exec(successCallback, errorCallback, "Device", "getDeviceInfo", []); +}; + +module.exports = new Device(); + +}); + +// file: lib/common/plugin/echo.js +define("cordova/plugin/echo", function(require, exports, module) { +var exec = require('cordova/exec'); + +/** + * Sends the given message through exec() to the Echo plugink, which sends it back to the successCallback. + * @param successCallback invoked with a FileSystem object + * @param errorCallback invoked if error occurs retrieving file system + * @param message The string to be echoed. + * @param forceAsync Whether to force an async return value (for testing native->js bridge). + */ +module.exports = function(successCallback, errorCallback, message, forceAsync) { + var action = forceAsync ? 'echoAsync' : 'echo'; + exec(successCallback, errorCallback, "Echo", action, [message]); +}; + + +}); + // file: lib/common/plugin/geolocation.js define("cordova/plugin/geolocation", function(require, exports, module) { var utils = require('cordova/utils'), @@ -4104,7 +4204,7 @@ var geolocation = { } else if (options.timeout === 0) { fail({ code:PositionError.TIMEOUT, - message:"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceed's provided PositionOptions' maximumAge parameter." + message:"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceeds provided PositionOptions' maximumAge parameter." }); // Otherwise we have to call into native to retrieve a position. } else { @@ -4444,50 +4544,24 @@ module.exports = { * allowsEditing: boolean AS STRING * "true" to allow editing the contact * "false" (default) display contact + * fields: array of fields to return in contact object (see ContactOptions.fields) + * + * @returns + * id of contact selected + * ContactObject + * if no fields provided contact contains just id information + * if fields provided contact object contains information for the specified fields * - * returns: the id of the selected contact as param to successCallback */ - exec(successCallback, null, "Contacts","chooseContact", [options]); + var win = function(result) { + var fullContact = require('cordova/plugin/contacts').create(result); + successCallback(fullContact.id, fullContact); + }; + exec(win, null, "Contacts","chooseContact", [options]); } }; }); -// file: lib/ios/plugin/ios/device.js -define("cordova/plugin/ios/device", function(require, exports, module) { -/** - * this represents the mobile device, and provides properties for inspecting the model, version, UUID of the - * phone, etc. - * @constructor - */ -var exec = require('cordova/exec'), - utils = require('cordova/utils'), - channel = require('cordova/channel'); - -var Device = function() { - this.platform = null; - this.version = null; - this.name = null; - this.cordova = null; - this.uuid = null; -}; - -Device.prototype.setInfo = function(info) { - try { - this.platform = info.platform; - this.version = info.version; - this.name = info.name; - this.cordova = info.cordova; - this.uuid = info.uuid; - channel.onCordovaInfoReady.fire(); - } catch(e) { - utils.alert('Error during device info setting in cordova/plugin/ios/device!'); - } -}; - -module.exports = new Device(); - -}); - // file: lib/ios/plugin/ios/nativecomm.js define("cordova/plugin/ios/nativecomm", function(require, exports, module) { var cordova = require('cordova'); @@ -4496,10 +4570,12 @@ var cordova = require('cordova'); * Called by native code to retrieve all queued commands and clear the queue. */ module.exports = function() { - var json = JSON.stringify(cordova.commandQueue); - cordova.commandQueue = []; + // Each entry in commandQueue is a JSON string already. + var json = '[' + cordova.commandQueue.join(',') + ']'; + cordova.commandQueue.length = 0; return json; }; + }); // file: lib/ios/plugin/ios/notification.js @@ -4587,7 +4663,7 @@ CurrentLevel = LevelsMap.WARN; * * The value used determines which messages get printed. The logging * values above are in order, and only messages logged at the logging - * level or above will actually be displayed to the user. Eg, the + * level or above will actually be displayed to the user. E.g., the * default level is WARN, so only messages logged with LOG, ERROR, or * WARN will be displayed; INFO and DEBUG messages will be ignored. */ @@ -4966,6 +5042,9 @@ define("cordova/plugin/splashscreen", function(require, exports, module) { var exec = require('cordova/exec'); var splashscreen = { + show:function() { + exec(null, null, "SplashScreen", "show", []); + }, hide:function() { exec(null, null, "SplashScreen", "hide", []); } @@ -5223,4 +5302,4 @@ window.cordova = require('cordova'); }(window)); -})();
\ No newline at end of file +})();var PhoneGap = cordova; diff --git a/phonegap/www/css/mobile.css b/phonegap/www/css/mobile.css index f17f753fd..0cabbe5d5 100644 --- a/phonegap/www/css/mobile.css +++ b/phonegap/www/css/mobile.css @@ -8,13 +8,16 @@ padding-bottom: 0; } +.nodisplay { + display: none; +} + .mobile-nav-banner { position: fixed; background: black; } .mobile-sign-in-banner { - display: none; background: none; } @@ -26,7 +29,6 @@ } .mobile-info { - position: fixed; bottom: 0px; width: 100%; height: 20px; diff --git a/phonegap/www/email_sent.html b/phonegap/www/email_sent.html index 529ccb693..288b1f118 100644 --- a/phonegap/www/email_sent.html +++ b/phonegap/www/email_sent.html @@ -13,7 +13,7 @@ <meta http-equiv="content-type" content="text/html; charset=utf-8"> <script type="text/javascript" src="js/json2.js"></script> <script type="text/javascript" src="js/config.js"></script> - <script type="text/javascript" src="cordova-1.8.0.js"></script> + <script type="text/javascript" src="cordova-independent.js"></script> <script type="text/javascript" src="js/jquery-1.7.0.min.js"></script> <script type="text/javascript" src="js/mobile.js"></script> diff --git a/phonegap/www/index.html b/phonegap/www/index.html index 77de47165..40787ac37 100644 --- a/phonegap/www/index.html +++ b/phonegap/www/index.html @@ -8,10 +8,12 @@ <link rel="stylesheet" href="css/base.css"> <link rel="stylesheet" href="css/mobile.css"> + + <script type="text/javascript" src="js/jquery-1.7.0.min.js"></script> + <script type="text/javascript" src="cordova-independent.js"></script> + <script type="text/javascript" src="js/json2.js"></script> <script type="text/javascript" src="js/config.js"></script> - <script type="text/javascript" charset="utf-8" src="cordova-1.8.0.js"></script> - <script type="text/javascript" src="js/jquery-1.7.0.min.js"></script> <script src="js/jquery.validate.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript" src="js/geo.min.js"></script> @@ -87,7 +89,7 @@ </div> <div class="big-green-banner mobile-map-banner mobile-sign-in-banner"> - <a id="sign_in" href="sign_in.html">Sign In</a><a id="sign_out" href="#" onclick="sign_out();">Sign Out</a> + <a id="account" href="account.html">Account</a> </div> </div> <!-- .wrapper --> diff --git a/phonegap/www/js/mobile.js b/phonegap/www/js/mobile.js index 07d973315..c44501d97 100644 --- a/phonegap/www/js/mobile.js +++ b/phonegap/www/js/mobile.js @@ -281,21 +281,29 @@ function postReport(e) { service: 'iphone', title: $('#form_title').val(), detail: $('#form_detail').val(), - name: $('#form_name').val(), - may_show_name: $('#form_may_show_name').attr('checked') ? 1 : 0, - email: $('#form_email').val(), + may_show_name: $('#form_may_show_name').attr('checked') ? 1 : 0, category: $('#form_category').val(), lat: $('#fixmystreet\\.latitude').val(), lon: $('#fixmystreet\\.longitude').val(), - password_sign_in: $('#password_sign_in').val(), phone: $('#form_phone').val(), pc: $('#pc').val() }; - if ( submit_clicked.attr('id') == 'submit_sign_in' ) { + if ( localStorage.username && localStorage.password && localStorage.name ) { + params.name = localStorage.name; + params.email = localStorage.username; + params.password_sign_in = localStorage.password; params.submit_sign_in = 1; } else { - params.submit_register = 1; + params.name = $('#form_name').val(); + params.email = $('#form_email').val(); + params.password_sign_in = $('#password_sign_in').val(); + + if ( submit_clicked.attr('id') == 'submit_sign_in' ) { + params.submit_sign_in = 1; + } else { + params.submit_register = 1; + } } showBusy( 'Sending Report', 'Please wait while your report is sent' ); @@ -330,6 +338,11 @@ function postReport(e) { hideBusy(); window.location = 'email_sent.html'; } + if ( !localStorage.name && $('#password_sign_in').val() ) { + localStorage.name = $('#form_name').val(); + localStorage.username = $('#form_email').val(); + localStorage.password = $('#password_sign_in').val(); + } } else { if ( data.check_name ) { check_name( data.check_name, data.errors.name ); @@ -350,6 +363,8 @@ function postReport(e) { function sign_in() { showBusy( 'Signing In', 'Please wait while you are signed in' ); + $('#form_email').blur(); + $('#password_sign_in').blur(); jQuery.ajax( { url: CONFIG.FMS_URL + "auth/ajax/sign_in", type: 'POST', @@ -362,10 +377,14 @@ function sign_in() { console.log(data); if ( data.name ) { localStorage.name = data.name; + localStorage.username = $('#form_email').val(); + localStorage.password = $('#password_sign_in').val(); hideBusy(); - window.location = 'signed_in.html'; - $('#sign_out').show(); - $('#sign_in').hide(); + $('#user-meta').html('<p>You are signed in as ' + localStorage.username + '.</p>'); + $('#form_sign_in_only').hide(); + $('#forget_button').show(); + $('#form_email').val(''); + $('#password_sign_in').val(''); } else { hideBusy(); $('#form_email').before('<div class="form-error">There was a problem with your email/password combination.</div>'); @@ -378,8 +397,17 @@ function sign_in() { function display_signed_out_msg() { if ( localStorage.signed_out == 1 ) { $('#user-meta').html('<p>You’ve been signed out.</p>'); + $('#form_sign_in_only').show(); localStorage.signed_out = null; } + if ( localStorage.name ) { + $('#user-meta').html('<p>You are signed in as ' + localStorage.username + '.</p>'); + $('#form_sign_in_only').hide(); + $('#forget_button').show(); + } else { + $('#forget_button').hide(); + $('#form_sign_in_only').show(); + } } function sign_out() { @@ -418,46 +446,12 @@ function sign_out_around() { } ); } -function check_auth() { - if ( $('#user-meta').length && localStorage.signed_out != 1 ) { - var sign_out_function = sign_out; - if ( $('body').hasClass('mappage') ) { - sign_out_function = sign_out_around; - } - jQuery.ajax( { - url: CONFIG.FMS_URL + "auth/ajax/check_auth?" + new Date().getTime() , - type: 'GET', - statusCode: { - 200: function(data) { - localStorage.name = data.name; - $('#user-meta').html('<p>Hi ' + localStorage.name + '<a href="#" id="meta_sign_out">Sign out</a></p>'); - $('#meta_sign_out').on('click', sign_out_function ); - $('.mobile-sign-in-banner').show(); - $('#sign_in').hide(); - $('#sign_out').show(); - }, - 401: function() { - $('#user-meta').html(''); - localStorage.name = ''; - $('.mobile-sign-in-banner').show(); - $('#sign_out').hide(); - $('#sign_in').show(); - $('#user-meta').html(''); - } - } - } ); - } -} - -function signed_in() { +function account() { + $('.mobile-sign-in-banner').show(); + $('#account').show(); if ( localStorage.name ) { if ( $('body').hasClass('signed-in-page') ) { - var sign_out_function = sign_out; - if ( $('body').hasClass('mappage') ) { - sign_out_function = sign_out_around; - } - $('#user-meta').html('<p>Hi ' + localStorage.name + '<a href="#" id="meta_sign_out">Sign out</a></p>'); - $('#meta_sign_out').on('click', sign_out_function ); + $('#user-meta').html('<p>Hi ' + localStorage.name + '</p>'); } if ( $('#form_sign_in').length ) { @@ -467,6 +461,14 @@ function signed_in() { } } +function forget() { + delete localStorage.name; + delete localStorage.username; + delete localStorage.password; + localStorage.signed_out = 1; + display_signed_out_msg(); +} + function onDeviceReady() { var location = document.location + ''; if ( location.indexOf('no_connection.html') < 0 && ( @@ -478,9 +480,9 @@ function onDeviceReady() { $('#mapForm').submit(postReport); $('#signInForm').submit(sign_in); $('#ffo').click(getPosition); + $('#forget').click(forget); $('#mapForm :input[type=submit]').on('click', function() { submit_clicked = $(this); }); - check_auth(); - signed_in(); + account(); hideBusy(); } diff --git a/phonegap/www/no_connection.html b/phonegap/www/no_connection.html index 8a77d9c26..d81f5f83a 100644 --- a/phonegap/www/no_connection.html +++ b/phonegap/www/no_connection.html @@ -10,7 +10,7 @@ <link rel="stylesheet" href="css/mobile.css"> <script type="text/javascript" src="js/json2.js"></script> <script type="text/javascript" src="js/config.js"></script> - <script type="text/javascript" charset="utf-8" src="cordova-1.8.0.js"></script> + <script type="text/javascript" charset="utf-8" src="cordova-independent.js"></script> <script type="text/javascript" src="js/jquery-1.7.0.min.js"></script> <script src="js/jquery.validate.min.js" type="text/javascript" charset="utf-8"></script> diff --git a/phonegap/www/report_created.html b/phonegap/www/report_created.html index 6810ac60e..fe454259e 100644 --- a/phonegap/www/report_created.html +++ b/phonegap/www/report_created.html @@ -12,7 +12,7 @@ <meta http-equiv="content-type" content="text/html; charset=utf-8"> <script type="text/javascript" src="js/config.js"></script> - <script type="text/javascript" charset="utf-8" src="cordova-1.8.0.js"></script> + <script type="text/javascript" charset="utf-8" src="cordova-independent.js"></script> <script type="text/javascript" src="js/jquery-1.7.0.min.js"></script> <script type="text/javascript" src="js/mobile.js"></script> diff --git a/phonegap/www/signed_in.html b/phonegap/www/signed_in.html deleted file mode 100644 index 1ef6e284f..000000000 --- a/phonegap/www/signed_in.html +++ /dev/null @@ -1,83 +0,0 @@ -<!doctype html> -<html class="no-js" lang="en-gb"> - <head> - <meta name="viewport" content="initial-scale=1.0"> - - <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"> - <meta name="HandHeldFriendly" content="true"> - <meta name="mobileoptimized" content="0"> - - <link rel="stylesheet" href="css/base.css"> - <link rel="stylesheet" href="css/mobile.css"> - <link rel="stylesheet" href="css/layout.css" media="(min-width:48em)"> - - <script type="text/javascript" src="js/config.js"></script> - - <script type="text/javascript" charset="utf-8" src="cordova-1.8.0.js"></script> - - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <script type="text/javascript" src="js/jquery-1.7.0.min.js"></script> - - <script src="js/jquery.validate.min.js" type="text/javascript" charset="utf-8"></script> - - <script type="text/javascript" src="js/json2.js"></script> - <script type="text/javascript" src="js/geo.min.js"></script> - <script type="text/javascript" src="js/fixmystreet.js"></script> - <script type="text/javascript" src="js/mobile.js"></script> - <script type="text/javascript" src="js/OpenLayers.fixmystreet.js"></script> - <script type="text/javascript" src="js/map-OpenLayers.js"></script> - <script type="text/javascript" src="js/map-bing-ol.js"></script> - <script type="text/javascript" src="js/jquery.ba-hashchange.min.js"></script> - - <script type="text/javascript"> - validation_strings = { - update: 'Please enter a message', - title: 'Please enter a subject', - detail: 'Please enter some details', - name: { - required: 'Please enter your name', - validName: 'Please enter your full name, councils need this information – if you do not wish your name to be shown on the site, untick the box below' - }, - category: 'Please choose a category', - rznvy: { - required: 'Please enter your email', - email: 'Please enter a valid email' - }, - email: { - required: 'Please enter your email', - email: 'Please enter a valid email' - } - }; - </script> - <title> Viewing a location :: FixMyStreet </title> - </head> - - <body class="mobile-header signed-in-page" id="container"> - - <div class="wrapper"> - <div class="table-cell"> - <header id="site-header" role="banner"> - <div class="container"> - <span id="site-logo"></span> - </div> - </header> - - <div id="user-meta"> - - </div> - - <div class="container"> - <div class="content" role="main"> - - </div><!-- .content role=main --> - </div><!-- .container --> - </div><!-- .table-cell --> - - <div class="big-green-banner mobile-map-banner mobile-nav-banner"> - <a href="index.html">home</a> - Signed In - </div> - - </div> <!-- .wrapper --> -</body> -</html> diff --git a/t/app/controller/alert.t b/t/app/controller/alert.t index e1ebbecb6..3d95bef6d 100644 --- a/t/app/controller/alert.t +++ b/t/app/controller/alert.t @@ -40,7 +40,7 @@ $mech->get_ok('/alert/list?pc=High Street'); $mech->content_contains('We found more than one match for that location'); $mech->get_ok('/alert/list?pc='); -$mech->content_contains('hat location does not appear to be covered by a council'); +$mech->content_contains('To find out what local alerts we have for you'); $mech->get_ok('/alert/list?pc=GL502PR'); $mech->content_contains('Problems within the boundary of'); diff --git a/t/app/controller/alert_new.t b/t/app/controller/alert_new.t index 84634273a..c849b9485 100644 --- a/t/app/controller/alert_new.t +++ b/t/app/controller/alert_new.t @@ -330,7 +330,7 @@ subtest "Test two-tier council alerts" => sub { feed => $alert->{feed}, } } ); - is $mech->uri->path, $alert->{result}; + is $mech->uri->path, $alert->{result}, 'Redirected to right RSS feed'; } }; @@ -390,7 +390,7 @@ subtest "Test normal alert signups and that alerts are sent" => sub { used_map => 1, name => $user1->name, anonymous => 0, - state => 'confirmed', + state => 'fixed - user', confirmed => $dt, lastupdate => $dt, whensent => $dt->clone->add( minutes => 5 ), @@ -430,7 +430,7 @@ subtest "Test normal alert signups and that alerts are sent" => sub { problem_id => $report_id, user_id => $user2->id, name => 'Anonymous User', - mark_fixed => 'false', + mark_fixed => 'true', text => 'This is some more update text', state => 'confirmed', confirmed => $dt->clone->add( hours => 8 ), @@ -450,13 +450,23 @@ subtest "Test normal alert signups and that alerts are sent" => sub { $count++ if $_->body =~ /The following nearby problems have been added:/; $count++ if $_->body =~ /\s+-\s+Testing/; } - is $count, 5, 'Five emails with the right things in them'; + is $count, 5, 'Three emails, with five matching lines in them'; my $email = $emails[0]; like $email->body, qr/Other User/, 'Update name given'; unlike $email->body, qr/Anonymous User/, 'Update name not given'; - my ( $url, $url_token ) = $emails[0]->body =~ m{http://\S+(/A/(\S+))}; + # The update alert was to the problem reporter, so has a login update URL + $mech->get_ok( "/report/$report_id" ); + $mech->content_lacks( 'has not been fixed' ); + my ($url) = $email->body =~ m{(http://\S+/M/\S+)}; + ok $url, "extracted update url '$url'"; + $mech->get_ok( $url ); + is $mech->uri->path, "/report/" . $report_id, "redirected to report page"; + $mech->content_contains( 'has not been fixed' ); + $mech->logged_in_ok; + + ($url) = $emails[0]->body =~ m{http://\S+(/A/\S+)}; $mech->get_ok( $url ); $mech->content_contains('successfully deleted'); @@ -553,7 +563,7 @@ for my $test ( FixMyStreet::App->model('DB::AlertType')->email_alerts(); $mech->email_count_is(1); my $email = $mech->get_email; - like $email->body, qr/Alert test for non public reports/, 'alert contains public report'; + like $email->body, qr/Alert\s+test\s+for\s+non\s+public\s+reports/, 'alert contains public report'; $mech->delete_user( $user1 ); $mech->delete_user( $user2 ); diff --git a/t/app/controller/around.t b/t/app/controller/around.t index e1c76ff9f..d973543ce 100644 --- a/t/app/controller/around.t +++ b/t/app/controller/around.t @@ -66,6 +66,11 @@ foreach my $test ( latitude => '51.50101', longitude => '-0.141587', }, + { + pc => 'TQ 388 773', + latitude => '51.478074', + longitude => '-0.001966', + }, ) { subtest "check lat/lng for '$test->{pc}'" => sub { diff --git a/t/app/controller/index.t b/t/app/controller/index.t index 86d5e2d8c..462b21064 100644 --- a/t/app/controller/index.t +++ b/t/app/controller/index.t @@ -57,18 +57,21 @@ subtest "does pc, (x,y), (e,n) or (lat,lon) go to /around" => sub { $mech->delete_problems_for_council( 2651 ); +my $problem_rs = FixMyStreet::App->model('DB::Problem'); +my $num = $problem_rs->count; + my @edinburgh_problems = $mech->create_problems_for_council(5, 2651, 'Front page'); is scalar @edinburgh_problems, 5, 'correct number of edinburgh problems created'; -$mech->get_ok('/'); +$mech->get_ok('/report/' . $edinburgh_problems[2]->id); $mech->content_contains('Front page Test 3 for 2651', 'problem to be marked non public visible'); -$mech->content_contains('5</big> reports recently', 'number of recent problems correct'); +is $problem_rs->count, $num+5; my $private = $edinburgh_problems[2]; ok $private->update( { non_public => 1 } ), 'problem marked non public'; -$mech->get_ok('/'); -$mech->content_lacks('Front page Test 3 for 2651', 'non public problem is not visible'); -$mech->content_contains('5</big> reports recently', 'non public problems listed in recent problems stats'); +ok $mech->get('/report/' . $edinburgh_problems[2]->id); +is $mech->res->code, 403, 'page forbidden'; +is $problem_rs->count, $num+5; done_testing(); diff --git a/t/app/controller/questionnaire.t b/t/app/controller/questionnaire.t index 3475307fb..3a6a3d6ad 100644 --- a/t/app/controller/questionnaire.t +++ b/t/app/controller/questionnaire.t @@ -190,6 +190,25 @@ foreach my $test ( # update => 'Dummy', Error for not setting this tested below }, }, + { + desc => 'Closed report, said fixed, reported before, no update, no further questionnaire', + problem_state => 'closed', + fields => { + been_fixed => 'Yes', + reported => 'Yes', + another => 'No', + }, + }, + { + desc => 'Closed report, said not fixed, reported before, no update, no further questionnaire', + problem_state => 'closed', + fields => { + been_fixed => 'No', + reported => 'Yes', + another => 'No', + }, + lastupdate_static => 1, + }, ) { subtest $test->{desc} => sub { $report->state ( $test->{problem_state} ); @@ -224,7 +243,8 @@ foreach my $test ( $result = 'fixed' if $test->{fields}{been_fixed} eq 'Yes' && $test->{problem_state} eq 'fixed'; - $result = 'confirmed' if $test->{fields}{been_fixed} eq 'No'; + $result = 'confirmed' if $test->{fields}{been_fixed} eq 'No' && $test->{problem_state} ne 'closed'; + $result = 'closed' if $test->{fields}{been_fixed} eq 'No' && $test->{problem_state} eq 'closed'; $result = 'unknown' if $test->{fields}{been_fixed} eq 'Unknown'; my $another = 0; @@ -234,10 +254,12 @@ foreach my $test ( $mech->content_like( qr/<title>[^<]*Questionnaire/m ); $mech->content_contains( 'glad to hear it’s been fixed' ) if $result =~ /fixed/; + $mech->content_lacks( 'glad to hear it’s been fixed' ) + if $result !~ /fixed/; $mech->content_contains( 'get some more information about the status of your problem' ) if $result eq 'unknown'; $mech->content_contains( "sorry to hear that" ) - if $result eq 'confirmed'; + if $result eq 'confirmed' || $result eq 'closed'; # Check the database has the right information $report->discard_changes; diff --git a/t/app/controller/report_interest_count.t b/t/app/controller/report_interest_count.t new file mode 100644 index 000000000..dd44a83d4 --- /dev/null +++ b/t/app/controller/report_interest_count.t @@ -0,0 +1,143 @@ +use strict; +use warnings; +use Test::More; + +use FixMyStreet::TestMech; +use Web::Scraper; +use Path::Class; +use DateTime; + +my $mech = FixMyStreet::TestMech->new; + +# create a test user and report +$mech->delete_user('test@example.com'); +my $user = + FixMyStreet::App->model('DB::User') + ->find_or_create( { email => 'test@example.com', name => 'Test User' } ); +ok $user, "created test user"; + +my $user2 = + FixMyStreet::App->model('DB::User') + ->find_or_create( { email => 'test2@example.com', name => 'Other User' } ); +ok $user2, "created test user"; + +my $dt = DateTime->new( + year => 2011, + month => 04, + day => 16, + hour => 15, + minute => 47, + second => 23 +); + +my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( + { + postcode => 'SW1A 1AA', + council => '2504', + areas => ',105255,11806,11828,2247,2504,', + category => 'Other', + title => 'Test 2', + detail => 'Test 2 Detail', + used_map => 't', + name => 'Test User', + anonymous => 'f', + state => 'confirmed', + confirmed => $dt->ymd . ' ' . $dt->hms, + lang => 'en-gb', + service => '', + cobrand => 'default', + cobrand_data => '', + send_questionnaire => 't', + latitude => '51.5016605453401', + longitude => '-0.142497580865087', + user_id => $user->id, + } +); +my $report_id = $report->id; +ok $report, "created test report - $report_id"; + +SKIP: { + skip( "Need 'fixmybarangay' in ALLOWED_COBRANDS config", 29 ) + unless FixMyStreet::Cobrand->exists('fixmybarangay'); + for my $test ( + { + desc => 'if not from council then no supporter button', + from_council => 0, + support_string => 'No supporters', + }, + { + desc => 'from council user can increment supported count', + from_council => 2504, + support_string => 'No supporters', + updated_support => '1 supporter' + }, + { + desc => 'correct grammar for more than one supporter', + from_council => 2504, + support_string => '1 supporter', + updated_support => '2 supporters' + }, + ) { + subtest $test->{desc} => sub { + ok $mech->host('fixmybarangay.com'), 'changed to fixmybarangay'; + $mech->log_in_ok( $user->email ); + $user->from_council( $test->{from_council} ); + $user->update; + + $report->discard_changes; + $report->council( $test->{report_council} ); + $report->update; + + $mech->get_ok("/report/$report_id"); + $mech->content_contains( $test->{support_string} ); + + if ( $test->{from_council} ) { + $mech->content_contains('Add support'); + $mech->submit_form_ok( { form_number => 1 } ); + + is $mech->uri, "http://fixmybarangay.com/report/$report_id", 'add support redirects to report page'; + + $mech->content_contains($test->{updated_support}); + } else { + $mech->content_lacks( 'Add support' ); + } + }; + } + + subtest 'check non council user cannot increment support count' => sub { + ok $mech->host('fixmybarangay.com'), 'changed to fixmybarangay'; + $report->discard_changes; + $report->interest_count(1); + ok $report->update(), 'updated interest count'; + + $report->discard_changes; + is $report->interest_count, 1, 'correct interest count'; + + $mech->get_ok("/report/$report_id"); + $mech->content_contains( '1 supporter' ); + + $mech->post_ok("/report/support", { id => $report_id } ); + + is $mech->uri, "http://fixmybarangay.com/report/$report_id", 'add support redirects to report page'; + + $mech->content_contains( '1 supporter' ); + }; +}; + +subtest 'check support details not shown if not enabled in cobrand' => sub { + ok $mech->host('fixmystreet.com'), 'changed to fixmystreet'; + + $report->interest_count(1); + ok $report->update, 'updated interest count'; + + $mech->get_ok("/report/$report_id"); + $mech->content_lacks( '1 supporter' ); +}; + +$report->discard_changes; +$report->council( 2504 ); +$report->update; + +# tidy up +$mech->delete_user('test@example.com'); +done_testing(); diff --git a/t/app/controller/report_new.t b/t/app/controller/report_new.t index 2e7e60f75..77afb071c 100644 --- a/t/app/controller/report_new.t +++ b/t/app/controller/report_new.t @@ -1028,6 +1028,53 @@ for my $test ( }; } +subtest 'user title not reset if no user title in submission' => sub { + $mech->log_out_ok; + $mech->host( 'http://fixmystreet.com' ); + + my $user = $mech->log_in_ok( 'userwithtitle@example.com' ); + + ok $user->update( + { + name => 'Has Title', + phone => '0789 654321', + title => 'MR', + } + ), + "set users details"; + + + my $submission_fields = { + title => "Test Report", + detail => 'Test report details.', + photo => '', + name => 'Has Title', + may_show_name => '1', + phone => '07903 123 456', + category => 'Trees', + }; + + $mech->get_ok('/'); + $mech->submit_form_ok( { with_fields => { pc => 'EH99 1SP', } }, + "submit location" ); + $mech->follow_link_ok( + { text_regex => qr/skip this step/i, }, + "follow 'skip this step' link" + ); + + my $fields = $mech->visible_form_values('mapSkippedForm'); + ok !exists( $fields->{fms_extra_title} ), 'user title field not displayed'; + + $mech->submit_form_ok( { with_fields => $submission_fields }, + "submit good details" ); + + $user->discard_changes; + my $report = $user->problems->first; + ok $report, "Found report"; + is $report->title, "Test Report", "Report title correct"; + is $user->title, 'MR', 'User title unchanged'; +}; + SKIP: { skip( "Need 'lichfielddc' in ALLOWED_COBRANDS config", 100 ) unless FixMyStreet::Cobrand->exists('lichfielddc'); diff --git a/t/app/model/alert_type.t b/t/app/model/alert_type.t index 7df4c44c0..c592e9d3f 100644 --- a/t/app/model/alert_type.t +++ b/t/app/model/alert_type.t @@ -22,6 +22,10 @@ my $user2 = ->find_or_create( { email => 'commenter@example.com', name => 'Commenter' } ); ok $user2, "created comment user"; +my $user3 = + FixMyStreet::App->model('DB::User') + ->find_or_create( { email => 'bystander@example.com', name => 'Bystander' } ); +ok $user3, "created bystander"; my $dt = DateTime->new( year => 2011, @@ -96,6 +100,16 @@ my $alert = FixMyStreet::App->model('DB::Alert')->find_or_create( } ); +my $alert3 = FixMyStreet::App->model('DB::Alert')->find_or_create( + { + user => $user3, + parameter => $report_id, + alert_type => 'new_updates', + whensubscribed => $dt->ymd . ' ' . $dt->hms, + confirmed => 1, + } +); + for my $test ( { state => 'closed', @@ -115,7 +129,7 @@ for my $test ( my $sent = FixMyStreet::App->model('DB::AlertSent')->search( { - alert_id => $alert->id, + alert_id => [ $alert->id, $alert3->id ], parameter => $comment->id, } )->delete; @@ -125,18 +139,25 @@ for my $test ( FixMyStreet::App->model('DB::AlertType')->email_alerts(); - $mech->email_count_is( 1 ); - my $email = $mech->get_email; + $mech->email_count_is( 2 ); + my @emails = $mech->get_email; my $msg = $test->{msg}; - my $body = $email->body; - - like $body, qr/$msg/, 'email says problem is ' . $test->{state}; - like $body, qr{report/$report_id}, 'contains problem url'; - like $body, qr/This is some update text/, 'contains update text'; - unlike $body, qr/This is other update text/, 'does not contains other update text'; + for my $email (@emails) { + my $body = $email->body; + my $to = $email->header('To'); + + like $body, qr/$msg/, 'email says problem is ' . $test->{state}; + if ($to eq $user->email) { + like $body, qr{/M/}, 'contains problem login url'; + } elsif ($to eq $user3->email) { + like $body, qr{/report/$report_id}, 'contains problem url'; + } + like $body, qr/This is some update text/, 'contains update text'; + unlike $body, qr/This is other update text/, 'does not contains other update text'; - my $comments = $body =~ s/(------)//gs; - is $comments, 1, 'only 1 update'; + my $comments = $body =~ s/(------)//gs; + is $comments, 1, 'only 1 update'; + } }; } @@ -166,7 +187,6 @@ subtest "correct text for title after URL" => sub { )->delete; FixMyStreet::App->model('DB::AlertType')->email_alerts(); - $mech->email_count_is( 1 ); my $email = $mech->get_email; (my $title = $report->title) =~ s/ /\\s+/; my $body = $email->body; @@ -300,7 +320,6 @@ foreach my $test ( FixMyStreet::App->model('DB::AlertType')->email_alerts(); - $mech->email_count_is( 1 ); my $email = $mech->get_email; my $body = $email->body; @@ -406,7 +425,6 @@ subtest "check alerts from cobrand send main site url for alerts for different c FixMyStreet::App->model('DB::AlertType')->email_alerts(); - $mech->email_count_is( 1 ); my $email = $mech->get_email; my $body = $email->body; @@ -444,7 +462,6 @@ subtest "check local alerts from cobrand send main site url for alerts for diffe FixMyStreet::App->model('DB::AlertType')->email_alerts(); - $mech->email_count_is( 1 ); my $email = $mech->get_email; my $body = $email->body; diff --git a/t/app/model/problem.t b/t/app/model/problem.t index 8aabce4f7..9aa52c3cf 100644 --- a/t/app/model/problem.t +++ b/t/app/model/problem.t @@ -483,6 +483,10 @@ foreach my $test ( { }, ) { subtest $test->{ desc } => sub { + if ( $test->{cobrand} && $test->{cobrand} =~ /lichfielddc/ && !FixMyStreet::Cobrand->exists('lichfielddc') ) { + plan skip_all => 'Skipping Lichfield tests without Lichfield cobrand'; + } + $mech->clear_emails_ok; FixMyStreet::App->model('DB::Problem')->search( @@ -491,10 +495,6 @@ foreach my $test ( { } )->update( { whensent => \'ms_current_timestamp()' } ); - if ( $test->{cobrand} && $test->{cobrand} =~ /lichfielddc/ && !FixMyStreet::Cobrand->exists('lichfielddc') ) { - plan skip_all => 'Skipping Lichfield tests without Lichfield cobrand'; - } - $problem->discard_changes; $problem->update( { council => $test->{ council }, diff --git a/t/cobrand/councils.t b/t/cobrand/councils.t new file mode 100644 index 000000000..8fb10cfbe --- /dev/null +++ b/t/cobrand/councils.t @@ -0,0 +1,18 @@ +use strict; +use warnings; +use Test::More; + +use FixMyStreet::TestMech; +my $mech = FixMyStreet::TestMech->new; + +foreach my $council (qw/southampton reading bromley/) { + SKIP: { + skip( "Need '$council' in ALLOWED_COBRANDS config", 3 ) + unless FixMyStreet::Cobrand->exists($council); + ok $mech->host("$council.fixmystreet.com"), "change host to $council"; + $mech->get_ok('/'); + $mech->content_like( qr/$council/i ); + } +} + +done_testing(); diff --git a/t/cobrand/get_council_sender.t b/t/cobrand/get_council_sender.t index 9004a47f5..e61f36370 100644 --- a/t/cobrand/get_council_sender.t +++ b/t/cobrand/get_council_sender.t @@ -13,8 +13,8 @@ mySociety::Locale::gettext_domain( 'FixMyStreet' ); my $c = FixMyStreet::Cobrand::FixMyStreet->new(); -is $c->get_council_sender( '1000', { type => 'DIS' } ), 'Email', 'defaults to email'; -is $c->get_council_sender( '1000', { type => 'LBO' } ), 'London', 'returns london report it if London borough'; +is_deeply $c->get_council_sender( '1000', { type => 'DIS' } ), { method => 'Email' }, 'defaults to email'; +is_deeply $c->get_council_sender( '1000', { type => 'LBO' } ), { method=> 'London' }, 'returns london report it if London borough'; my $conf = FixMyStreet::App->model('DB::Open311Conf')->find_or_create( area_id => 1000, @@ -22,8 +22,8 @@ my $conf = FixMyStreet::App->model('DB::Open311Conf')->find_or_create( send_method => 'TestMethod' ); -is $c->get_council_sender( '1000', { type => 'LBO' } ), 'TestMethod', 'uses send_method in preference to London'; -is $c->get_council_sender( '1000', { type => 'DIS' } ), 'TestMethod', 'uses send_method in preference to Email'; +is $c->get_council_sender( '1000', { type => 'LBO' } )->{ method }, 'TestMethod', 'uses send_method in preference to London'; +is $c->get_council_sender( '1000', { type => 'DIS' } )->{ method }, 'TestMethod', 'uses send_method in preference to Email'; $conf->delete; @@ -7,6 +7,7 @@ use FixMyStreet; use mySociety::Locale; use Encode; use Data::Dumper; +use HTTP::Headers; use Sort::Key qw(keysort); use POSIX 'strcoll'; local $Data::Dumper::Sortkeys = 1; @@ -18,6 +19,16 @@ die "You need to run 'commonlib/bin/gettext-makemo --quiet FixMyStreet' " unless -e FixMyStreet->path_to( 'locale/cy_GB.UTF-8/LC_MESSAGES/FixMyStreet-EmptyHomes.mo'); +# Test the language negotiation works +my $lang = mySociety::Locale::negotiate_language( + 'en-gb,English,en_GB|cy,Cymraeg,cy_GB|es,Spanish,es_ES', + undef, + HTTP::Headers->new( + Accept_Language => 'es,en-gb;q=0.6,en;q=0.4' + ) +); +is $lang, 'es', 'Language negotiation works okay'; + # Example strings my $english = "Please enter a valid email"; my $welsh = "Cofnodwch gyfeiriad e-bost dilys"; diff --git a/t/open311.t b/t/open311.t index 15a3f2646..2371c53bc 100644 --- a/t/open311.t +++ b/t/open311.t @@ -37,9 +37,10 @@ my $p = FixMyStreet::App->model('DB::Problem')->new( { title => 'title', detail => 'detail', user => $u, + id => 1, } ); -my $expected_error = qr{.*request failed: 500 Can.t connect to 192.168.50.1:80 \([^)]*\).*}; +my $expected_error = qr{Failed to submit problem 1 over Open311}ism; warning_like {$o2->send_service_request( $p, { url => 'http://example.com/' }, 1 )} $expected_error, 'warning generated on failed call'; diff --git a/templates/email/fixmybarangay/site-name.txt b/templates/email/fixmybarangay/site-name.txt new file mode 100644 index 000000000..075d881b5 --- /dev/null +++ b/templates/email/fixmybarangay/site-name.txt @@ -0,0 +1 @@ +FixMyBarangay diff --git a/templates/web/default/admin/council_contacts.html b/templates/web/default/admin/council_contacts.html index 60e270c7c..eb9606a31 100644 --- a/templates/web/default/admin/council_contacts.html +++ b/templates/web/default/admin/council_contacts.html @@ -1,5 +1,7 @@ [% INCLUDE 'admin/header.html' title=tprintf(loc('Council contacts for %s'), council_name) -%] +[% conf = open311.next %] + [% IF updated %] <p> <em>[% updated %]</em> @@ -36,6 +38,7 @@ <th>[% loc('Email') %]</th> <th>[% loc('Confirmed') %]</th> <th>[% loc('Deleted') %]</th> + <th>[% loc('Devolved') %]</th> <th>[% loc('Last editor') %]</th> <th>[% loc('Note') %]</th> <th>[% loc('Public') %]</th> @@ -48,6 +51,7 @@ <td>[% contact.email | html %]</td> <td>[% IF contact.confirmed %][% loc('Yes') %][% ELSE %][% loc('No') %][% END %]</td> <td>[% IF contact.deleted %][% loc('Yes') %][% ELSE %][% loc('No') %][% END %]</td> + <td>[% IF conf.can_be_devolved && contact.send_method %][% loc('Yes') %][% ELSE %][% loc('No') %][% END %]</td> <td>[% contact.editor %]</td> <td>[% contact.note | html %]</td> <td>[% contact.non_public ? loc('Non Public') : loc('Public') %]</td> @@ -111,7 +115,6 @@ <h2>[% loc('Configure Open311 integration') %]</h2> <form method="post" action="[% c.uri_for('council_contacts', area_id ) %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8"> - [% conf = open311.next %] <p> <label for="endpoint">Endpoint</label>: <input type="text" name="endpoint" id="endpoint" value="[% conf.endpoint %]" size="50"> @@ -153,6 +156,11 @@ </p> <p> + <label for="devolved">Endpoint lookup can be devolved to contacts</label>: + <input type="checkbox" name="devolved"[% ' checked' IF conf.can_be_devolved %]> + </p> + + <p> <input type="hidden" name="open311_id" value="[% conf.id %]"> <input type="hidden" name="area_id" value="[% area_id %]"> <input type="hidden" name="posted" value="open311"> diff --git a/templates/web/default/admin/council_edit.html b/templates/web/default/admin/council_edit.html index 9ec0578ff..408466b51 100644 --- a/templates/web/default/admin/council_edit.html +++ b/templates/web/default/admin/council_edit.html @@ -31,6 +31,33 @@ <strong>[% loc('Note:') %] </strong><textarea name="note" rows="3" cols="40">[% contact.note | html %]</textarea> <br> + <h2>[% loc('Configure Endpoint') %]</h2> + <form method="post" action="[% c.uri_for('council_contacts', area_id ) %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8"> + <p> + <label for="endpoint">Endpoint</label>: + <input type="text" name="endpoint" id="endpoint" value="[% contact.endpoint %]" size="50"> + </p> + + <p> + <label for="jurisdiction">Jurisdiction</label>: + <input type="text" name="jurisdiction" id="jurisdiction" value="[% contact.jurisdiction %]" size="50"> + </p> + + <p> + <label for="api_key">Api Key</label>: + <input type="text" name="api_key" id="api_key" value="[% contact.api_key %]" size="25"> + </p> + + <p> + <label for="send_method">Send Method</label>: + <select name="send_method"> + <option value=""> -- Select a method -- </option> + [% FOR method IN send_methods %] + <option value="[% method %]"[% ' selected' IF contact.send_method == method %]>[% method %]</option> + [% END %] + </select> + </p> + <input type="hidden" name="area_id" value="[% area_id %]"> <input type="hidden" name="posted" value="new"> <input type="submit" name="Save changes" value="[% loc('Save changes') %]"> diff --git a/templates/web/default/admin/index.html b/templates/web/default/admin/index.html index b1eddaa3a..2c5ee55db 100644 --- a/templates/web/default/admin/index.html +++ b/templates/web/default/admin/index.html @@ -21,7 +21,7 @@ [% IF c.cobrand.admin_show_creation_graph -%] <p> - <a href="[% c.config.BASE_URL %]/bci-live-creation.png">[% loc('Graph of problem creation by status over time') %]</a> + <a href="[% c.config.BASE_URL %]/fms-live-creation.png">[% loc('Graph of problem creation by status over time') %]</a> </p> [% END -%] diff --git a/templates/web/default/admin/report_edit.html b/templates/web/default/admin/report_edit.html index d283037c2..ea98a9be9 100644 --- a/templates/web/default/admin/report_edit.html +++ b/templates/web/default/admin/report_edit.html @@ -40,7 +40,7 @@ <li>[% loc('Extra data:') %] [% problem.extra ? 'Yes' : 'No' %]</li> <li>[% loc('Going to send questionnaire?') %] [% IF problem.send_questionnaire %][% loc('Yes') %][% ELSE %][% loc('No') %][% END %]</li> <li><label for="flagged">[% loc('Flagged:') %]</label> <input type="checkbox" name="flagged"[% ' checked' IF problem.flagged %]></li> -<li><label for="non_public">[% loc('Private:') %]</label> <input type="checkbox" name="non_public"[% ' checked' IF problem.non_public %]></li> +<li><label for="non_public">[% loc('Private') %]:</label> <input type="checkbox" name="non_public"[% ' checked' IF problem.non_public %]></li> [% IF problem.photo %] [% photo = problem.get_photo_params %] diff --git a/templates/web/default/admin/stats.html b/templates/web/default/admin/stats.html index 3b9f4a264..273a71aec 100644 --- a/templates/web/default/admin/stats.html +++ b/templates/web/default/admin/stats.html @@ -2,7 +2,7 @@ [% IF show_count %] <p> -<strong>[% tprintf( loc( '%sreports between %s and %s' ), ( unconfirmed ? loc( 'All' ) _ ' ' : loc( 'Confirmed' ) _ ' ' ), start_date.ymd, end_date.ymd ) | html %]</strong> +<strong>[% tprintf( unconfirmed ? loc( 'All reports between %s and %s' ) : loc( 'Confirmed reports between %s and %s' ), start_date.ymd, end_date.ymd ) | html %]</strong> </p> [% IF bymonth %] <table> diff --git a/templates/web/default/around/_report_banner.html b/templates/web/default/around/_report_banner.html new file mode 100755 index 000000000..024fe08d9 --- /dev/null +++ b/templates/web/default/around/_report_banner.html @@ -0,0 +1,10 @@ +<p id="text_map" class="banner"> + [% loc( 'To <strong>report a problem</strong>, click on the map at the correct location.' ) %] + [% + tprintf( + loc("<small>If you cannot see the map, <a href='%s' rel='nofollow'>skip this step</a>.</small>"), + url_skip + ) + %] + <span id="text_map_arrow"></span> +</p> diff --git a/templates/web/default/around/_updates.html b/templates/web/default/around/_updates.html new file mode 100755 index 000000000..8110a6c7c --- /dev/null +++ b/templates/web/default/around/_updates.html @@ -0,0 +1,12 @@ +<h1>[% loc('Problems in this area') %]</h1> + +<p id="alert_links_area"> + <a id="email_alert" rel="nofollow" href="[% email_url | html %]"> + [%- loc('Email me new local problems') -%] +</a> | + <a href="[% rss_url | html %]" id="rss_alert"> + <span>[% rss_alt %]</span> + <img src="/i/feed.png" width="16" height="16" title="[% rss_title %]" alt="[% rss_alt %]" border="0" style="vertical-align: top"> + </a> +</p> + diff --git a/templates/web/default/around/display_location.html b/templates/web/default/around/display_location.html index 88f8b89ae..d50009299 100755 --- a/templates/web/default/around/display_location.html +++ b/templates/web/default/around/display_location.html @@ -32,97 +32,72 @@ INCLUDE 'header.html', title => loc('Viewing a location') rss => [ loc('Recent local problems, FixMyStreet'), rss_url ], + bodyclass => 'mappage', robots => 'noindex,nofollow'; + + allow_creation = !c.cobrand.only_authed_can_create || (c.user && c.user.from_council); %] +[% IF allow_creation %] <form action="[% c.uri_for('/report/new') %]" method="post" name="mapForm" id="mapForm" enctype="multipart/form-data" class="validate"> -[% IF c.req.params.map_override %] -<input type="hidden" name="map_override" value="[% c.req.params.map_override | html %]"> + [% IF c.req.params.map_override %] + <input type="hidden" name="map_override" value="[% c.req.params.map_override | html %]"> + [% END %] + <input type="hidden" name="pc" value="[% pc | html %]"> + + <input type="hidden" name="latitude" id="fixmystreet.latitude" value="[% short_latitude | html %]"> + <input type="hidden" name="longitude" id="fixmystreet.longitude" value="[% short_longitude | html %]"> [% END %] -<input type="hidden" name="pc" value="[% pc | html %]"> -<input type="hidden" name="latitude" id="fixmystreet.latitude" value="[% short_latitude | html %]"> -<input type="hidden" name="longitude" id="fixmystreet.longitude" value="[% short_longitude | html %]"> + [% map_html %] -[% map_html %] + <p id='sub_map_links'> + [% IF c.req.params.no_pins %] + <a id='hide_pins_link' rel='nofollow' href='[% c.uri_with( { no_pins => 0 } ) %]'>[% loc('Show pins') %]</a> + [% ELSE %] + <a id='hide_pins_link' rel='nofollow' href='[% c.uri_with( { no_pins => 1 } ) %]'>[% loc('Hide pins') %]</a> + [% END %] + [% IF c.cobrand.country == 'GB' || c.cobrand.country == 'NO' %] + <span class="hidden">|</span> + [% IF c.req.params.all_pins %] + <a id='all_pins_link' rel='nofollow' href='[% c.uri_with( { no_pins => undef, all_pins => undef } ) %]'>[% loc('Hide old') %]</a> + [% ELSE %] + <a id='all_pins_link' rel='nofollow' href='[% c.uri_with( { no_pins => undef, all_pins => 1 } ) %]'>[% loc('Show old') %]</a> + [% END %] + [% END %] + </p> -<p id='sub_map_links'> - [% IF c.req.params.no_pins %] - <a id='hide_pins_link' rel='nofollow' href='[% c.uri_with( { no_pins => 0 } ) %]'>[% loc('Show pins') %]</a> - [% ELSE %] - <a id='hide_pins_link' rel='nofollow' href='[% c.uri_with( { no_pins => 1 } ) %]'>[% loc('Hide pins') %]</a> - [% END %] - [% IF c.cobrand.country == 'GB' || c.cobrand.country == 'NO' %] - | - [% IF c.req.params.all_pins %] - <a id='all_pins_link' rel='nofollow' href='[% c.uri_with( { no_pins => undef, all_pins => undef } ) %]'>[% loc('Hide old') %]</a> - [% ELSE %] - <a id='all_pins_link' rel='nofollow' href='[% c.uri_with( { no_pins => undef, all_pins => 1 } ) %]'>[% loc('Show old') %]</a> + </div> + + + + + <div id="side"> + + [% IF allow_creation %] + [% INCLUDE 'around/_report_banner.html' %] + [% TRY %][% INCLUDE 'around/extra_text.html' %][% CATCH file %][% END %] [% END %] - [% END %] -</p> - -</div> -<div id="side"> - -<p id="text_map" class="banner"> - [% loc( 'To <strong>report a problem</strong>, click on the map at the correct location.' ) %] - [% - tprintf( - loc("<small>If you cannot see the map, <a href='%s' rel='nofollow'>skip this step</a>.</small>"), - url_skip - ) + + [% INCLUDE 'around/_updates.html' %] + + <section class="full-width"> + [% INCLUDE "around/tabbed_lists.html" %] + </section> + </div> + + [% IF allow_creation %] + <div style="display:none" id="side-form"> + [% INCLUDE "report/new/fill_in_details_form.html" + js = 1, + report.used_map = 1 + report.name = c.user.name %] - <span id="text_map_arrow"></span> -</p> - -[% TRY %][% INCLUDE 'around/extra_text.html' %][% CATCH file %][% END %] - -<h1>[% loc('Problems in this area') %]</h1> - -<p id="alert_links_area"> - <a id="email_alert" rel="nofollow" href="[% email_url | html %]"> - [%- loc('Email me new local problems') -%] -</a> | - <a href="[% rss_url | html %]" id="rss_alert"> - <span>[% rss_alt %]</span> - <img src="/i/feed.png" width="16" height="16" title="[% rss_title %]" alt="[% rss_alt %]" border="0" style="vertical-align: top"> - </a> -</p> - -<div id="nearby_lists"> - - <h2>[% loc('Reports on and around the map') %]</h2> - - <ul id="current"> - [% INCLUDE "around/on_map_list_items.html" %] - </ul> - - - <h2> - [% - tprintf( - loc( 'Closest nearby problems <small>(within %skm)</small>' ), - distance - ) - %] - </h2> - - <ul id="current_near"> - [% INCLUDE "around/around_map_list_items.html" %] - </ul> - -</div> - -</div> - -<div style="display:none" id="side-form"> -[% INCLUDE "report/new/fill_in_details_form.html" - js = 1, - report.used_map = 1 -%] -</div> + </div> + [% END %] +[% IF allow_creation %] </form> +[% END %] [% INCLUDE 'footer.html' %] diff --git a/templates/web/default/around/tabbed_lists.html b/templates/web/default/around/tabbed_lists.html new file mode 100755 index 000000000..4ad7b35fc --- /dev/null +++ b/templates/web/default/around/tabbed_lists.html @@ -0,0 +1,23 @@ +<div id="nearby_lists"> + + <h2>[% loc('Reports on and around the map') %]</h2> + + <ul id="current"> + [% INCLUDE "around/on_map_list_items.html" %] + </ul> + + <h2> + [% + tprintf( + loc( 'Closest nearby problems <small>(within %skm)</small>' ), + distance + ) + %] + </h2> + + <ul id="current_near"> + [% INCLUDE "around/around_map_list_items.html" %] + </ul> + +</div> + diff --git a/templates/web/default/dashboard/index.html b/templates/web/default/dashboard/index.html index c2bfa9ea3..169d7d3fe 100644 --- a/templates/web/default/dashboard/index.html +++ b/templates/web/default/dashboard/index.html @@ -17,6 +17,7 @@ </hgroup> <div class="filters"> + [% IF c.cobrand.moniker != 'fixmybarangay' %] <p> <label for="ward">Ward:</label> <select name="ward"><option value=''>All</option> @@ -25,6 +26,7 @@ [% END %] </select> </p> + [% END %] <p> <label for="category">Report category:</label> diff --git a/templates/web/default/faq/faq-en-gb.html b/templates/web/default/faq/faq-en-gb.html index f0030dcb9..26f93afb8 100755 --- a/templates/web/default/faq/faq-en-gb.html +++ b/templates/web/default/faq/faq-en-gb.html @@ -190,7 +190,7 @@ rights reserved, Ministry of Justice 100037819 2008), Yahoo! for their BSD-licensed JavaScript libraries, the entire free software community (this particular project was brought to you by Perl, PostgreSQL, and the number 161.290) and <a -href="http://www.m247.com/">M247</a> (who kindly host all +href="http://www.bytemark.co.uk/">Bytemark</a> (who kindly host all our servers). Let us know if we’ve missed anyone.</dd> diff --git a/templates/web/default/index-steps.html b/templates/web/default/index-steps.html new file mode 100644 index 000000000..7129241d2 --- /dev/null +++ b/templates/web/default/index-steps.html @@ -0,0 +1,24 @@ +<h2>[% loc('How to report a problem') %]</h2> + +<ol class="big-numbers"> +[% IF c.cobrand.moniker == 'fixmybarangay' %] + <li>Text LUZ or BSN followed by your report to 12345</li> + <li>Visit the Barangay Center in person</li> + <li>Staff? <a href="/auth">Sign in</a> and click on the map! +[% ELSE %] + <li>[% question %]</li> + <li>[% loc('Locate the problem on a map of the area') %]</li> + <li>[% loc('Enter details of the problem') %]</li> + [% IF c.cobrand.is_council %] + <li>Confirm the report and [% c.cobrand.council_name %] will investigate</li> + [% ELSE %] + <li>[% loc('We send it to the council on your behalf') %]</li> + [% END %] +[% END %] +</ol> + +<section class="full-width"> +[% INCLUDE "front/stats.html" %] +[% TRY %][% INCLUDE "front/tips.html" %][% CATCH file %][% END %] +</section> + diff --git a/templates/web/default/index.html b/templates/web/default/index.html index 159a595bc..3698d6494 100644 --- a/templates/web/default/index.html +++ b/templates/web/default/index.html @@ -1,4 +1,4 @@ -[% INCLUDE 'header.html', title => '' %] +[% INCLUDE 'header.html', title = '' %] [% IF error %] <p class="error">[% error %]</p> @@ -24,19 +24,7 @@ [% PROCESS 'around/postcode_form.html' %] <div id="front_intro"> - - <h2>[% loc('How to report a problem') %]</h2> - - <ol> - <li>[% question %]</li> - <li>[% loc('Locate the problem on a map of the area') %]</li> - <li>[% loc('Enter details of the problem') %]</li> - <li>[% loc('We send it to the council on your behalf') %]</li> - </ol> - - [% INCLUDE "front/stats.html" %] - [% TRY %][% INCLUDE "front/tips.html" %][% CATCH file %][% END %] - + [% INCLUDE 'index-steps.html' %] </div> [% @@ -44,7 +32,6 @@ probs = c.cobrand.recent(); %] - [% IF probs.size || recent_photos.size %] <div id="front_recent"> <h2>[% loc('Recently reported problems') %]</h2> @@ -58,8 +45,6 @@ [% END %] [% IF probs.size %] - - <ul id="nearby_lists"> [% FOREACH p IN probs %] <li> diff --git a/templates/web/default/maps/openlayers.html b/templates/web/default/maps/openlayers.html index e815642f1..b75e2bbd8 100644 --- a/templates/web/default/maps/openlayers.html +++ b/templates/web/default/maps/openlayers.html @@ -8,7 +8,7 @@ <script type="text/javascript"> var fixmystreet = { 'page': '[% page %]', - 'area': '[% map.area %]', + 'area': [ [% map.area.join(',') %] ], 'all_pins': '[% all_pins %]', 'latitude': [% map.latitude %], 'longitude': [% map.longitude %], diff --git a/templates/web/default/questionnaire/completed-open.html b/templates/web/default/questionnaire/completed-open.html index 7c5469259..06e17cc0b 100644 --- a/templates/web/default/questionnaire/completed-open.html +++ b/templates/web/default/questionnaire/completed-open.html @@ -1,5 +1,11 @@ +[% IF c.cobrand.is_council %] +<p style="font-size: 150%"> +Thank you very much for filling in our questionnaire. +</p> +[% ELSE %] [% loc('<p style="font-size:150%">We’re sorry to hear that. We have two suggestions: why not try writing to your local representative or, if it’s a problem that could be fixed by local people working together, why not <a href="http://www.pledgebank.com/new">make and publicise a pledge</a>? </p>') %] +[% END %] diff --git a/templates/web/default/questionnaire/completed.html b/templates/web/default/questionnaire/completed.html index a125d48bd..52c20652c 100644 --- a/templates/web/default/questionnaire/completed.html +++ b/templates/web/default/questionnaire/completed.html @@ -10,12 +10,12 @@ get some more information about the status of your problem, please come back to the site and leave an update.</p>') %] -[% ELSIF new_state == 'confirmed' OR (!new_state AND problem.is_open) %] +[% ELSIF new_state == 'confirmed' OR (!new_state AND problem.is_open) OR (!new_state AND problem.is_closed) %] [% INCLUDE 'questionnaire/completed-open.html' %] [% advert_outcome = 0 %] -[% ELSE %] +[% ELSIF been_fixed == 'Yes' %] [% loc('<p style="font-size:150%">Thank you very much for filling in our questionnaire; glad to hear it’s been fixed.</p>') %] diff --git a/templates/web/default/report/_main.html b/templates/web/default/report/_main.html index 3a9e60e7b..b9779db69 100644 --- a/templates/web/default/report/_main.html +++ b/templates/web/default/report/_main.html @@ -1,20 +1,27 @@ -<h1>[% problem.title | html %]</h1> +<div class="problem-header cf"> + <h1>[% problem.title | html %]</h1> -<p><em>[% problem.meta_line(c) | html %] -[% IF problem.council %] - [% IF problem.whensent || problem.can_display_external_id %] - <small class="council_sent_info"><br> - [% problem.processed_summary_string(c) %] - </small> - [% END %] -[% ELSE %] -<br><small>[% loc('Not reported to council') %]</small> -[% END %] - -</em></p> - -[% add_links( problem.detail ) | html_para %] - -[% INCLUDE 'report/photo.html' object=problem center=1 %] + <p><em> + [% problem.meta_line(c) | html %] + [%- IF !problem.used_map %]; <strong>[% loc('there is no pin shown as the user did not use the map') %]</strong>[% END %] + [% IF problem.council %] + [% IF problem.whensent || problem.can_display_external_id %] + <small class="council_sent_info"><br> + [% problem.processed_summary_string(c) %] + </small> + [% END %] + [% ELSE %] + <br><small>[% loc('Not reported to council') %]</small> + [% END %] + </em></p> + [% INCLUDE 'report/_support.html' %] + [% IF c.cobrand.moniker == 'southampton' %] + [% add_links( problem.detail ) | html_para %] + [% INCLUDE 'report/photo.html' object=problem %] + [% ELSE %] + [% INCLUDE 'report/photo.html' object=problem %] + [% add_links( problem.detail ) | html_para %] + [% END %] +</div> diff --git a/templates/web/default/report/_support.html b/templates/web/default/report/_support.html new file mode 100644 index 000000000..e8b958940 --- /dev/null +++ b/templates/web/default/report/_support.html @@ -0,0 +1,11 @@ +[% IF c.cobrand.can_support_problems %] +<p id="supporter"><small> + [% IF !problem.interest_count %][% text=loc('No supporters') %][% ELSIF problem.interest_count == 1 %][% text = loc('1 supporter') %][% ELSE %][% text = tprintf( loc('%d supporters' ), problem.interest_count ) %][% END %] + [% IF c.user && c.user.from_council %]<form action="[% c.uri_for( '/report/support' ) %]"> + [% text %] <input type="hidden" name="id" value="[% problem.id %]"><input type="submit" class="green-btn" value="Add support"> + </form> + [% ELSE %] + [% text %] + [% END %] +</small></p> +[% END %] diff --git a/templates/web/default/report/photo.html b/templates/web/default/report/photo.html index 451a0479c..02ab9228b 100644 --- a/templates/web/default/report/photo.html +++ b/templates/web/default/report/photo.html @@ -1,6 +1,8 @@ [% IF c.cobrand.allow_photo_display && object.photo %] [% photo = object.get_photo_params %] -<p[% ' align="center"' IF center %]> - <img alt="" height="[% photo.height %]" width="[% photo.width %]" src="[% photo.url %]"> -</p> +<div class="update-img"> + [% IF photo.url_full %]<a href="[% photo.url_full %]" rel="fancy">[% END + %]<img alt="Photo of this report" [% IF photo.height %]height="[% photo.height %]" width="[% photo.width %]"[% END %] src="[% photo.url %]"> + [%- IF photo.url_full %]<span>zoom</span></a>[% END %] +</div> [% END %] diff --git a/templates/web/default/reports/index.html b/templates/web/default/reports/index.html index 283df5285..76c2afcd2 100755 --- a/templates/web/default/reports/index.html +++ b/templates/web/default/reports/index.html @@ -34,6 +34,7 @@ <td class="data">[% fixed.${area.id}.new or 0 %]</td> <td class="data">[% fixed.${area.id}.old or 0 %]</td> </tr> +[% TRY %][% PROCESS "reports/_extras.html" %][% CATCH file %][% END %] [% END %] </tbody> </table> diff --git a/templates/web/emptyhomes/faq/faq-cy.html b/templates/web/emptyhomes/faq/faq-cy.html index 3bea990c8..c462b9719 100644 --- a/templates/web/emptyhomes/faq/faq-cy.html +++ b/templates/web/emptyhomes/faq/faq-cy.html @@ -54,7 +54,7 @@ Os taw’r llywodraeth neu un o’i hasiantaethau sy’n berchen ar yr eiddo gwa , Y Weinyddiaeth Gyfiawnder 100037819 2008), Yahoo! am eu llyfrgelloedd JavaScript wedi’u trwyddedu gan BSD, y gymuned meddalwedd am ddim gyfan (daethpwyd â’r prosiect arbennig hwn i chi gan Perl, PostgreSQL, a’r rhif 161.290) ac <a - href="http://www.m247.com/">M247</a> (sydd mor garedig â gwesteia’n holl weinyddion). + href="http://www.bytemark.co.uk/">Bytemark</a> (sydd mor garedig â gwesteia’n holl weinyddion). Rhowch wybod i ni os ydym wedi hepgor unrhyw un.</dd> diff --git a/templates/web/emptyhomes/faq/faq-en-gb.html b/templates/web/emptyhomes/faq/faq-en-gb.html index 9f66613a7..e010ddae0 100755 --- a/templates/web/emptyhomes/faq/faq-en-gb.html +++ b/templates/web/emptyhomes/faq/faq-en-gb.html @@ -98,7 +98,7 @@ rights reserved, Ministry of Justice 100037819 2008), Yahoo! for their BSD-licensed JavaScript libraries, the entire free software community (this particular project was brought to you by Perl, PostgreSQL, and the number 161.290) and <a -href="http://www.m247.com/">M247</a> (who kindly host all +href="http://www.bytemark.co.uk/">Bytemark</a> (who kindly host all our servers). Let us know if we’ve missed anyone.</dd> diff --git a/templates/web/emptyhomes/report/display.html b/templates/web/emptyhomes/report/display.html index e9a101e3e..545a4ca44 100644 --- a/templates/web/emptyhomes/report/display.html +++ b/templates/web/emptyhomes/report/display.html @@ -9,7 +9,7 @@ [% IF problem.is_fixed %] <p class="banner" id="fixed"> - [% loc('This problem has been fixed') . '.' %]; + [% loc('This problem has been fixed') %]. </p> [% END %] diff --git a/templates/web/fixmybarangay/_barangay_buttons.html b/templates/web/fixmybarangay/_barangay_buttons.html new file mode 100644 index 000000000..2925a487d --- /dev/null +++ b/templates/web/fixmybarangay/_barangay_buttons.html @@ -0,0 +1,4 @@ +<p id="barangay_buttons"> + <a href="/around?latitude=10.322;longitude=123.907" class="yellow-btn">Bgy. Luz</a> + <a href="/around?latitude=10.288;longitude=123.870" class="yellow-btn">Bgy. Basak San Nicolas</a> +</p> diff --git a/templates/web/fixmybarangay/alert/_list.html b/templates/web/fixmybarangay/alert/_list.html new file mode 100644 index 000000000..8491b4562 --- /dev/null +++ b/templates/web/fixmybarangay/alert/_list.html @@ -0,0 +1,45 @@ + <input type="hidden" name="type" value="local"> + <input type="hidden" name="pc" value="[% pc | html %]"> + + + <p> + [% loc("Subscribe to an alert based upon what baranagay you’re in:") %] + </p> + + [% INCLUDE 'errors.html' %] + + <div id="rss_list"> + <p><strong> + [% loc('Problems within the boundary of:') %] + </strong></p> + <ul class="plain-list"> + + [% FOREACH option IN options %] + <li[% IF ! (loop.count % 2) %] class="a"[% END %]> + <input type="radio" name="feed" id="[% option.id %]" value="[% option.id %]"[% IF option.id == selected_feed %] checked[% END %]> + <label class="inline" for="[% option.id %]">[% option.text %]</label> + <a href="[% option.uri %]"><img src="/i/feed.png" width="16" height="16" +title="[% option.rss_text %]" alt="RSS feed" border="0"></a> + </li> + [% END %] +</ul> + + <p> + <input type="submit" name="rss" value="[% loc('Give me an RSS feed') %]"> + <p> + + <p id="alert_or"> + [% loc('or') %] + </p> + + [% UNLESS c.user_exists %] + <p> + [% loc('Your email:') %] <input type="text" id="rznvy" name="rznvy" value="[% rznvy | html %]" size="30"> + </p> + [% END %] + + <p> + <input type="submit" name="alert" value="[% loc('Subscribe me to an email alert') %]"> + </p> + </div> <!-- ???? --> + diff --git a/templates/web/fixmybarangay/alert/index.html b/templates/web/fixmybarangay/alert/index.html new file mode 100644 index 000000000..d9bb74ee9 --- /dev/null +++ b/templates/web/fixmybarangay/alert/index.html @@ -0,0 +1,45 @@ +[% INCLUDE 'header.html', title = loc('Local RSS feeds and email alerts'), bodyclass = 'twothirdswidthpage' %] + +<h1>[% loc('Local RSS feeds and email alerts') %]</h1> + +<p> +FixMyBarangay has a RSS feeds and email alerts for local problems. +</p> + +[% IF location_error %] + <div class="error">[% location_error %]</div> +[% ELSE %] + [% INCLUDE 'errors.html' %] +[% END %] + +[% options = [ { + id => 'council:1:Luz', + text => 'Luz', + uri => '/rss/reports/Luz' + }, + { + id => 'council:2:Basak_San_Nicolas', + text => 'Basak San Nicolas' + uri => '/rss/reports/Basak+San_Nicolas' + } ]; +%] + +<form id="alerts" name="alerts" method="post" action="/alert/subscribe"> + +[% IF photos.size %] +<div class="sticky-sidebar" id="alert_recent"> + <aside> + <h2>[% loc('Some photos of recent reports') %]</h2> + [% FOREACH p IN photos %] + <a href="/report/[% p.id %]"><img border="0" height="100" + src="/photo/[% p.id %].tn.jpeg" alt="[% p.title | html %]" title="[% p.title | html %]"></a> + [% END %] + </aside> +</div> +[% END %] + +[% INCLUDE 'alert/_list.html' %] + +</form> + +[% INCLUDE 'footer.html' %] diff --git a/templates/web/fixmybarangay/around/tabbed_lists.html b/templates/web/fixmybarangay/around/tabbed_lists.html new file mode 100644 index 000000000..c9f1c2a38 --- /dev/null +++ b/templates/web/fixmybarangay/around/tabbed_lists.html @@ -0,0 +1,18 @@ +[% allow_creation = !c.cobrand.only_authed_can_create || (c.user && c.user.from_council); + +IF allow_creation %] +<menu id="problems-nav" class="tab-nav"> + <ul> + <li><a href="#current">Problems on the map</a></li> + <li><a href="#message_manager">Problems via text</a></li> + </ul> +</menu> +[% END %] + +<ul id="current" class="issue-list-a tab"> + [% INCLUDE "around/on_map_list_items.html" %] +</ul> + +[% IF allow_creation %] + [% INCLUDE 'report/_message_manager.html' %] +[% END %] diff --git a/templates/web/fixmybarangay/faq/faq-en-gb.html b/templates/web/fixmybarangay/faq/faq-en-gb.html new file mode 100644 index 000000000..320a7528e --- /dev/null +++ b/templates/web/fixmybarangay/faq/faq-en-gb.html @@ -0,0 +1,135 @@ +[% INCLUDE 'header.html', title => loc('Frequently Asked Questions'), bodyclass => 'twothirdswidthpage' %] + +<div class="sticky-sidebar"> + <aside> + <ul class="plain-list"> + <li><a href="#faq">Frequently Asked Questions</a></li> + <li><a href="#practical">Staff Questions</a></li> + <li><a href="#organisation">Organisation Questions</a></li> + </ul> + </aside> +</div> + +<h1><a name="faq"></a>Frequently Asked Questions</h1> + <dl> + <dt>What is FixMyBarangay?</dt> + <dd>FixMyBarangay is a site to help people report, view, +or discuss local problems they’ve found to the city departments. +The pilot project lets you report the problems by SMS (or dropping +into the barangay center). +</dd> + <dt>What areas are covered?</dt> + <dd> + The pilot project is just running in two barangays in Cebu – + Luz and Basak San Nicolas. + </dd> + <dt>What sort of problems should I report with FixMyBarangay?</dt> + <dd>The FixMyBarangay pilot project is just for potholes (and similar + road surface problems) and broken streetlights. + </dd> + + <dt>What isn’t FixMyBarangay for?</dt> + <dd>FixMyStreet is not a way of getting in touch with Cebu City Hall for other problems + – please use FixMyBarangay only for potholes and streetlights while the pilot + project is running.. + </dd> + + <dt>Staff only: How do I use the site?</dt> + <dd>If you have a staff login, you can view problems already reported in that area, +or report ones of your own simply by clicking on the map at the location of +the problem.</dd> + <dt>How are the problems solved?</dt> + <dd>Problems sent by SMS are initially handled by the barangay staff – they'll + confirm the problem and report it to the relevant department automatically. + Once it's in the department's problem-tracking system, they'll get onto it as + soon as they can.</dd> + <dt>Is it free?</dt> + <dd>The site is free to use, yes. The pilot project has been funded by the World Bank.</dd> + + </dl> + + <h2><a name="practical"></a>Staff questions</h2> + <dl> + <dt>What's my login?</dt> + <dd> + You can use your email address and set a password right away, but your + account won't be enabled as a <em>staff account</em> until one of the + system administrators has checked it. TODO: contact details. + </dd> + <dt>I've forgotten my password, what do I do?</dt> + <dd> + No problem — when you log in, if you can't remember your password we'll + send you a confirmation link which lasts for one session, and you can + reset your password once you've clicked on that. + </dd> + <dt>How do I sign out?</dt> + <dd> + Either click on <a href="/auth/sign_out">sign out</a> on the page you're on, + or quit the browser (just closing the window without quitting the browser is not enough). + </dd> + <dt>Reporting</dt> + <dd>TODO</dd> + <dt>How do I see the SMS messages people have sent?</dt> + <dd>When you look at the barangay problems, click on "Problems via text" + (or, if you're viewing a specific report, click "Show messages") to see the + currently available messages. You'll need a username and password + for the Message Manager (your manager will have told you what these + are). Note that you can only see messages that have not yet been used to + create a report (and also their replies). + </dd> + <dt>Is my Message Manager username and password the same as the ones I use for FixMyBarangay?</dt> + <dd> + No, it's a separate account (some FMB users don't have any access to the SMS messages). + Your manager will tell you what your login for Message Manager system is, if you have one. + </dd> + <dt>I tried to work with a message but it said "lock not granted". What's up?</dt> + <dd> + This means another staff member is working on the message. To prevent you both creating + a report, or sending a reply, we use a first-come-first-serve locking mechanism. + Collisions like this are rare, but if they do happen, try again a few minutes later + because the lock may have expired by then. + </dd> + <dt>Can I delete a message?</dt> + <dd> + Yes. Click on the red cross when you hover over it (although really you're only hiding it). + You need an <em>administrator</em> account in the Message Manager to be able to see the + messages that have been hidden, so hiding them is as good as deleting them. + </dd> + <dt>It looks like an incoming message is wrongly shown as a reply. Can I fix it?</dt> + <dd> + FixMyBarangay tries to recognise SMS replies, and automatically matches them to the right thread. If it + gets this wrong, the reply may appear as a new "available" message, or a new message might be + mistaken for a reply. You need to ask an administrator to log into Message Manager to sort this out for you. + </dd> + <dt>How do the replies get back to the original sender?</dt> + <dd> + Although you're replying from within FixMyBarangay, the replies are sent by SMS. + There may be a delay of a few minutes between the moment you press <strong>reply</strong> + and the message's arrival. + </dd> + + <h2><a name="organisation"></a>Organisation Questions</h2> + <dl> + <dt>Who built FixMyBarangay?</dt> + <dd>This site was built by <a href="http://www.mysociety.org/">mySociety</a>, in conjunction with the <a href="www.worldbank.org/">World Bank</a>. +mySociety is the project of a registered charity which has grown out of the community of +volunteers who built sites like <a href="http://www.theyworkforyou.com/">TheyWorkForYou.com</a> in the UK. +mySociety’s primary mission is to build Internet projects which give people simple, tangible +benefits in the civic and community aspects of their lives. +The charity is called UK Citizens Online Democracy and is charity number 1076346. mySociety +can be contacted by email at <a href="mailto:hello@mysociety.org">hello@mysociety.org</a>, +or by post at:<br> +mySociety<br> +483 Green Lanes<br> +London<br> +N13 4BS<br> +UK</dd> + <dt>I’d like a site like this for my own location/ where’s the "source code" to this site?</dt> + <dd> +The software behind this site is open source, and available +to you mainly under the GNU Affero GPL software license. +See <a href="http://code.fixmystreet.com/">code.fixmystreet.com</a> for more information about setting up +and running sites like these. +</dd> + </dl> +[% INCLUDE 'footer.html' pagefooter = 'yes' %] diff --git a/templates/web/fixmybarangay/footer.html b/templates/web/fixmybarangay/footer.html new file mode 100644 index 000000000..737b151ac --- /dev/null +++ b/templates/web/fixmybarangay/footer.html @@ -0,0 +1,82 @@ + </div><!-- .content role=main --> + </div><!-- .container --> + </div><!-- .table-cell --> + + <div class="nav-wrapper"> + <div class="nav-wrapper-2"> + <div id="main-nav" role="navigation"> + <ul id="mysoc-menu"> + <li><a id="mysoc-logo" href="http://www.mysociety.org/">mySociety</a></li>[% + %]<!--<li><a href="http://mysociety.org/donate/">Donate</a></li>[% + %]<li><a href="http://www.mysociety.org/projects/">Our Sites</a></li>--> + </ul> + + <ul id="main-menu"> + <li><a href="/around?latitude=10.322;longitude=123.907" class="fmb-bgy-btn">Luz</a></li> + <li><a href="/around?latitude=10.288;longitude=123.870" class="fmb-bgy-btn">BSN</a></li> + <li><[% IF c.req.uri.path == '/' %]span[% ELSE %]a href="/"[% END %] class="report-a-problem-btn" + >View problems</[% c.req.uri.path == '/' ? 'span' : 'a' %]></li>[% + %]<li><[% IF c.req.uri.path == '/reports' %]span[% ELSE %]a href="/reports"[% END + %]>[% loc("All reports") %]</[% c.req.uri.path == '/reports' ? 'span' : 'a' %]></li>[% + %]<li><[% IF c.req.uri.path == '/alert' %]span[% ELSE %]a href="/alert[% pc ? '/list?pc=' : '' %][% pc | uri %]"[% END + %]>[% loc("Local alerts") %]</[% c.req.uri.path == '/alert' ? 'span' : 'a' %]></li>[% + %]<li><[% IF c.req.uri.path == '/faq' %]span[% ELSE %]a href="/faq"[% END + %]>[% loc("Help") %]</[% c.req.uri.path == '/faq' ? 'span' : 'a' %]></li> + </ul> + </div> + </div> + </div> + +[% IF global.want_fmb_hidden_dialogs %] + <!-- fancybox hidden dialogues for message-manager reply/hide --> + <div style="display:none"> + <div id="reply-form-container"> + <form action="#" id="reply-form" onsubmit="event.returnValue = false; return false;" method="post" accept-charset="utf-8"> + <div style="display:none;"> + <input type="hidden" name="_method" value="POST"/> + </div> + <!-- populated by Ajax call --> + <div class="input" id="mm-boilerplate-replies-box"> + <label for="boilerplate-replies">Use preloaded reply:</label> + <select name="boilerplate-replies" id="mm-boilerplate-replies"></select> + </div> + <div class="input text"> + <label for="reply_text">Reply text</label> + <textarea name="reply_text" id="reply_text" cols="32" rows="3"></textarea> + </div> + <input type="hidden" name="message_id" id="reply_to_msg_id"/> + <div class="submit"> + <input id="reply-submit" type="submit" value="Send Reply"/> + </div> + </form> + </div> + </div> + <div style="display:none"> + <div id="hide-form-container"> + <p style="color:#000">Hiding message: <span id="hide-form-message-text"></span></p> + <form action="#" id="hide-form" onsubmit="event.returnValue = false; return false;" method="post" accept-charset="utf-8"> + <div style="display:none;"> + <input type="hidden" name="_method" value="POST"/> + </div> + <!-- populated by Ajax call --> + <div class="input" id="mm-boilerplate-hide-reasons-box"> + <label for="boilerplate-hide-reasons">Use preloaded reason:</label> + <select name="boilerplate-hide-reasons" id="mm-hide-reasons"></select> + </div> + <div class="input textarea"> + <label for="reason_text">Reason for hiding message</label> + <textarea name="reason_text" id="reason_text" cols="32" rows="3"></textarea> + </div> + <input type="hidden" name="msg_id" id="hide_msg_id"/> + <div class="submit"> + <input id="hide-submit" type="submit" value="Hide Message"/> + </div> + </form> + </div> + </div> +[% END %] + +<!-- [% INCLUDE 'debug_footer.html' %] --> + </div> <!-- .wrapper --> +</body> +</html> diff --git a/templates/web/fixmybarangay/header.html b/templates/web/fixmybarangay/header.html new file mode 100644 index 000000000..2557a26cb --- /dev/null +++ b/templates/web/fixmybarangay/header.html @@ -0,0 +1,79 @@ +<!doctype html> +<!--[if lt IE 7]><html class="no-js ie6 oldie" lang="[% lang_code %]"><![endif]--> +<!--[if IE 7]> <html class="no-js ie7 oldie" lang="[% lang_code %]"><![endif]--> +<!--[if IE 8]> <html class="no-js ie8 oldie" lang="[% lang_code %]"><![endif]--> +<!--[if IE 9]> <html class="no-js ie9 oldie" lang="[% lang_code %]"><![endif]--> +<!--[if gt IE 9]><!--><html class="no-js" lang="[% lang_code %]"><!--<![endif]--> + <head> + <meta name="viewport" content="initial-scale=1.0"> + + <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"> + <meta name="HandHeldFriendly" content="true"> + <meta name="mobileoptimized" content="0"> + + <link rel="stylesheet" href="[% version('/cobrands/fixmybarangay/base.css') %]"> + <link rel="stylesheet" href="[% version('/cobrands/fixmybarangay/layout.css') %]" media="(min-width:48em)"> + [% extra_css %] + <!--[if (lt IE 9) & (!IEMobile)]> + <link rel="stylesheet" href="[% version('/cobrands/fixmybarangay/layout.css') %]"> + <![endif]--> + + <script src="[% version('/js/modernizr.custom.js') %]" charset="utf-8"></script> + <script src="[% version('/cobrands/fixmybarangay/position_map.js') %]" charset="utf-8"></script> + [% INCLUDE 'common_header_tags.html', site_title = 'FixMyBarangay', js_override = '/cobrands/fixmystreet/fixmystreet.js' %] + [% extra_js %] + + [% allow_creation = !c.cobrand.only_authed_can_create || (c.user && c.user.from_council); %] + [% IF allow_creation %] + + <link rel="stylesheet" href="[% version('/js/fancybox/jquery.fancybox-1.3.4.css') %]"> + <script src="[% version('/js/fancybox/jquery.fancybox-1.3.4.pack.js') %]" charset="utf-8"></script> + + <script src="[% version('/cobrands/fixmybarangay/message_manager_client.js') %]" charset="utf-8"></script> + <script> + $(document).ready(function() { + + $('#mm_sign_out').click(function(){ + message_manager.sign_out(); + }); + + [% IF c.req.params.external_source_id && problem && problem.external_source_id.match('^\d+$') %] + var mm_msg_id ="[% c.req.params.external_source_id %]"; + var fms_id = "[% problem.id %]"; + if (mm_msg_id && fms_id) { + message_manager.config({url_root: "[% c.config.MESSAGE_MANAGER_URL %]"}); + message_manager.assign_fms_id(mm_msg_id, fms_id); + } + [% END %] + }); + </script> + [% END %] + </head> + <body class="[% bodyclass | html IF bodyclass %]"> + + <div class="wrapper"> + <div class="table-cell"> + <header id="site-header" role="banner"> + <div class="container"> + <a href="/" id="site-logo">FixMyBarangay</a> + <a href="#main-nav" id="nav-link">Main Navigation</a> + </div> + </header> + + <div id="user-meta"> + [% IF c.user_exists %] + <p> + [% tprintf(loc('Hi %s'), c.user.name || c.user.email) %] + <a href="/auth/sign_out" id="mm_sign_out">[% loc('sign out') %]</a> + </p> + [% ELSE %] + <!-- <a href="/auth">[% loc('Sign in') %]</a> --> + [% END %] + </div> + + [% pre_container_extra %] + + <div class="container"> + <div class="content[% " $mainclass" | html IF mainclass %]" role="main"> + + <!-- [% INCLUDE 'debug_header.html' %] --> diff --git a/templates/web/fixmybarangay/report/_message_manager.html b/templates/web/fixmybarangay/report/_message_manager.html new file mode 100644 index 000000000..41544a754 --- /dev/null +++ b/templates/web/fixmybarangay/report/_message_manager.html @@ -0,0 +1,203 @@ +[% IF c.user && c.user.from_council %] + +[% IF problem.id %] + <input type="button" class="green-btn" value="Show Messages" id="show_messages"> +[% END %] + +<ul id="message_manager" class="issue-list-a tab" style="display: none"> + <li id="message-control"> + <div id="mm-admin-buttons"> + <a id="mm-link-to-admin" href="[% c.config.MESSAGE_MANAGER_URL %]">[admin]</a> + <a id="mm-link-to-refresh" href="#">[refresh]</a> + </div> + <div id="mm-username-container">username: <span id="mm-received-username"></span></div> + <div id="mm-status-message-container"> + <div id="mm-status-message"></div> + </div> + <div id="mm-login-container"> + <div> + <label for="mm-htauth-username">Username:</label> + <input name="mm-htauth-username" id="mm-htauth-username" type="text"/> + </div> + <div> + <label for="mm-htauth-password">Password:</label> + <input name="mm-htauth-password" id="mm-htauth-password" type="password"/> + </div> + <div class="submit"> + <input id="available-submit" type="submit" value="Get available messages" class="green-btn"/> + </div> + </div> + </li> + <li> + <div id="mm-message-list" style="min-height:1em;"></div> + </li> +</ul> + +<script type="text/javascript"> + +$(document).ready(function() { + var $mm_message_list = $('#mm-message-list'); + var mm_url = "[% c.config.MESSAGE_MANAGER_URL %]"; // from config + var problem_id = "[% problem.id %]"; + var dummy_busy = false; + var fms_username = "[% c.user.email | replace('\@.*', '') %]"; + var timeout_id = 0; + var can_refresh = true; // disable refresh + var refresh_period = 60000 * 3; // refresh messages every three minutes + + function sanitise_id(css_id) { + return css_id.replace(/\D/g, ""); + } + + var mm_refresh_messages = function() { + $('#mm-link-to-refresh').fadeOut(); + $('#available-submit').click(); + } + + var mm_populate_list = function(data) { + $('#mm-status-message-container').text("Accessed Message Manager as " + data['username']); + $('input[name=mm_text]').prop('checked', false); // uncheck all + $('#mm-link-to-refresh').delay(2000).fadeIn(); + if (refresh_period && can_refresh) { + if (timeout_id) { + clearTimeout(timeout_id); + } + timeout_id = setTimeout(mm_refresh_messages, refresh_period); + } + } + + var mm_selected_message = function(data) { + var msg_text = ""; + var service_id = ""; + $('li.msg-is-active', $mm_message_list).removeClass('msg-is-active'); + if (data['success']) { + // msg_text = $('#form_detail').val( $('input[name=mm_text]:checked').val() ); # == message data + msg_text = data['data']['Message']['message']; + service_id = data['data']['Message']['id']; + $('#msg-' + service_id).addClass('msg-is-active'); + } else { + $('input[name=mm_text]').prop('checked', false); // uncheck all + } + $('#form_detail').val(msg_text); + $('#external_source_id').val(service_id); + } + + var dummy_reply_cleanup = function(data) { + $('#reply_text').val(''); + dummy_busy = false; + mm_refresh_messages(); + } + + var dummy_hide_cleanup = function(data) { + $('#reason_text').val(''); + dummy_busy = false; + } + + message_manager.config({url_root: mm_url, want_nice_msgs: true}); + message_manager.setup_click_listener({callback:mm_selected_message}); + + // problem form hidden input "external_source_id": pass the MM id into FMS, if used + var $problem_form = $('#problem_form').size()? $('#problem_form') : $('#form_update_form'); + $('<input type="hidden"/>').attr({ + 'id': 'external_source_id', + 'name': 'external_source_id', + }).appendTo($problem_form); + + $('#available-submit').click(function(e){ + e.preventDefault(); + message_manager.get_available_messages({ + callback: mm_populate_list, + suggest_username: fms_username, + anim_duration: 500 + }); + }); + $('#available-submit').click(); + + $mm_message_list.on('mouseover', 'li.mm-msg', function(e){ + e.stopPropagation(); // because replies are nested + $('.mm-msg-action', $mm_message_list).stop().fadeOut(200); + $(this).find('> .mm-msg-action').stop().show(); + }); + + $('#mm-message-list').on('click', '.mm-info', function(e){ + message_manager.show_info(sanitise_id($(this).parent().attr('id'))); + }); + + $('#mm-hide-reasons').change(function(e){ + $('#reason_text').val($(this).val()); // load reason_text with boilerplate reason + }); + $('#mm-boilerplate-replies').change(function(e){ + $('#reply_text').val($(this).val()); // load reason_text with boilerplate reason + }); + + $('#reply-submit').click(function(e) { + e.preventDefault(); + // TODO: pending fancybox callbacks working, force dummy_busy here + // this is possibly overly cautious anyway + dummy_busy = false; + if (! dummy_busy) { + dummy_busy = true; + message_manager.reply( + $('#reply_to_msg_id').val(), + $('#reply_text').val(), + {callback:dummy_reply_cleanup}); + } + }); + + $('#hide-submit').click(function(e) { + e.preventDefault(); + // TODO: pending fancybox callbacks working, force dummy_busy here + // this is possibly overly cautious anyway + dummy_busy = false; + if (! dummy_busy) { + dummy_busy = true; + message_manager.hide( + $('#hide_msg_id').val(), + $('#reason_text').val(), + {callback:dummy_hide_cleanup}); + } + }); + + $("a#reply").fancybox({onClosed: function(){dummy_busy=false;}}); + + // only show on problem display page + if (problem_id) { + $('<input type="button" value="Copy to update"/>').attr({ + 'id': 'add_support', + 'name': 'add_support', + 'class': 'green-btn' + }).appendTo($('#message_manager')); + } + + $('#add_support').click(function(e){ + e.preventDefault(); + $('#mm-message-list input:checked').each( function(index) { + var id = $(this).attr('id'); + id = id.replace('mm_text_',''); + $('#external_source_id').val(id); + $('#form_update').val( $(this).val() ); + $('#form_update_form').on('submit', function(e) { + message_manager.assign_fms_id( $('#external_source_id').val(), problem_id, { 'is_async': false } ); + }); + }); + }); + + $('#show_messages').on('click', function(e) { + $('#message_manager').toggle(); + $('#show_messages').val( $('#show_messages').val() == 'Show Messages' ? 'Hide Messages' : 'Show Messages' ); + }); + + $('#mm-link-to-refresh').on('click', function(e) { + e.preventDefault(); + mm_refresh_messages(); + }); + + message_manager.populate_boilerplate_strings('hide-reason'); + message_manager.populate_boilerplate_strings('reply'); +}); + +</script> + +[% global.want_fmb_hidden_dialogs = 1 %] + +[% END %] diff --git a/templates/web/fixmybarangay/report/new/councils_text.html b/templates/web/fixmybarangay/report/new/councils_text.html new file mode 100644 index 000000000..24c54ea50 --- /dev/null +++ b/templates/web/fixmybarangay/report/new/councils_text.html @@ -0,0 +1,5 @@ +<p> +The information provided here will be displayed publicly on the site as well as being sent to the +relevant authority (DPWH, DEPW, or DPS). If you select the Fix Locally category then the +information will not be sent anywhere. +</p> diff --git a/templates/web/fixmybarangay/report/new/fill_in_details_text.html b/templates/web/fixmybarangay/report/new/fill_in_details_text.html new file mode 100644 index 000000000..51dc1e3f1 --- /dev/null +++ b/templates/web/fixmybarangay/report/new/fill_in_details_text.html @@ -0,0 +1,12 @@ +[% + IF area_ids_to_list.size != 0; + loc('Please fill in details of the problem below. Leave as much detail as you can, +and if possible describe the exact location of +the problem (e.g. if there is a streetlight number or road name).'); + IF category_extras; + ' ' _ loc('Some categories may require additional information.'); + END; + ELSE; + loc('Please fill in details of the problem below.'); + END; +%] diff --git a/templates/web/fixmybarangay/report/new/notes.html b/templates/web/fixmybarangay/report/new/notes.html new file mode 100644 index 000000000..8195051db --- /dev/null +++ b/templates/web/fixmybarangay/report/new/notes.html @@ -0,0 +1,11 @@ +<p style="clear:both">[% loc("Please note:") %]</p> + +<ul> +<!-- + <li>[% loc("We will only use your personal information in accordance with our <a href=\"/faq#privacy\">privacy policy.</a>") %]</li> +--> + <li>[% loc("Be sure to choose the right category, because we use that to determine to whom the report is sent.") %]</li> + <li>[% loc("Writing your message entirely in block capitals makes it hard to read, as does a lack of punctuation.") %]</li> + <li>[% loc("Remember that, for the pilot project, FixMyBarangay is only for reporting potholes and streetlights in bgy. Luz or Basak San Nicolas.") %]</li> + +</ul> diff --git a/templates/web/fixmystreet/around/_report_banner.html b/templates/web/fixmystreet/around/_report_banner.html new file mode 100755 index 000000000..9edf6e171 --- /dev/null +++ b/templates/web/fixmystreet/around/_report_banner.html @@ -0,0 +1,14 @@ +<h1 class="big-green-banner"> + [% loc( 'Click map to report a problem' ) %] + [% IF c.cobrand.moniker == 'bromley' %] + <span>Yellow pins show existing reports</span> + [% END %] +</h1> +<p id="skip-this-step"> + [% + tprintf( + loc("Can't see the map? <a href='%s' rel='nofollow'>Skip this step</a>"), + url_skip + ) + %] +</p> diff --git a/templates/web/fixmystreet/around/_updates.html b/templates/web/fixmystreet/around/_updates.html new file mode 100755 index 000000000..75327c935 --- /dev/null +++ b/templates/web/fixmystreet/around/_updates.html @@ -0,0 +1,5 @@ +<div class="shadow-wrap"> + <ul id="key-tools" class="singleton"> + <li><a class="feed" id="key-tool-around-updates" href="[% email_url | html %]">Get updates</a></li> + </ul> +</div> diff --git a/templates/web/fixmystreet/around/display_location.html b/templates/web/fixmystreet/around/display_location.html deleted file mode 100755 index a7240688f..000000000 --- a/templates/web/fixmystreet/around/display_location.html +++ /dev/null @@ -1,121 +0,0 @@ -[% - - rss_alt = loc('RSS feed'); - rss_title = loc('RSS feed of recent local problems'); - - rss_url - = pc - ? c.uri_for( "/rss/pc", pc ) - : c.uri_for( "/rss/l/$short_latitude,$short_longitude" ); - - email_url = c.uri_for( - '/alert/list', - { - lat => short_latitude, - lon => short_longitude, - feed => "local:$short_latitude:$short_longitude", - } - ); - - url_skip = c.uri_for( - '/report/new', - { - pc => pc - latitude => short_latitude, - longitude => short_longitude, - skipped => 1, - } - ); - - PROCESS "maps/${map.type}.html"; - - INCLUDE 'header.html', - title => loc('Viewing a location') - rss => [ loc('Recent local problems, FixMyStreet'), rss_url ], - bodyclass => 'mappage', - robots => 'noindex,nofollow'; -%] - -<form action="[% c.uri_for('/report/new') %]" method="post" name="mapForm" id="mapForm" enctype="multipart/form-data" class="validate"> - [% IF c.req.params.map_override %] - <input type="hidden" name="map_override" value="[% c.req.params.map_override | html %]"> - [% END %] - <input type="hidden" name="pc" value="[% pc | html %]"> - - <input type="hidden" name="latitude" id="fixmystreet.latitude" value="[% short_latitude | html %]"> - <input type="hidden" name="longitude" id="fixmystreet.longitude" value="[% short_longitude | html %]"> - - [% map_html %] - - <p id='sub_map_links'> - [% IF c.req.params.no_pins %] - <a id='hide_pins_link' rel='nofollow' href='[% c.uri_with( { no_pins => 0 } ) %]'>[% loc('Show pins') %]</a> - [% ELSE %] - <a id='hide_pins_link' rel='nofollow' href='[% c.uri_with( { no_pins => 1 } ) %]'>[% loc('Hide pins') %]</a> - [% END %] - [% IF c.cobrand.country == 'GB' || c.cobrand.country == 'NO' %] - [% IF c.req.params.all_pins %] - <a id='all_pins_link' rel='nofollow' href='[% c.uri_with( { no_pins => undef, all_pins => undef } ) %]'>[% loc('Hide old') %]</a> - [% ELSE %] - <a id='all_pins_link' rel='nofollow' href='[% c.uri_with( { no_pins => undef, all_pins => 1 } ) %]'>[% loc('Show old') %]</a> - [% END %] - [% END %] - </p> - - </div> - - - - - <div id="side"> - - <h1 class="big-green-banner">[% - loc( 'Click map to report a problem' ); - IF c.cobrand.moniker == 'bromley'; - '<span>Yellow pins show existing reports</span>'; - END - %]</h1> - - <p id="skip-this-step"> - [% - tprintf( - loc("Can't see the map? <a href='%s' rel='nofollow'>Skip this step</a>"), - url_skip - ) - %] - </p> - - <div class="shadow-wrap"> - <ul id="key-tools" class="singleton"> - <li><a class="feed" id="key-tool-around-updates" href="[% email_url | html %]">Get updates</a></li> - </ul> - </div> - - <section class="full-width"> - <menu id="problems-nav" class="tab-nav"> - <ul> - <li><a href="#current">[% loc('Problems on the map') %]</a></li> - <li><a href="#current_near">[% loc( 'Problems nearby' ) %]</a></li> - </ul> - </menu> - - <ul id="current" class="issue-list-a tab"> - [% INCLUDE "around/on_map_list_items.html" %] - </ul> - - <ul id="current_near" class="issue-list-a tab"> - [% INCLUDE "around/around_map_list_items.html" %] - </ul> - </section> - </div> - - <div style="display:none" id="side-form"> - [% INCLUDE "report/new/fill_in_details_form.html" - js = 1, - report.used_map = 1 - report.name = c.user.name - %] - </div> -</form> - -[% INCLUDE 'footer.html' %] diff --git a/templates/web/fixmystreet/around/postcode_form.html b/templates/web/fixmystreet/around/postcode_form.html index 5805d1ff5..d48a53183 100644 --- a/templates/web/fixmystreet/around/postcode_form.html +++ b/templates/web/fixmystreet/around/postcode_form.html @@ -1,11 +1,19 @@ <div id="front-main"> <div id="front-main-container"> - [% INCLUDE 'around/intro.html' %] + [% IF c.cobrand.moniker == 'fixmybarangay' %] + <h1>View local problems</h1> + <h2>(potholes or street lighting)</h2> + [% ELSE %] + [% INCLUDE 'around/intro.html' %] + [% END %] [% question = c.cobrand.enter_postcode_text || loc('Enter a nearby street name and area'); %] + [% IF c.cobrand.moniker == 'fixmybarangay' %] + [% INCLUDE '_barangay_buttons.html' %] + [% ELSE %] <form action="[% c.uri_for('/around') %]" method="get" name="postcodeForm" id="postcodeForm"> <label for="pc">[% question %]:</label> <div> @@ -13,10 +21,11 @@ <input type="submit" value="[% loc('Go') %]" id="submit"> </div> - [% IF partial_token %] - <input type="hidden" name="partial" value="[% partial_token.token %]"> - [% END %] + [% IF partial_token %] + <input type="hidden" name="partial" value="[% partial_token.token %]"> + [% END %] </form> + [% END %] </div> </div> diff --git a/templates/web/fixmystreet/around/tabbed_lists.html b/templates/web/fixmystreet/around/tabbed_lists.html new file mode 100644 index 000000000..77c5a521b --- /dev/null +++ b/templates/web/fixmystreet/around/tabbed_lists.html @@ -0,0 +1,14 @@ +<menu id="problems-nav" class="tab-nav"> + <ul> + <li><a href="#current">[% loc('Problems on the map') %]</a></li> + <li><a href="#current_near">[% loc( 'Problems nearby' ) %]</a></li> + </ul> +</menu> + +<ul id="current" class="issue-list-a tab"> + [% INCLUDE "around/on_map_list_items.html" %] +</ul> + +<ul id="current_near" class="issue-list-a tab"> + [% INCLUDE "around/around_map_list_items.html" %] +</ul> diff --git a/templates/web/fixmystreet/auth/general.html b/templates/web/fixmystreet/auth/general.html index 6ecbcadc5..7fa2b57fe 100644 --- a/templates/web/fixmystreet/auth/general.html +++ b/templates/web/fixmystreet/auth/general.html @@ -26,7 +26,11 @@ <input type="email" class="required email" id="email" name="email" value="[% email | html %]" placeholder="[% loc('Your email address') %]"> <div id="form_sign_in"> + [% IF c.cobrand.moniker == 'fixmybarangay' %] + <h3>[% loc("Do you have a FixMyBarangay password?") %]</h3> + [% ELSE %] <h3>[% loc("Do you have a FixMyStreet password?") %]</h3> + [% END %] <div id="form_sign_in_yes" class="form-box"> <h5>[% loc('<strong>Yes</strong> I have a password') %]</h5> diff --git a/templates/web/fixmystreet/faq/faq-en-gb.html b/templates/web/fixmystreet/faq/faq-en-gb.html index 9edb21426..8628085e5 100755 --- a/templates/web/fixmystreet/faq/faq-en-gb.html +++ b/templates/web/fixmystreet/faq/faq-en-gb.html @@ -7,6 +7,7 @@ <li><a href="#practical">Practical Questions</a></li> <li><a href="#organisation">Organisation Questions</a></li> <li><a href="/privacy">Privacy and cookies</a></li> + <li><a href="/contact">Contact FixMyStreet</a></li> </ul> </aside> </div> @@ -186,7 +187,7 @@ rights reserved, Ministry of Justice 100037819 2008), Yahoo! for their BSD-licensed JavaScript libraries, the entire free software community (this particular project was brought to you by Perl, PostgreSQL, and the number 161.290) and <a -href="http://www.m247.com/">M247</a> (who kindly host all +href="http://www.bytemark.co.uk/">Bytemark</a> (who kindly host all our servers). Let us know if we’ve missed anyone.</dd> diff --git a/templates/web/fixmystreet/index.html b/templates/web/fixmystreet/index.html index 492adbbe5..5d7d31baa 100644 --- a/templates/web/fixmystreet/index.html +++ b/templates/web/fixmystreet/index.html @@ -33,26 +33,9 @@ kinds of problems like missed bins use our <div class="tablewrapper"> <div id="front-howto"> - <h2>[% loc('How to report a problem') %]</h2> - - <ol class="big-numbers"> - <li>[% question %]</li> - <li>[% loc('Locate the problem on a map of the area') %]</li> - <li>[% loc('Enter details of the problem') %]</li> - [% IF c.cobrand.is_council %] - <li>Confirm the report and [% c.cobrand.council_name %] will investigate</li> - [% ELSE %] - <li>[% loc('We send it to the council on your behalf') %]</li> - [% END %] - </ol> - - <section class="full-width"> - [% INCLUDE "front/stats.html" %] - [% TRY %][% INCLUDE "front/tips.html" %][% CATCH file %][% END %] - </section> + [% INCLUDE 'index-steps.html' %] </div> - [% recent_photos = c.cobrand.recent_photos('front', 5); %] diff --git a/templates/web/fixmystreet/my/my.html b/templates/web/fixmystreet/my/my.html index e170202de..258f147c6 100644 --- a/templates/web/fixmystreet/my/my.html +++ b/templates/web/fixmystreet/my/my.html @@ -13,6 +13,10 @@ <h1>[% loc('Your Reports') %]</h1> +[% IF c.cobrand.moniker == 'fixmybarangay' %] + [% INCLUDE '_barangay_buttons.html' %] +[% END %] + [% INCLUDE 'pagination.html', pager = problems_pager, param = 'p' diff --git a/templates/web/fixmystreet/questionnaire/completed-open.html b/templates/web/fixmystreet/questionnaire/completed-open.html index 2bb3bad1f..f39083cce 100644 --- a/templates/web/fixmystreet/questionnaire/completed-open.html +++ b/templates/web/fixmystreet/questionnaire/completed-open.html @@ -1,6 +1,12 @@ +[% IF c.cobrand.is_council %] +<p style="font-size: 150%"> +Thank you very much for filling in our questionnaire. +</p> +[% ELSE %] [% loc('<p style="font-size:150%">We’re sorry to hear that. We have two suggestions: why not try <a href="http://www.writetothem.com/">writing direct to your councillor(s)</a> or, if it’s a problem that could be fixed by local people working together, why not <a href="http://www.pledgebank.com/new">make and publicise a pledge</a>? </p>' ) %] +[% END %] diff --git a/templates/web/fixmystreet/report/_main.html b/templates/web/fixmystreet/report/_main.html deleted file mode 100644 index 7ceb1f6a5..000000000 --- a/templates/web/fixmystreet/report/_main.html +++ /dev/null @@ -1,21 +0,0 @@ -<div class="problem-header cf"> - <h1>[% problem.title | html %]</h1> - - <p><em> - [% problem.meta_line(c) | html %] - [% IF problem.council %] - [% IF problem.whensent || problem.can_display_external_id %] - <small class="council_sent_info"><br> - [% problem.processed_summary_string(c) %] - </small> - [% END %] - [% ELSE %] - <br><small>[% loc('Not reported to council') %]</small> - [% END %] - </em></p> - - [% INCLUDE 'report/photo.html' object=problem center=1 %] - - [% add_links( problem.detail ) | html_para %] - -</div> diff --git a/templates/web/fixmystreet/report/display.html b/templates/web/fixmystreet/report/display.html index 8df29229d..c71694da5 100644 --- a/templates/web/fixmystreet/report/display.html +++ b/templates/web/fixmystreet/report/display.html @@ -7,7 +7,9 @@ title = problem_title rss = [ loc('Updates to this problem, FixMyStreet'), "/rss/$problem.id" ] robots = 'index, nofollow' - bodyclass = 'mappage' + bodyclass = 'mappage'; + + allow_creation = !c.cobrand.only_authed_can_create || (c.user && c.user.from_council); %] [% map_html %] @@ -15,20 +17,33 @@ </div> [% INCLUDE 'report/banner.html' %] + [% INCLUDE 'report/_main.html' %] +[% TRY %][% INCLUDE 'report/_message_manager.html' %][% CATCH file %][% END %] <div class="shadow-wrap"> <ul id="key-tools"> <li><a rel="nofollow" id="key-tool-report-abuse" class="abuse" href="[% c.uri_for( '/contact', { id => problem.id } ) %]">[% loc('Report abuse' ) %]</a></li> <li><a rel="nofollow" id="key-tool-report-updates" class="feed" href="[% c.uri_for( '/alert/subscribe', { id => problem.id } ) %]">[% loc('Get updates' ) %]</a></li> + [% IF c.cobrand.moniker == 'fixmystreet' %] + <li><a rel="nofollow" id="key-tool-report-share" class="share" href="#report-share">[% loc('Share') %]</a></li> + [% END %] <li><a class="chevron" id="key-tool-problems-nearby" href="[% c.uri_for( '/around', { lat => short_latitude, lon => short_longitude } ) %]">[% loc( 'Problems nearby' ) %]</a></li> </ul> +[% IF c.cobrand.moniker == 'fixmystreet' %] + <div id="report-share" class="hidden-js" align="center"> + <a href="https://twitter.com/share" class="twitter-share-button" data-text="I just reported ‘[% problem.title | html %]’" data-via="fixmystreet" data-related="mysociety" data-count="none" data-dnt="true">Tweet</a> +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script> + <iframe src="//www.facebook.com/plugins/like.php?href=[% c.req.uri | uri %]&send=false&layout=button_count&width=90&show_faces=false&action=like&colorscheme=light&font&height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:90px; height:21px;" allowTransparency="true"></iframe> + </div> +[% END %] + <div id="report-updates-data" class="hidden-js"> <form action="[% c.uri_for( '/alert/subscribe' ) %]" method="post"> - <p><a href="[% c.uri_for( '/rss', problem.id ) %]"> - <img src="/i/feed.png" width="16" height="16" title="[% loc('RSS feed') %]" alt="[% loc('RSS feed of updates to this problem' ) %]" border="0" style="float: right"> - </a></p> + <a href="[% c.uri_for( '/rss', problem.id ) %]"> + <img src="/i/feed.png" width="16" height="16" title="[% loc('RSS feed') %]" alt="[% loc('RSS feed of updates to this problem' ) %]" border="0"> + </a> <p>[% loc('Receive email when updates are left on this problem.' ) %]</p> <fieldset> <label class="hidden n" for="alert_rznvy">[% loc('Your email') %]</label> @@ -46,6 +61,7 @@ [% INCLUDE 'report/updates.html' %] +[% IF allow_creation %] <div id="update_form"> <h2>[% loc( 'Provide an update') %]</h2> @@ -57,7 +73,7 @@ [% INCLUDE 'errors.html' %] - <form method="post" action="[% c.uri_for( '/report/update' ) %]" name="updateForm" class="validate"[% IF c.cobrand.allow_photo_upload %] enctype="multipart/form-data"[% END %]> + <form method="post" action="[% c.uri_for( '/report/update' ) %]" id="form_update_form" name="updateForm" class="validate"[% IF c.cobrand.allow_photo_upload %] enctype="multipart/form-data"[% END %]> <fieldset> <input type="hidden" name="submit_update" value="1"> <input type="hidden" name="id" value="[% problem.id | html %]"> @@ -143,6 +159,12 @@ <input type="checkbox" id="remember_me" name="remember_me" value='1'[% ' checked' IF remember_me %]> <label class="inline n" for="remember_me">[% loc('Keep me signed in on this computer') %]</label> </div> + + <div class="general-sidebar-notes" id="forgotten-pw"> + <p class="dark">[% loc('Forgotten your password?') %]</p> + <p>[% loc('Confirm by email below, providing a new password at that point. When you confirm, your password will be updated.') %]</p> + </div> + </div> <div id="form_sign_in_no" class="form-box"> <h5>[% loc('<strong>No</strong> Let me confirm my update by email') %]</h5> @@ -167,7 +189,7 @@ </fieldset> </form> </div> - +[% END %] [% INCLUDE 'footer.html' %] diff --git a/templates/web/fixmystreet/report/new/fill_in_details_form.html b/templates/web/fixmystreet/report/new/fill_in_details_form.html index 57d9ef98e..82f9b0da5 100644 --- a/templates/web/fixmystreet/report/new/fill_in_details_form.html +++ b/templates/web/fixmystreet/report/new/fill_in_details_form.html @@ -15,6 +15,7 @@ [% PROCESS 'report/new/councils_text.html' %] [% END %] + [% IF c.cobrand.moniker != 'fixmybarangay' || ( c.user && c.user.from_council ) %] <div id="report-a-problem-sidebar"> <!-- The text for this section needs checking, but I can't work out which bit comes from where @@ -35,12 +36,13 @@ [% END %] </p> </div> - + <div class="sidebar-notes"> [% INCLUDE 'report/new/notes.html' %] </div> </div> + [% END %] [% INCLUDE 'errors.html' %] <fieldset> @@ -110,6 +112,9 @@ [% IF c.user_exists %] <div class="form-box"> + <label for="form_email">[% loc('Your email') %]</label> + <input disabled type="text" value="[% c.user.email | html %]"> + [% INCLUDE 'report/new/extra_name.html' %] <label for="form_name">[% loc('Name') %]</label> @@ -120,13 +125,25 @@ [%# if there is nothing in the name field then set check box as default on form %] <div class="checkbox-group"> - <input type="checkbox" name="may_show_name" id="form_may_show_name" value="1"[% ' checked' IF !report.anonymous %]> - <label class="inline" for="form_may_show_name">[% loc('Show my name publicly') %]</label> + <input type="checkbox" name="may_show_name" id="form_may_show_name" value="1" + [% IF c.cobrand.moniker == 'fixmybarangay' && c.user.from_council %] + [%# + FMB staff reports are anonymous by default; so may_show_name is checked only if explicitly set to 0. + If the user has not set it (that is, it is null) TemplateToolkit sees an empty string. + %] + [% 'checked' IF report.anonymous==0 %] + [% ELSE %] + [% 'checked' IF !report.anonymous %] + [% END %] + > + <label class="inline" for="form_may_show_name">[% loc('Show my name publicly') %] </label> </div> + [% IF c.cobrand.moniker != 'fixmybarangay' || c.user.from_council %] <div class="general-sidebar-notes"> <p>[% loc('We never show your email address or phone number.') %]</p> </div> + [% END %] <label for="form_phone">[% loc('Phone number (optional)') %]</label> <input class="" type="text" value="[% report.user.phone | html %]" name="phone" id="form_phone" placeholder="[% loc('Your phone number') %]"> @@ -164,6 +181,12 @@ <input type="checkbox" id="remember_me" name="remember_me" value='1'[% ' checked' IF remember_me %]> <label class="n inline" for="remember_me">[% loc('Keep me signed in on this computer') %]</label> </div> + + <div class="general-sidebar-notes" id="forgotten-pw"> + <p class="dark">[% loc('Forgotten your password?') %]</p> + <p>[% loc('Confirm by email below, providing a new password at that point. When you confirm, your password will be updated.') %]</p> + </div> + </div> <div id="form_sign_in_no" class="form-box"> diff --git a/templates/web/fixmystreet/report/photo.html b/templates/web/fixmystreet/report/photo.html deleted file mode 100644 index 02ab9228b..000000000 --- a/templates/web/fixmystreet/report/photo.html +++ /dev/null @@ -1,8 +0,0 @@ -[% IF c.cobrand.allow_photo_display && object.photo %] -[% photo = object.get_photo_params %] -<div class="update-img"> - [% IF photo.url_full %]<a href="[% photo.url_full %]" rel="fancy">[% END - %]<img alt="Photo of this report" [% IF photo.height %]height="[% photo.height %]" width="[% photo.width %]"[% END %] src="[% photo.url %]"> - [%- IF photo.url_full %]<span>zoom</span></a>[% END %] -</div> -[% END %] diff --git a/templates/web/fixmystreet/reports/_extras.html b/templates/web/fixmystreet/reports/_extras.html new file mode 100755 index 000000000..e210b9c07 --- /dev/null +++ b/templates/web/fixmystreet/reports/_extras.html @@ -0,0 +1,24 @@ +[% + fms_councils = { + 'Bromley Council' = 'fix.bromley.gov.uk' + 'Barnet Borough Council' = 'barnet.fixmystreet.com' + 'Lichfield District Council' = 'lichfielddc.fixmystreet.com' + 'Reading Borough Council' = 'reading.fixmystreet.com' + 'Southampton City Council' = 'southampton.fixmystreet.com' + } + secure = { + 'fix.bromley.gov.uk' = 's' + } + site = fms_councils.${area.name} +%] +[% IF site %] +<tr align="center" +[%- IF ! (loop.count % 2) %] class="a" +[%- END %]> +<td class="title" colspan="6" style="padding-top:0"> + <small title="This council's online reporting is powered by FixMyStreet">(includes reports from + <a href="http[% secure.$site %]://[% site %]">[% site %]</a> using + <a href="http://www.mysociety.org/for-councils/fixmystreet/">FixMyStreet for Councils</a>)</small> +</td> +</tr> +[% END %] diff --git a/templates/web/southampton/header.html b/templates/web/southampton/header.html index 43553468c..e02083a99 100644 --- a/templates/web/southampton/header.html +++ b/templates/web/southampton/header.html @@ -51,7 +51,6 @@ </form> </div> - <a class="mctv" href="http://www.southampton.mycounciltv.org"><img src="/cobrands/southampton/mctv.png" alt="Link to MyCouncilTV videos" /></a> <ul id="topNav"> <li><a href="http://www.southampton.gov.uk/online/">Do it online</a></li> <li><a href="http://www.southampton.gov.uk/customer-service/">Customer Services</a></li> diff --git a/templates/web/southampton/report/photo.html b/templates/web/southampton/report/photo.html deleted file mode 100644 index 07b6a8558..000000000 --- a/templates/web/southampton/report/photo.html +++ /dev/null @@ -1,6 +0,0 @@ -[% IF c.cobrand.allow_photo_display && object.photo %] -[% photo = object.get_photo_params %] -<p> - <img alt="" height="[% photo.height %]" width="[% photo.width %]" src="[% photo.url %]"> -</p> -[% END %] diff --git a/templates/web/southampton/tokens/confirm_problem.html b/templates/web/southampton/tokens/confirm_problem.html new file mode 100644 index 000000000..f6bc2bc6c --- /dev/null +++ b/templates/web/southampton/tokens/confirm_problem.html @@ -0,0 +1,14 @@ +[% INCLUDE 'header.html', title = loc('Confirmation') %] + +<h1>[% loc('Confirmation') %]</h1> + +<p class="confirmed"> +Thank you for your report which will be updated as soon as possible. +You can <a href="[% c.cobrand.base_url_for_report( problem ) %][% problem.url %]">view the problem on this site</a>. +</p> + +<p>Your reference for this problem is [% problem.id %], please quote it in any enquiries. + +[% display_crosssell_advert( problem.user.email, problem.name ) %] + +[% INCLUDE 'footer.html' %] diff --git a/templates/web/zurich/faq/faq-de.html b/templates/web/zurich/faq/faq-de.html index bd94ecd38..a739f1b74 100755 --- a/templates/web/zurich/faq/faq-de.html +++ b/templates/web/zurich/faq/faq-de.html @@ -184,7 +184,7 @@ rights reserved, Ministry of Justice 100037819 2008), Yahoo! for their BSD-licensed JavaScript libraries, the entire free software community (this particular project was brought to you by Perl, PostgreSQL, and the number 161.290) and <a -href="http://www.m247.com/">M247</a> (who kindly host all +href="http://www.bytemark.co.uk/">Bytemark</a> (who kindly host all our servers). Let us know if we’ve missed anyone.</dd> diff --git a/web/.gitignore b/web/.gitignore index 124be032a..d6e2f1a1a 100644 --- a/web/.gitignore +++ b/web/.gitignore @@ -1,4 +1,4 @@ /down.html /_Inline -/bci-live-creation.png -/bci-live-line.png +/fms-live-creation.png +/fms-live-line.png diff --git a/web/cobrands/barnet/layout.scss b/web/cobrands/barnet/layout.scss index 97b27cfff..483f1f20f 100644 --- a/web/cobrands/barnet/layout.scss +++ b/web/cobrands/barnet/layout.scss @@ -231,7 +231,7 @@ body.frontpage { .general-sidebar-notes { - left: 25em; + left: 25.5em; width: 14em; font-size: 1.2em; p { diff --git a/web/cobrands/fixmybarangay/_colours.scss b/web/cobrands/fixmybarangay/_colours.scss new file mode 100644 index 000000000..fcaba8924 --- /dev/null +++ b/web/cobrands/fixmybarangay/_colours.scss @@ -0,0 +1,9 @@ +/* COLOURS */ + +$primary: #fff; //E6DBD6 +$primary_b: #000000; +$primary_text: #222222; + +$contrast1: #00BD08; +$contrast1_dark: #4B8304; +$contrast2: #AA8D11; diff --git a/web/cobrands/fixmybarangay/base.scss b/web/cobrands/fixmybarangay/base.scss new file mode 100644 index 000000000..71c2d8205 --- /dev/null +++ b/web/cobrands/fixmybarangay/base.scss @@ -0,0 +1,56 @@ +@import "../fixmystreet/_h5bp"; +@import "./_colours"; +@import "../fixmystreet/_mixins"; +@import "compass"; + +@import "../fixmystreet/_base"; + +#site-logo{ + width: 225px !important; + background: url('images/sprite.png') -3px -3px no-repeat; +} + +#barangay_buttons { + padding: 1em; +} + +.yellow-btn, +a.yellow-btn, +button.yellow-btn, +input.yellow-btn{ + @include button-reset(#FFD000, #cc9000, #aa7000, #300, #FFD000, #cc9000, #aa7000, #300); + &:visited, &:hover { + color:#300; + } +} + +body.mappage .nav-wrapper div.nav-wrapper-2 { + background: url('images/city6.png') 30% 0% repeat-x; + border-bottom: 2px solid #333; +} +#main-nav ul#main-menu li a.report-a-problem-btn:hover { + background: #fff; +} + + +// Replace Sprite with cobrand sprite +.ie6 #site-logo, +.ie7 #site-logo, +.ie6 body.frontpage #site-logo, +.ie6 #main-nav ul#mysoc-menu li a#mysoc-logo, +.ie7 #main-nav ul#mysoc-menu li a#mysoc-logo, +#fms_pan_zoom_panup, #fms_pan_zoom_pandown, +#fms_pan_zoom_panleft, +#fms_pan_zoom_panright, +#fms_pan_zoom_zoomin, +#fms_pan_zoom_zoomout, +.button-right, +a.button-right, +:hover.button-right, +a:hover.button-right, +.button-left, +a.button-left, +:hover.button-left, +a:hover.button-left { + background-image: url('images/sprite.png'); +}
\ No newline at end of file diff --git a/web/cobrands/fixmybarangay/config.rb b/web/cobrands/fixmybarangay/config.rb new file mode 100644 index 000000000..cab97b18f --- /dev/null +++ b/web/cobrands/fixmybarangay/config.rb @@ -0,0 +1,25 @@ +# Require any additional compass plugins here. + +# Set this to the root of your project when deployed: +http_path = "/" +css_dir = "" +sass_dir = "" +images_dir = "" +javascripts_dir = "" + +# You can select your preferred output style here (can be overridden via the command line): +# output_style = :expanded or :nested or :compact or :compressed + +# To enable relative paths to assets via compass helper functions. Uncomment: +# relative_assets = true + +# To disable debugging comments that display the original location of your selectors. Uncomment: +# line_comments = false + +# If you prefer the indented syntax, you might want to regenerate this +# project again passing --syntax sass, or you can uncomment this: +# preferred_syntax = :sass +# and then run: +# sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass + +line_comments = false # by Compass.app diff --git a/web/cobrands/fixmybarangay/images/city6.png b/web/cobrands/fixmybarangay/images/city6.png Binary files differnew file mode 100644 index 000000000..63d7e674c --- /dev/null +++ b/web/cobrands/fixmybarangay/images/city6.png diff --git a/web/cobrands/fixmybarangay/images/city7.png b/web/cobrands/fixmybarangay/images/city7.png Binary files differnew file mode 100644 index 000000000..cea65cb82 --- /dev/null +++ b/web/cobrands/fixmybarangay/images/city7.png diff --git a/web/cobrands/fixmybarangay/images/ie_front_logo.gif b/web/cobrands/fixmybarangay/images/ie_front_logo.gif Binary files differnew file mode 100644 index 000000000..2eeda87ef --- /dev/null +++ b/web/cobrands/fixmybarangay/images/ie_front_logo.gif diff --git a/web/cobrands/fixmybarangay/images/ie_logo.png b/web/cobrands/fixmybarangay/images/ie_logo.png Binary files differnew file mode 100644 index 000000000..454297104 --- /dev/null +++ b/web/cobrands/fixmybarangay/images/ie_logo.png diff --git a/web/cobrands/fixmybarangay/images/pat3.png b/web/cobrands/fixmybarangay/images/pat3.png Binary files differnew file mode 100644 index 000000000..a0f755de9 --- /dev/null +++ b/web/cobrands/fixmybarangay/images/pat3.png diff --git a/web/cobrands/fixmybarangay/images/sprite.png b/web/cobrands/fixmybarangay/images/sprite.png Binary files differnew file mode 100644 index 000000000..cbde4ac7f --- /dev/null +++ b/web/cobrands/fixmybarangay/images/sprite.png diff --git a/web/cobrands/fixmybarangay/layout.scss b/web/cobrands/fixmybarangay/layout.scss new file mode 100644 index 000000000..ccbf00748 --- /dev/null +++ b/web/cobrands/fixmybarangay/layout.scss @@ -0,0 +1,135 @@ +@import "_colours"; +@import "../fixmystreet/_layout"; + +@mixin box_round($radius) { + -webkit-border-radius: $radius; /* Safari 3-4, iOS 1-3.2, Android ≤1.6 */ + border-radius: $radius; /* Opera 10.5, IE9+, Safari 5, Chrome, Firefox 4+, iOS 4, Android 2.1+ */ + + /* useful if you don't want a bg color from leaking outside the border: */ + -moz-background-clip: padding; -webkit-background-clip: padding-box; background-clip: padding-box; +} + +body { + background: #C7B299; + background-image: url(images/pat3.png); + + .wrapper{ + background: url('images/city7.png') 30% 0% repeat-x; + } +} + + + body.frontpage { + #site-logo{ + width: 370px !important; + height: 70px; + background: url('images/sprite.png') -3px -106px no-repeat; + } + + .wrapper{ + background: url('images/city7.png') 30% 0% repeat-x; + } +} +#main-nav ul#mysoc-menu li a#mysoc-logo { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIkAAAAyCAMAAABf9whNAAAA0lBMVEUAAABAQEBAQEBAQEBNTU1NTU1AQEBNTU1AQEBAQEBAQEBAQEBAQEBAQEBAQEBNTU1NTU1AQEBNTU1AQEBNTU1AQEBAQEBNTU2Mxj9NTU33kx5NTU1NTU1NTU3tHCRmLZEpq+JNTU2TJ4/tHCSTJ4/87iEpq+L3kx5NTU387iH87iHtHCSTJ4/3kx51K5CTJ49mLZGMxj/tHCSx0zVmLZH6wSBmLZFmLZFDdb/zYCFbuZGMxj/3kx5AQEBNTU0pq+LtHCSMxj/3kx787iFmLZGTJ49ns3BGAAAAPXRSTlMAQL+AQIAQECBwMGBQj98gn5/Pr+/vzzC/r79wYI9wv69QcK+vcICfv68QQBAwj0AwMBBggIBQr3BwgEBgSmaQCwAAAflJREFUeF7t1Ndy2zAQhtGfAAX2IpFUseSSOLGd3nt27bT3f6UsQHusRFcKmVxkcGa4wvCG34AQ8V/wPM/zPM8zSaOaxGBHtFpF+IfikqwYO0LmELfiHH/XlLokSBrsiurtPdGkMJJFWFWTSQUZC0RhWMFNRQWuvTw9RS/VOolNEBgAudYpkE5pHqRpEACIZQ4x4RkztxMWd6KWa2DDvFDUBeg9urr6cPAZMIqEDogCmDmJKdwtlbjXOCc1sIRnhyxj0vIMNbeQMUNun5DBOTo6/3oASMhUF6krka3IM1lkikqdGaICMVE2sKSNICkR1sxYyMag5TWQd7bFPH4G8eT8zcOUKIGwJUYuSE7hzoldlZAwM7Dkwg4GQjtmXMtvBZHNiZJ7P+5C3P/2oH9SXyKXo1yJq0sbmmLMkg23h7xCryR1W5L8WqKsmz1BSbqjfNSSiMUGMEB/Bp8ePwdeLF/ZAn1TEssFR1MJIZmyGLUENXNrI8pCK6IMx99fn50tvyyBcuvEKuqKXDcuocgAQ/I7conMGgA5BfD23fvLy4/LT0Ba/v4vphRxR9dnlmIMU4ULO0IgsgPr/rya3H7F4JycoCf3sq0vW5ICiLXO3YtsMC4JqbG3uCFKMSb3nYuwNyLKMK6Q6wj7a7oMY4vwJwwG8TzP8zzP834CEcRJKkEhVogAAAAASUVORK5CYII="); +} +#front-main { + color: $primary_text; + background: rgba(255,255,255,0.1); + margin-top: 70px; + + #postcodeForm { + margin-left: 0; + margin-right: 0; + } + + a { + text-decoration:none; + } + + p { + padding-bottom:4px; + } +} + +.nav-wrapper { + .nav-wrapper-2 { + border-top: solid 4px $primary; + @include border-image(none); + } +} +#main-nav { + ul { + &#mysoc-menu { + background:$primary; + padding: 1px 0.5em; + } + &#main-menu{ + padding: 3px 0; + li{ + a{ + //@extend .report-a-problem-btn; + color: #fff; + padding: 0.7em; + background-color: rgba(0,0,0,0); + background-image: none; + &:hover{ + background-color: rgba(0,0,0,0.8); + } + } + } + } + + } +} +body.mappage #main-nav ul#main-menu li a, +body.mappage #main-nav ul#main-menu li span, +body #main-nav ul#main-menu li a, +body #main-nav ul#main-menu li span +{ + color: #fff; + padding: 0.7em; + background-color: rgba(0,0,0,0); + background-image: none; + @include box_round(0.35em); + margin-left: 3px; + + &.report-a-problem-btn{ + color: #fff; + padding: 0.7em; + background-color: rgba(0,0,0,0); + background-image: none; + margin: 0; + } + + &.fmb-bgy-btn { + color: #fcc921; + } + + + &:hover{ + background-color: rgba(0,0,0,0.75); + background-image: none; + } + +} + + +#user-meta { + max-width: 96%; +} + + + +#front-howto { + #front_stats { + border-top: 0.25em solid #000; + div { + big { + color: #000; + } + } + } +} + +@import "message_manager";
\ No newline at end of file diff --git a/web/cobrands/fixmybarangay/message_manager.scss b/web/cobrands/fixmybarangay/message_manager.scss new file mode 100644 index 000000000..9d9555640 --- /dev/null +++ b/web/cobrands/fixmybarangay/message_manager.scss @@ -0,0 +1,174 @@ +@import "_colours"; + +$mm_status_message_color: #a66; +$mm_border_color: #eee; + +$color_reply_bg: #cccccc; +$color_bg_reply_0: #E8E8E8; +$color_bg_reply_1: #DEDEDE; +$color_bg_reply_2: #D6D6D6; +$color_bg_reply_3: #D1D1D1; +$color_bg_reply_4: #C9C9C9; +$color_bg_reply_5: #BFBFBF; +$color_bg_reply_6: #B8B8B8; +$color_bg_mm_list: #F6F6F6; + +$weak_text_color: #666; + +#message_manager { + + #message-control { + #mm-username-container { + display: none; // hidden during dev + padding: 8px; + text-align: right; + color: $mm_status_message_color; + font-style: italic; + span { + color: #000; + font-style: normal; + } + } + #mm-status-message-container { + min-height: 1.4em; + margin: 0 0 8px 0.5em; + padding: 8px 4px; + color: $mm_status_message_color; + font-style: italic; + } + #mm-login-container { + display: none; // only shown on/after a 403 + border: 1px solid $mm_border_color; + padding: 0 1em; + margin: 1em; + input { + margin-bottom: 1em; + } + } + } + + #mm-message-list { + ul { + list-style-type: none; + padding: 0; + margin: 0; + li, ul.mm-reply-thread li { + position: relative; + clear: both; + margin: 4px 0 0 0; + padding: 0; + cursor: pointer; + background-color: $color_bg_mm_list; + p { + background-color: inherit; + margin: 0.25em 0 0 0; + padding: 0.5em 1em; + &:hover { background-color: #efe;} + .msg-info-box { + font-style: italic; + font-size: 90%; + color: #666; + border-top: 1px dashed #666; + padding:4px 0 0 0; + margin: 4px 0 0 0; + display: none; + } + } + ul.mm-reply-thread { + li { + margin:0; + } + .mm-reply { + background-color: #ccc; + &:hover {background-color: #eef;} + } + .mm-reply-0 { margin-left: 0em; background-color: $color_bg_reply_0;} + .mm-reply-1 { margin-left: 1em; background-color: $color_bg_reply_1;} + .mm-reply-2 { margin-left: 2em; background-color: $color_bg_reply_2;} + .mm-reply-3 { margin-left: 3em; background-color: $color_bg_reply_3;} + .mm-reply-4 { margin-left: 4em; background-color: $color_bg_reply_4;} + .mm-reply-5 { margin-left: 5em; background-color: $color_bg_reply_5;} + .mm-reply-6 { margin-left: 6em; background-color: $color_bg_reply_6;} + } + &:hover { background-color: #efe;} + &.msg-is-locked { background-color: #fdd;} + &.msg-is-busy { background-color: #ffd;} + &.msg-is-owned { background-color: #dfd;} + &.msg-is-active { + background-color: $contrast1; color:#fff; + p:hover { background-color: $contrast1; color:#fff; } // fix for mouseover on p + } + span.msg-tag { + width: 3em; + float:left; + } + input[type=radio] { + display: block; + float: left; + } + label, span.msg-text { + display: block; + font-weight: normal; + margin: 0.1em 0 0.1em 4.5em; + } + .mm-msg-action { + display: none; + padding: 0.2em 0.4em; + color: white; + text-align: center; + position: absolute; + top: 4px; + &:hover { background-color: black;} + } + .mm-hide { + right:0px; + background-color: red; + } + .mm-info { + right:1.5em; + background-color: blue; + } + .mm-rep { + right:2.6em; + background-color: green; + } + } + } + } + p.mm-empty { + margin: 1em; + } +} +#show_messages, #add_support, #reply-submit { // COPY TO UPDATE button + margin: 1em; +} + +#reply-form-container, +#hide-form-container { + p { + color: #000; + } + #hide-form, + #reply-form{ + margin-top: 2em; + textarea { + min-height: 3em; + margin-bottom: 0.5em; + } + } + #mm-boilerplate-replies-box, #mm-boilerplate-hide-reasons-box { + overflow: hidden; + display: none; + } +} +div#mm-admin-buttons { + display:block; + text-align: right; + float:right; + font-size:80%; + padding:4px 8px 4px 0; + a { + display: block; + } + +} diff --git a/web/cobrands/fixmybarangay/message_manager_client.js b/web/cobrands/fixmybarangay/message_manager_client.js new file mode 100644 index 000000000..fa04063c8 --- /dev/null +++ b/web/cobrands/fixmybarangay/message_manager_client.js @@ -0,0 +1,686 @@ +/* + * creates a message_manage object that uses the Message Manager API: + * include this file, then initialise the object when the page is loaded with + * message_manager.config(settings) + * + * i.e., you *must* do something like: + * + * $(document).ready(function() { + * message_manager.config({url_root:'http://yourdomain.com/messages'}) + * } + * + * You'll need to set the url_root, but you can leave everything else to default + * provided your HTML ids and classes are the same as ours (which they might be: + * see the Message Manager's dummy client (at /client) to see the HTML we use). + * + * The (optional) single parameter for .config() is a hash of name-value pairs: + * + * url_root accepts the root URL to the message manager. + * + * want_unique_locks normally MM clients should relinquish all other locks + * when claiming a new one so want_unique_locks defaults + * to true; but you can set it explicitly here. + * + * mm_name name of Message Manager (used in error messages shown + * to user, e.g., "please log in to Message Manager") + * + * msg_prefix all message <li> items have this as their ID prefix + * + * want_nice_msgs don't use language like "lock granted" + * + * *_selector these are the jQuery selects that will be used to find + * the respective elements: + * + * message_list_selector: list of messages + * status_selector: status message display + * login_selector: login form + * + * + * Summary of all methods: + * message_manager.config([options]) + * message_manager.setup_click_listener([options]) + * message_manager.get_available_messages([options]) + * message_manager.request_lock(msg_id, [options]) (default use: client code doesn't need to call this explicitly) + * message_manager.assign_fms_id(msg_id, fms_id, [options]) + * message_manager.hide(msg_id, reason_text, [options]) + * message_manager.reply(msg_id, reply_text, [options]) + * message_manager.show_info(msg_id) + * message_manager.sign_out() + * + * Note: options are {name:value, ...} hashes and often include "callback" which is a function that is executed on success + * but see the docs (request_lock executes callback if the call is successful even if the lock was denied, for example). + * Some methods take 'callback' as the only option, but you still need to pass it as a named option. +*/ + +var message_manager = (function() { + + // default/config values: to be overridden using "config({name:value, ...})" + + var _url_root = 'http://www.example.com/message_manager/'; + var _want_unique_locks = true; + var _msg_prefix = "msg-"; + var _username; + var _mm_name = "Message Manager"; + var _use_fancybox = true; // note: currently *must* have fancybox! + var _want_nice_msgs = false; + + // cached jQuery elements, populated by the (mandatory) call to config() + var $message_list_element; + var $status_element; + var $login_element; + var $htauth_username; + var $htauth_password; + var $hide_reasons; + var $boilerplate_replies; + + var msg_no_config_err = "Config error: no Message Manager URL has been specified"; + + var msg_trying_for_lock = ["Trying for lock...", "Checking message..." ]; + var msg_checking_lock = ["Checking lock...", "Checking message..." ]; + var msg_claiming_lock = ["Claiming lock...", "Checking message..." ]; + var msg_lock_granted_ok = ["Lock granted OK", "Checking message... OK"]; + var msg_lock_denied = ["", "Someone is working with that message right now!"]; + + function get_msg(msg) { + return msg[_want_nice_msgs? 1 : 0]; + } + + var config = function(settings) { + var selectors = { + message_list_selector: '#mm-message-list', + status_selector: '#mm-status-message-container', + login_selector: '#mm-login-container', + username_selector: '#mm-received-username', + htauth_username_selector: '#mm-htauth-username', + htauth_password_selector: '#mm-htauth-password', + boilerplate_hide_reasons: '#mm-boilerplate-hide-reasons-box', + boilerplate_replies: '#mm-boilerplate-replies-box' + }; + if (settings) { + if (typeof settings.url_root === 'string') { + _url_root = settings.url_root; + if (_url_root.length > 0 && _url_root.charAt(_url_root.length-1) !== "/") { + _url_root+="/"; + } + } + if (typeof settings.want_unique_locks !== 'undefined') { + _want_unique_locks = settings.want_unique_locks; + } + if (typeof settings.msg_prefix === 'string') { + _msg_prefix = settings.msg_prefix; + } + for (var sel in selectors) { + if (typeof settings[sel] === 'string') { + selectors[sel] = settings[sel]; + } + } + if (typeof settings.mm_name === 'string') { + _mm_name = settings.mm_name; + } + if (typeof settings.want_nice_msgs !== 'undefined') { + _want_nice_msgs = settings.want_nice_msgs; + } + } + $message_list_element = $(selectors.message_list_selector); + $status_element = $(selectors.status_selector); + $login_element = $(selectors.login_selector); + $htauth_username = $(selectors.htauth_username_selector); + $htauth_password = $(selectors.htauth_password_selector); + $hide_reasons = $(selectors.boilerplate_hide_reasons); + $boilerplate_replies = $(selectors.boilerplate_replies); + if (typeof settings.url_root === 'string' && _url_root.length===0) { + say_status(msg_no_config_err); + } + }; + + // btoa doesn't work on all browers? + var make_base_auth = function(user, password) { + var tok = user + ':' + password; + var hash = btoa(tok); + return "Basic " + hash; + }; + + var get_current_auth_credentials = function() { + var base_auth = ""; + var htauth_un = ""; + var htauth_pw = ""; + if ($htauth_username.size()) { + htauth_un = $htauth_username.val(); + htauth_pw = $htauth_password.val(); + } + if (htauth_un.length === 0 && Modernizr.sessionstorage && sessionStorage.getItem('mm_auth')) { + base_auth = sessionStorage.getItem('mm_auth'); + } else { + base_auth = make_base_auth(htauth_un, htauth_pw); + if (Modernizr.sessionstorage) { + sessionStorage.mm_auth = base_auth; + } + } + return base_auth; + }; + + var sign_out = function() { // clear_current_auth_credentials + if (Modernizr.sessionstorage) { + sessionStorage.removeItem('mm_auth'); + } + if ($htauth_password) { + $htauth_password.val(''); + } + }; + + var show_login_form = function(suggest_username) { + $('.mm-msg', $message_list_element).remove(); // remove (old) messages + if ($htauth_username.size() && ! $htauth_username.val()) { + $htauth_username.val(suggest_username); + } + $login_element.stop().slideDown(); + }; + + var say_status = function (msg) { + if ($status_element) { + $status_element.stop().show().text(msg); + } + }; + + var extract_replies = function(replies, depth) { + var $ul = ""; + if (replies && replies.length > 0) { + $ul = $('<ul class="mm-reply-thread"/>'); + for (var i=0; i<replies.length; i++) { + $ul.append(get_message_li(replies[i], depth)); + } + } + return $ul; + }; + + var get_message_li = function(message_root, depth) { + var msg = message_root.Message; // or use label value + var lockkeeper = message_root.Lockkeeper.username; + var escaped_text = $('<div/>').text(msg.message).html(); + var $p = $('<p/>'); + var $hide_button = $('<a class="mm-msg-action mm-hide" id="mm-hide-' + msg.id + '" href="#hide-form-container">X</a>'); + var $info_button = $('<span class="mm-msg-action mm-info" id="mm-info-' + msg.id + '">i</span>'); + var $reply_button = $('<a class="mm-msg-action mm-rep" id="mm-rep-' + msg.id + '" href="#reply-form-container">reply</a>'); + if (_use_fancybox) { + $reply_button.fancybox(); + $hide_button.fancybox(); + } + if (depth === 0) { + var tag = (!msg.tag || msg.tag === 'null')? ' ' : msg.tag; + tag = $('<span class="msg-tag"/>').html(tag); + var radio = depth > 0? null : $('<input type="radio"/>').attr({ + 'id': 'mm_text_' + msg.id, + 'name': 'mm_text', + 'value': escaped_text + }).wrap('<p/>').parent().html(); + var label = $('<label/>', { + 'class': 'msg-text', + 'for': 'mm_text_' + msg.id + }).text(escaped_text).wrap('<p/>').parent().html(); + $p.append(tag).append(radio).append(label); + } else { + $p.text(escaped_text).addClass('mm-reply mm-reply-' + depth); + } + var $litem = $('<li id="' + _msg_prefix + msg.id + '" class="mm-msg">').append($p).append($hide_button).append($info_button); + if (msg.is_outbound != 1) { + $litem.append($reply_button); + } + if (lockkeeper) { + $litem.addClass(lockkeeper == _username? 'msg-is-owned' : 'msg-is-locked'); + } + var info_text = ""; + if (msg.is_outbound == 1) { + info_text = 'sent on ' + msg.created + ' by ' + msg.sender_token; + } else { + info_text = 'received on ' + msg.created + ' from ' + '<abbr title="'+ msg.sender_token + '">user</abbr>'; + } + $p.append('<div class="msg-info-box" id="msg-info-box-' + msg.id + '">' + info_text + '</div>'); + if (message_root.children) { + $litem.append(extract_replies(message_root.children, depth+1)); + } + return $litem; + }; + + var show_available_messages = function(data, anim_duration) { + var messages = data.messages; + _username = data.username; + var $output = $message_list_element; + if (anim_duration > 0) { + $output.stop().fadeOut(anim_duration, function(){ + render_available_messages(data, anim_duration); + }); + } else { + render_available_messages(data, anim_duration); + } + }; + + // render allows animation (if required) to hide messages before repainting and then revealing them + var render_available_messages = function(data, anim_duration) { + var messages = data.messages; + _username = data.username; + var $output = $message_list_element; + if (messages instanceof Array) { + if (messages.length === 0) { + $output.html('<p class="mm-empty">No messages available.</p>'); + } else { + var $ul = $('<ul class="mm-root"/>'); + for(var i=0; i< messages.length; i++) { + var litem = get_message_li(messages[i], 0); + $ul.append(litem); + } + $output.empty().append($ul); + } + } else { + $output.html('<p>No messages (server did not send a list).</p>'); + } + if (anim_duration > 0) { + $output.slideDown(anim_duration); + } + }; + + // accept an element (e.g., message_list) and add the click event to the *radio button* within it + // A bit specific to expect li's perhaps. + // options are passed through to the lock + var setup_click_listener = function(options) { + $message_list_element.on('click', 'input[type=radio]', function(event) { + var $li = $(this).closest('li'); + var id = $li.attr('id').replace(_msg_prefix, ''); + if ($li.hasClass('msg-is-locked')) { + say_status(get_msg(msg_trying_for_lock)); + } else if ($li.hasClass('msg-is-owned')) { + say_status(get_msg(msg_checking_lock)); + } else { + say_status(get_msg(msg_claiming_lock)); + } + request_lock(id, options); + }); + // clicking the reply button loads the id into the (modal/fancybox) reply form + $message_list_element.on('click', '.mm-rep', function(event) { + $('#reply_to_msg_id').val($(this).closest('li').attr('id').replace(_msg_prefix, '')); + }); + // clicking the hide button loads the id into the (modal/fancybox) hide form + $message_list_element.on('click', '.mm-hide', function(event) { + $('#hide_msg_id').val($(this).closest('li').attr('id').replace(_msg_prefix, '')); + // $('#hide-form-message-text').val(TODO); + }); + }; + + // gets messages or else requests login + // options: suggest_username, if provided, is preloaded into the login form if provided + // anim_duration: duration of fade/reveal (0, by defaut, does no animation) + var get_available_messages = function(options) { + var base_auth = get_current_auth_credentials(); + var suggest_username = ""; + var anim_duration = 0; + var callback = null; + if (options) { + if (typeof(options.callback) === 'function') { + callback = options.callback; + } + if (typeof options.suggest_username === 'string') { + suggest_username = options.suggest_username; + } + if (typeof options.anim_duration === 'string' || typeof options.anim_duration === 'number') { + anim_duration = parseInt(options.anim_duration, 10); + if (isNaN(anim_duration)) { + anim_duration = 0; + } + } + } + if (base_auth === "") { + show_login_form(suggest_username); + return; + } + $login_element.stop().hide(); + if (_url_root.length === 0) { + say_status(msg_no_config_err); + } else { + $.ajax({ + dataType: "json", + type: "post", + url: _url_root +"messages/available.json", + beforeSend: function (xhr){ + xhr.setRequestHeader('Authorization', get_current_auth_credentials()); + xhr.withCredentials = true; + }, + success: function(data, textStatus) { + show_available_messages(data, anim_duration); + if (typeof(callback) === "function") { + callback.call($(this), data); // execute callback + } + }, + error: function(jqXHR, textStatus, errorThrown) { + var st = jqXHR.status; + if (st == 401 || st == 403) { + var msg = (st == 401 ? "Invalid username or password for" : "Access denied: please log in to") + " " + _mm_name; + say_status(msg); + show_login_form(suggest_username); + } else { + var err_msg = "Unable to load messages: "; + if (st === 0 && textStatus === 'error') { // x-domain hard to detect, sometimes intermittent? + err_msg += "maybe try refreshing page?"; + } else { + err_msg += textStatus + " (" + st + ")"; + } + say_status(err_msg); + } + } + }); + } + }; + + var request_lock = function(msg_id, options) { + var $li = $('#' + _msg_prefix + msg_id); + var lock_unique = _want_unique_locks; + var callback = null; + if (options) { + if (typeof(options.callback) === 'function') { + callback = options.callback; + } + if (typeof(options.lock_unique) !== undefined && options.lock_unique !== undefined) { + lock_unique = options.lock_unique; + } + } + $li.addClass('msg-is-busy'); + $.ajax({ + dataType:"json", + type:"post", + url: _url_root +"messages/" + + (lock_unique? "lock_unique" : "lock") + + "/" + msg_id + ".json", + beforeSend: function (xhr){ + xhr.setRequestHeader('Authorization', get_current_auth_credentials()); + xhr.withCredentials = true; + }, + success:function(data, textStatus) { + if (data.success) { + if (lock_unique) { + $('.msg-is-owned', $message_list_element).removeClass('msg-is-owned'); + } + $li.removeClass('msg-is-busy msg-is-locked').addClass('msg-is-owned'); + say_status(get_msg(msg_lock_granted_ok)); // to data['data']['Lockkeeper']['username']? + } else { + $li.removeClass('msg-is-busy').addClass('msg-is-locked'); + say_status(get_msg(msg_lock_denied) || ("lock failed: " + data.error)); + } + if (typeof(callback) === "function") { // note callbacks must check data['success'] + callback.call($(this), data); // returned data['data'] is 'Message', 'Source', 'Lockkeeper' for success + } + }, + error: function(jqXHR, textStatus, errorThrown) { + $li.removeClass('msg-is-busy'); + say_status("error: " + textStatus + ": " + errorThrown); + } + }); + }; + + var assign_fms_id = function(msg_id, fms_id, options) { + var check_li_exists = false; + var is_async = true; + var callback = null; + if (options) { + if (typeof(options.callback) === 'function') { + callback = options.callback; + } + if (typeof(options.check_li_exists) !== undefined && options.check_li_exists !== undefined) { + check_li_exists = true; // MM dummy + } + if (typeof(options.is_async) !== undefined && options.is_async !== undefined) { + is_async = options.is_async; + } + } + var $li = $('#' + _msg_prefix + msg_id); + if (check_li_exists) { + if ($li.size() === 0) { + say_status("Couldn't find message with ID " + msg_id); + return; + } + } + if (isNaN(parseInt(fms_id,10))) { + say_status("missing FMS id"); + return; + } + $li.addClass('msg-is-busy'); + $.ajax({ + async:is_async, + dataType:"json", + type:"post", + data: {fms_id: fms_id}, + url: _url_root +"messages/assign_fms_id/" + msg_id + ".json", + beforeSend: function (xhr){ + xhr.setRequestHeader('Authorization', get_current_auth_credentials()); + xhr.withCredentials = true; + }, + success:function(data, textStatus) { + if (data.success) { + $li.removeClass('msg-is-busy msg-is-locked').addClass('msg-is-owned').fadeOut('slow'); // no longer available + say_status("OK: report ID was assigned to message."); + if (typeof(callback) === "function") { + callback.call($(this), data.data); // returned data['data'] is 'Message', 'Source', 'Lockkeeper' for success + } + } else { + $li.removeClass('msg-is-busy').addClass('msg-is-locked'); + say_status("failed: " + data.error); + } + }, + error: function(jqXHR, textStatus, errorThrown) { + say_status("error: " + textStatus + ": " + errorThrown); + $li.removeClass('msg-is-busy'); + } + }); + }; + + var reply = function(msg_id, reply_text, options) { + if (_use_fancybox){ + $.fancybox.close(); + } + var callback = null; + var check_li_exists = false; + if (options) { + if (typeof(options.callback) === 'function') { + callback = options.callback; + } + if (typeof(options.check_li_exists) !== undefined && options.check_li_exists !== undefined) { + check_li_exists = true; // MM dummy + } + } + var $li = $('#' + _msg_prefix + msg_id); + if (check_li_exists) { + if ($li.size() === 0) { + say_status("Couldn't find message with ID " + msg_id); + return; + } + } + reply_text = $.trim(reply_text); + if (reply_text === '') { + say_status("No reply sent: message was empty!"); + return; + } + $li.addClass('msg-is-busy'); + $.ajax({ + dataType:"json", + type:"post", + data: {reply_text: reply_text}, + url: _url_root +"messages/reply/" + msg_id + ".json", + beforeSend: function (xhr){ + xhr.setRequestHeader('Authorization', get_current_auth_credentials()); + xhr.withCredentials = true; + }, + success:function(data, textStatus) { + if (data.success) { + $li.removeClass('msg-is-busy msg-is-locked').addClass('msg-is-owned'); // no longer available + say_status("Reply sent OK"); + if (typeof(callback) === "function") { + callback.call($(this), data.data); // returned data['data'] is null but may change in future + } + } else { + $li.removeClass('msg-is-busy').addClass('msg-is-locked'); + say_status("Reply failed: " + data.error); + } + }, + error: function(jqXHR, textStatus, errorThrown) { + say_status("Reply error: " + textStatus + ": " + errorThrown); + $li.removeClass('msg-is-busy'); + } + }); + }; + + var hide = function(msg_id, reason_text, options) { + if (_use_fancybox){ + $.fancybox.close(); + } + var callback = null; + var check_li_exists = false; + if (options) { + if (typeof(options.callback) === 'function') { + callback = options.callback; + } + if (typeof(options.check_li_exists) !== undefined && options.check_li_exists !== undefined) { + check_li_exists = true; // MM dummy + } + } + var $li = $('#' + _msg_prefix + msg_id); + if (check_li_exists) { + if ($li.size() === 0) { + say_status("Couldn't find message with ID " + msg_id); + return; + } + } + reason_text = $.trim(reason_text); + $li.addClass('msg-is-busy'); + $.ajax({ + dataType:"json", + type:"post", + data: {reason_text: reason_text}, + url: _url_root +"messages/hide/" + msg_id + ".json", + beforeSend: function (xhr){ + xhr.setRequestHeader('Authorization', get_current_auth_credentials()); + xhr.withCredentials = true; + }, + success:function(data, textStatus) { + if (data.success) { + $li.removeClass('msg-is-busy msg-is-locked').addClass('msg-is-owned').fadeOut('slow'); // no longer available + say_status("Message hidden"); + if (typeof(callback) === "function") { + callback.call($(this), data.data); + } + } else { + $li.removeClass('msg-is-busy').addClass('msg-is-locked'); + say_status("Hide failed: " + data.error); + } + }, + error: function(jqXHR, textStatus, errorThrown) { + say_status("Hide error: " + textStatus + ": " + errorThrown); + $li.removeClass('msg-is-busy'); + } + }); + }; + + var show_info = function(msg_id) { + var $info = $("#msg-info-box-" + msg_id); + if ($info.size()==1) { + if ($info.is(':hidden')) { + $info.slideDown(); + } else { + $info.slideUp(); + } + } + }; + + // if boilerplate is not already in local storage, make ajax call and load them + // otherwise, populate the boilerplate select lists: these are currently the + // reasons for hiding a message, and pre-loaded replies.message-manager.dev.mysociety.org + // NB no auth required on this call + var populate_boilerplate_strings = function(boilerplate_type, options) { + if (Modernizr.sessionstorage && sessionStorage.getItem('boilerplate_' + boilerplate_type)) { + populate_boilerplate(boilerplate_type, sessionStorage.getItem('boilerplate_' + boilerplate_type)); + return; + } + var callback = null; + if (options) { + if (typeof(options.callback) === 'function') { + callback = options.callback; + } + } + $.ajax({ + dataType:"json", + type:"get", + url: _url_root +"boilerplate_strings/index/" + boilerplate_type + ".json", + success:function(data, textStatus) { + if (data.success) { + var raw_data = data.data; + var select_html = get_select_tag_html(data.data, boilerplate_type); + if (Modernizr.sessionstorage) { + sessionStorage.setItem('boilerplate_' + boilerplate_type, select_html); + } + populate_boilerplate(boilerplate_type, select_html); + if (typeof(callback) === "function") { + callback.call($(this), data.data); + } + } else { + // console.log("failed to load boilerplate"); + } + }, + error: function(jqXHR, textStatus, errorThrown) { + // console.log("boilerplate error: " + textStatus + ": " + errorThrown); + } + }); + }; + + // TODO flatten all HTML in boilerplate text + var get_select_tag_html = function(boilerplate_data, boilerplate_type) { + var html = "<option value=''>--none--</option>\n"; + var qty_langs = 0; + var qty_strings = 0; + if (boilerplate_data.langs) { + for (var i=0; i< boilerplate_data.langs.length; i++) { + var lang = boilerplate_data.langs[i]; + var options = ""; + for (var j in boilerplate_data[lang]) { + if (boilerplate_data[lang].hasOwnProperty(j)) { + options += "<option>" + boilerplate_data[lang][j] + "</option>\n"; + qty_strings++; + } + } + if (boilerplate_data.langs.length > 1) { // really need pretty name for language + options = '<optgroup label="' + lang + '">\n' + options + '</optgroup>\n'; + } + html += options; + } + } + if (qty_strings === 0) { + html = ''; + } + return html; + }; + + // actually load the select tag + var populate_boilerplate = function(boilerplate_type, html) { + var $target = null; + switch(boilerplate_type) { + case 'hide-reason': $target = $hide_reasons; break; + case 'reply': $target = $boilerplate_replies; break; + } + if ($target) { + if (html) { + $target.show().find('select').html(html); + } else { + $target.hide(); + } + } + }; + + // revealed public methods: + return { + config: config, + setup_click_listener: setup_click_listener, + get_available_messages: get_available_messages, + request_lock: request_lock, + assign_fms_id: assign_fms_id, + reply: reply, + hide: hide, + show_info: show_info, + sign_out: sign_out, + populate_boilerplate_strings: populate_boilerplate_strings + }; +})(); diff --git a/web/cobrands/fixmybarangay/messages.js b/web/cobrands/fixmybarangay/messages.js new file mode 100644 index 000000000..aebf35156 --- /dev/null +++ b/web/cobrands/fixmybarangay/messages.js @@ -0,0 +1,26 @@ +$(function(){ + + var mm = $('#message_manager'); + + $.getJSON('/cobrands/fixmybarangay/test-texts.json', function(data) { + var items = []; + $.each(data, function(k, v) { + var item = $('<input type="radio"/>').attr({ + 'id': 'mm_text_' + v.id, + 'name': 'mm_text', + 'value': v.text + }).wrap('<p/>').parent().html(); + var label = $('<label/>', { + 'class': 'inline', + 'for': 'mm_text_' + v.id + }).text(v.text).wrap('<p/>').parent().html(); + item = '<li><p>' + item + ' ' + label + '</p></li>'; + items.push(item); + }); + mm.html(items.join('')); + mm.find('input').click(function(){ + $('#form_detail').val( $('input[name=mm_text]:checked').val() ); + }); + }); + +}); diff --git a/web/cobrands/fixmybarangay/position_map.js b/web/cobrands/fixmybarangay/position_map.js new file mode 100644 index 000000000..753b5f854 --- /dev/null +++ b/web/cobrands/fixmybarangay/position_map.js @@ -0,0 +1,22 @@ +function position_map_box() { + var $html = $('html'); + if ($html.hasClass('ie6')) { + $('#map_box').prependTo('.wrapper').css({ + zIndex: 0, position: 'absolute', + top: 0, left: 0, right: 0, bottom: 0, + width: '100%', height: $(window).height(), + margin: 0 + }); + } else { + $('#map_box').prependTo('.wrapper').css({ + zIndex: 0, position: 'fixed', + top: 0, left: 0, right: 0, bottom: 0, + width: '100%', height: '100%', + margin: 0 + }); + } +} + +function map_fix() {} +var slide_wards_down = 0; + diff --git a/web/cobrands/fixmybarangay/test-texts.json b/web/cobrands/fixmybarangay/test-texts.json new file mode 100644 index 000000000..7acde1e32 --- /dev/null +++ b/web/cobrands/fixmybarangay/test-texts.json @@ -0,0 +1,17 @@ +[ + { + "id" : 1, + "number" : "032-9999999", + "text" : "Pothole on corner of G. De Vera and T. Padilla" + }, + { + "id" : 2, + "number" : "032-1234567", + "text" : "Broken street light on Rahmann Street" + }, + { + "id" : 3, + "number" : "+63 917 0000000", + "text" : "F. Manalo giant pothole" + } +] diff --git a/web/cobrands/fixmystreet/_base.scss b/web/cobrands/fixmystreet/_base.scss index 5d71c33e6..1173e3061 100644 --- a/web/cobrands/fixmystreet/_base.scss +++ b/web/cobrands/fixmystreet/_base.scss @@ -585,6 +585,10 @@ p.label-valid { background-image:url('/cobrands/fixmystreet/images/sprite.png'); background-position:center -2563px; } + &.share { + background-image: url('/cobrands/fixmystreet/images/share.png'); + background-position: center 25%; + } &.chevron { background-image:url('/cobrands/fixmystreet/images/sprite.png'); background-position:center -2716px; @@ -631,6 +635,13 @@ p.label-valid { } } +#report-updates-data img { + float: right; +} + +#report-share iframe { + vertical-align: top; +} //footer blocks #footer-mobileapps { @@ -1146,25 +1157,29 @@ a:hover.button-left { } } &.map_complete { - background:none; - display:block; - border-bottom:4px solid #fff; + height: 100%; + background: none; + display: block; + border-bottom: 4px solid #fff; a#try_again { - display:block; - margin:0 auto 6em auto; - background:rgba(0, 0, 0, 0.8); + position: absolute; + display: block; + left: 25%; + bottom: 0; + margin-bottom: 6em; + background: rgba(0, 0, 0, 0.8); @include border-radius(0.5em); } a#mob_ok { - position:absolute; - right:1em; - bottom:0; - height:20px; - padding-top:30px; - display:block; - width:4em; - background:#fff url('/cobrands/fixmystreet/images/sprite.png') 12px -4140px no-repeat; - color:#000; + position: absolute; + display: block; + right: 1em; + bottom: 0; + height: 20px; + padding-top: 30px; + width: 4em; + background: #fff url('/cobrands/fixmystreet/images/sprite.png') 12px -4140px no-repeat; + color: #000; } } } @@ -1306,9 +1321,6 @@ table.nicetable { &.a { background:#f6f6f6; } - &:nth-child(even) { - background:#f6f6f6; - } &.gone { color: #666666; background-color: #cccccc; diff --git a/web/cobrands/fixmystreet/_layout.scss b/web/cobrands/fixmystreet/_layout.scss index 56b2f41d5..855e453b8 100644 --- a/web/cobrands/fixmystreet/_layout.scss +++ b/web/cobrands/fixmystreet/_layout.scss @@ -203,7 +203,7 @@ h1 { margin-top: 3em; margin-bottom: -1em; margin-left: 0.5em; - padding: 1em 1em 3em; + padding: 1em 1em 10em; background: #fff; @include box-shadow(0px 0px 6px 1px #000); } @@ -589,6 +589,11 @@ body.twothirdswidthpage { background-image:url(/cobrands/fixmystreet/images/sprite.png); background-position:right -3074px; } + &.share { + min-width: 5em; + background-image: url(/cobrands/fixmystreet/images/share.png); + background-position: 90% 50%; + } &.chevron { background-image:url(/cobrands/fixmystreet/images/sprite.png); background-position:right -3225px; @@ -618,6 +623,15 @@ body.twothirdswidthpage { padding-top: 0; } +// If JS is disabled, these are still CSS positioned, so don't want behind shining through. +#report-share, #report-updates-data { + background-color: #fff; +} +// Prevent gap in non-JS, and looks better with JS, due to some padding/margin effect. +#report-updates-data fieldset { + margin-bottom: 0; +} + // pokes over the RHS with a little triangle .big-green-banner { top:auto; @@ -732,7 +746,7 @@ textarea.form-error { .no-js #report-a-problem-sidebar { position: static; width: auto; - @include box-shadow(rgba(0, 0, 0, 0), 0, 0, 0); + @include box-shadow(rgba(0, 0, 0, 0) 0 0 0); .sidebar-tips, .sidebar-notes { font-size:1em; @@ -758,6 +772,14 @@ textarea.form-error { } } +/* Adjust the above so text flow can be different from display */ +#forgotten-pw { + position: relative; + left: 27em; + top: -7em; + margin-bottom: -7em; // So no gap in main flow +} + // Frontpage body.frontpage { @@ -1012,7 +1034,7 @@ body.frontpage { .general-sidebar-notes { position: static; width: auto; - @include box-shadow(rgba(0, 0, 0, 0), 0, 0, 0); + @include box-shadow(rgba(0, 0, 0, 0) 0 0 0); .sidebar-tips, .sidebar-notes { font-size:1em; diff --git a/web/cobrands/fixmystreet/fixmystreet.js b/web/cobrands/fixmystreet/fixmystreet.js index c8ed8ae51..714699386 100644 --- a/web/cobrands/fixmystreet/fixmystreet.js +++ b/web/cobrands/fixmystreet/fixmystreet.js @@ -92,8 +92,7 @@ $(function(){ $('.big-green-banner') .addClass('mobile-map-banner') .appendTo('#map_box') - .text('Place pin on map') - .prepend('<a href="/">home</a>'); + .html('<a href="/">Home</a> Place pin on map'); } $('span.report-a-problem-btn').on('click.reportBtn', function(){ $('html, body').animate({scrollTop:0}, 500); @@ -247,23 +246,34 @@ $(function(){ // A sliding drawer from the bottom of the page, small version // that doesn't change the main content at all. -$.fn.small_drawer = function(id) { - this.toggle(function(){ - var $this = $(this), d = $('#' + id); - if (!$this.addClass('hover').data('setup')) { - d.hide().removeClass('hidden-js').css({ +(function($){ + + var opened; + + $.fn.small_drawer = function(id) { + this.toggle(function(){ + if (opened) { + opened.click(); + } + var $this = $(this), d = $('#' + id); + if (!$this.addClass('hover').data('setup')) { + d.hide().removeClass('hidden-js').css({ padding: '1em', background: '#fff' - }); - $this.data('setup', true); - } - d.slideDown(); - }, function(e){ - var $this = $(this), d = $('#' + id); - $this.removeClass('hover'); - d.slideUp(); - }); -}; + }); + $this.data('setup', true); + } + d.slideDown(); + opened = $this; + }, function(e){ + var $this = $(this), d = $('#' + id); + $this.removeClass('hover'); + d.slideUp(); + opened = null; + }); + }; + +})(jQuery); // A sliding drawer from the bottom of the page, large version $.fn.drawer = function(id, ajax) { @@ -338,6 +348,7 @@ $.fn.drawer = function(id, ajax) { $('#key-tool-around-updates').drawer('updates_ajax', true); } $('#key-tool-report-updates').small_drawer('report-updates-data'); + $('#key-tool-report-share').small_drawer('report-share'); // Go directly to RSS feed if RSS button clicked on alert page // (due to not wanting around form to submit, though good thing anyway) diff --git a/web/cobrands/fixmystreet/images/share.png b/web/cobrands/fixmystreet/images/share.png Binary files differnew file mode 100644 index 000000000..6eb1b6cdb --- /dev/null +++ b/web/cobrands/fixmystreet/images/share.png diff --git a/web/cobrands/southampton/css.scss b/web/cobrands/southampton/css.scss index 3bc2f1b54..592e72f2b 100644 --- a/web/cobrands/southampton/css.scss +++ b/web/cobrands/southampton/css.scss @@ -64,4 +64,8 @@ $darker: #768EB5; #update_form { clear: right; } + + .update-img { + text-align: left; + } } diff --git a/web/css/core.scss b/web/css/core.scss index 72e483dfa..c7fac1717 100644 --- a/web/css/core.scss +++ b/web/css/core.scss @@ -431,6 +431,16 @@ $map_width: 500px; font-size: smaller; } + .update-img { + text-align: center; + } + .update-img span { + display: none; + } + #updates .update-img { + text-align: left; + } + // RSS feed XSL #rss_items { diff --git a/web/js/fixmystreet.js b/web/js/fixmystreet.js index b689d501c..6ae4ed92d 100644 --- a/web/js/fixmystreet.js +++ b/web/js/fixmystreet.js @@ -134,10 +134,12 @@ $(function(){ // Geolocation if (geo_position_js.init()) { + var link = '<a href="#LINK" id="geolocate_link">… or locate me automatically</a>'; + $('form[action="/alert/list"]').append(link.replace('LINK','alert/list')); if ($('body.frontpage').length) { - $('#postcodeForm').after('<a href="#" id="geolocate_link">… or locate me automatically</a>'); + $('#postcodeForm').after(link.replace('LINK','around')); } else{ - $('#postcodeForm').append('<a href="#" id="geolocate_link">… or locate me automatically</a>'); + $('#postcodeForm').append(link.replace('LINK','around')); } $('#geolocate_link').click(function(e) { var $link = $(this); @@ -152,7 +154,8 @@ $(function(){ $link.find('img').remove(); var latitude = pos.coords.latitude; var longitude = pos.coords.longitude; - location.href = '/around?latitude=' + latitude + ';longitude=' + longitude; + var page = $link.attr('href').substr(1); + location.href = '/' + page + '?latitude=' + latitude + ';longitude=' + longitude; }, function(err) { $link.find('img').remove(); if (err.code == 1) { // User said no diff --git a/web/js/map-OpenLayers.js b/web/js/map-OpenLayers.js index d98994d84..0a5f339f5 100644 --- a/web/js/map-OpenLayers.js +++ b/web/js/map-OpenLayers.js @@ -70,26 +70,30 @@ function fms_markers_list(pins, transform) { } function fixmystreet_onload() { - if ( fixmystreet.area ) { - var area = new OpenLayers.Layer.Vector("KML", { - strategies: [ new OpenLayers.Strategy.Fixed() ], - protocol: new OpenLayers.Protocol.HTTP({ - url: "/mapit/area/" + fixmystreet.area + ".kml?simplify_tolerance=0.0001", - format: new OpenLayers.Format.KML() - }) - }); - fixmystreet.map.addLayer(area); - area.events.register('loadend', null, function(a,b,c) { - var bounds = area.getDataExtent(); - if (bounds) { - var center = bounds.getCenterLonLat(); - var z = fixmystreet.map.getZoomForExtent(bounds); - if ( z < 13 && $('html').hasClass('mobile') ) { - z = 13; - } - fixmystreet.map.setCenter(center, z, false, true); + if ( fixmystreet.area.length ) { + for (var i=0; i<fixmystreet.area.length; i++) { + var area = new OpenLayers.Layer.Vector("KML", { + strategies: [ new OpenLayers.Strategy.Fixed() ], + protocol: new OpenLayers.Protocol.HTTP({ + url: "/mapit/area/" + fixmystreet.area[i] + ".kml?simplify_tolerance=0.0001", + format: new OpenLayers.Format.KML() + }) + }); + fixmystreet.map.addLayer(area); + if ( fixmystreet.area.length == 1 ) { + area.events.register('loadend', null, function(a,b,c) { + var bounds = area.getDataExtent(); + if (bounds) { + var center = bounds.getCenterLonLat(); + var z = fixmystreet.map.getZoomForExtent(bounds); + if ( z < 13 && $('html').hasClass('mobile') ) { + z = 13; + } + fixmystreet.map.setCenter(center, z, false, true); + } + }); } - }); + } } var pin_layer_style_map = new OpenLayers.StyleMap({ @@ -333,7 +337,7 @@ $(function(){ $('#sub_map_links').show(); //only on mobile $('#mob_sub_map_links').remove(); - $('.mobile-map-banner').text('Place pin on map'); + $('.mobile-map-banner').html('<a href="/">Home</a> Place pin on map'); fixmystreet.page = 'around'; }); @@ -528,7 +532,7 @@ OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, { ).css({ position: 'relative', width: width, height: height, marginBottom: '1em' }); // Making it relative here makes it much easier to do the scrolling later - $('.mobile-map-banner').text('Right place?'); + $('.mobile-map-banner').html('<a href="/">Home</a> Right place?'); // mobile user clicks 'ok' on map $('#mob_ok').toggle(function(){ diff --git a/web/js/modernizr.custom.js b/web/js/modernizr.custom.js index c4d6ffdfc..026c0efad 100644 --- a/web/js/modernizr.custom.js +++ b/web/js/modernizr.custom.js @@ -1,4 +1,4 @@ -/* Modernizr 2.5.3 (Custom Build) | MIT & BSD
- * Build: http://www.modernizr.com/download/#-shiv-load
+/* Modernizr 2.6.1 (Custom Build) | MIT & BSD
+ * Build: http://modernizr.com/download/#-sessionstorage-shiv-load
*/
-;window.Modernizr=function(a,b,c){function t(a){i.cssText=a}function u(a,b){return t(prefixes.join(a+";")+(b||""))}function v(a,b){return typeof a===b}function w(a,b){return!!~(""+a).indexOf(b)}function x(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:v(f,"function")?f.bind(d||b):f}return!1}var d="2.5.3",e={},f=b.documentElement,g="modernizr",h=b.createElement(g),i=h.style,j,k={}.toString,l={},m={},n={},o=[],p=o.slice,q,r={}.hasOwnProperty,s;!v(r,"undefined")&&!v(r.call,"undefined")?s=function(a,b){return r.call(a,b)}:s=function(a,b){return b in a&&v(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=p.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(p.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(p.call(arguments)))};return e});for(var y in l)s(l,y)&&(q=y.toLowerCase(),e[q]=l[y](),o.push((e[q]?"":"no-")+q));return t(""),h=j=null,function(a,b){function g(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function h(){var a=k.elements;return typeof a=="string"?a.split(" "):a}function i(a){var b={},c=a.createElement,e=a.createDocumentFragment,f=e();a.createElement=function(a){var e=(b[a]||(b[a]=c(a))).cloneNode();return k.shivMethods&&e.canHaveChildren&&!d.test(a)?f.appendChild(e):e},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+h().join().replace(/\w+/g,function(a){return b[a]=c(a),f.createElement(a),'c("'+a+'")'})+");return n}")(k,f)}function j(a){var b;return a.documentShived?a:(k.shivCSS&&!e&&(b=!!g(a,"article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio{display:none}canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden]{display:none}audio[controls]{display:inline-block;*display:inline;*zoom:1}mark{background:#FF0;color:#000}")),f||(b=!i(a)),b&&(a.documentShived=b),a)}var c=a.html5||{},d=/^<|^(?:button|form|map|select|textarea)$/i,e,f;(function(){var a=b.createElement("a");a.innerHTML="<xyz></xyz>",e="hidden"in a,f=a.childNodes.length==1||function(){try{b.createElement("a")}catch(a){return!0}var c=b.createDocumentFragment();return typeof c.cloneNode=="undefined"||typeof c.createDocumentFragment=="undefined"||typeof c.createElement=="undefined"}()})();var k={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:j};a.html5=k,j(b)}(this,b),e._version=d,e}(this,this.document),function(a,b,c){function d(a){return o.call(a)=="[object Function]"}function e(a){return typeof a=="string"}function f(){}function g(a){return!a||a=="loaded"||a=="complete"||a=="uninitialized"}function h(){var a=p.shift();q=1,a?a.t?m(function(){(a.t=="c"?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){a!="img"&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l={},o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};y[c]===1&&(r=1,y[c]=[],l=b.createElement(a)),a=="object"?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),a!="img"&&(r||y[c]===2?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i(b=="c"?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),p.length==1&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&o.call(a.opera)=="[object Opera]",l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return o.call(a)=="[object Array]"},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f<d;f++)g=a[f].split("="),(e=z[g.shift()])&&(c=e(c,g));for(f=0;f<b;f++)c=x[f](c);return c}function g(a,e,f,g,i){var j=b(a),l=j.autoCallback;j.url.split(".").pop().split("?").shift(),j.bypass||(e&&(e=d(e)?e:e[a]||e[g]||e[a.split("/").pop().split("?")[0]]||h),j.instead?j.instead(a,e,f,g,i):(y[j.url]?j.noexec=!0:y[j.url]=1,f.load(j.url,j.forceCSS||!j.forceJS&&"css"==j.url.split(".").pop().split("?").shift()?"c":c,j.noexec,j.attrs,j.timeout),(d(e)||d(l))&&f.load(function(){k(),e&&e(j.origUrl,i,g),l&&l(j.origUrl,i,g),y[j.url]=2})))}function i(a,b){function c(a,c){if(a){if(e(a))c||(j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}),g(a,j,b,0,h);else if(Object(a)===a)for(n in m=function(){var b=0,c;for(c in a)a.hasOwnProperty(c)&&b++;return b}(),a)a.hasOwnProperty(n)&&(!c&&!--m&&(d(j)?j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}:j[n]=function(a){return function(){var b=[].slice.call(arguments);a&&a.apply(this,b),l()}}(k[n])),g(a[n],j,b,n,h))}else!c&&l()}var h=!!a.test,i=a.load||a.both,j=a.callback||f,k=j,l=a.complete||f,m,n;c(h?a.yep:a.nope,!!i),i&&c(i)}var j,l,m=this.yepnope.loader;if(e(a))g(a,0,m,0);else if(w(a))for(j=0;j<a.length;j++)l=a[j],e(l)?g(l,0,m,0):w(l)?B(l):Object(l)===l&&i(l,m);else Object(a)===a&&i(a,m)},B.addPrefix=function(a,b){z[a]=b},B.addFilter=function(a){x.push(a)},B.errorTimeout=1e4,b.readyState==null&&b.addEventListener&&(b.readyState="loading",b.addEventListener("DOMContentLoaded",A=function(){b.removeEventListener("DOMContentLoaded",A,0),b.readyState="complete"},0)),a.yepnope=k(),a.yepnope.executeStack=h,a.yepnope.injectJs=function(a,c,d,e,i,j){var k=b.createElement("script"),l,o,e=e||B.errorTimeout;k.src=a;for(o in d)k.setAttribute(o,d[o]);c=j?h:c||f,k.onreadystatechange=k.onload=function(){!l&&g(k.readyState)&&(l=1,c(),k.onload=k.onreadystatechange=null)},m(function(){l||(l=1,c(1))},e),i?k.onload():n.parentNode.insertBefore(k,n)},a.yepnope.injectCss=function(a,c,d,e,g,i){var e=b.createElement("link"),j,c=i?h:c||f;e.href=a,e.rel="stylesheet",e.type="text/css";for(j in d)e.setAttribute(j,d[j]);g||(n.parentNode.insertBefore(e,n),m(c,0))}}(this,document),Modernizr.load=function(){yepnope.apply(window,[].slice.call(arguments,0))};
\ No newline at end of file +;window.Modernizr=function(a,b,c){function t(a){i.cssText=a}function u(a,b){return t(prefixes.join(a+";")+(b||""))}function v(a,b){return typeof a===b}function w(a,b){return!!~(""+a).indexOf(b)}function x(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:v(f,"function")?f.bind(d||b):f}return!1}var d="2.6.1",e={},f=b.documentElement,g="modernizr",h=b.createElement(g),i=h.style,j,k={}.toString,l={},m={},n={},o=[],p=o.slice,q,r={}.hasOwnProperty,s;!v(r,"undefined")&&!v(r.call,"undefined")?s=function(a,b){return r.call(a,b)}:s=function(a,b){return b in a&&v(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=p.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(p.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(p.call(arguments)))};return e}),l.sessionstorage=function(){try{return sessionStorage.setItem(g,g),sessionStorage.removeItem(g),!0}catch(a){return!1}};for(var y in l)s(l,y)&&(q=y.toLowerCase(),e[q]=l[y](),o.push((e[q]?"":"no-")+q));return e.addTest=function(a,b){if(typeof a=="object")for(var d in a)s(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,enableClasses&&(f.className+=" "+(b?"":"no-")+a),e[a]=b}return e},t(""),h=j=null,function(a,b){function k(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function l(){var a=r.elements;return typeof a=="string"?a.split(" "):a}function m(a){var b=i[a[g]];return b||(b={},h++,a[g]=h,i[h]=b),b}function n(a,c,f){c||(c=b);if(j)return c.createElement(a);f||(f=m(c));var g;return f.cache[a]?g=f.cache[a].cloneNode():e.test(a)?g=(f.cache[a]=f.createElem(a)).cloneNode():g=f.createElem(a),g.canHaveChildren&&!d.test(a)?f.frag.appendChild(g):g}function o(a,c){a||(a=b);if(j)return a.createDocumentFragment();c=c||m(a);var d=c.frag.cloneNode(),e=0,f=l(),g=f.length;for(;e<g;e++)d.createElement(f[e]);return d}function p(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return r.shivMethods?n(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+l().join().replace(/\w+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(r,b.frag)}function q(a){a||(a=b);var c=m(a);return r.shivCSS&&!f&&!c.hasCSS&&(c.hasCSS=!!k(a,"article,aside,figcaption,figure,footer,header,hgroup,nav,section{display:block}mark{background:#FF0;color:#000}")),j||p(a,c),a}var c=a.html5||{},d=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,e=/^<|^(?:a|b|button|code|div|fieldset|form|h1|h2|h3|h4|h5|h6|i|iframe|img|input|label|li|link|ol|option|p|param|q|script|select|span|strong|style|table|tbody|td|textarea|tfoot|th|thead|tr|ul)$/i,f,g="_html5shiv",h=0,i={},j;(function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",f="hidden"in a,j=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){f=!0,j=!0}})();var r={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,supportsUnknownElements:j,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:q,createElement:n,createDocumentFragment:o};a.html5=r,q(b)}(this,b),e._version=d,e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f<d;f++)g=a[f].split("="),(e=z[g.shift()])&&(c=e(c,g));for(f=0;f<b;f++)c=x[f](c);return c}function g(a,e,f,g,h){var i=b(a),j=i.autoCallback;i.url.split(".").pop().split("?").shift(),i.bypass||(e&&(e=d(e)?e:e[a]||e[g]||e[a.split("/").pop().split("?")[0]]),i.instead?i.instead(a,e,f,g,h):(y[i.url]?i.noexec=!0:y[i.url]=1,f.load(i.url,i.forceCSS||!i.forceJS&&"css"==i.url.split(".").pop().split("?").shift()?"c":c,i.noexec,i.attrs,i.timeout),(d(e)||d(j))&&f.load(function(){k(),e&&e(i.origUrl,h,g),j&&j(i.origUrl,h,g),y[i.url]=2})))}function h(a,b){function c(a,c){if(a){if(e(a))c||(j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}),g(a,j,b,0,h);else if(Object(a)===a)for(n in m=function(){var b=0,c;for(c in a)a.hasOwnProperty(c)&&b++;return b}(),a)a.hasOwnProperty(n)&&(!c&&!--m&&(d(j)?j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}:j[n]=function(a){return function(){var b=[].slice.call(arguments);a&&a.apply(this,b),l()}}(k[n])),g(a[n],j,b,n,h))}else!c&&l()}var h=!!a.test,i=a.load||a.both,j=a.callback||f,k=j,l=a.complete||f,m,n;c(h?a.yep:a.nope,!!i),i&&c(i)}var i,j,l=this.yepnope.loader;if(e(a))g(a,0,l,0);else if(w(a))for(i=0;i<a.length;i++)j=a[i],e(j)?g(j,0,l,0):w(j)?B(j):Object(j)===j&&h(j,l);else Object(a)===a&&h(a,l)},B.addPrefix=function(a,b){z[a]=b},B.addFilter=function(a){x.push(a)},B.errorTimeout=1e4,null==b.readyState&&b.addEventListener&&(b.readyState="loading",b.addEventListener("DOMContentLoaded",A=function(){b.removeEventListener("DOMContentLoaded",A,0),b.readyState="complete"},0)),a.yepnope=k(),a.yepnope.executeStack=h,a.yepnope.injectJs=function(a,c,d,e,i,j){var k=b.createElement("script"),l,o,e=e||B.errorTimeout;k.src=a;for(o in d)k.setAttribute(o,d[o]);c=j?h:c||f,k.onreadystatechange=k.onload=function(){!l&&g(k.readyState)&&(l=1,c(),k.onload=k.onreadystatechange=null)},m(function(){l||(l=1,c(1))},e),i?k.onload():n.parentNode.insertBefore(k,n)},a.yepnope.injectCss=function(a,c,d,e,g,i){var e=b.createElement("link"),j,c=i?h:c||f;e.href=a,e.rel="stylesheet",e.type="text/css";for(j in d)e.setAttribute(j,d[j]);g||(n.parentNode.insertBefore(e,n),m(c,0))}}(this,document),Modernizr.load=function(){yepnope.apply(window,[].slice.call(arguments,0))};
\ No newline at end of file |