onStart
or onCreate
first will be triggered in android activity?In the Android Activity lifecycle, onCreate()
is triggered before onStart()
. Here’s a brief overview of the sequence of method calls when an Activity is created:
onCreate()
: This method is called when the activity is first created. It is where you typically perform one-time initialization such as setting up the user interface, binding data to lists, or initializing variables.
onStart()
: This method is called after onCreate()
(if the activity is being started for the first time) or when the activity is being brought back to the foreground from a stopped state. It is where the activity becomes visible to the user, but it may not yet be in the foreground and interactive.
So, onCreate()
is always triggered before onStart()
in the Android Activity lifecycle.
Here’s the basic lifecycle of an Android Activity:
onCreate(): This method is called when the activity is first created. Here, you typically perform initialization of the activity, such as setting up the user interface with setContentView()
and initializing variables.
onStart(): This method is called when the activity becomes visible to the user. It prepares the activity to enter the foreground and become interactive.
onResume(): This method is called when the activity is about to start interacting with the user. It signals that the activity is now in the foreground and ready to receive user input.
onPause(): This method is called when the activity is going into the background but is still partially visible to the user. It indicates that the activity is no longer in the foreground and may be paused or stopped.
onStop(): This method is called when the activity is no longer visible to the user. It typically happens when the activity is being covered by another activity or when the user navigates away from it.
onDestroy(): This method is called when the activity is being destroyed. It is the final callback that the activity receives before it is removed from memory. Here, you release any resources or unregister any listeners that were associated with the activity.
Additionally, there are two other methods that are important for handling configuration changes:
onRestart(): This method is called when the activity is being restarted after being stopped. It is called after onStop()
and before onStart()
.
onSaveInstanceState() and onRestoreInstanceState(): These methods are called when the activity is being temporarily destroyed and recreated due to a configuration change (such as screen rotation). They allow you to save and restore the state of your activity’s UI and data.
Understanding these lifecycle methods is crucial for properly managing the state and behavior of your Android activities.
here’s a graphical representation of the Android Activity lifecycle:
+-------------------+ | | | onCreate() | | | +---------+---------+ | v +-------------------+ | | | onStart() | | | +---------+---------+ | v +-------------------+ | | | onResume() | | | +---------+---------+ | v+-------------------------+| || User interacts with the || Activity || |+------------+------------+ | v +-------------------+ | | | onPause() | | | +---------+---------+ | v +-------------------+ | | | onStop() | | | +---------+---------+ | v +-------------------+ | | | onDestroy() | | | +-------------------+
Yes, you can certainly extend a superclass that extends AppCompatActivity
in your Android application. In fact, it’s a common practice to create a custom base activity that extends AppCompatActivity
and then have your other activities in the application extend this custom base activity.
For example, you might create a custom base activity like this:
java
import androidx.appcompat.app.AppCompatActivity;public class MyBaseActivity extends AppCompatActivity { // Common functionality or configurations can be implemented here}
And then your other activities can extend this base activity:
java
public class MyActivity extends MyBaseActivity { // Your activity-specific code goes here}
This approach allows you to centralize common functionality or configurations in one place, making it easier to maintain and manage your activities.
]]>requires:
[versions]webkit = "1.10.0"okhttp = "4.12.0"[libraries]webkit = { module = "androidx.webkit:webkit", version.ref = "webkit" }okhttp = { module = "com.squareup.okhttp3:okhttp-bom", version.ref = "okhttp" }okhttp-lib = { module = "com.squareup.okhttp3:okhttp" }
implementation libs.webkitimplementation platform(libs.okhttp)implementation libs.okhttp.lib
create WebkitCookieManager.kt
import android.content.Contextimport android.webkit.WebViewimport okhttp3.Cookieimport okhttp3.CookieJarimport okhttp3.HttpUrlimport java.net.CookieHandlerimport java.net.CookiePolicyimport java.net.HttpCookie/** * android webkit webview cookie manager. * [FULL USAGES](https://dimaslanjaka.github.io/2024/03/okhttp-cookie-handling-on-android.html) * * @author Dimas Lanjaka <a href="https://www.webmanajemen.com">https://www.webmanajemen.com</a> */open class WebkitCookieManager : CookieJar { /** * support for below android 10 */ private var webkitCookieManager: android.webkit.CookieManager? = null /** * support for jvm or android 10+ */ private var javaCookieManager: java.net.CookieManager? = null /** * support for webview intercept connection cookie handling */ private var webview: WebView? = null /** * the android context for clearing cookies on non-webview instance */ private var context: Context? = null /** * for non-persistent cookies */ private val cookieStore = mutableMapOf<HttpUrl, List<Cookie>>() /** * construct android cookie manager without webview */ constructor(manager: android.webkit.CookieManager, ctx: Context? = null) { webkitCookieManager = manager setupAndroidCookieManager() this.context = ctx } /** * construct android cookie manager with webview */ constructor(manager: android.webkit.CookieManager, webView: WebView, ctx: Context? = null) { webkitCookieManager = manager setupAndroidCookieManager(webView) this.webview = webView this.context = ctx } /** * construct non-persistent cookie manager */ constructor(ctx: Context? = null) { this.context = ctx } /** * construct java cookie manager */ constructor(manager: java.net.CookieManager, ctx: Context? = null) { manager.setCookiePolicy(CookiePolicy.ACCEPT_ALL) javaCookieManager = manager CookieHandler.setDefault(javaCookieManager) this.context = ctx } /** * make android webkit cookie manager accept third-party cookies */ private fun setupAndroidCookieManager(webView: WebView? = null) { webkitCookieManager?.setAcceptCookie(true); if (webView != null) webkitCookieManager?.setAcceptThirdPartyCookies(webView, true); } /** * save cookies after request finished */ override fun saveFromResponse(url: HttpUrl, cookies: List<Cookie>) { cookies.forEach { cookie -> webkitCookieManager?.setCookie(url.toString(), cookie.toString()) javaCookieManager?.cookieStore?.add(url.toUri(), HttpCookie.parse(cookie.toString())[0]) } cookieStore.put(url, cookies); } /** * load cookies before okhttp execute request {@link okhttp3.OkHttpClient#newCall(request)} */ override fun loadForRequest(url: HttpUrl): List<Cookie> { return if (webkitCookieManager != null) { // get from android webkit cookie manager when (val cookies = webkitCookieManager?.getCookie(url.toString())) { null -> emptyList() else -> cookies.split("; ").mapNotNull { Cookie.parse(url, it) } } } else if (javaCookieManager != null) { // get from java cookie manager when (val cookies = javaCookieManager?.cookieStore?.cookies) { null -> emptyList() else -> cookies.toString().split("; ").mapNotNull { Cookie.parse(url, it) } } } else { // get from non-persisten cookie store val cookies = cookieStore[url] return cookies ?: ArrayList() } } /** * clear all stored cookies everywhere */ fun clearCookies() { // remove non-persistent stored cookies cookieStore.clear() // initialize android webkit cookie manager on null if (webkitCookieManager == null) { webkitCookieManager = android.webkit.CookieManager.getInstance() setupAndroidCookieManager() } // indicator when webview not initialized var standaloneWebview = false // initalize fake webview instance if (webview == null && context != null) { // declare standalone webview webview = WebView(context!!) // treat as standalone webview standaloneWebview = true } // remove all stored cookies from android webkit cookie manager webkitCookieManager?.removeAllCookies(null) webkitCookieManager?.flush() webkitCookieManager?.removeSessionCookies(null); // clear all caches from webview webview?.clearCache(true) webview?.clearHistory() webview?.clearFormData(); webview?.clearSslPreferences(); if (standaloneWebview) { // destroy standalone webview webview?.destroy() webview = null } // initialize java cookie manager if (javaCookieManager == null) { javaCookieManager = java.net.CookieManager(null, CookiePolicy.ACCEPT_ALL) java.net.CookieHandler.setDefault(javaCookieManager) } // remove all stored cookies from java cookie manager javaCookieManager?.cookieStore?.removeAll() }}
my usage within view binding webview + custom webviewclient intercept using okhttp
val clientBuilder = OkHttpClient.Builder()clientBuilder.cookieJar(WebkitCookieManager(CookieManager.getInstance(), binding!!webview, applicationContext))
this work and tested, when i clear cookies the value of cookies on website changed, otherwise all same until expiration date of cookie.
]]>echo "writing github commit history"git log --pretty=format:"%ad%n%h %s%n%b" --date=format:"%Y-%m-%d %H:%M:%S" | while IFS= read -r line; do trimmed_line="${line#"${line%%[![:space:]]*}"}" trimmed_line="${trimmed_line%"${trimmed_line##*[![:space:]]}"}" if [ -n "$trimmed_line" ]; then if [[ "$trimmed_line" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}\ [0-9]{2}:[0-9]{2}:[0-9]{2}$ ]]; then echo -e "**$trimmed_line**\n" elif [ "$first_line" = true ]; then first_line=false else echo -e " $trimmed_line\n" fi fidone > release-repo/changelog-commit.md# Wait for 3 secondssleep 3
the format markdown like
**2024-03-07 18:41:29**- 39d989ee chore: round double value**2024-03-07 18:38:32**- 0586bd98 chore: improve performance
above script also works with multiline commits, looks like below:
**2024-03-07 18:37:53**- 064c3b79 chore: update preparation activity UI improve performance stability
]]>studio.vmoptions
file. This file contains configuration settings for Android Studio, including memory-related settings. Follow these steps:Locate the studio.vmoptions
file:
bin
directory of the Android Studio installation directory. For example, C:\Program Files\Android\Android Studio\bin\studio64.exe.vmoptions
.Contents/bin
directory within the application bundle. For example, /Applications/Android Studio.app/Contents/bin/studio.vmoptions
.bin
directory of the installation. For example, /opt/android-studio/bin/studio64.vmoptions
.Open the studio.vmoptions
file in a text editor: Use a text editor like Notepad (on Windows), TextEdit (on macOS), or any code editor of your choice.
Modify the memory settings: Add or modify the following lines to set the maximum heap size (Xmx) and the initial heap size (Xms). Adjust the values according to your system’s available memory.
-Xms256m-Xmx2048m
Example values are used above (-Xms256m
for the initial heap size and -Xmx2048m
for the maximum heap size). You can increase or decrease these values based on your system’s configuration.
studio.vmoptions
file and restart Android Studio for the changes to take effect.Keep in mind that setting the maximum heap size too high might cause issues if your system doesn’t have enough available memory. Adjust the values based on your system’s specifications to achieve optimal performance.
To add garbage collection options and parallelism while limiting the maximum heap size to 1GB in Android Studio, you can modify the studio.vmoptions
file. Here’s an example configuration:
java
# custom Android Studio VM options# Set the maximum heap size to 1GB-Xmx1g# Set the initial heap size-Xms256m# Enable parallel garbage collection-XX:+UseParallelGC# Enable concurrent garbage collection (for parallel)-XX:+UseConcMarkSweepGC# Set the size of the young generation (you may adjust this based on your needs)-XX:NewSize=512m-XX:MaxNewSize=512m# Enable automatic heap resizing-XX:+UseAdaptiveSizePolicy
In this configuration:
-XX:+UseParallelGC
enables the parallel garbage collector.-XX:+UseConcMarkSweepGC
enables concurrent garbage collection, which works in conjunction with parallel garbage collection.-XX:NewSize
and -XX:MaxNewSize
set the size of the young generation, which is part of the heap where new objects are created. Adjust these values based on your requirements.-XX:+UseAdaptiveSizePolicy
enables automatic heap resizing based on the application’s behavior.Feel free to adjust these settings based on your system’s specifications and the specific needs of your Android Studio projects. Keep in mind that tuning garbage collection settings can be a trial-and-error process, so monitor the performance and adjust as needed. Save the changes, restart Android Studio, and observe the impact on performance.
]]>Screen density refers to the resources used in your Android app and affects how your app runs on different devices with different screen densities.
This is not configured at build time.
To clarify, when you set screen density in the ‘build.gradle’ file, you typically specify different versions of the drawable resource for different screen densities.
For example:
gradle
android { // ... splits { density { enable true exclude "ldpi", "xxxhdpi" compatibleScreens 'small', 'normal', 'large', 'xlarge' } }}
This configuration is more about generating APKs with different drawables for different screen densities and is not directly related to build times.
To improve your Android project build time, you may want to consider other strategies such as:
Caching: Utilize Gradle’s built-in caching mechanisms to avoid redundant work in subsequent builds.
Parallel Builds: Configure Gradle to perform parallel builds, allowing it to build multiple modules concurrently.
Incremental Builds: Enable incremental builds to only rebuild the parts of the project that have changed.
Dependency Analysis: Use tools like the Gradle build scans or build dashboard to analyze dependencies and understand which dependencies are impacting build times.
Profile Your Build: Use tools like the Gradle profiler or Android Studio’s built-in profiler to identify bottlenecks in your build process.
Remember that screen density configurations are important for the runtime behavior of your app on different devices, but they aren’t the primary factor influencing build times.
]]>Here are some suggestions for setting VM options in IntelliJ IDEA with an 8GB RAM machine and an Intel i3 processor:
Heap Memory (Xmx and Xms):
-Xmx
) to a value that is suitable for your system. With 8GB of RAM, you could allocate a significant portion, but not all, of the memory to IntelliJ. For example, you might use -Xmx4g
to allocate 4GB of memory. Adjust this value based on your preferences and the other applications you might be running.-Xms
) to a reasonable value, perhaps half of the maximum heap size. For example, -Xms2g
for 2GB.Example:
-Xms2g -Xmx4g
Permsize and Metaspace:
Example:
-XX:MaxMetaspaceSize=512m
Garbage Collection:
Additional Configuration:
Example:
-XX:MaxPermSize=512m -XX:+UseConcMarkSweepGC
To set these options in IntelliJ IDEA:
Keep in mind to screen your system’s execution whereas utilizing IntelliJ Idea, particularly in the event that you run other memory-intensive applications at the same time. Alter the JVM alternatives based on your real needs and accessible assets.
Here my optimal setup for low-end device:
-Xms128m-Xmx1024m-XX:ReservedCodeCacheSize=100m-XX:+IgnoreUnrecognizedVMOptions-XX:MaxPermSize=512m-XX:+UseConcMarkSweepGC-XX:+UseCodeCacheFlushing-XX:+UseCompressedOops--add-opens=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED--add-opens=java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED-javaagent:D:\ja-netfilter-all\ja-netfilter.jar=jetbrains
-Xmx
: Sets the maximum heap size, specifying the maximum amount of memory that the Java Virtual Machine (JVM) can use for the heap. For example, -Xmx2000m
sets the maximum heap size to 2000 megabytes.
-Xms
: Sets the initial heap size, defining the amount of memory reserved for the heap when the JVM starts. For example, -Xms300m
sets the initial heap size to 300 megabytes.
-XX:MaxMetaspaceSize
: Sets the maximum size of the Metaspace, which is the memory area used for class metadata in Java 8 and later versions. For example, -XX:MaxMetaspaceSize=256m
sets the maximum Metaspace size to 256 megabytes.
To use Kotlin BOM, you typically follow these steps:
You need to add the BOM dependency to your build file. If you’re using Gradle, you can add it like this:
implementation platform("org.jetbrains.kotlin:kotlin-bom:1.5.31")
Make sure to replace 1.5.31
with the kotlin version you want to use.
After adding the BOM dependency, you can declare dependencies without specifying their versions. The BOM will manage the versions for you. For example:
implementation "org.jetbrains.kotlin:kotlin-stdlib"implementation "org.jetbrains.kotlin:kotlin-reflect"
You don’t need to specify the version for kotlin-stdlib
and kotlin-reflect
as it will be inherited from the BOM.
After making changes to your build file, sync your project with your build tool (e.g., run ./gradlew
or click “Sync Project with Gradle Files” in Android Studio).
Here’s an example of how your build.gradle (Kotlin DSL) file might look like:
plugins { kotlin("jvm") version "1.5.31"}repositories { mavenCentral()}dependencies { implementation platform("org.jetbrains.kotlin:kotlin-bom:1.5.31") implementation "org.jetbrains.kotlin:kotlin-stdlib" implementation "org.jetbrains.kotlin:kotlin-reflect"}
This way, you only need to update the version of the Kotlin BOM in one place, and it will automatically update the versions of all Kotlin dependencies in your project.
Keep in mind that the syntax might vary slightly depending on your build tool (Gradle, Maven, etc.) and the Kotlin plugin version you are using. Always refer to the official documentation for the most accurate and up-to-date information.
Gradle’s ResolutionStrategy allows you to force all subprojects to use the same Kotlin version.
The following is an example of using the ResolutionStrategy block in the root project’s. Here the implementation of both build.gradle.kts
and build.gradle
file:
Ensure you set the right kotlin version.
For example i will set the kotlin version in variable
build.gradle
file:ext { kotlin_version = '1.5.31'}
// force kotlin same versionconfigurations.configureEach { resolutionStrategy.eachDependency { details -> if (requested.group == "org.jetbrains.kotlin") { useVersion "$kotlin_version" because "To avoid different kotlin version" } }}
build.gradle.kts
file:ext { val kotlinVersion = "1.5.31"}
configure<DependencyResolutionManagement> { resolutionStrategy { eachDependency { details -> if (details.requested.group == "org.jetbrains.kotlin") { details.useVersion("$kotlin_version") } } }}
]]>check your _config.yml
url: https://www.webmanajemen.com/root: /# Home page setting# path: Root path for your blogs index page. (default = '')# per_page: Posts displayed per page. (0 = disable pagination)# order_by: Posts order. (Order by date descending by default)index_generator: path: '/' per_page: 10 order_by: -updated # updated | date | -date | -updated pagination_dir: page
Ensure that you are accessing the correct URL.
Hexo may be configured to generate content under different paths.
For example, if your site is located in a subdirectory, you might need to access http://localhost:4000/subdirectory/
Sometimes, issues can arise from corrupted dependencies.
You can try deleting the node_modules directory and reinstalling dependencies:
rm -rf node_modulesnpm install
]]>CommonJS modules can use the require.main
object to determine whether the module is executed directly or imported. The require.main
object is the main module that started your Node.js application.
// CommonJS// main.jsif (require.main === module) { // This script is being run directly console.log('This script is the main module.');} else { // This script is being imported as a module console.log('This script is being imported as a module.');}
In this example, if you run main.js
directly using the main.js
node, you will see the output This script is the main module. When I import main.js
into another script or module using require('./main')
I get the output This script will be imported as a module.
Note that this approach works with Node.js versions that support ES Module (ESM) syntax.
If you are using CommonJS
syntax, you may want to use the require.main === module
check.
In the ECMAScript Module (ESM), you can use the “import.meta” object to determine whether a module is executed directly or imported. In particular, you can check the import.meta.url
property.
// main.mjsif (import.meta.url === `file://${process.argv[1]}`) { // This module is being run directly console.log('This module is the main module.');} else { // This module is being imported as a module console.log('This module is being imported as a module.');}
or you can using module es-main:
// ESMimport esMain from 'es-main';if (esMain(import.meta)) { console.log('called directly');} else { console.log('required as a module');}
In this example, if you run main.mjs
directly using the main.mjs
node, you will see the output: "This module is the main module.
" If you import main.mjs
into another ESM module using import './main.mjs';
, you will see the output This module will be imported as a module. Note the ESM file extension.
Modules are usually .mjs
. If you want to use CommonJS syntax, you can use the approach described in the previous answer ("require.main === module")
.
WebRTC is often talked about on VPN Websites.
WebRTC is a Technology that allows your Browser to have Video and Voice Communication Abilities.
When you use Google Meet to hold a Video Conference, you’re using WebRTC.
The same is with the Facebook Messenger Video Call.
There are other Applications that make use of WebRTC. For Example, if you’re on Discord.
It enables live Communications in real Time.
WebRTC works by sending Audio/Video Feeds between two Entities.
This means your Browser will share some of your Information with the Website, which will include your IP Address.
And these Channels can bypass the encrypted Tunnel you have Setup.
So basically, a WebRTC Leak can reveal your real IP Address even if you are using a VPN.
To see if your IP is leaked go to IPLEAK.NET.
If you see your real IP on the Website, your IP is being leaked.
If you can see the IP Address of the VPN Server, you’re safe and your browsing is secure.
One Way is by getting a VPN that doesn’t allow these Leaks.
Another Option is to block the WebRTC Requests directly from the Browser.
You can also use browser Extensions if you cannot disable WebRTC.
Keep in Mind that if you disable WebRTC, you won’t be able to enjoy the Functionalities that come with it.
You cannot disable WebRTC in Chrome. The only thing you can do is use Add-ons. A good Chrome Add-on is WebRTC Leak Prevent.
It controls the hidden WebRTC Settings and protects you against the Leaks.
chrome://flags/#disable-webrtc
in your Android Chrome Address Bar. It will open a Settings Pageabout:config
and press EnterAccept the Risk and Continue
media.peerconnection.enabled
Preferences
Show Develop menu in menu bar
Experimental Features
Remove Legacy WebRTC API
Opera doesn’t have a Way to disable WebRTC. You can use third-party Addons like
WebRTC Leak Prevent
just like you did with Chrome.
Keep in mind that these Extensions do not fix the Leak. Instead, they block the Attempts the Websites make to collect IP Addresses.
about:flags
in the Address Bar & press EnterHide my local IP address over WebRTC connections
to activate.]]>Make sure you use a VPN. The VPN should be able to bypass the WebRTC Leak.
With a VPN, you can use a Secure Browsers like LibreWolf that does not keep any of your Details.
In IntelliJ IDEA and Android Studio, you can exclude specific log tags in the Logcat view. Here’s how you can do it:
HardwareCodecCapability AudioCapabilities OpenGLRenderer ViewRoot ForceDarkHelper Looper PlayCore AudioTrack SurfaceUtils cr_ChildProcessConn FA ActivityThread DynamiteModule Perf DynamitePackage EgretLoader cr_LibraryLoader BpBinder chatty FeatureParser MediaCodec ExtendedACodec MapperHal OMXClient VideoCapabilities Gralloc3 MetadataUtil AdrenoGLES chromium DpmTcmClient WebViewFactory cr_CachingUmaRecorder AdrenoUtils cr_media AudioManager cr_SpareChildConn Chrome_InProcGp Choreographer AdInternalSettings Keep-Alive Vary pool-15-thread- WifiMulticast WifiHW MtpService PushClient EGL_emulation OpenGl* InputReader art dalvik Environment DataRouter AlarmManager WindowManager PhoneStatusBar ActivityManager ResourceType PackageManager gralloc Gnss NetRec ResolverController GAv4 AsyncOperation AppOps WificondControl aofp wifi netmgr ctxmgr BestClock FirebaseInstanceId android.os.Debug memtrack netd system_server StrictMode bluetooth NetworkMonitor BroadcastQueue ConnextivityService WakeLock HttpClientWrapper RAWR Tenor BgTask WifiService BluetoothAdapter UpdateStatsService AppIdleHistory Connectivity VelvetNetworkClient WorkerManager ActivityTaskManager UsageStatsService ocess.gservice DropBoxManagerService EventLogChimeraService PContextMetricsRunner MemoryController MultiDex AutofillManager libMEOW
Put below pattern to logcat filter column
-tag~:GeckoConsole|SurfaceComposerClient|BufferQueueConsumer|GeckoSession|GeckoThread|Web\sContent|GeckoEventDispatcher|BLASTBufferQueue|GeckoNetworkManager|linker
Done, now all common anoying tags should not be displayed on logcat logs. Looks like below screenshot, no more annoying tags shown :)
]]>To resolve this issue, you’ll have to be give a type annotation for ‘X’ or adjust your module determination settings.
Here are a few of methods you’ll be able take:
For example I will resolve these error
The inferred type of 'loadSavedCredentialsIfExist' cannot be named without a reference to 'googleapis-common/node_modules/google-auth-library/build/src/auth/googleauth'. This is likely not portable. A type annotation is necessary.ts(2742)
with the problem codes is
import { Auth, google } from 'googleapis';/** * Reads previously authorized credentials from the save file. * * @return */export function loadSavedCredentialsIfExist() { try { const content = fs.readFileSync(TOKEN_PATH).toString(); const credentials = JSON.parse(content); // const uri = 'https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=' + credentials.accestoken; return google.auth.fromJSON(credentials); } catch (err) { return null; }}
Guarantees a New Begin: Expelling any existing establishments and arrangements guarantees simply begin with a clean slate. This will be accommodating on the off chance that you’ve experienced issues or irregularities along with your past Yarn setup.
Settle Dependency Conflicts: A clean introduce makes a difference in settling potential reliance clashes or issues with obsolete bundles. It guarantees merely bring the most recent forms of Yarn and its dependencies.
Dodges Versioning Issues: Over time, you might have different forms of Yarn introduced on your framework. A clean introduce guarantees merely are working with the most recent steady form, diminishing the chance of versioning issues.
Makes strides Framework Soundness: Evacuating any leftovers of past establishments can contribute to a more steady and unsurprising environment. It makes a difference in avoiding unforeseen behavior caused by obsolete or clashing setups.
Improves Security: Remaining up-to-date with the most recent forms of bundle directors is vital for security. A clean introduce guarantees simply have the foremost later form of Yarn, which may incorporate security patches and advancements.
Tackles Establishment Issues: In the event that you’ve experienced troubles amid the establishment of Yarn or have issues related to lost conditions, a clean introduce can offer assistance resolve these issues.
Simplifies Troubleshooting: When looking for offer assistance or investigating issues with Yarn, beginning with a clean establishment gives a steady standard. It makes it simpler for others to help you, as they won’t got to consider potential complications from past configurations.
Advances Best Practices: Intermittently performing clean installs could be a great hone to preserve a solid improvement environment. It guarantees that you’re working with an optimized setup and diminishes the probability of experiencing unforeseen issues.
On Unix-based systems (Linux or macOS):
rm -rf node_modulesrm yarn.lockrm package-lock.jsonyarn cache cleannpm cache clean --force
On Windows (using Command Prompt):
rmdir /s /q node_modulesdel yarn.lockdel package-lock.jsonyarn cache cleannpm cache clean --force
then yarn install
or npm install
again
Provide a type annotation for ‘loadSavedCredentialsIfExist’. For example:
const loadSavedCredentialsIfExist: import('googleapis-common/node_modules/google-auth-library/build/src/auth/googleauth').JSONClient = function () { try { const content = fs.readFileSync(TOKEN_PATH).toString(); const credentials = JSON.parse(content); // const uri = 'https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=' + credentials.accestoken; return google.auth.fromJSON(credentials); } catch (err) { return null; }}
Provide a boundary return type for ‘loadSavedCredentialsIfExist’. For example:
/** * Reads previously authorized credentials from the save file. * * @return */export function loadSavedCredentialsIfExist(): import('googleapis-common/node_modules/google-auth-library/build/src/auth/googleauth').JSONClient { try { const content = fs.readFileSync(TOKEN_PATH).toString(); const credentials = JSON.parse(content); // const uri = 'https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=' + credentials.accestoken; return google.auth.fromJSON(credentials); } catch (err) { return null; }}
]]>by default to list all posts you can using below codes:
const posts = hexo.locals.get('posts').data.map(({ title, keywords, description, raw, tags, categories, path }) => ({ title, keywords, description, raw, path, tags: tags.data.map((tag) => tag.name), categories: categories.data.map((category) => category.name)}));
by default hexo not provide property description
, you have to add it manually to all your Hexo Markdown posts. Or you provide the post excerpt
to assign with missing description
const posts = hexo.locals.get('posts').data.map(({ description, excerpt }) => ({ description: description || excerpt}));
in typescript you should declare custom type
interface PostList { title: string; description: string; keywords: string[]; tags: string[]; categories: string[]; permalink: string;}const posts = hexo.locals .get('posts') .data.map( ({ title, keywords, description, excerpt, raw, tags, categories, path }) => ({ title, // fix non-array keywords keywords: Array.isArray(keywords) ? keywords : [keywords], // fix missing description description: description || excerpt, raw, permalink: path, tags: tags.data.map((tag) => tag.name), categories: categories.data.map((category) => category.name) }) ) as PostList;
]]>pre-commit
allow you to configure and run hooks before each commit.To toggle enable git hooks you can do following:
git config core.hooksPath ./git-hooks
To toggle disable git hooks you can do following:
git config --unset core.hookspath
]]>You can use the Trigger Task on Save extension.
To set it up, add the following to your .vscode/settings.json
:
{ "task.saveBeforeRun":"always", // task name to run on save action "triggerTaskOnSave.selectedTask":"bootRun", // enable plugin "triggerTaskOnSave.on":true, // restart task when running "triggerTaskOnSave.restart":true, // run in background "triggerTaskOnSave.showNotifications":false, // run in background "triggerTaskOnSave.showStatusBarToggle":false, "triggerTaskOnSave.tasks":{ "build":[ // watch file patterns "server/**/*.html", "jvm/**/*.java", "server/**/*.java" ] }}
{ "version": "2.0.0", "tasks": [ { // run in background "isBackground": true, // task name "label": "bootRun", "type": "shell", // command shell to run "command": "gradlew bootRun", "args": [], "group": { "kind": "build", "isDefault": true }, // task description "detail": "run gradle bootRun", "presentation": { // run in background "reveal": "silent", "panel": "shared" }, "problemMatcher": [], "options": { // working directory "cwd": "${workspaceFolder}" }, "runOptions": { "runOn": "default" } } ]}
Open your project in Visual Studio Code.
Press Ctrl + Shift + B
(Windows/Linux) or Cmd + Shift + B
(Mac) to open the “Run Build Task” menu.
Select “Configure Build Task” and then choose the type of task you want to create (e.g., “Create tasks.json file from template”).
Choose the appropriate template based on your project (e.g., “Others”).
Modify the generated “tasks.json” file to include a task that runs on save. For example:
{ "version": "2.0.0", "tasks": [ { "label": "Run On Save", "type": "shell", "command": "your_command_here", "group": { "kind": "build", "isDefault": true }, "presentation": { "reveal": "always", "panel": "new" }, "runOptions": { "runOn": "save" } } ]}
Replace “your_command_here” with the actual command you want to run. Make sure the command is something that can be executed from the command line.
Note: option “runOn”: “save” triggers the execution of the task when the file is saved.
Make sure the task is properly configured for your project and that the necessary tools are installed.
"runOptions": { "runOn": "save"}
Now, when you save a file in your project, the specified task will be executed automatically.
The two tricks above worked when I tested previously. That’s the article about Run task on save using VSCode (Visual Studio Code)
]]>Bootstrap 5 does not come with a built-in theme switcher but you can easily implement one using Use JavaScript and CSS.
Here’s a simple example of how you can create a Bootstrap 5 color theme selector:
<style/>
tag with attribute data-bs-theme="light|dark"
where you will automatically insert the CSS of the selected theme.<button class="btn btn-sm btn-secondary" data-bs-theme-value="dark">Dark</button><button class="btn btn-sm btn-primary" data-bs-theme-value="light">Light</button>
main of this trick is
<div data-bs-theme="light|dark"><!-- your html code here --></div>
and you should add bg-[dark|light]
or text-[light|dark]
on wrapper to get switcher works
<div data-bs-theme="light"><!-- here the indicator --> <div class="container mt-3"> <div class="mb-2"> switcher <button class="btn btn-sm btn-secondary" data-bs-theme-value="dark">Dark</button> <button class="btn btn-sm btn-primary" data-bs-theme-value="light">Light</button> <button class="btn btn-sm btn-danger" type="button" onClick="refreshPage()">Refresh</button> </div> <div class="text-light bg-dark p-4" id="description"> <h1 class="text-center">Boostrap 5.3 Color Theme Switcher</h1> main of this trick is <pre class="m-2"><code><div data-bs-theme="light|dark"><!-- your html code here --></div></code></pre> and you should add <kbd>bg-[dark|light]</kbd> or <kbd>text-[light|dark]</kbd> on wrapper to get switcher works </div> <h2>Override class <kbd>*-light</kbd></h2> <table class="table table-light"> <thead> <tr> <th scope="col">#</th> <th scope="col">First</th> <th scope="col">Last</th> <th scope="col">Handle</th> </tr> </thead> <tbody> <tr> <th scope="row">1</th> <td>Mark</td> <td>Otto</td> <td>@mdo</td> </tr> <tr> <th scope="row">2</th> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> </tr> <tr> <th scope="row">3</th> <td colspan="2">Larry the Bird</td> <td>@twitter</td> </tr> </tbody> </table> <div class="card" style="width: 18rem;"> <img src="https://getbootstrap.com/docs/5.3/assets/brand/bootstrap-social.png" class="card-img-top" alt="..."> <div class="card-body"> <h5 class="card-title">Card title</h5> <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p> <a href="#" class="btn btn-primary">Go somewhere</a> </div> </div> </div></div>
"use strict";/*! * Color mode toggler for Bootstrap's * Copyright 2011-2023 The Bootstrap Authors * Licensed under the Creative Commons Attribution 3.0 Unported License. * Modified by L3n4r0x */(function () { const getPreferredTheme = () => { const storedTheme = localStorage.getItem("theme"); if (storedTheme) { return storedTheme; } return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"; }; function setTheme(theme) { let value = "light"; if ( theme === "auto" && window.matchMedia("(prefers-color-scheme: dark)").matches ) { value = "dark"; } else { value = theme; } // hide button switcher if (value == "dark") { // show light button document .querySelector("[data-bs-theme-value=dark]") .classList.add("d-none"); document .querySelector("[data-bs-theme-value=light]") .classList.remove("d-none"); } else if (value == "light") { document .querySelector("[data-bs-theme-value=light]") .classList.add("d-none"); document .querySelector("[data-bs-theme-value=dark]") .classList.remove("d-none"); } const wrapper = document.querySelectorAll("[data-bs-theme]"); // change value data-bs-theme wrapper.forEach((el) => { el.setAttribute("data-bs-theme", value); }); const isDark = value === "dark"; const elements = Array.from(document.querySelectorAll("[class*=-light]")) .concat(Array.from(document.querySelectorAll("[class*=-white]"))) .concat(Array.from(document.querySelectorAll("[class*=-dark]"))); const regex = /(-(light|white|dark)$)/g; elements.forEach((el) => { const className = el.className.replace( regex, isDark ? "-dark" : "-light" ); el.setAttribute("class", className); }); } // auto switch theme (uncomment) setTheme(getPreferredTheme()); // listen click document.querySelectorAll("[data-bs-theme-value]").forEach(function (toggle) { toggle.addEventListener("click", function () { const theme = toggle.getAttribute("data-bs-theme-value"); localStorage.setItem("theme", theme); setTheme(theme); }); });})();function refreshPage() { const a = "reload", b = "location"; window[b][a]();}
You can customize styles in the JavaScript code to match your desired color theme for light and dark modes.
Adjust background color, text color, and other styles as needed.
Add the LiveReload server as a dependency to your project. If you use Maven, you can include the following dependencies in your pom.xml
file:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional></dependency>
If you’re using Gradle, include the following in your build.gradle file:
dependencies { implementation 'org.springframework.boot:spring-boot-devtools'}
Enable LiveReload in either application.properties
or application.yml
.
Open the src/main/resources/application.properties
or src/main/resources/application.yml
file and add the following property:
spring.devtools.livereload.enabled=truespring.devtools.livereload.livereload=true
spring: devtools: restart: enabled: true livereload: enabled: true
Call the livereload javascript into your html template. For example using thymeleaf
:
<script th:inline="javascript"> (function () { const port = /*[(${@environment.getProperty('server.port')})]*/ '8080'; if (location.port == port && location.hostname == 'localhost') { const script = document.createElement('script'); script.src = 'http://localhost:35729/livereload.js'; script.async = true; document.body.appendChild(script); } })();</script>
Launch your program in the browser.
Now, whenever you make changes to your code or resources, the LiveReload server will detect them and reload the browser to reflect the changes.
Keep in mind that spring-boot-devtools
is only advised for development and should not be used in production. Also, keep in mind that LiveReload may not operate completely in all cases, particularly if you’re utilizing sophisticated frameworks or setups.
21-06-10 15:32:10.363 ERROR [-nio-8080-exec-8] c.e.pay.common.ResponseErrorHandler :50 - Base Exception caughtorg.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-not supported at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:235) at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:147) at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:125) at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:99) at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:832) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:743) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:961) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:895) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:869) at javax.servlet. at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) at javax.servlet. at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528) at org.apache.coyote. at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:687) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.base/java.lang.Thread.run(Thread.java:835)
The following actions can be taken to troubleshoot and fix this problem:
Modify your post data model type, for example ProxyAddModel.java
package web.models;import jakarta.validation.constraints.NotNull;import lombok.AllArgsConstructor;import lombok.Getter;import lombok.NoArgsConstructor;import lombok.Setter;@Getter@Setter@NoArgsConstructor@AllArgsConstructorpublic class ProxyAddModel { @NotNull(message = "Proxies should not be empty") public String proxies;}
Modify your controller method to accept Content-Type: application/x-www-form-urlencoded;
using consumes = { MediaType.APPLICATION_FORM_URLENCODED_VALUE }
, and add jakarta validation @Valid
before Post data model type.
Below here working code:
package web.proxy;import java.util.List;import org.springframework.http.MediaType;import org.springframework.http.ResponseEntity;import org.springframework.security.access.prepost.PreAuthorize;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.ResponseBody;import com.fasterxml.jackson.databind.JsonNode;import jakarta.validation.Valid;import utility.proxy.ProxyModel;import utility.proxy.ProxyUtils;import web.models.AjaxResponse;import web.models.ProxyAddModel;@Controllerpublic class ProxyList { @PostMapping(value = { "/proxy/add" }, consumes = { MediaType.APPLICATION_FORM_URLENCODED_VALUE }) @ResponseBody public ResponseEntity<JsonNode> addReceiver(@Valid ProxyAddModel postBody) { if (postBody != null && postBody.proxies != null) { // process post body ProxyUtils proxyUtils = new ProxyUtils(); proxyUtils.fromLocal(postBody.proxies); } // return "redirect:/proxy?success=add"; return new AjaxResponse(false, "proxies added").toHttpResponse(); }}
If you want redirect user after post body received, you can using below codes:
@PostMapping(value = { "/proxy/add" }, consumes = { MediaType.APPLICATION_FORM_URLENCODED_VALUE })// @ResponseBodypublic String addReceiver(@Valid ProxyAddModel postBody) { if (postBody != null && postBody.proxies != null) { // process post body ProxyUtils proxyUtils = new ProxyUtils(); proxyUtils.fromLocal(postBody.proxies); } // return new AjaxResponse(false, "proxies added").toHttpResponse(); return "redirect:/proxy?success=add";}
now test send form post to your endpoint.
]]>Below is an example of how you can create a dynamic toast component in React using flowbite-react
.
save below codes with filename FlowbiteToast.tsx
in folder src/component
import { Toast } from 'flowbite-react';import React from 'react';import { HiFire } from 'react-icons/hi';interface FlowbiteToastProps { [key: string]: any; /** show toast indicator */ showToast: boolean; /** parent state handler to set `showToast` useful for dismissable toast */ handler: (showToast: boolean) => any;}const FlowbiteToast: React.FC<FlowbiteToastProps> = ({ showToast, handler }) => { // show toast when indicator=true return ( showToast && ( <Toast className="absolute top-5 end-5 z-50 shadow"> <div className="inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-cyan-100 text-cyan-500 dark:bg-cyan-800 dark:text-cyan-200"> <HiFire className="h-5 w-5" /> </div> <div className="ml-3 text-sm font-normal"> <span className="mb-1 text-sm font-semibold text-gray-900 dark:text-white">Update available</span> <div className="mb-2 text-sm font-normal">A new software version is available for download.</div> </div> <Toast.Toggle onDismiss={() => { // hide toast when X button clicked handler(false); }} /> </Toast> ) );};export default FlowbiteToast;
<FlowbiteToast/>
in parent react elementfor example we create Login.tsx
and showing flowbite toast after executing fetch
ajax.
import React from 'react';import FlowbiteToast from './component/FlowbiteToast';export default function Login() { // declare parent toast state const [showToast, setShowToast] = React.useState(false); useEffect(() => { // execute fetch ajax fetch('https://httpbin.org/post', { method: 'POST', headers: { 'Accept': 'application/json, text/plain, */*', 'Content-Type': 'application/json' }, body: JSON.stringify({a: 7, str: 'Some string: &=&'}) }).then(() => { // show toast setShowToast(true); }); }, []); return (<main><FlowbiteToast showToast={showToast} handler={setShowToast} /></main>);}
Now your dynamic flowbite-react toast ready to modify. Here My Own FLowbite React Dynamic Toast
Thanks for reading my article of:
answers for exported variable that uses a private type from an external module:
To fix exported variable using private type from external module, you can consider a few approaches:
just declare the type, for example:
in external lib has code like below:
interface privateProperty { name: string;}export const config = { propName: {} as privateProperty}
in your code
// this config['propName'] contains non-exported type/interfaceimport { config } from 'external-lib';// declare new type from private propertytype Y = config['propName']; // or typeof config['propName']// declare new type that extends Yexport interface X extends Y {}// apply interface X which contains Private Type Nameexport const yourVariable = {} as X;
done. now the problem fixed
result
]]>