diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..5e6922b --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,54 @@ +name: Build + +on: + push: + branches: ["master"] + pull_request: + branches: ["master"] + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-24.04 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up JDK 8 + uses: actions/setup-java@v4 + with: + java-version: 8 + distribution: 'zulu' + + - name: Set up Android SDK + uses: android-actions/setup-android@v3 + with: + cmdline-tools-version: 8512546 + log-accepted-android-sdk-licenses: false + + - name: Make gradlew executable + run: chmod +x gradlew + + - name: Build APK + run: ./gradlew assembleFdroidDebug + + - name: Rename APK + id: rename + run: | + if [ "${{ github.event_name }}" == "pull_request" ]; then + SHA_FULL="${{ github.event.pull_request.head.sha }}" + else + SHA_FULL="${{ github.sha }}" + fi + SHA_SHORT="${SHA_FULL:0:7}" + + APK_NAME="app-fdroid-debug-$SHA_SHORT.apk" + mv app/build/outputs/apk/fdroid/debug/app-fdroid-debug.apk "app/build/outputs/apk/fdroid/debug/$APK_NAME" + echo "apk_name=$APK_NAME" >> $GITHUB_OUTPUT + + - name: Upload APK artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ steps.rename.outputs.apk_name }} + path: app/build/outputs/apk/fdroid/debug/${{ steps.rename.outputs.apk_name }} + retention-days: 7 diff --git a/.github/workflows/publish-dev-release.yml b/.github/workflows/publish-dev-release.yml deleted file mode 100644 index a75a358..0000000 --- a/.github/workflows/publish-dev-release.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: Publish development release - -on: - push: - branches: - - master - workflow_dispatch: - -jobs: - release_development_build: - runs-on: ubuntu-latest - - steps: - - name: Checkout master branch - uses: actions/checkout@v4 - - - name: Set up JDK 8 - uses: actions/setup-java@v4 - with: - java-version: 8 - distribution: 'zulu' - - - name: Set up Android SDK - uses: android-actions/setup-android@v3 - with: - cmdline-tools-version: 8512546 - log-accepted-android-sdk-licenses: false - - - name: Make gradlew executable - run: chmod +x gradlew - - - name: Build APK - run: ./gradlew assembleFdroidDebug - - - name: Set environment variables - run: | - SHA_SHORT=$(git rev-parse --short HEAD) - echo "APK_PATH=app/build/outputs/apk/fdroid/debug" >> $GITHUB_ENV - echo "APK_NAME=LRC.Editor.Dev.Debug.$SHA_SHORT" >> $GITHUB_ENV - - - name: Rename APK - run: mv $APK_PATH/app-fdroid-debug.apk $APK_PATH/$APK_NAME.apk - - - name: Cleanup v-dev tag and release - run: gh release delete v-dev --cleanup-tag --yes || true - env: - GH_TOKEN: ${{ github.token }} - - - name: Upload APK release - run: | - gh release create v-dev $APK_PATH/$APK_NAME.apk \ - --title "LRC Editor Developer Build" \ - --notes "Unreleased developer build (\`fdroid\` build variant) with the latest updates" \ - --target ${{ github.sha }} \ - --prerelease - env: - GH_TOKEN: ${{ github.token }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..6cc7911 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,57 @@ +name: Publish + +on: + workflow_run: + workflows: ["Build"] + types: + - completed + branches: + - master + +permissions: + contents: write + actions: read + +jobs: + publish: + runs-on: ubuntu-24.04 + if: "${{ github.event.workflow_run.conclusion == 'success' }}" + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + ref: "${{ github.event.workflow_run.head_sha }}" + + - name: Set environment variables + run: | + SHA_FULL="${{ github.event.workflow_run.head_sha }}" + SHA_SHORT="${SHA_FULL:0:7}" + echo "BUILD_ARTIFACT_NAME=app-fdroid-debug-$SHA_SHORT.apk" >> $GITHUB_ENV + echo "APK_NAME=LRC.Editor.Dev.Debug.$SHA_SHORT.apk" >> $GITHUB_ENV + + - name: Download APK artifact + uses: actions/download-artifact@v4 + with: + name: ${{ env.BUILD_ARTIFACT_NAME }} + path: apk_output + run-id: "${{ github.event.workflow_run.id }}" + github-token: "${{ github.token }}" + + - name: Rename APK + run: mv apk_output/${{ env.BUILD_ARTIFACT_NAME }} apk_output/${{ env.APK_NAME }} + + - name: Cleanup v-dev tag and release + run: gh release delete v-dev --cleanup-tag --yes || true + env: + GH_TOKEN: "${{ github.token }}" + + - name: Upload APK release + run: | + gh release create v-dev apk_output/${{ env.APK_NAME }} \ + --title "LRC Editor Developer Build" \ + --notes "Unreleased developer build (\`fdroid\` build variant) with the latest updates" \ + --target "${{ github.event.workflow_run.head_sha }}" \ + --prerelease + env: + GH_TOKEN: "${{ github.token }}" + diff --git a/app/src/main/java/com/cg/lrceditor/Constants.java b/app/src/main/java/com/cg/lrceditor/Constants.java index 1d4d829..213b3ce 100644 --- a/app/src/main/java/com/cg/lrceditor/Constants.java +++ b/app/src/main/java/com/cg/lrceditor/Constants.java @@ -16,6 +16,7 @@ class Constants { static final String SAVE_LOCATION_PREFERENCE = "saveLocation"; static final String TIMESTAMP_STEP_AMOUNT_PREFERENCE = "timestamp_step_amount"; static final String THREE_DIGIT_MILLISECONDS_PREFERENCE = "three_digit_milliseconds"; + static final String LYRIC_LEADING_SPACE_PREFERENCE = "lyric_leading_space"; static final String THEME_PREFERENCE = "current_theme"; static final String PURCHASED_PREFERENCE = "lrceditor_purchased"; } diff --git a/app/src/main/java/com/cg/lrceditor/FinalizeActivity.java b/app/src/main/java/com/cg/lrceditor/FinalizeActivity.java index b738c84..127e718 100644 --- a/app/src/main/java/com/cg/lrceditor/FinalizeActivity.java +++ b/app/src/main/java/com/cg/lrceditor/FinalizeActivity.java @@ -71,6 +71,7 @@ public class FinalizeActivity extends AppCompatActivity { private boolean overwriteFailed = false; private boolean threadIsExecuting = false; private boolean useThreeDigitMilliseconds = false; + private boolean useLyricLeadingSpace = false; @SuppressLint("ClickableViewAccessibility") @Override @@ -111,6 +112,7 @@ protected void onCreate(Bundle savedInstanceState) { }); useThreeDigitMilliseconds = preferences.getBoolean(Constants.THREE_DIGIT_MILLISECONDS_PREFERENCE, false); + useLyricLeadingSpace = preferences.getBoolean(Constants.LYRIC_LEADING_SPACE_PREFERENCE, false); Toolbar toolbar = findViewById(R.id.toolbar); if (isDarkTheme) { @@ -296,7 +298,7 @@ private void writeLyrics(final String filePath, final String fileName) { file = file.createFile("application/*", fileName); OutputStream out = getContentResolver().openOutputStream(file.getUri()); - InputStream in = new ByteArrayInputStream(lyricsToString(useThreeDigitMilliseconds).getBytes(StandardCharsets.UTF_8)); + InputStream in = new ByteArrayInputStream(lyricsToString(useThreeDigitMilliseconds, useLyricLeadingSpace).getBytes(StandardCharsets.UTF_8)); byte[] buffer = new byte[1024]; int read; @@ -327,7 +329,7 @@ public void setAsLRCFileName(View view) { ((EditText) dialogView.findViewById(R.id.dialog_edittext)).setText(lrcFileName); } - private String lyricsToString(boolean useThreeDigitMilliseconds) { + private String lyricsToString(boolean useThreeDigitMilliseconds, boolean useLyricLeadingSpace) { StringBuilder sb = new StringBuilder(); String str; @@ -360,7 +362,10 @@ private String lyricsToString(boolean useThreeDigitMilliseconds) { // Some players might skip empty lyric lines (I'm looking at you Huawei music player) // Hence we replace empty lyric lines with a space lyric = " "; + } else if (useLyricLeadingSpace) { + lyric = " " + lyric; } + if (useThreeDigitMilliseconds) { sb.append("[").append(timestamp.toStringWithThreeDigitMilliseconds(Locale.ENGLISH)).append("]").append(lyric).append("\n"); } else { @@ -468,7 +473,7 @@ public boolean isExternalStorageWritable() { public void copyLrc(View view) { ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); - ClipData clip = ClipData.newPlainText("Generated LRC data", lyricsToString(useThreeDigitMilliseconds)); + ClipData clip = ClipData.newPlainText("Generated LRC data", lyricsToString(useThreeDigitMilliseconds, useLyricLeadingSpace)); if (clipboard != null) { clipboard.setPrimaryClip(clip); } else { diff --git a/app/src/main/java/com/cg/lrceditor/SettingsActivity.java b/app/src/main/java/com/cg/lrceditor/SettingsActivity.java index d6616b7..5477e72 100644 --- a/app/src/main/java/com/cg/lrceditor/SettingsActivity.java +++ b/app/src/main/java/com/cg/lrceditor/SettingsActivity.java @@ -29,6 +29,7 @@ public class SettingsActivity extends AppCompatActivity { private TextView readLocation; private TextView timestampStep; private Switch threeDigitMillisecondsSwitch; + private Switch lyricLeadingSpaceSwitch; private RadioButton light, dark, darker; @@ -78,6 +79,14 @@ protected void onCreate(Bundle savedInstanceState) { editor.apply(); }); + lyricLeadingSpaceSwitch = findViewById(R.id.lyric_leading_space_switch); + lyricLeadingSpaceSwitch.setChecked(preferences.getBoolean(Constants.LYRIC_LEADING_SPACE_PREFERENCE, false)); + lyricLeadingSpaceSwitch.setOnCheckedChangeListener((compoundButton, checked) -> { + SharedPreferences.Editor editor = preferences.edit(); + editor.putBoolean(Constants.LYRIC_LEADING_SPACE_PREFERENCE, checked); + editor.apply(); + }); + RadioGroup themeGroup = findViewById(R.id.theme_group); light = findViewById(R.id.radioButtonLight); dark = findViewById(R.id.radioButtonDark); @@ -212,7 +221,7 @@ public void adjustTimestampStep(View v) { public void showTimestampStepHelp(View view) { new AlertDialog.Builder(this) .setMessage(R.string.timestamp_step_help) - .setNeutralButton(getString(R.string.ok), null) + .setNegativeButton(getString(R.string.ok), null) .create() .show(); } @@ -224,7 +233,19 @@ public void toggleThreeDigitMillisecondSwitch(View view) { public void showThreeDigitMillisecondsHelp(View view) { new AlertDialog.Builder(this) .setMessage(R.string.three_digit_milliseconds_help) - .setNeutralButton(getString(R.string.ok), null) + .setNegativeButton(getString(R.string.ok), null) + .create() + .show(); + } + + public void toggleLyricLeadingSpaceSwitch(View view) { + lyricLeadingSpaceSwitch.toggle(); + } + + public void showLyricLeadingSpaceHelp(View view) { + new AlertDialog.Builder(this) + .setMessage(R.string.lyric_leading_space_help) + .setNegativeButton(getString(R.string.ok), null) .create() .show(); } diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index 4ae584a..1413710 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -178,6 +178,39 @@ + + + + + + +