Fix path to ffmpeg and ffprobe.
Added the ability to select the path to ffmpeg and ffprobe.
This commit is contained in:
		@@ -11,11 +11,19 @@ import (
 | 
				
			|||||||
type ServiceContract interface {
 | 
					type ServiceContract interface {
 | 
				
			||||||
	RunConvert(setting ConvertSetting) error
 | 
						RunConvert(setting ConvertSetting) error
 | 
				
			||||||
	GetTotalDuration(file *File) (float64, error)
 | 
						GetTotalDuration(file *File) (float64, error)
 | 
				
			||||||
 | 
						GetFFmpegVesrion() (string, error)
 | 
				
			||||||
 | 
						GetFFprobeVersion() (string, error)
 | 
				
			||||||
 | 
						ChangeFFmpegPath(path string) (bool, error)
 | 
				
			||||||
 | 
						ChangeFFprobePath(path string) (bool, error)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type FFPathUtilities struct {
 | 
				
			||||||
 | 
						FFmpeg  string
 | 
				
			||||||
 | 
						FFprobe string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Service struct {
 | 
					type Service struct {
 | 
				
			||||||
	pathFFmpeg  string
 | 
						ffPathUtilities *FFPathUtilities
 | 
				
			||||||
	pathFFprobe string
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type File struct {
 | 
					type File struct {
 | 
				
			||||||
@@ -33,10 +41,9 @@ type ConvertData struct {
 | 
				
			|||||||
	totalDuration float64
 | 
						totalDuration float64
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewService(pathFFmpeg string, pathFFprobe string) *Service {
 | 
					func NewService(ffPathUtilities FFPathUtilities) *Service {
 | 
				
			||||||
	return &Service{
 | 
						return &Service{
 | 
				
			||||||
		pathFFmpeg:  pathFFmpeg,
 | 
							ffPathUtilities: &ffPathUtilities,
 | 
				
			||||||
		pathFFprobe: pathFFprobe,
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -48,7 +55,7 @@ func (s Service) RunConvert(setting ConvertSetting) error {
 | 
				
			|||||||
	//args := "-n -i " + setting.VideoFileInput.Path + " -c:v libx264 -progress unix://" + setting.SocketPath + " output-file.mp4"
 | 
						//args := "-n -i " + setting.VideoFileInput.Path + " -c:v libx264 -progress unix://" + setting.SocketPath + " output-file.mp4"
 | 
				
			||||||
	//args := "-y -i " + setting.VideoFileInput.Path + " -c:v libx264 -progress unix://" + setting.SocketPath + " output-file.mp4"
 | 
						//args := "-y -i " + setting.VideoFileInput.Path + " -c:v libx264 -progress unix://" + setting.SocketPath + " output-file.mp4"
 | 
				
			||||||
	args := []string{"-y", "-i", setting.VideoFileInput.Path, "-c:v", "libx264", "-progress", "unix://" + setting.SocketPath, "output-file.mp4"}
 | 
						args := []string{"-y", "-i", setting.VideoFileInput.Path, "-c:v", "libx264", "-progress", "unix://" + setting.SocketPath, "output-file.mp4"}
 | 
				
			||||||
	cmd := exec.Command(s.pathFFmpeg, args...)
 | 
						cmd := exec.Command(s.ffPathUtilities.FFmpeg, args...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	out, err := cmd.CombinedOutput()
 | 
						out, err := cmd.CombinedOutput()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -64,7 +71,7 @@ func (s Service) RunConvert(setting ConvertSetting) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (s Service) GetTotalDuration(file *File) (duration float64, err error) {
 | 
					func (s Service) GetTotalDuration(file *File) (duration float64, err error) {
 | 
				
			||||||
	args := []string{"-v", "error", "-select_streams", "v:0", "-count_packets", "-show_entries", "stream=nb_read_packets", "-of", "csv=p=0", file.Path}
 | 
						args := []string{"-v", "error", "-select_streams", "v:0", "-count_packets", "-show_entries", "stream=nb_read_packets", "-of", "csv=p=0", file.Path}
 | 
				
			||||||
	cmd := exec.Command(s.pathFFprobe, args...)
 | 
						cmd := exec.Command(s.ffPathUtilities.FFprobe, args...)
 | 
				
			||||||
	out, err := cmd.CombinedOutput()
 | 
						out, err := cmd.CombinedOutput()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		errString := strings.TrimSpace(string(out))
 | 
							errString := strings.TrimSpace(string(out))
 | 
				
			||||||
@@ -75,3 +82,49 @@ func (s Service) GetTotalDuration(file *File) (duration float64, err error) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	return strconv.ParseFloat(strings.TrimSpace(string(out)), 64)
 | 
						return strconv.ParseFloat(strings.TrimSpace(string(out)), 64)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s Service) GetFFmpegVesrion() (string, error) {
 | 
				
			||||||
 | 
						cmd := exec.Command(s.ffPathUtilities.FFmpeg, "-version")
 | 
				
			||||||
 | 
						out, err := cmd.CombinedOutput()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return "", err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						text := regexp.MustCompile("\r?\n").Split(strings.TrimSpace(string(out)), -1)
 | 
				
			||||||
 | 
						return text[0], nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s Service) GetFFprobeVersion() (string, error) {
 | 
				
			||||||
 | 
						cmd := exec.Command(s.ffPathUtilities.FFprobe, "-version")
 | 
				
			||||||
 | 
						out, err := cmd.CombinedOutput()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return "", err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						text := regexp.MustCompile("\r?\n").Split(strings.TrimSpace(string(out)), -1)
 | 
				
			||||||
 | 
						return text[0], nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s Service) ChangeFFmpegPath(path string) (bool, error) {
 | 
				
			||||||
 | 
						cmd := exec.Command(path, "-version")
 | 
				
			||||||
 | 
						out, err := cmd.CombinedOutput()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return false, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if strings.Contains(strings.TrimSpace(string(out)), "ffmpeg") == false {
 | 
				
			||||||
 | 
							return false, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						s.ffPathUtilities.FFmpeg = path
 | 
				
			||||||
 | 
						return true, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s Service) ChangeFFprobePath(path string) (bool, error) {
 | 
				
			||||||
 | 
						cmd := exec.Command(path, "-version")
 | 
				
			||||||
 | 
						out, err := cmd.CombinedOutput()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return false, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if strings.Contains(strings.TrimSpace(string(out)), "ffprobe") == false {
 | 
				
			||||||
 | 
							return false, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						s.ffPathUtilities.FFprobe = path
 | 
				
			||||||
 | 
						return true, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								src/data/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								src/data/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					*
 | 
				
			||||||
 | 
					!.gitignore
 | 
				
			||||||
@@ -17,7 +17,10 @@ require (
 | 
				
			|||||||
	github.com/go-text/typesetting v0.0.0-20230616162802-9c17dd34aa4a // indirect
 | 
						github.com/go-text/typesetting v0.0.0-20230616162802-9c17dd34aa4a // indirect
 | 
				
			||||||
	github.com/godbus/dbus/v5 v5.1.0 // indirect
 | 
						github.com/godbus/dbus/v5 v5.1.0 // indirect
 | 
				
			||||||
	github.com/gopherjs/gopherjs v1.17.2 // indirect
 | 
						github.com/gopherjs/gopherjs v1.17.2 // indirect
 | 
				
			||||||
 | 
						github.com/jinzhu/inflection v1.0.0 // indirect
 | 
				
			||||||
 | 
						github.com/jinzhu/now v1.1.5 // indirect
 | 
				
			||||||
	github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e // indirect
 | 
						github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e // indirect
 | 
				
			||||||
 | 
						github.com/mattn/go-sqlite3 v1.14.19 // indirect
 | 
				
			||||||
	github.com/pmezard/go-difflib v1.0.0 // indirect
 | 
						github.com/pmezard/go-difflib v1.0.0 // indirect
 | 
				
			||||||
	github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect
 | 
						github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect
 | 
				
			||||||
	github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect
 | 
						github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect
 | 
				
			||||||
@@ -30,5 +33,7 @@ require (
 | 
				
			|||||||
	golang.org/x/sys v0.13.0 // indirect
 | 
						golang.org/x/sys v0.13.0 // indirect
 | 
				
			||||||
	golang.org/x/text v0.13.0 // indirect
 | 
						golang.org/x/text v0.13.0 // indirect
 | 
				
			||||||
	gopkg.in/yaml.v3 v3.0.1 // indirect
 | 
						gopkg.in/yaml.v3 v3.0.1 // indirect
 | 
				
			||||||
 | 
						gorm.io/driver/sqlite v1.5.4 // indirect
 | 
				
			||||||
 | 
						gorm.io/gorm v1.25.5 // indirect
 | 
				
			||||||
	honnef.co/go/js/dom v0.0.0-20210725211120-f030747120f2 // indirect
 | 
						honnef.co/go/js/dom v0.0.0-20210725211120-f030747120f2 // indirect
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										12
									
								
								src/go.sum
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/go.sum
									
									
									
									
									
								
							@@ -191,6 +191,10 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J
 | 
				
			|||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 | 
					github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 | 
				
			||||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 | 
					github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 | 
				
			||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
 | 
					github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
 | 
				
			||||||
 | 
					github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
 | 
				
			||||||
 | 
					github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
 | 
				
			||||||
 | 
					github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
 | 
				
			||||||
 | 
					github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
 | 
				
			||||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 | 
					github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 | 
				
			||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
 | 
					github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
 | 
				
			||||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
 | 
					github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
 | 
				
			||||||
@@ -206,6 +210,8 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 | 
				
			|||||||
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
 | 
					github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
 | 
				
			||||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
 | 
					github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
 | 
				
			||||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
 | 
					github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
 | 
				
			||||||
 | 
					github.com/mattn/go-sqlite3 v1.14.19 h1:fhGleo2h1p8tVChob4I9HpmVFIAkKGpiukdrgQbWfGI=
 | 
				
			||||||
 | 
					github.com/mattn/go-sqlite3 v1.14.19/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
 | 
				
			||||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
 | 
					github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
 | 
				
			||||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
 | 
					github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
 | 
				
			||||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
 | 
					github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
 | 
				
			||||||
@@ -647,6 +653,12 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
 | 
				
			|||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 | 
					gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 | 
				
			||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 | 
					gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 | 
				
			||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 | 
					gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 | 
				
			||||||
 | 
					gorm.io/driver/sqlite v1.5.4 h1:IqXwXi8M/ZlPzH/947tn5uik3aYQslP9BVveoax0nV0=
 | 
				
			||||||
 | 
					gorm.io/driver/sqlite v1.5.4/go.mod h1:qxAuCol+2r6PannQDpOP1FP6ag3mKi4esLnB/jHed+4=
 | 
				
			||||||
 | 
					gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55 h1:sC1Xj4TYrLqg1n3AN10w871An7wJM0gzgcm8jkIkECQ=
 | 
				
			||||||
 | 
					gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
 | 
				
			||||||
 | 
					gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls=
 | 
				
			||||||
 | 
					gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
 | 
				
			||||||
honnef.co/go/js/dom v0.0.0-20210725211120-f030747120f2 h1:oomkgU6VaQDsV6qZby2uz1Lap0eXmku8+2em3A/l700=
 | 
					honnef.co/go/js/dom v0.0.0-20210725211120-f030747120f2 h1:oomkgU6VaQDsV6qZby2uz1Lap0eXmku8+2em3A/l700=
 | 
				
			||||||
honnef.co/go/js/dom v0.0.0-20210725211120-f030747120f2/go.mod h1:sUMDUKNB2ZcVjt92UnLy3cdGs+wDAcrPdV3JP6sVgA4=
 | 
					honnef.co/go/js/dom v0.0.0-20210725211120-f030747120f2/go.mod h1:sUMDUKNB2ZcVjt92UnLy3cdGs+wDAcrPdV3JP6sVgA4=
 | 
				
			||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 | 
					honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,9 @@
 | 
				
			|||||||
package handler
 | 
					package handler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
	"ffmpegGui/convertor"
 | 
						"ffmpegGui/convertor"
 | 
				
			||||||
	myError "ffmpegGui/error"
 | 
						"ffmpegGui/setting"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"fyne.io/fyne/v2/widget"
 | 
						"fyne.io/fyne/v2/widget"
 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
@@ -11,31 +12,39 @@ import (
 | 
				
			|||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"path"
 | 
						"path"
 | 
				
			||||||
	"regexp"
 | 
						"regexp"
 | 
				
			||||||
 | 
						"runtime"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ConvertorHandler struct {
 | 
					type ConvertorHandler struct {
 | 
				
			||||||
	convertorService convertor.ServiceContract
 | 
						convertorService  convertor.ServiceContract
 | 
				
			||||||
	convertorView    convertor.ViewContract
 | 
						convertorView     convertor.ViewContract
 | 
				
			||||||
	errorView        myError.ViewContract
 | 
						settingView       setting.ViewContract
 | 
				
			||||||
 | 
						settingRepository setting.RepositoryContract
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewConvertorHandler(
 | 
					func NewConvertorHandler(
 | 
				
			||||||
	convertorService convertor.ServiceContract,
 | 
						convertorService convertor.ServiceContract,
 | 
				
			||||||
	convertorView convertor.ViewContract,
 | 
						convertorView convertor.ViewContract,
 | 
				
			||||||
	errorView myError.ViewContract,
 | 
						settingView setting.ViewContract,
 | 
				
			||||||
 | 
						settingRepository setting.RepositoryContract,
 | 
				
			||||||
) *ConvertorHandler {
 | 
					) *ConvertorHandler {
 | 
				
			||||||
	return &ConvertorHandler{
 | 
						return &ConvertorHandler{
 | 
				
			||||||
		convertorService,
 | 
							convertorService,
 | 
				
			||||||
		convertorView,
 | 
							convertorView,
 | 
				
			||||||
		errorView,
 | 
							settingView,
 | 
				
			||||||
 | 
							settingRepository,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (h ConvertorHandler) GetConvertor() {
 | 
					func (h ConvertorHandler) GetConvertor() {
 | 
				
			||||||
	h.convertorView.Main(h.runConvert, h.getSockPath)
 | 
						if h.checkingFFPathUtilities() == true {
 | 
				
			||||||
 | 
							h.convertorView.Main(h.runConvert, h.getSockPath)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						h.settingView.SelectFFPath(h.saveSettingFFPath)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (h ConvertorHandler) getSockPath(file *convertor.File, progressbar *widget.ProgressBar) (string, error) {
 | 
					func (h ConvertorHandler) getSockPath(file *convertor.File, progressbar *widget.ProgressBar) (string, error) {
 | 
				
			||||||
@@ -104,3 +113,68 @@ func (h ConvertorHandler) runConvert(setting convertor.HandleConvertSetting) err
 | 
				
			|||||||
func (h ConvertorHandler) getTotalDuration(file *convertor.File) (float64, error) {
 | 
					func (h ConvertorHandler) getTotalDuration(file *convertor.File) (float64, error) {
 | 
				
			||||||
	return h.convertorService.GetTotalDuration(file)
 | 
						return h.convertorService.GetTotalDuration(file)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h ConvertorHandler) checkingFFPathUtilities() bool {
 | 
				
			||||||
 | 
						if h.checkingFFPath() == true {
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var pathsToFF []convertor.FFPathUtilities
 | 
				
			||||||
 | 
						if runtime.GOOS == "windows" {
 | 
				
			||||||
 | 
							pathsToFF = []convertor.FFPathUtilities{{"ffmpeg/bin/ffmpeg.exe", "ffmpeg/bin/ffprobe.exe"}}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							pathsToFF = []convertor.FFPathUtilities{{"ffmpeg/bin/ffmpeg", "ffmpeg/bin/ffprobe"}, {"ffmpeg", "ffprobe"}}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, item := range pathsToFF {
 | 
				
			||||||
 | 
							ffmpegChecking, _ := h.convertorService.ChangeFFmpegPath(item.FFmpeg)
 | 
				
			||||||
 | 
							if ffmpegChecking == false {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							ffprobeChecking, _ := h.convertorService.ChangeFFprobePath(item.FFprobe)
 | 
				
			||||||
 | 
							if ffprobeChecking == false {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							ffmpegEntity := setting.Setting{Code: "ffmpeg", Value: item.FFmpeg}
 | 
				
			||||||
 | 
							h.settingRepository.Create(ffmpegEntity)
 | 
				
			||||||
 | 
							ffprobeEntity := setting.Setting{Code: "ffprobe", Value: item.FFprobe}
 | 
				
			||||||
 | 
							h.settingRepository.Create(ffprobeEntity)
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h ConvertorHandler) saveSettingFFPath(ffmpegPath string, ffprobePath string) error {
 | 
				
			||||||
 | 
						ffmpegChecking, _ := h.convertorService.ChangeFFmpegPath(ffmpegPath)
 | 
				
			||||||
 | 
						if ffmpegChecking == false {
 | 
				
			||||||
 | 
							return errors.New("Это не FFmpeg")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ffprobeChecking, _ := h.convertorService.ChangeFFprobePath(ffprobePath)
 | 
				
			||||||
 | 
						if ffprobeChecking == false {
 | 
				
			||||||
 | 
							return errors.New("Это не FFprobe")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ffmpegEntity := setting.Setting{Code: "ffmpeg", Value: ffmpegPath}
 | 
				
			||||||
 | 
						h.settingRepository.Create(ffmpegEntity)
 | 
				
			||||||
 | 
						ffprobeEntity := setting.Setting{Code: "ffprobe", Value: ffprobePath}
 | 
				
			||||||
 | 
						h.settingRepository.Create(ffprobeEntity)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						h.GetConvertor()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h ConvertorHandler) checkingFFPath() bool {
 | 
				
			||||||
 | 
						_, err := h.convertorService.GetFFmpegVesrion()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err = h.convertorService.GetFFprobeVersion()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										67
									
								
								src/main.go
									
									
									
									
									
								
							
							
						
						
									
										67
									
								
								src/main.go
									
									
									
									
									
								
							@@ -1,11 +1,18 @@
 | 
				
			|||||||
package main
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
	"ffmpegGui/convertor"
 | 
						"ffmpegGui/convertor"
 | 
				
			||||||
	myError "ffmpegGui/error"
 | 
						myError "ffmpegGui/error"
 | 
				
			||||||
	"ffmpegGui/handler"
 | 
						"ffmpegGui/handler"
 | 
				
			||||||
 | 
						"ffmpegGui/migration"
 | 
				
			||||||
 | 
						"ffmpegGui/setting"
 | 
				
			||||||
	"fyne.io/fyne/v2"
 | 
						"fyne.io/fyne/v2"
 | 
				
			||||||
	"fyne.io/fyne/v2/app"
 | 
						"fyne.io/fyne/v2/app"
 | 
				
			||||||
 | 
						_ "github.com/mattn/go-sqlite3"
 | 
				
			||||||
 | 
						"gorm.io/driver/sqlite"
 | 
				
			||||||
 | 
						"gorm.io/gorm"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const appVersion string = "0.1.0"
 | 
					const appVersion string = "0.1.0"
 | 
				
			||||||
@@ -17,14 +24,66 @@ func main() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	errorView := myError.NewView(w)
 | 
						errorView := myError.NewView(w)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pathFFmpeg := "ffmpeg"
 | 
						if canCreateFile("data/database") != true {
 | 
				
			||||||
	pathFFprobe := "ffprobe"
 | 
							errorView.PanicError(errors.New("Не смогли создать файл 'database' в папке 'data'"))
 | 
				
			||||||
 | 
							w.ShowAndRun()
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						db, err := gorm.Open(sqlite.Open("data/database"), &gorm.Config{})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							errorView.PanicError(err)
 | 
				
			||||||
 | 
							w.ShowAndRun()
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						defer appClose(db)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = migration.Run(db)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							errorView.PanicError(err)
 | 
				
			||||||
 | 
							w.ShowAndRun()
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						settingRepository := setting.NewRepository(db)
 | 
				
			||||||
 | 
						pathFFmpeg, err := settingRepository.GetValue("ffmpeg")
 | 
				
			||||||
 | 
						if err != nil && errors.Is(err, gorm.ErrRecordNotFound) == false {
 | 
				
			||||||
 | 
							errorView.PanicError(err)
 | 
				
			||||||
 | 
							w.ShowAndRun()
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						pathFFprobe, err := settingRepository.GetValue("ffprobe")
 | 
				
			||||||
 | 
						if err != nil && errors.Is(err, gorm.ErrRecordNotFound) == false {
 | 
				
			||||||
 | 
							errorView.PanicError(err)
 | 
				
			||||||
 | 
							w.ShowAndRun()
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ffPathUtilities := convertor.FFPathUtilities{FFmpeg: pathFFmpeg, FFprobe: pathFFprobe}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	convertorView := convertor.NewView(w)
 | 
						convertorView := convertor.NewView(w)
 | 
				
			||||||
	convertorService := convertor.NewService(pathFFmpeg, pathFFprobe)
 | 
						settingView := setting.NewView(w)
 | 
				
			||||||
	mainHandler := handler.NewConvertorHandler(convertorService, convertorView, errorView)
 | 
						convertorService := convertor.NewService(ffPathUtilities)
 | 
				
			||||||
 | 
						mainHandler := handler.NewConvertorHandler(convertorService, convertorView, settingView, settingRepository)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mainHandler.GetConvertor()
 | 
						mainHandler.GetConvertor()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	w.ShowAndRun()
 | 
						w.ShowAndRun()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func appClose(db *gorm.DB) {
 | 
				
			||||||
 | 
						sqlDB, err := db.DB()
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							_ = sqlDB.Close()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func canCreateFile(path string) bool {
 | 
				
			||||||
 | 
						file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0666)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_ = file.Close()
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										15
									
								
								src/migration/migration.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/migration/migration.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					package migration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"ffmpegGui/setting"
 | 
				
			||||||
 | 
						"gorm.io/gorm"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func Run(db *gorm.DB) error {
 | 
				
			||||||
 | 
						err := db.AutoMigrate(&setting.Setting{})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										7
									
								
								src/setting/entity.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/setting/entity.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					package setting
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Setting struct {
 | 
				
			||||||
 | 
						ID    uint   `gorm:"primary_key"`
 | 
				
			||||||
 | 
						Code  string `gorm:"type:varchar(100);uniqueIndex;not null"`
 | 
				
			||||||
 | 
						Value string `gorm:"type:text"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										35
									
								
								src/setting/repository.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/setting/repository.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
				
			|||||||
 | 
					package setting
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"gorm.io/gorm"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type RepositoryContract interface {
 | 
				
			||||||
 | 
						Create(setting Setting) (Setting, error)
 | 
				
			||||||
 | 
						GetValue(code string) (value string, err error)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Repository struct {
 | 
				
			||||||
 | 
						db *gorm.DB
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewRepository(db *gorm.DB) *Repository {
 | 
				
			||||||
 | 
						return &Repository{db}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r Repository) GetValue(code string) (value string, err error) {
 | 
				
			||||||
 | 
						var setting Setting
 | 
				
			||||||
 | 
						err = r.db.Where("code = ?", code).First(&setting).Error
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return "", err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return setting.Value, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r Repository) Create(setting Setting) (Setting, error) {
 | 
				
			||||||
 | 
						err := r.db.Create(&setting).Error
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return setting, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return setting, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										98
									
								
								src/setting/view.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								src/setting/view.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,98 @@
 | 
				
			|||||||
 | 
					package setting
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fyne.io/fyne/v2"
 | 
				
			||||||
 | 
						"fyne.io/fyne/v2/canvas"
 | 
				
			||||||
 | 
						"fyne.io/fyne/v2/container"
 | 
				
			||||||
 | 
						"fyne.io/fyne/v2/dialog"
 | 
				
			||||||
 | 
						"fyne.io/fyne/v2/widget"
 | 
				
			||||||
 | 
						"image/color"
 | 
				
			||||||
 | 
						"net/url"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ViewContract interface {
 | 
				
			||||||
 | 
						SelectFFPath(func(ffmpegPath string, ffprobePath string) error)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type View struct {
 | 
				
			||||||
 | 
						w fyne.Window
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewView(w fyne.Window) *View {
 | 
				
			||||||
 | 
						return &View{w}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (v View) SelectFFPath(save func(ffmpegPath string, ffprobePath string) error) {
 | 
				
			||||||
 | 
						errorMessage := canvas.NewText("", color.RGBA{255, 0, 0, 255})
 | 
				
			||||||
 | 
						errorMessage.TextSize = 16
 | 
				
			||||||
 | 
						errorMessage.TextStyle = fyne.TextStyle{Bold: true}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ffmpegPath, buttonFFmpeg, buttonFFmpegMessage := v.getButtonSelectFile()
 | 
				
			||||||
 | 
						ffprobePath, buttonFFprobe, buttonFFprobeMessage := v.getButtonSelectFile()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						link := widget.NewHyperlink("https://ffmpeg.org/download.html", &url.URL{
 | 
				
			||||||
 | 
							Scheme: "https",
 | 
				
			||||||
 | 
							Host:   "ffmpeg.org",
 | 
				
			||||||
 | 
							Path:   "download.html",
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						form := &widget.Form{
 | 
				
			||||||
 | 
							Items: []*widget.FormItem{
 | 
				
			||||||
 | 
								{Text: "Скачать можно от сюда", Widget: link},
 | 
				
			||||||
 | 
								{Text: "Путь к ffmpeg:", Widget: buttonFFmpeg},
 | 
				
			||||||
 | 
								{Widget: buttonFFmpegMessage},
 | 
				
			||||||
 | 
								{Text: "Путь к ffprobe:", Widget: buttonFFprobe},
 | 
				
			||||||
 | 
								{Widget: buttonFFprobeMessage},
 | 
				
			||||||
 | 
								{Widget: errorMessage},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							SubmitText: "Сохранить",
 | 
				
			||||||
 | 
							OnSubmit: func() {
 | 
				
			||||||
 | 
								err := save(string(*ffmpegPath), string(*ffprobePath))
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									errorMessage.Text = err.Error()
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						v.w.SetContent(widget.NewCard("Укажите путь к FFmpeg и к FFprobe", "", container.NewVBox(form)))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (v View) getButtonSelectFile() (filePath *string, button *widget.Button, buttonMessage *canvas.Text) {
 | 
				
			||||||
 | 
						path := ""
 | 
				
			||||||
 | 
						filePath = &path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buttonMessage = canvas.NewText("", color.RGBA{255, 0, 0, 255})
 | 
				
			||||||
 | 
						buttonMessage.TextSize = 16
 | 
				
			||||||
 | 
						buttonMessage.TextStyle = fyne.TextStyle{Bold: true}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						button = widget.NewButton("выбрать", func() {
 | 
				
			||||||
 | 
							fileDialog := dialog.NewFileOpen(
 | 
				
			||||||
 | 
								func(r fyne.URIReadCloser, err error) {
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										buttonMessage.Text = err.Error()
 | 
				
			||||||
 | 
										setStringErrorStyle(buttonMessage)
 | 
				
			||||||
 | 
										return
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if r == nil {
 | 
				
			||||||
 | 
										return
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									path = r.URI().Path()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									buttonMessage.Text = r.URI().Path()
 | 
				
			||||||
 | 
									setStringSuccessStyle(buttonMessage)
 | 
				
			||||||
 | 
								}, v.w)
 | 
				
			||||||
 | 
							fileDialog.Show()
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func setStringErrorStyle(text *canvas.Text) {
 | 
				
			||||||
 | 
						text.Color = color.RGBA{255, 0, 0, 255}
 | 
				
			||||||
 | 
						text.Refresh()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func setStringSuccessStyle(text *canvas.Text) {
 | 
				
			||||||
 | 
						text.Color = color.RGBA{49, 127, 114, 255}
 | 
				
			||||||
 | 
						text.Refresh()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user