diff --git a/components/SavePalette.js b/components/SavePalette.js
index efc44028..1a82a059 100644
--- a/components/SavePalette.js
+++ b/components/SavePalette.js
@@ -40,7 +40,7 @@ export const SavePalette = (props) => {
setTimeout(() => {
setIsUnlockProNotification(false);
}, 5000);
- }, [colorList]);
+ }, [colorList, isPro]);
const [paletteName, setPaletteName] = useState(suggestedName ?? '');
useEffect(() => {
diff --git a/components/SingleColorView.js b/components/SingleColorView.js
index 9d816a3f..6149a656 100644
--- a/components/SingleColorView.js
+++ b/components/SingleColorView.js
@@ -1,37 +1,88 @@
import * as React from 'react';
-import { Platform, StyleSheet, Text, Clipboard, TouchableOpacity } from 'react-native';
+import { Platform, StyleSheet, Text, Clipboard, TouchableOpacity, View } from 'react-native';
import { notifyMessage } from '../libs/Helpers';
+import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
+import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
-export class SingleColorView extends React.Component {
- render() {
- return (
- {
- if (Platform?.OS === 'android' || Platform.OS === 'ios') {
- notifyMessage(this.props.color.color + ' copied to clipboard!');
- }
- Clipboard.setString(this.props.color.color);
- }}
- style={[styles.container, { backgroundColor: this.props.color.color }]}>
-
- {this.props.color.color +
- (this.props.color.name ? ' (' + this.props.color.name + ')' : '')}
-
-
- );
- }
+function getContrastColor(bgColor) {
+ var color = bgColor.charAt(0) === '#' ? bgColor.substring(1, 7) : bgColor;
+ var r = parseInt(color.substring(0, 2), 16); // hexToR
+ var g = parseInt(color.substring(2, 4), 16); // hexToG
+ var b = parseInt(color.substring(4, 6), 16); // hexToB
+ var uicolors = [r / 255, g / 255, b / 255];
+ var c = uicolors.map((col) => {
+ if (col <= 0.03928) {
+ return col / 12.92;
+ }
+ return Math.pow((col + 0.055) / 1.055, 2.4);
+ });
+ var L = 0.2126 * c[0] + 0.7152 * c[1] + 0.0722 * c[2];
+ return L > 0.179 ? 'black' : 'white';
}
+export const SingleColorView = ({ color, onColorChange, drag }) => {
+ const handlePress = () => {
+ if (Platform?.OS === 'android' || Platform.OS === 'ios') {
+ notifyMessage(color.color + ' copied to clipboard!');
+ }
+ Clipboard.setString(color.color);
+ };
+
+ const textColor = getContrastColor(color.color);
+
+ return (
+
+
+ {color.color.toUpperCase() + (color.name ? ' (' + color.name + ')' : '')}
+
+
+ {
+ onColorChange({ ...color, color: color.color, locked: !color.locked });
+ }}>
+
+
+
+
+
+
+
+ );
+};
+
const styles = StyleSheet.create({
container: {
- height: 56,
- justifyContent: 'center',
- alignItems: 'center'
+ height: 72,
+ //justifyContent: 'center',
+ alignItems: 'center',
+ flex: 1,
+ flexDirection: 'row'
},
colorText: {
fontWeight: '700',
- backgroundColor: 'rgba(255, 255, 255, .3)',
- paddingLeft: 8,
+ paddingLeft: 16,
paddingRight: 8
+ },
+ actionArea: {
+ position: 'absolute',
+ right: 0,
+ padding: 8,
+ flex: 1,
+ flexDirection: 'row'
+ },
+ icon: {
+ fontSize: 24
+ },
+ actionAreaItem: {
+ marginRight: 8,
+ marginLeft: 8
}
});
diff --git a/screens/ColorListScreen.js b/screens/ColorListScreen.js
index e5db3bf6..cbdc68bc 100644
--- a/screens/ColorListScreen.js
+++ b/screens/ColorListScreen.js
@@ -1,15 +1,16 @@
import React, { useLayoutEffect } from 'react';
import { SingleColorView } from '../components/SingleColorView';
-import { ScrollView, StyleSheet, View, Text, Platform } from 'react-native';
+import { StyleSheet, View, Text, Platform } from 'react-native';
import CromaButton from '../components/CromaButton';
-import { logEvent } from '../libs/Helpers';
+import { logEvent, notifyMessage } from '../libs/Helpers';
import { CromaContext } from '../store/store';
import { useTranslation } from 'react-i18next';
+import DraggableFlatList from 'react-native-draggable-flatlist';
export default function ColorListScreen({ navigation }) {
const { t } = useTranslation();
- const { colorList } = React.useContext(CromaContext);
+ const { colorList, setColorList } = React.useContext(CromaContext);
const colors = uniqueColors(colorList);
useLayoutEffect(() => {
@@ -20,22 +21,70 @@ export default function ColorListScreen({ navigation }) {
: t('Colors')
});
}, []);
+ const renderItem = ({ item, drag }) => (
+ {
+ const index = colors.findIndex((color) => color.color === updatedColor.color);
+ const updatedColors = [...colors];
+ updatedColors[index] = updatedColor;
+ setColorList(updatedColors);
+ }}
+ key={item.color + '-' + item.locked}
+ color={item}
+ drag={drag}
+ />
+ );
+
+ const onDragEnd = ({ data }) => {
+ logEvent('drag_end_event_color_list');
+ setColorList(data);
+ };
+ const regenerateUnlockedColors = () => {
+ logEvent('regenerate_unlocked_colors', colors.filter((color) => !color.locked).length);
+ if (colors.filter((color) => !color.locked).length == 0) {
+ notifyMessage(t('Please unlock at least one color'));
+ } else {
+ // TODO: improve this algorithm.
+ const newColors = colors.map((color) => {
+ if (!color.locked) {
+ color.color = '#' + Math.floor(Math.random() * 16777215).toString(16);
+ }
+ return color;
+ });
+ setColorList(newColors);
+ }
+ };
logEvent('color_list_screen');
return (
-
-
- {colors.map((color) => (
-
- ))}
+
+ {/* this is to make sure scrolling works */}
+
+ item.color + '-' + item.locked}
+ onDragEnd={onDragEnd}
+ autoscrollThreshold={100}
+ />
+ Generate new colors for unlocked colors
+ {
+ regenerateUnlockedColors();
+ }}>
+ {t('Generate new colors')}
+
+
{
navigation.navigate('SavePalette');
}}>
{t('SAVE AS NEW PALETTE')}
-
+
);
}
function uniqueColors(colors) {
@@ -43,6 +92,9 @@ function uniqueColors(colors) {
let uniqueColors = [];
colors.forEach((color) => {
if (!set.has(color.color)) {
+ if (color.locked === undefined) {
+ color.locked = true;
+ }
uniqueColors.push(color);
}
set.add(color.color);
@@ -73,10 +125,26 @@ const CustomHeader = () => {
};
const styles = StyleSheet.create({
- listview: {
- margin: 8
+ container: {
+ flex: 1,
+ marginTop: 8,
+ marginBottom: 8
+ },
+ hintText: {
+ fontSize: 12,
+ color: '#888',
+ marginTop: 8,
+ marginBottom: 4,
+ textAlign: 'center'
+ },
+ separator: {
+ height: 1,
+ backgroundColor: '#ccc',
+ marginVertical: 16,
+ marginHorizontal: 8
},
- doneButton: {
- marginRight: '20%'
+ button: {
+ marginLeft: 32,
+ marginRight: 32
}
});