Skip to content

Commit

Permalink
Merge pull request #9 from MOVACT/develop
Browse files Browse the repository at this point in the history
Add new languages
  • Loading branch information
mxmtsk authored Aug 7, 2021
2 parents d94801f + 394f424 commit bb369d1
Show file tree
Hide file tree
Showing 27 changed files with 570 additions and 701 deletions.
675 changes: 0 additions & 675 deletions LICENSE.md

This file was deleted.

9 changes: 3 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
# VoteSwiper / WahlSwiper - App

[![License](https://img.shields.io/badge/License-GPL%203.0-green.svg)](./LICENSE) [![Build status](https://build.appcenter.ms/v0.1/apps/0f3f9d82-48f5-436f-929f-221e97867550/branches/master/badge)](https://appcenter.ms) [![Last Commit](https://img.shields.io/github/last-commit/movact/voteswiper-app)](https://github.com/MOVACT/voteswiper-app/commits) [![Open issues](https://img.shields.io/github/issues/movact/voteswiper-app)](https://github.com/MOVACT/voteswiper-app/issues) [![Follow WahlSwiper](https://img.shields.io/twitter/follow/wahlswiper)](https://www.twitter.com/wahlswiper)
[![Last Commit](https://img.shields.io/github/last-commit/movact/voteswiper-app)](https://github.com/MOVACT/voteswiper-app/commits) [![Open issues](https://img.shields.io/github/issues/movact/voteswiper-app)](https://github.com/MOVACT/voteswiper-app/issues) [![Follow WahlSwiper](https://img.shields.io/twitter/follow/wahlswiper)](https://www.twitter.com/wahlswiper)

VoteSwiper (in Germany better known as WahlSwiper) is a cross-platform voting advice app for Android, iOS and web browsers. The app is operated by [MOVACT](https://www.movact.de) primarily for German federale and state elections. The content for the surveys is researched and developed by various institutions, most recently mainly by political scientists at the University of Freiburg.

We started this project in 2017 for the federal election and since then grow a user base of over one million. While we operated closed source for a long time, we believe the right thing to do is to disclose the source code of the whole project for transparency and to invite others to help grow this project.

We started this project in 2017 for the federal election and since then grow a user base of over one million. While we operated closed source for a long time, we believe the right thing to do is to disclose the source code of the whole project for transparency.
**Source code for the API will be available soon.**

## Development
Expand All @@ -32,7 +31,7 @@ react-native run-android

## How to contribute

We appreciate any contribution and feedback. Feel free to open an issue if you find errors or use the discussion board if you'd like to suggest new features. You can also contribute code directly by opening a pull request. If you want to implement a new feature, please open a discussion first to see if we would merge it.
We appreciate any feedback. Feel free to open an issue if you find errors or use the discussion board if you'd like to suggest new features.

## Security Bugs

Expand All @@ -45,5 +44,3 @@ If you find any security related issues we would appreciate if you safely disclo
## License

Copyright MOVACT UG (haftungsbeschränkt)

Licensed under [GNU GENERAL PUBLIC LICENSE 3.0](./LICENSE).
6 changes: 6 additions & 0 deletions ios/ar.lproj/InfoPlist.strings
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/*
Tutorial: https://hackernoon.com/localize-an-application-name-in-react-native-c36c4b2be7c3
*/
"CFBundleDisplayName" = "VoteSwiper";
"CFBundleName" = "VoteSwiper";
"NSPhotoLibraryAddUsageDescription" = "To save your VoteSwiper result as image.";
6 changes: 6 additions & 0 deletions ios/fa.lproj/InfoPlist.strings
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/*
Tutorial: https://hackernoon.com/localize-an-application-name-in-react-native-c36c4b2be7c3
*/
"CFBundleDisplayName" = "VoteSwiper";
"CFBundleName" = "VoteSwiper";
"NSPhotoLibraryAddUsageDescription" = "To save your VoteSwiper result as image.";
6 changes: 6 additions & 0 deletions ios/ru.lproj/InfoPlist.strings
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/*
Tutorial: https://hackernoon.com/localize-an-application-name-in-react-native-c36c4b2be7c3
*/
"CFBundleDisplayName" = "VoteSwiper";
"CFBundleName" = "VoteSwiper";
"NSPhotoLibraryAddUsageDescription" = "To save your VoteSwiper result as image.";
6 changes: 6 additions & 0 deletions ios/tr.lproj/InfoPlist.strings
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/*
Tutorial: https://hackernoon.com/localize-an-application-name-in-react-native-c36c4b2be7c3
*/
"CFBundleDisplayName" = "VoteSwiper";
"CFBundleName" = "VoteSwiper";
"NSPhotoLibraryAddUsageDescription" = "To save your VoteSwiper result as image.";
20 changes: 16 additions & 4 deletions ios/voteswiper.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@
32A051032225DBD20050CB5E /* voteswiper-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "voteswiper-Bridging-Header.h"; sourceTree = "<group>"; };
32A051042225DBD30050CB5E /* test.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = test.swift; sourceTree = "<group>"; };
32C3EA4525923D9B0085C376 /* OneSignalNotificationServiceExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = OneSignalNotificationServiceExtension.entitlements; sourceTree = "<group>"; };
32DDB4B126BD6DBA00449724 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/InfoPlist.strings; sourceTree = "<group>"; };
32DDB4B226BD6DC300449724 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = "<group>"; };
32DDB4B326BD6DC800449724 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/InfoPlist.strings; sourceTree = "<group>"; };
32DDB4B426BD6DF800449724 /* fa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fa; path = fa.lproj/InfoPlist.strings; sourceTree = "<group>"; };
32E16CC2223E8E3C00931DF4 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/InfoPlist.strings; sourceTree = "<group>"; };
32E16CC3223E8E4300931DF4 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/InfoPlist.strings; sourceTree = "<group>"; };
35B1A23B5A2A8D26B24848E0 /* Pods-voteswiper-voteswiperTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-voteswiper-voteswiperTests.release.xcconfig"; path = "Target Support Files/Pods-voteswiper-voteswiperTests/Pods-voteswiper-voteswiperTests.release.xcconfig"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -505,6 +509,10 @@
fr,
sv,
fi,
ar,
ru,
tr,
fa,
);
mainGroup = 83CBB9F61A601CBA00E9B192;
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
Expand Down Expand Up @@ -818,6 +826,10 @@
320A853522233C9000ECE289 /* fr */,
32E16CC2223E8E3C00931DF4 /* sv */,
32E16CC3223E8E4300931DF4 /* fi */,
32DDB4B126BD6DBA00449724 /* ar */,
32DDB4B226BD6DC300449724 /* ru */,
32DDB4B326BD6DC800449724 /* tr */,
32DDB4B426BD6DF800449724 /* fa */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
Expand Down Expand Up @@ -949,7 +961,7 @@
);
INFOPLIST_FILE = voteswiper/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 3.3.0;
MARKETING_VERSION = 3.4.0;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
Expand Down Expand Up @@ -989,7 +1001,7 @@
);
INFOPLIST_FILE = voteswiper/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 3.3.0;
MARKETING_VERSION = 3.4.0;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
Expand Down Expand Up @@ -1248,7 +1260,7 @@
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
);
MARKETING_VERSION = 3.3.0;
MARKETING_VERSION = 3.4.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = de.movact.wahlswiper.OneSignalNotificationServiceExtension;
Expand Down Expand Up @@ -1285,7 +1297,7 @@
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
);
MARKETING_VERSION = 3.3.0;
MARKETING_VERSION = 3.4.0;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = de.movact.wahlswiper.OneSignalNotificationServiceExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down
3 changes: 2 additions & 1 deletion src/common/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ const config = {
api: 'https://api.voteswiper.org/api',
apiVersion: 1,
fallbackLocale: 'en',
locales: ['en', 'de', 'fr', 'fi', 'sv'],
locales: ['en', 'de', 'ru', 'tr', 'fr', 'fi', 'sv', 'ar', 'fa'],
rtlLocales: ['ar', 'fa'],
storyblokAccessToken: 'b7BTTUOEkSa786viucYnjwtt',
};

Expand Down
12 changes: 10 additions & 2 deletions src/components/ElectionPill/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import LinearGradient from 'react-native-linear-gradient';
import {Election} from 'types/api';
import moment from 'util/momentLocale';
import ArrowRightCircle from '../../icons/ArrowRightCircle';
import rtl from '../../rtl';
import Txt from '../Txt';
import styles from './styles';

Expand All @@ -25,9 +26,11 @@ const ElectionPill: React.FC<Props> = ({
playable,
playable_date,
}) => {
const {t} = useApp();
const {t, language} = useApp();
const [clickActive, setActiveClick] = React.useState(false);

moment.locale(language || 'de');

return (
<TouchableWithoutFeedback
onPress={onPress}
Expand Down Expand Up @@ -64,7 +67,12 @@ const ElectionPill: React.FC<Props> = ({
</Txt>
</View>
<View>
<ArrowRightCircle fill="#8186D7" width={20} height={20} />
<ArrowRightCircle
fill="#8186D7"
width={20}
height={20}
style={rtl.mirror}
/>
</View>
</LinearGradient>
</View>
Expand Down
3 changes: 2 additions & 1 deletion src/components/ResultBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import {GestureResponderEvent, TouchableOpacity, View} from 'react-native';
import Animated, {Easing} from 'react-native-reanimated';
import ChevronRight from '../../icons/ChevronRight';
import rtl from '../../rtl';
import Txt from '../Txt';
import styles from './styles';

Expand Down Expand Up @@ -128,7 +129,7 @@ const ResultBar: React.FC<Props> = ({
</Txt>
{shareBar !== true ? (
<View style={styles.icon}>
<ChevronRight />
<ChevronRight style={rtl.mirror} />
</View>
) : null}
</View>
Expand Down
3 changes: 2 additions & 1 deletion src/components/Txt/styles.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import {Platform, StyleSheet} from 'react-native';
import {I18nManager, Platform, StyleSheet} from 'react-native';

export default StyleSheet.create({
text: {
backgroundColor: 'transparent',
fontFamily: Platform.isTV ? 'System' : 'Rubik-Regular',
writingDirection: I18nManager.isRTL ? 'rtl' : 'ltr',
},
textMedium: {
fontFamily: Platform.isTV ? 'System' : 'Rubik-Medium',
Expand Down
11 changes: 11 additions & 0 deletions src/rtl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {I18nManager, StyleSheet} from 'react-native';

export default StyleSheet.create({
mirror: {
transform: [
{
scaleX: I18nManager.isRTL ? -1 : 1,
},
],
},
});
2 changes: 2 additions & 0 deletions src/screens/ElectionDetails/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ const ElectionDetails: React.FC = () => {
const {setElection} = useSwiper();
const {params} = useRoute<ElectionDetailsScreenRouteProp>();

moment.locale(language || 'de');

const {loading, error, data} = useFetch<Question[], QuestionsData>(
ENDPOINTS.QUESTIONS,
{data: {id: params.election.id}},
Expand Down
3 changes: 2 additions & 1 deletion src/screens/ElectionsIndex/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {Election, ElectionsData} from 'types/api';
import getCountryFlag from 'util/getCountryFlag';
import moment from 'util/momentLocale';
import ChevronRight from '../../icons/ChevronRight';
import rtl from '../../rtl';
import styles from './styles';

const ElectionsIndex: React.FC = () => {
Expand Down Expand Up @@ -43,7 +44,7 @@ const ElectionsIndex: React.FC = () => {
<Txt style={styles.countryLinkText} medium>
{country!.name}
</Txt>
<ChevronRight />
<ChevronRight style={rtl.mirror} />
</TouchableOpacity>
),
title: '',
Expand Down
14 changes: 12 additions & 2 deletions src/screens/Settings/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Title from 'components/Title';
import Txt from 'components/Txt';
import {useApp} from 'contexts/app';
import React from 'react';
import {TouchableOpacity, View} from 'react-native';
import {I18nManager, TouchableOpacity, View} from 'react-native';
import RNRestart from 'react-native-restart';
import translations from 'translations';
import styles from './styles';
Expand Down Expand Up @@ -60,6 +60,7 @@ const Settings: React.FC = () => {
<Txt copy>{t('settings.systemDefaultText')}</Txt>
</TouchableOpacity>
{config.locales.map((lang) => {
console.log(config.rtlLocales.indexOf(lang) > -1);
return (
<TouchableOpacity
onPress={() => {
Expand All @@ -71,7 +72,14 @@ const Settings: React.FC = () => {
}}
style={[styles.language, activeStyle(lang)]}
key={lang}>
<Txt copy medium>
<Txt
copy
medium
style={
config.rtlLocales.indexOf(lang) > -1
? styles.rtl
: styles.ltr
}>
{/* @ts-ignore */}
{translations[lang].name}
</Txt>
Expand All @@ -89,6 +97,8 @@ const Settings: React.FC = () => {
onPress={() => {
setLocale(pick === 'default' ? null : pick);
setTimeout(() => {
I18nManager.forceRTL(config.rtlLocales.indexOf(pick) > -1);

RNRestart.Restart();
}, 500);
}}
Expand Down
6 changes: 6 additions & 0 deletions src/screens/Settings/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,10 @@ export default StyleSheet.create({
padding: 15,
backgroundColor: 'rgba(0,0,0,0.3)',
},
rtl: {
writingDirection: 'rtl',
},
ltr: {
writingDirection: 'ltr',
},
});
3 changes: 2 additions & 1 deletion src/screens/Swiper/components/Card/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {Image, Platform, TouchableOpacity, View} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import Animated, {Easing} from 'react-native-reanimated';
import {Question} from 'types/api';
import rtl from '../../../../rtl';
import styles from './styles';

const Card: React.FC<Question> = ({
Expand Down Expand Up @@ -56,7 +57,7 @@ const Card: React.FC<Question> = ({
colors={['#DB67AE', '#8186D7']}
style={styles.videoButton}>
{video_url ? (
<Play height={24} width={21} />
<Play height={24} width={21} style={rtl.mirror} />
) : (
<SvgCircleInfo style={styles.infoIcon} />
)}
Expand Down
7 changes: 6 additions & 1 deletion src/screens/Swiper/components/NavigationButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import ArrowRight from 'icons/ArrowRight';
import React from 'react';
import {GestureResponderEvent, TouchableOpacity} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import rtl from '../../../../rtl';
import styles from './styles';

interface Props {
Expand All @@ -22,7 +23,11 @@ const NavigationButton: React.FC<Props> = ({onPress, disabled, type}) => {
end={{x: 0, y: 0}}
colors={['#464872', '#5D5D94']}
style={[styles.bg, disabled ? styles.disabled : {}]}>
{type === 'previous' ? <ArrowLeft /> : <ArrowRight />}
{type === 'previous' ? (
<ArrowLeft style={rtl.mirror} />
) : (
<ArrowRight style={rtl.mirror} />
)}
</LinearGradient>
</TouchableOpacity>
);
Expand Down
3 changes: 2 additions & 1 deletion src/screens/Swiper/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import DeckSwiper from 'react-native-deck-swiper';
import {TouchableOpacity} from 'react-native-gesture-handler';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import {CountAnswerData, Question} from 'types/api';
import rtl from '../../rtl';
import Card from './components/Card';
import ExitConfirmDialog from './components/ExitConfirmDialog';
import MainButton from './components/MainButton';
Expand Down Expand Up @@ -273,7 +274,7 @@ const Swiper: React.FC = () => {
}
}}
style={styles.skip}>
<Skip width={20} height={20} />
<Skip width={20} height={20} style={rtl.mirror} />
<Txt style={styles.skipText}>{t('swiper.skip')}</Txt>
</TouchableOpacity>
<MainButton
Expand Down
4 changes: 2 additions & 2 deletions src/screens/Swiper/styles.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {sm} from 'common/breakpoints';
import {Dimensions, StyleSheet} from 'react-native';
import {Dimensions, I18nManager, StyleSheet} from 'react-native';
import {cardBorderRadius} from './components/Card/styles';

const {width} = Dimensions.get('window');
Expand Down Expand Up @@ -53,7 +53,7 @@ export default StyleSheet.create({
},
controls: {
paddingTop: controlsPaddingTop,
flexDirection: 'row',
flexDirection: I18nManager.isRTL ? 'row-reverse' : 'row',
justifyContent: 'space-around',
alignItems: 'center',
position: 'relative',
Expand Down
Loading

0 comments on commit bb369d1

Please sign in to comment.