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

Tab complete "Real Case" user names instead of login names (display name over login name) #1199

Closed
TalVivian opened this issue Aug 11, 2019 · 4 comments · Fixed by #1883
Closed

Comments

@TalVivian
Copy link

Currently users get added to the list as their messages show up in here:

const QString &username = message->loginName;
if (!username.isEmpty())
{
// TODO: Add recent chatters display name
this->addRecentChatter(message);
}

and once in a while we fetch a full list from api:

// get viewer list
NetworkRequest request("https://tmi.twitch.tv/group/user/" +
this->getName() + "/chatters");
request.setCaller(QThread::currentThread());
request.onSuccess(
[this, weak = weakOf<Channel>(this)](auto result) -> Outcome {
// channel still exists?
auto shared = weak.lock();
if (!shared)
return Failure;
auto pair = parseChatters(result.parseJson());
if (pair.first)
{
*this->chatters_.access() = std::move(pair.second);
}
return pair.first;
});
request.execute();
}

The problem is that while we can fix the first one by just swapping to display name, the second requires an extra call to api to aquire the display name. I wrote a POC in python to show how it can be extracted.

#!/usr/bin/env python3
import argparse
import math
import requests

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--client-id', required=True)
    parser.add_argument('--target-channel', required=True, help='for example pajlada')
    parser.add_argument('--api', choices=['helix', 'kraken'], required=True)
    args = parser.parse_args()

    url = f'https://tmi.twitch.tv/group/user/{args.target_channel}/chatters'
    response = requests.get(url)
    response.raise_for_status()
    chatters = [chatter for group in response.json().get('chatters').values() for chatter in group]

    mapping = dict()
    at_once = 100
    for i in range(math.ceil(len(chatters) / at_once)):
        start = i * at_once
        end = start + at_once
        current_chatters = chatters[start:end]

        if args.api == 'helix':
            url = f'https://api.twitch.tv/helix/users?login={"&login=".join(current_chatters)}'
            headers = {'Client-Id': args.client_id}
            response = requests.get(url, headers=headers)
            response.raise_for_status()

            for user in response.json().get('data'):
                mapping[user['login']] = user['display_name']
        elif args.api == 'kraken':
            url = f'https://api.twitch.tv/kraken/users?login={",".join(current_chatters)}'
            headers = {'Client-Id': args.client_id,
                       'Accept': 'application/vnd.twitchtv.v5+json'}
            response = requests.get(url, headers=headers)
            response.raise_for_status()

            for user in response.json().get('users'):
                mapping[user['name']] = user['display_name']

    for login, display in mapping.items():
        # stolen from official twitch chat source code PepeS:
        # user.isIntl = user.login && user.displayName && user.displayName.trim().toLowerCase() !== user.login;
        if display.strip().lower() == login:
            print(f'{login}: {display}')
        else:
            print(f'{login}: {display}({login})')
 python3 main.py --client-id <REDACTED> --target-channel pajlada --api helix

I bet it can be nicely cached too. There is one caveat and it's the fact that some display names might be in CJK. Right now chatterino doesn't support tab completion with them, while twitch client is happy to accept for example japanese input and tab complete it.

Sadly I lack skills to do it properly in C++/Qt5 so I'll leave it as an exercise to the reader ⏰

PS: For now I swapped to message->displayName and commented out the request and it kinda works.

@fourtf
Copy link
Member

fourtf commented Aug 17, 2019

Is this supposed to make tabbing users case sensitive (e.g. can't tab Peter when searching with "pe") or just when you actual tab the name, and the text gets inserted into the text editor?

@TalVivian
Copy link
Author

When you tab the name it shows display name (case sensitive) instead of login name (lower case). The second one.
I believe the right way is to treat the input as case insensitive (so it shouldn't matter if I type talv, TalV or TALV) and output as case sensitive (so it always becomes TalVivian).

@RancidSwine
Copy link

So are there plans to fix this? It's the one reason I switched to Chatty. I'd prefer using Chatterino because I love it, but the names being all lowercase is a deal breaker for me.
I hope this gets addressed soon, would love to switch back.

@leon-richardt
Copy link
Collaborator

So are there plans to fix this?

Well, there are no open pull requests at least. I suppose this isn't as big of a nuisance for most people so it's probably rather low on the list of priorities.

@pajlada pajlada changed the title Make results from tab completion case sensitive Tab complete "Real Case" user names instead of login names (display name over login name) Dec 13, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants