tolgee / tolgee-js

Tolgee JavaScript libraries monorepo
https://tolgee.io
MIT License
219 stars 24 forks source link

Translation concept #3206

Closed ecstrema closed 1 month ago

ecstrema commented 1 year ago

I had some time, so I designed my dream InContext translation chooser: here's the CodePen

Throw your comments!

ecstrema commented 1 year ago

Edit: updated the link

stepan662 commented 1 year ago

Hey, this looks like an cool idea. I understand that you want to highlight all translations which are on the page when user hits the alt click. But I'm not sure if you also suggest some changes with the events.

I've already played a bit with the events in current implementation. I've found out that you can block/capture events on document level and you don't have to set it on all elements individually. Then there is also handy elementFromPoint api, which allows us to find out which element was clicked without the event actually ever arriving to it. The resulting effect makes the page freeze so e.g. interactive tooltips stay visible. It doesn't work perfectly (e.g. css still reacts to mouse movements), but I found it pretty good.

https://github.com/tolgee/tolgee-js/blob/main/packages/web/src/observers/general/MouseEventHandler.ts

ecstrema commented 1 year ago

I find a few problems with the existing implementation:

1) The application often gets stuck in translation mode. For example, just press alt-tab to switch window. When you come back, you still can't click on anything, and the app is waiting for you to choose a translation, even though you're not pressing alt anymore. 2) Since you only see translatable text when you hover it, it's not easy to spot if you forgot to make something translatable. 3) In translation mode, you have no indicator of what you need to do. For new users, it can be weird. You don't immediately realize that if you click on a translated string, a popup will open, since really nothing has changed in the UI until you start hovering things. 4) The red box is very visible, but not very sympathetic to the eyes, and not completely visible proof. e.g. it may be hardly visible for text on a red image, although they're pretty rare.

ecstrema commented 1 year ago

css still reacts to mouse movements

That's also the advantage of using the "highlight all" approach. Even if the element disappears, its highlighter is still there, and so the element can still be clicked, until alt is released. In other words, pressing alt creates a snapshot of the page, and you can translate everything that was visible at that moment.

stepan662 commented 1 year ago

Ok, these are legit concerns. I wanned to make some more improvements to the highlighter, so I'll look into this once I'll start that.

ecstrema commented 1 year ago

Ok, here's another idea. I'm wondering how it could be integrated into Tolgee directly: Here's what we just added to our website:

...
interface RecursiveStringObject {
  [key: string]: string | RecursiveStringObject
}

// Function to recursively copy the object and its properties, but replacing the property value with a string
// This is used to create an empty object with the same structure as the original object
function emptyObject(obj: RecursiveStringObject) {
  const result: RecursiveStringObject = {};
  for (const prop in obj) {
    if (typeof obj[prop] === "object") {
      result[prop] = emptyObject(obj[prop] as any);
    } else {
      result[prop] = " ";
    }
  }
  return result;
}

const tolgee = Tolgee()
  .init({
    // for development
    defaultLanguage: "en",
    ...
    staticData: {
      en,
      cs: emptyObject(en),
    },
  });

export default function MyApp({ Component, pageProps }: AppProps<any>) {
  // Subscribe to the key combination ctrl + shift+ alt + L to toggle the language
  useEffect(() => {
    function toggleLanguageEvent(e: KeyboardEvent) {
      if (e.ctrlKey && e.shiftKey && e.altKey && e.key === "L") {
        e.preventDefault();
        e.stopPropagation();
        tolgee.changeLanguage(tolgee.getLanguage() === "en" ? "cs" : "en");
        console.log(`Language changed to ${tolgee.getLanguage()}`);
      }
    }
    document.addEventListener("keyup", toggleLanguageEvent);
    return () => {
      document.removeEventListener("keyup", toggleLanguageEvent);
    };
  });

  return (
    <TolgeeProvider tolgee={tolgee} options={{ useSuspense: false }}>
        ...
    </TolgeeProvider>
  );
}

The core idea is: You create an empty translation language, and use it as a toggle to show/hide translated strings.

Whenever you press the key combination, all translations get hidden, so all that's left is the text we forgot to translate. That makes it very very easy to discover the untranslated strings in your app.

stepan662 commented 1 month ago

I'm closing this for low interest from userbase. But feel free to comment on these ideas here and we can reopen this.