Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: twireapp/Twire
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v2.10.6
Choose a base ref
...
head repository: twireapp/Twire
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v2.10.7
Choose a head ref
  • 13 commits
  • 19 files changed
  • 3 contributors

Commits on May 13, 2023

  1. Verified

    This commit was signed with the committer’s verified signature.
    Copy the full SHA
    6d377c5 View commit details
  2. Verified

    This commit was signed with the committer’s verified signature.
    Copy the full SHA
    2500ff4 View commit details
  3. Verified

    This commit was signed with the committer’s verified signature.
    Copy the full SHA
    77ef560 View commit details
  4. Verified

    This commit was signed with the committer’s verified signature.
    Copy the full SHA
    98c38f4 View commit details

Commits on May 14, 2023

  1. Verified

    This commit was signed with the committer’s verified signature.
    Copy the full SHA
    70f67a0 View commit details
  2. Fix two pagination issues

    1. Pagination not being reset on refresh
    2. Pagination not being set on some views
    samfundev committed May 14, 2023

    Verified

    This commit was signed with the committer’s verified signature.
    Copy the full SHA
    48a455b View commit details

Commits on May 20, 2023

  1. Add system messages

    samfundev committed May 20, 2023

    Verified

    This commit was signed with the committer’s verified signature.
    Copy the full SHA
    0559a54 View commit details
  2. Remove unneeded test code

    samfundev committed May 20, 2023

    Verified

    This commit was signed with the committer’s verified signature.
    Copy the full SHA
    489ba60 View commit details
  3. Verified

    This commit was signed with the committer’s verified signature.
    Copy the full SHA
    be731fc View commit details
  4. Skip broken badges

    samfundev committed May 20, 2023

    Verified

    This commit was signed with the committer’s verified signature.
    Copy the full SHA
    f7f1a90 View commit details

Commits on May 21, 2023

  1. Translated using Weblate (Polish)

    Currently translated at 100.0% (3 of 3 strings)
    
    Update Polish translations (100.0%, 237/237)
    
    Co-authored-by: Hosted Weblate <hosted@weblate.org>
    Co-authored-by: skajmer <skajmer@protonmail.com>
    Translate-URL: https://hosted.weblate.org/projects/twire/metadata/pl/
    Translate-URL: https://hosted.weblate.org/projects/twire/strings/pl/
    Translation: Twire/Metadata
    Translation: Twire/Strings
    weblate and skajmer committed May 21, 2023

    Verified

    This commit was signed with the committer’s verified signature.
    weblate Weblate (bot)
    Copy the full SHA
    2b8eaa3 View commit details
  2. Update translation files

    Updated by "Squash Git commits" hook in Weblate.
    
    Translation: Twire/Metadata
    Translate-URL: https://hosted.weblate.org/projects/twire/metadata/
    weblate committed May 21, 2023

    Verified

    This commit was signed with the committer’s verified signature.
    weblate Weblate (bot)
    Copy the full SHA
    346fd6c View commit details
  3. 2.10.7

    samfundev committed May 21, 2023

    Verified

    This commit was signed with the committer’s verified signature.
    Copy the full SHA
    2782274 View commit details
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -10,8 +10,8 @@ android {
applicationId "com.perflyst.twire"
minSdkVersion 16
targetSdkVersion 33
versionCode 530
versionName "2.10.6"
versionCode 531
versionName "2.10.7"

multiDexEnabled true
vectorDrawables.useSupportLibrary true
Original file line number Diff line number Diff line change
@@ -61,18 +61,17 @@ public void addToAdapter(List<StreamInfo> streamsToAdd) {
mAdapter.addList(streamsToAdd);
}

private String pagination = "";

@Override
public List<StreamInfo> getVisualElements() throws JSONException, MalformedURLException, UnsupportedEncodingException {
String languageFilter = settings.getGeneralFilterTopStreamsByLanguage() ? "&language=" + getSystemLanguage() : "";

String url = "https://api.twitch.tv/helix/streams?game_id=" + game.getGameId() + "&first=" + getLimit() + (!pagination.isEmpty() ? "&after=" + pagination : "") + languageFilter;
String url = "https://api.twitch.tv/helix/streams?game_id=" + game.getGameId() + "&first=" + getLimit() + (getCursor() != null ? "&after=" + getCursor() : "") + languageFilter;

List<StreamInfo> mResultList = new ArrayList<>();
String jsonString = Service.urlToJSONStringHelix(url, this);
JSONObject fullDataObject = new JSONObject(jsonString);
JSONArray topStreamsArray = fullDataObject.getJSONArray("data");
setCursor(fullDataObject.getJSONObject("pagination").getString("cursor"));

for (int i = 0; i < topStreamsArray.length(); i++) {
JSONObject streamObject = topStreamsArray.getJSONObject(i);
Original file line number Diff line number Diff line change
@@ -59,19 +59,17 @@ public void addToAdapter(List<StreamInfo> aObjectList) {
/**
* Methods for functionality and for controlling the SwipeRefreshLayout
*/

private String pagination = "";

@Override
public List<StreamInfo> getVisualElements() throws JSONException, MalformedURLException {
List<StreamInfo> resultList = new ArrayList<>();

//Indentation is meant to mimic the structure of the JSON code
final String URL = "https://api.twitch.tv/helix/streams?first=" + getLimit() + (!pagination.isEmpty() ? "&after=" + pagination : "");
final String URL = "https://api.twitch.tv/helix/streams?first=" + getLimit() + (getCursor() != null ? "&after=" + getCursor() : "");

String jsonString = Service.urlToJSONStringHelix(URL, this);
JSONObject fullDataObject = new JSONObject(jsonString);
JSONArray topFeaturedArray = fullDataObject.getJSONArray("data");
setCursor(fullDataObject.getJSONObject("pagination").getString("cursor"));

for (int i = 0; i < topFeaturedArray.length(); i++) {
// Get all the JSON objects we need to get all the required data.
Original file line number Diff line number Diff line change
@@ -57,18 +57,16 @@ public void addToAdapter(List<Game> aGamesList) {
return new GamesAdapter(recyclerView, getBaseContext(), this);
}

public String pagination = "";

@Override
public List<Game> getVisualElements() throws JSONException {
List<Game> resultList = new ArrayList<>();

//Indentation is meant to mimic the structure of the JSON code
final String URL = "https://api.twitch.tv/helix/games/top?first=" + getLimit() + (!pagination.isEmpty() ? "&after=" + pagination : "");
final String URL = "https://api.twitch.tv/helix/games/top?first=" + getLimit() + (getCursor() != null ? "&after=" + getCursor() : "");
String jsonString = Service.urlToJSONStringHelix(URL, this);
JSONObject fullDataObject = new JSONObject(jsonString);
JSONArray gamesArray = fullDataObject.getJSONArray("data");
this.pagination = fullDataObject.getJSONObject("pagination").getString("cursor");
setCursor(fullDataObject.getJSONObject("pagination").getString("cursor"));

for (int i = 0; i < gamesArray.length(); i++) {
// Get all the JSON objects we need to get all the required data.
Original file line number Diff line number Diff line change
@@ -50,18 +50,16 @@ public void addToAdapter(List<StreamInfo> streamsToAdd) {
Log.i(LOG_TAG, "Adding Top Streams: " + streamsToAdd.size());
}

private String pagination = "";

@Override
public List<StreamInfo> getVisualElements() throws JSONException, MalformedURLException {
final String languageFilter = settings.getGeneralFilterTopStreamsByLanguage() ? "&language=" + getSystemLanguage() : "";
final String URL = "https://api.twitch.tv/helix/streams?first=" + getLimit() + (!pagination.isEmpty() ? "&after=" + pagination : "") + languageFilter;
final String URL = "https://api.twitch.tv/helix/streams?first=" + getLimit() + (getCursor() != null ? "&after=" + getCursor() : "") + languageFilter;

List<StreamInfo> mResultList = new ArrayList<>();
String jsonString = Service.urlToJSONStringHelix(URL, this);
JSONObject fullDataObject = new JSONObject(jsonString);
JSONArray topStreamsArray = fullDataObject.getJSONArray("data");
this.pagination = fullDataObject.getJSONObject("pagination").getString("cursor");
setCursor(fullDataObject.getJSONObject("pagination").getString("cursor"));

for (int i = 0; i < topStreamsArray.length(); i++) {
JSONObject streamObject = topStreamsArray.getJSONObject(i);
56 changes: 32 additions & 24 deletions app/src/main/java/com/perflyst/twire/adapters/ChatAdapter.java
Original file line number Diff line number Diff line change
@@ -79,43 +79,51 @@ public ContactViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
public void onBindViewHolder(@NonNull final ContactViewHolder holder, int position) {
try {
final ChatMessage message = messages.get(position);
if (message.getMessage().equals("Test")) {
Log.d(LOG_TAG, "Binding Message for user");
Log.d(LOG_TAG, "Message: " + message);
}

if (message.getName() == null) {
return;
}

final SpannableStringBuilder builder = new SpannableStringBuilder();
for (Badge badge : message.getBadges()) {
final GlideImageSpan badgeSpan = new GlideImageSpan(context, badge.getUrl(2), holder.message, builder, 36, 1, badge.color);
appendSpan(builder, " ", badgeSpan).append(" ");
if (!message.systemMessage.isEmpty()) {
appendSpan(builder, message.systemMessage, new ForegroundColorSpan(Color.GRAY));
holder.message.setBackgroundResource(R.drawable.system_message);
} else {
holder.message.setBackgroundResource(0);
}

int nameColor = getNameColor(message.getColor());
appendSpan(builder, message.getName(), new ForegroundColorSpan(nameColor), new StyleSpan(Typeface.BOLD));
if (!message.getMessage().isEmpty()) {
if (!message.systemMessage.isEmpty()) builder.append('\n');

for (Badge badge : message.getBadges()) {
if (badge == null) { continue; }

final GlideImageSpan badgeSpan = new GlideImageSpan(context, badge.getUrl(2), holder.message, 36, 1, badge.color);
appendSpan(builder, " ", badgeSpan).append(" ");
}

int nameColor = getNameColor(message.getColor());
appendSpan(builder, message.getName(), new ForegroundColorSpan(nameColor), new StyleSpan(Typeface.BOLD));

int preLength = builder.length();
String beforeMessage = ": ";
String messageWithPre = beforeMessage + message.getMessage();
appendSpan(builder, messageWithPre, new ForegroundColorSpan(getMessageColor()));
int preLength = builder.length();
String beforeMessage = ": ";
String messageWithPre = beforeMessage + message.getMessage();
appendSpan(builder, messageWithPre, new ForegroundColorSpan(getMessageColor()));

checkForLink(builder.toString(), builder);
checkForLink(builder.toString(), builder);

for (ChatEmote chatEmote : message.getEmotes()) {
for (Integer emotePosition : chatEmote.getPositions()) {
final Emote emote = chatEmote.getEmote();
final int fromPosition = emotePosition + preLength;
final int toPosition = emotePosition + emote.getKeyword().length() - 1 + preLength;
for (ChatEmote chatEmote : message.getEmotes()) {
for (Integer emotePosition : chatEmote.getPositions()) {
final Emote emote = chatEmote.getEmote();
final int fromPosition = emotePosition + preLength;
final int toPosition = emotePosition + emote.getKeyword().length() - 1 + preLength;

int emoteSize = settings.getEmoteSize();
int emotePixels = emoteSize == 1 ? 28 : emoteSize == 2 ? 56 : 112;
int emoteSize = settings.getEmoteSize();
int emotePixels = emoteSize == 1 ? 28 : emoteSize == 2 ? 56 : 112;

final GlideImageSpan emoteSpan = new GlideImageSpan(context, emote.getEmoteUrl(emoteSize, isNightTheme), holder.message, builder, emotePixels, (float) emote.getBestAvailableSize(emoteSize) / emoteSize);
final GlideImageSpan emoteSpan = new GlideImageSpan(context, emote.getEmoteUrl(emoteSize, isNightTheme), holder.message, emotePixels, (float) emote.getBestAvailableSize(emoteSize) / emoteSize);

builder.setSpan(emoteSpan, fromPosition + beforeMessage.length(), toPosition + 1 + beforeMessage.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
builder.setSpan(emoteSpan, fromPosition + beforeMessage.length(), toPosition + 1 + beforeMessage.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
}
}
}

Original file line number Diff line number Diff line change
@@ -91,6 +91,7 @@ void handleElementOnClick(final View view) {
final int itemPosition = getRecyclerView().getChildAdapterPosition(view);
VideoOnDemand item = getElements().get(itemPosition);
if (activity instanceof VODActivity) {
activity.getIntent().putExtra(getContext().getString(R.string.stream_shared_transition), false);
((VODActivity) activity).startNewVOD(item);
} else {
Intent intent = VODActivity.createVODIntent(item, getContext(), true);
13 changes: 11 additions & 2 deletions app/src/main/java/com/perflyst/twire/chat/ChatManager.java
Original file line number Diff line number Diff line change
@@ -304,7 +304,10 @@ private void processVodChat() {
onUpdate(UpdateType.ON_CONNECTED);
}

if (dataObject.getJSONObject("video").isNull("comments")) continue;
if (dataObject.getJSONObject("video").isNull("comments")) {
cursor = "";
continue;
}

JSONObject commentsObject = dataObject.getJSONObject("video").getJSONObject("comments");
JSONArray comments = commentsObject.getJSONArray("edges");
@@ -366,7 +369,11 @@ private void processVodChat() {
JSONArray userBadgesArray = message.getJSONArray("userBadges");
for (int j = 0; j < userBadgesArray.length(); j++) {
JSONObject userBadge = userBadgesArray.getJSONObject(j);
badges.put(userBadge.getString("setID"), userBadge.getString("version"));
String setID = userBadge.getString("setID");
String version = userBadge.getString("version");
if (setID.isEmpty() || version.isEmpty()) continue;

badges.put(setID, version);
}
}

@@ -533,6 +540,7 @@ private void handleMessage(IRCMessage message) {

ChatMessage chatMessage = new ChatMessage(content, displayName, color, getBadges(badges), emotes, false);
chatMessage.setID(tags.get("id"));
chatMessage.systemMessage = tags.getOrDefault("system-msg", "");

if (content.contains("@" + getUserDisplayName())) {
Log.d(LOG_TAG, "Highlighting message with mention: " + content);
@@ -673,6 +681,7 @@ private Badge getBadge(String badgeSet, String version) {
if (globalSet != null && globalSet.get(version) != null)
return globalSet.get(version);

Log.e(LOG_TAG, "Badge failed to load: \"" + badgeSet + "\" \"" + version + "\"");
return null;
}

12 changes: 4 additions & 8 deletions app/src/main/java/com/perflyst/twire/misc/GlideImageSpan.java
Original file line number Diff line number Diff line change
@@ -6,9 +6,7 @@
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.text.SpannableStringBuilder;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import androidx.annotation.NonNull;
@@ -26,8 +24,8 @@ public class GlideImageSpan extends VerticalImageSpan implements Drawable.Callba
private Drawable mDrawable;
private Animatable animatable;

public GlideImageSpan(Context context, String url, TextView textView, SpannableStringBuilder builder, int assumedSize, float scale, String backgroundColor) {
this(context, url, textView, builder, assumedSize, scale);
public GlideImageSpan(Context context, String url, TextView textView, int assumedSize, float scale, String backgroundColor) {
this(context, url, textView, assumedSize, scale);

if (backgroundColor == null)
return;
@@ -39,7 +37,7 @@ public GlideImageSpan(Context context, String url, TextView textView, SpannableS
layerDrawable.setId(1, 1);
}

public GlideImageSpan(Context context, String url, TextView textView, SpannableStringBuilder builder, int assumedSize, float scale) {
public GlideImageSpan(Context context, String url, TextView textView, int assumedSize, float scale) {
super(new BlankDrawable());

this.textView = textView;
@@ -72,15 +70,13 @@ public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? s
animatable = (Animatable) resource;
resource.setCallback(instance);

instance.textView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

animatable.start();
}

mDrawable = resource;

if (resource.getIntrinsicWidth() != assumedSize) {
textView.setText(builder);
textView.setText(textView.getText());
Log.d("EmoteShift", "Got " + resource.getIntrinsicWidth() + " but assumed " + assumedSize + " (" + url + ")");
} else {
textView.invalidate();
2 changes: 2 additions & 0 deletions app/src/main/java/com/perflyst/twire/model/ChatMessage.java
Original file line number Diff line number Diff line change
@@ -16,6 +16,8 @@ public class ChatMessage {
private boolean highlight;
private String id = null;

public String systemMessage = "";

public ChatMessage(String message, String name, String color, List<Badge> badges, List<ChatEmote> emotes, boolean highlight) {
this.message = message;
this.name = name;
20 changes: 20 additions & 0 deletions app/src/main/res/drawable/system_message.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:paddingLeft="@dimen/chat_recyclerview_padding"
android:paddingRight="@dimen/chat_recyclerview_padding">
<item>
<inset
android:insetTop="-4dp"
android:insetRight="-4dp"
android:insetBottom="-4dp">

<shape android:shape="rectangle">
<stroke
android:width="3dp"
android:color="?attr/colorAccent" />
</shape>
</inset>
</item>
</layer-list>
3 changes: 1 addition & 2 deletions app/src/main/res/layout/chat_message.xml
Original file line number Diff line number Diff line change
@@ -10,5 +10,4 @@
android:scrollbars="none"
android:scrollHorizontally="false"
android:textColor="@color/black"
android:textSize="@dimen/chat_message_text_size"
android:textIsSelectable="true" />
android:textSize="@dimen/chat_message_text_size" />
3 changes: 2 additions & 1 deletion app/src/main/res/layout/chat_message_options.xml
Original file line number Diff line number Diff line change
@@ -19,7 +19,8 @@
style="@style/stream_settings_item"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:minHeight="48dp" />
android:minHeight="48dp"
android:textIsSelectable="true" />

<TextView
android:id="@+id/text_mention"
38 changes: 38 additions & 0 deletions app/src/main/res/values-in/strings.xml
Original file line number Diff line number Diff line change
@@ -60,4 +60,42 @@
<string name="vod_views">%,d tampilan</string>
<string name="preview_stream_game_and_viewers">1337 penonton - Judul game</string>
<string name="preview_stream_online_since">00:30:00</string>
<string name="card_size_huge">MAKS</string>
<string name="title_activity_vod">Video On Demand</string>
<string name="card_size_small">Kecil</string>
<string name="preview_game_title">Judul permainan</string>
<string name="preview_game_viewers">1337 pemirsa</string>
<string name="no_server_response_message">Ups, server Twitch tampaknya tidak merespons. Refresh\?</string>
<string name="my_channels_activity_label">Mengikuti</string>
<string name="stream_playback_failed">Gagal memutar streaming. Coba kualitas lain.</string>
<string name="title_activity_live_stream">Siaran langsung</string>
<string name="chat_send_message_hint">Ketik pesan</string>
<string name="chat_status_connecting">Menghubungkan ke Obrolan…</string>
<string name="chat_status_connected">Siap Mengobrol</string>
<string name="chat_status_reconnecting">Menghubungkan kembali…</string>
<string name="login_text_line_two">Pertama, masuk ke Twitch.</string>
<string name="login_user_cancel">Anda harus masuk untuk menggunakan Twire, meskipun…</string>
<string name="login_user_cancel_action">MENGERTI</string>
<string name="chat_paused">Obrolan dijeda karena gulir.</string>
<string name="login_user_no_internet">Anda akan membutuhkan koneksi internet untuk menyiapkan Twire.</string>
<string name="welcome_text_line_two">Twire</string>
<string name="login_user_no_internet_action">COBA LAGI</string>
<string name="streamerInfo_chat_tab">Obrolan</string>
<string name="card_style_normal">Normal</string>
<string name="card_size_normal">Normal</string>
<string name="card_size_large">Besar</string>
<string name="default_stream_title">%1$s memutar %2$s</string>
<string name="preview_stream_title">Judul streaming</string>
<string name="preview_stream_display_name">Nama</string>
<string name="error_external_playback_failed">Gagal mengirim URL ke pemutar eksternal</string>
<string name="error_nothing_found">Tidak ada apa-apa di sini</string>
<string name="my_streams_preview_image">Pratinjau saluran langsung</string>
<string name="my_streams_cell_current_viewers">%,d pemirsa</string>
<string name="login_text_line_one">Mari kita siapkan semuanya!</string>
<string name="login_on_success_message">Halo, %s</string>
<string name="chat_status_connection_failed">Koneksi Gagal</string>
<string name="title_activity_welcome">Pengaturan Twire</string>
<string name="welcome_text_line_one">Selamat datang di</string>
<string name="login_invalid_token_text_line_one">Sayangnya Anda</string>
<string name="login_invalid_token_text_line_two">harus masuk lagi</string>
</resources>
Loading