Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avatar placeholder should not take special characters #2044

Closed
skjnldsv opened this issue Jun 20, 2021 · 12 comments · Fixed by #4737
Closed

Avatar placeholder should not take special characters #2044

skjnldsv opened this issue Jun 20, 2021 · 12 comments · Fixed by #4737
Labels
1. to develop Accepted and waiting to be taken care of bug Something isn't working design Design, UX, interface and interaction design feature: avatar Related to the avatar component good first issue Small tasks with clear documentation about how and in which place you need to fix things in.

Comments

@skjnldsv
Copy link
Contributor

image

@skjnldsv skjnldsv added bug Something isn't working good first issue Small tasks with clear documentation about how and in which place you need to fix things in. 1. to develop Accepted and waiting to be taken care of design Design, UX, interface and interaction design feature: avatar Related to the avatar component labels Jun 20, 2021
@aloisdg
Copy link

aloisdg commented Oct 7, 2021

Can I give it a try? If so, I will create a PR to edit Avatar.vue.

@skjnldsv
Copy link
Contributor Author

@aloisdg go for it :)

@aloisdg
Copy link

aloisdg commented Nov 5, 2021

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); },

@ak090498
Copy link

Hi,
Is this still open ?

@aloisdg
Copy link

aloisdg commented Sep 17, 2022

@knowasaritra I didn't have any comment on my code. What do you think of it?

@ak090498
Copy link

@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.

@aloisdg
Copy link

aloisdg commented Sep 17, 2022

@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

@aloisdg
Copy link

aloisdg commented Sep 18, 2022

One more thing, what should we do with non latin character like "わ"?

@ak090498
Copy link

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.

@aloisdg
Copy link

aloisdg commented Oct 7, 2022

Alright then. I guess my fix should do the trick.

@skjnldsv
Copy link
Contributor Author

@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

@susnux
Copy link
Contributor

susnux commented Jun 15, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
1. to develop Accepted and waiting to be taken care of bug Something isn't working design Design, UX, interface and interaction design feature: avatar Related to the avatar component good first issue Small tasks with clear documentation about how and in which place you need to fix things in.
Projects
None yet
4 participants