Chatterino / chatterino2

Chat client for https://twitch.tv
MIT License
2.05k stars 449 forks source link

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

Closed TalVivian closed 3 years ago

TalVivian commented 5 years ago

Currently users get added to the list as their messages show up in here: https://github.com/Chatterino/chatterino2/blob/3679125e2f959dbd7cb981bc25ab56b6a82e188a/src/common/Channel.cpp#L73-L78

and once in a while we fetch a full list from api: https://github.com/Chatterino/chatterino2/blob/aac27c2a0d8fca560e4daa184075bb871e41f968/src/providers/twitch/TwitchChannel.cpp#L677-L699

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 :alarm_clock:

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

fourtf commented 5 years ago

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 commented 5 years ago

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 commented 4 years ago

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 commented 4 years ago

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.