nextcloud-vue
nextcloud-vue copied to clipboard
Avatar placeholder should not take special characters
Can I give it a try? If so, I will create a PR to edit Avatar.vue.
@aloisdg go for it :)
Hi!
Here is some testcases I would like to check with you:
input | before | after |
---|---|---|
? | ? | |
A | A | A |
B | B | B |
a | a | A |
b | b | B |
1 | 1 | 1 |
( | ( | ? |
Foo | F | F |
(Foo | ( | F |
_Foo | _ | F |
Foo Bar | FB | FB |
foo bar | FB | FB |
foo a bar | FA | FA |
foo _ bar | F_ | FB |
foo _bar | F_ | FB |
before is the behavior of the current code, after is my current implementation. Is it right for you?
Open to see the code
// https://stackoverflow.com/a/25352300/1248177
const isAlphaNumeric = (str) => {
for (let i = 0; i < str.length; i++) {
const code = str.charCodeAt(i);
if (!(code > 47 && code < 58) && // numeric (0-9)
!(code > 64 && code < 91) && // upper alpha (A-Z)
!(code > 96 && code < 123)) { // lower alpha (a-z)
return false;
}
}
return true;
};
const filterAlphaNumerics = (word) => [...word].filter(isAlphaNumeric);
const filterWords = (items) => items.split(' ').map(filterAlphaNumerics).filter(w => w.length > 0);
const extractInitials = (getUserIdentifier, shouldShowPlaceholder) => {
if (!shouldShowPlaceholder)
return undefined;
if (!getUserIdentifier)
return '?';
const words = filterWords(getUserIdentifier);
switch (words.length) {
case 0:
return "?";
case 1:
return words[0][0].toUpperCase();
default:
return (words[0][0] + words[1][0]).toUpperCase()
}
}
Note that this is a WIP.
~~Try it Online~~ Demo
Use it by replacing https://github.com/nextcloud/nextcloud-vue/blob/b5339a584ba62114f40635dfa1b9db4f346b421d/src/components/Avatar/Avatar.vue#L365 with
initials() { return extractInitials(this.getUserIdentifier, this.shouldShowPlaceholder); },
Hi, Is this still open ?
@knowasaritra I didn't have any comment on my code. What do you think of it?
@aloisdg won't it better if we use regex , the way you are handling isAlphaNumeric function can be modified with regex I guess ... I am still a beginner I can be wrong.
@knownasaritra from the stack overflow link:
str.charCodeAt(i)
appears to be faster than the regular expression alternative. In my test on jsPerf the RegExp option performs 66% slower in Chrome 36 (and slightly slower in Firefox 31).
one thing we could do though is to simplify this expression a bit:
const isAlphaNumeric = (str) => {
for (let i = 0; i < str.length; i++) {
const code = str.charCodeAt(i);
if (!(code > 47 && code < 58) && // numeric (0-9)
!(code > 64 && code < 91) && // upper alpha (A-Z)
!(code > 96 && code < 123)) { // lower alpha (a-z)
return false;
}
}
return true;
};
here what I got:
const isNumeric = code => code > 47 && code < 58;
const isUpperAlpha = code => code > 64 && code < 91;
const isLowerAlpha = code => code > 96 && code < 123;
const isLetterAlphaNumeric = code => isNumeric(code) || isUpperAlpha(code) || isLowerAlpha(code);
const isAlphaNumeric = (str) => Array.from(str)
.map((_, i) => str.charCodeAt(i))
.every(isLetterAlphaNumeric);
or
const isCodeAlphaNumeric = c => (c > 47 && c < 58) || (c > 64 && c < 91) || (c > 96 && c < 123);
const isAlphaNumeric = (str) => Array.from(str)
.map((_, i) => str.charCodeAt(i))
.every(isCodeAlphaNumeric);
note: isalnum IsCharAlphaNumericA
One more thing, what should we do with non latin character like "わ"?
hmm.....that will be a lot of work , if we consider every single possibility, because checks need to be made for every single non-latin languages.
Alright then. I guess my fix should do the trick.
@aloisdg thanks for diving into this. How would that work with foreign characters like Chinese, Japanese, Korean or Cyrillic ? It seems you could easily do that with regex. This library seems interesting: https://github.com/regexhq/word-regex See testing being done here https://github.com/regexhq/word-regex/blob/master/test.js
Rough example: https://codepen.io/skjnldsv/pen/oNdRVPj?editors=1010
No need for special library, ES2015 supports unicode classes:
const input = 'your string'
filtered = input.match(/[\p{L}\p{N}\s]/gu).join('')
-
\p{L}
: Letters of all languages -
\p{N}
: Numbers of all languages -
\s
: White space for breaking the string